home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / cbgi111 / src / ati / ati.c next >
Encoding:
C/C++ Source or Header  |  1990-07-11  |  41.5 KB  |  1,383 lines

  1. /***************************** ATI DRIVER *******************************/
  2. /*    ATI VGA Wonder BGI driver.  This program acts as a BGI driver    */
  3. /*  for the ATI VGA Wonder in the 256 colour modes.  In these modes    */
  4. /*  the memory is mapped as follows.  One pixel per byte, laid out     */
  5. /*  linearly in 64K pages (banks).  Only one bank is accesible at a    */
  6. /*  time.  Up to 8 banks of memory are used for the highest resolution    */
  7. /*  mode.                                */
  8. /*                                    */
  9. /*  640 x 400 mode memory layout:                    */
  10. /*                                    */
  11. /*  A0000:0 -> --------- <========================================\    */
  12. /*          |         |---------                                |    */
  13. /*          |         |         |----------                     |    */
  14. /*          |         |         |          |---------- <==\=====|    */
  15. /*          |         |         |          |          |   |     |    */
  16. /*           ---------|         |          |          |  64K    |    */
  17. /*            Page 0   ---------|          |          |   |   256,000    */
  18. /*               Page 1  ----------|          |   |     |    */
  19. /*                      Page 2  ---------- <==/=====/    */
  20. /*                            Page 3            */
  21. /*                                    */
  22. /*                                    */
  23. /*  640 x 480 mode memory layout:                    */
  24. /*                                    */
  25. /*  A0000:0 -> -------- <=========================================\    */
  26. /*            |        |--------                                  |    */
  27. /*          |        |        |--------                         |    */
  28. /*          |        |        |        |--------                |    */
  29. /*          |        |        |        |        |------- <=\    |    */
  30. /*           --------|        |        |        |       |  |    |    */
  31. /*            Page 0  --------|        |        |       | 64K   |    */
  32. /*                 Page 1  --------|        |       |  | 307,200    */
  33. /*                      Page 2  --------|       |  |    |    */
  34. /*                       Page 3  ------- <=/====/    */
  35. /*                            Page 4        */
  36. /*                                    */
  37. /*  640 x 800 mode memory layout:                    */
  38. /*                                    */
  39. /*  A0000:0 -> -------- <========================================\    */
  40. /*          |        |--------                                 |    */
  41. /*          |        |        |--------                        |    */
  42. /*          |        |        |        | \                     |    */
  43. /*          |        |        |        |  \                    |    */
  44. /*           --------|        |        |   \                   |    */
  45. /*            Page 0  --------|        |    \                  |    */
  46. /*                  Page 1  --------       -------- <=\  480,000    */
  47. /*                  Page 3  \    |        |  |     |    */
  48. /*                       \   |        | 64K    |    */
  49. /*                        \  |        |  |     |    */
  50. /*                         \ |        |  |     |    */
  51. /*                        -------- <=/=====/    */
  52. /*                         Page 7            */
  53. /*                                    */
  54. /*                                    */
  55. /*     V 0.90    01/04/89  Robert Adsett Original.            */
  56. /*     V 0.95    17/04/89  Robert Adsett Recode basic block operations    */
  57. /*                in assembler to increase the speed.     */
  58. /*                The effect is quite dramatic.        */
  59. /*    V 1.00  18/05/90  Robert Adsett Clean up the comments some.     */
  60. /*                This is the release version.  Some    */
  61. /*                features are not fully implemented yet    */
  62. /*                but it seems solid enough.        */
  63. /*    V 1.10    30/06/90  Robert Adsett Add colour setting code so that    */
  64. /*                colour commands other than         */
  65. /*                'setrgbcolor()' will work.        */
  66. /*    V 1.11    11/07/90  Robert Adsett Was copying one too many rows    */
  67. /*                    in save/restore bitmap.        */
  68. /*                                    */
  69. /*  LIMITATIONS:                            */
  70. /*    Flood fill is unimplemented at present.                */
  71. /*    Error checking & reporting are almost non-existant.        */
  72. /*    Everything that can be emulated is.  This seems to be         */
  73. /*   reasonably fast so changing this is not a high priority.        */
  74. /*                                    */
  75. /*  KNOWN BUGS:                                */
  76. /*    Line width is currently ignored.  This seems to be taken care    */
  77. /*   of by the kernal but should be changed.                */
  78. /************************************************************************/
  79.  
  80. #include <stdlib.h>
  81. #include <string.h>
  82. #include "bgi.h"
  83. #include "ati.h"
  84.  
  85. /*    Generic driver global variables.  Should be present in almost    */
  86. /*  every driver.                            */
  87.  
  88. const CHAR_TABLE_ENTRY far * const char_def = 
  89.             (CHAR_TABLE_ENTRY far *)MK_FP( 0xf000, 0xfa6e);
  90.                 /* Pointer to character definition    */
  91.                 /*  table in ROM.            */
  92.  
  93.                 /* Fill pattern definitions.        */
  94. const FILLPATTERN def_patterns[12] = {
  95.         { 0, 0, 0, 0, 0, 0, 0, 0 },     /* No Fill.        */
  96.         { 0xff, 0xff, 0xff, 0xff, 
  97.           0xff, 0xff, 0xff, 0xff },    /* Solid Fill.        */
  98.         { 0xff, 0xff, 0, 0, 0xff, 
  99.           0xff, 0, 0},            /* Line Fill.        */
  100.         { 1, 2, 4, 8, 0x10, 0x20,
  101.           0x40, 0x80},            /* Lt Slash fill.    */
  102.         { 0xE0, 0xC1, 0x83, 0x07, 
  103.           0x0E, 0x1C, 0x38, 0x70 },    /* Slash Fill.        */
  104.         { 0xF0, 0x78, 0x3C, 0x1E, 
  105.           0x0F, 0x87, 0xC3, 0xE1 },    /* Backslash Fill.    */
  106.         { 0xA5, 0xD2, 0x69, 0xB4, 
  107.           0x5A, 0x2D, 0x96, 0x4B },    /* Lt Backslash Fill.    */
  108.         { 0xFF, 0x88, 0x88, 0x88, 
  109.           0xFF, 0x88, 0x88, 0x88 },    /* Hatch Fill.        */
  110.         { 0x81, 0x42, 0x24, 0x18, 
  111.           0x18, 0x24, 0x42, 0x81 },    /* XHatch Fill.        */
  112.         { 0xCC, 0x33, 0xCC, 0x33, 
  113.           0xCC, 0x33, 0xCC, 0x33 },    /* Interleave Fill.    */
  114.         { 0x80, 0x00, 0x08, 0x00, 
  115.           0x80, 0x00, 0x08, 0x00 },     /* Wide Dot Fill.    */
  116.         { 0x88, 0x00, 0x22, 0x00, 
  117.           0x88, 0x00, 0x22, 0x00 }    /* Close Dot Fill.    */
  118.            };
  119. /*                                    */
  120. /*    The following structure defines the Bit Manipulation Utility    */
  121. /*    function table.                            */
  122. /*                                    */
  123.  
  124. const UTILITIES Utility_Table = {    /* Bit Utilities Function Table */
  125.   (NRFPTR) dispatch_enter_graphics,    /* Enter graphics mode function */
  126.   (NRFPTR) dispatch_leave_graphics,    /* Leave graphics mode function */
  127.   (NRFPTR) dispatch_putpix,        /* Write a pixel function    */
  128.   (NRFPTR) dispatch_getpix,        /* Read a pixel function    */
  129.   (NRFPTR) dispatch_bits_per_pixel,    /* Bits per pixel value        */
  130.   (NRFPTR) dispatch_set_page,        /* Set the active drawing page    */
  131.   (NRFPTR) dispatch_set_visual,        /* Set the active display page    */
  132.   (NRFPTR) dispatch_set_write_mode    /* Set the current write mode    */
  133.   };
  134.  
  135. int MAXY = 399, MAXX = 639, MINY = 0,     /* Clipping limits.        */
  136.     MINX = 0;
  137. int CURRENT_MODE, TEXT_MODE;
  138. unsigned int current_line_style = 0xffff;    /* Current line drawing    */
  139.                         /*  style.        */
  140. int current_write_mode = COPY;        /* Current drawing mode.    */
  141. int current_line_width = 1;        /* Current line width.        */
  142. unsigned char current_colour = 0xff,     /* Current drawing,        */
  143.           fill_colour = 0xff,    /*  filling,            */
  144.               background_colour = 0;    /*  and background colour.    */
  145.  
  146. unsigned int    CP_X = 0, CP_Y = 0;    /* Current Drawing Pointer CP.    */
  147. unsigned int    char_size, char_path;    /* Current character size and    */
  148.                     /*  drawing path.        */
  149.  
  150. const unsigned int line_style_mask[16] = {    /* A set of bit masks    */
  151.                     0x8000,    /*  used to mask bits    */
  152.                     0x4000,    /*  from the current    */
  153.                     0x2000,    /*  line style.        */
  154.                     0x1000,
  155.                     0x0800,
  156.                     0x0400,
  157.                     0x0200,
  158.                     0x0100,
  159.                     0x0080,
  160.                     0x0040,
  161.                     0x0020,
  162.                     0x0010,
  163.                     0x0008,
  164.                     0x0004,
  165.                     0x0002,
  166.                     0x0001
  167.                     };
  168.  
  169. STATUS    Stat_Block = {        /* Device status block.            */
  170.   0,                /* Current device status.        */
  171.   0,                /* Device Type Identifier.        */
  172.   639,                /* Device Full Resolution in X        */
  173.   399,                /* Device Full Resolution in Y        */
  174.   639,                /* Device Effective X Resolution    */
  175.   399,                /* Device Effective Y Resolution    */
  176.   9000,                /* Device X Size in inches*1000        */
  177.   7000,                /* Device Y Size in inches*1000        */
  178.   10000,            /* Aspect Ratio * 10000            */
  179.                   /* For compatibility the other fields     */
  180.                 /*  set so.                */
  181.   8,
  182.   8,
  183.   0x90,
  184.   0x90
  185.   };
  186.  
  187. ATIPALETTE Default_Palette = {    /* Default palette.              */
  188.   16, { 0x00, 0x00, 0x00,    /* In this case set during startup.    */
  189.       0x00, 0x00, 0x0f,
  190.     0x00, 0x0f, 0x00,
  191.     0x00, 0x00, 0x03,
  192.     0x00, 0x00, 0x04,
  193.     0x00, 0x00, 0x05,
  194.     0x00, 0x00, 0x07,
  195.     0x00, 0x00, 0x14,
  196.     0x00, 0x00, 0x38,
  197.     0x00, 0x00, 0x39,
  198.     0x00, 0x00, 0x3A,
  199.     0x00, 0x00, 0x3B,
  200.     0x00, 0x00, 0x3C,
  201.     0x00, 0x00, 0x3D,
  202.     0x00, 0x00, 0x3E,
  203.     0x00, 0x00, 0x3F,
  204.     0x00, 0x00, 0x00,
  205.     0x00, 0x00, 0x00,
  206.     0x00, 0x00, 0x00,
  207.     0x00, 0x00, 0x00,
  208.     0x00, 0x00, 0x00,
  209.     0x00, 0x00, 0x00,
  210.     0x00, 0x00, 0x00,
  211.     0x00, 0x00, 0x00,
  212.     0x00, 0x00, 0x00,
  213.     0x00, 0x00, 0x00,
  214.     0x00, 0x00, 0x00,
  215.     0x00, 0x00, 0x00,
  216.     0x00, 0x00, 0x00,
  217.     0x00, 0x00, 0x00,
  218.     0x00, 0x00, 0x00,
  219.     0x00, 0x00, 0x00,
  220.     0x00, 0x00, 0x00,
  221.     0x00, 0x00, 0x00,
  222.     0x00, 0x00, 0x00,
  223.     0x00, 0x00, 0x00,
  224.     0x00, 0x00, 0x00,
  225.     0x00, 0x00, 0x00,
  226.     0x00, 0x00, 0x00,
  227.     0x00, 0x00, 0x00,
  228.     0x00, 0x00, 0x00,
  229.     0x00, 0x00, 0x00,
  230.     0x00, 0x00, 0x00,
  231.     0x00, 0x00, 0x00,
  232.     0x00, 0x00, 0x00,
  233.     0x00, 0x00, 0x00,
  234.     0x00, 0x00, 0x00,
  235.     0x00, 0x00, 0x00,
  236.     0x00, 0x00, 0x00,
  237.     0x00, 0x00, 0x00,
  238.     0x00, 0x00, 0x00,
  239.     0x00, 0x00, 0x00,
  240.     0x00, 0x00, 0x00,
  241.     0x00, 0x00, 0x00,
  242.     0x00, 0x00, 0x00,
  243.     0x00, 0x00, 0x00,
  244.     0x00, 0x00, 0x00,
  245.     0x00, 0x00, 0x00,
  246.     0x00, 0x00, 0x00,
  247.     0x00, 0x00, 0x00,
  248.     0x00, 0x00, 0x00,
  249.     0x00, 0x00, 0x00,
  250.     0x00, 0x00, 0x00,
  251.     0x00, 0x00, 0x00,
  252.     0x00, 0x00, 0x00,
  253.     0x00, 0x00, 0x00,
  254.     0x00, 0x00, 0x00,
  255.     0x00, 0x00, 0x00,
  256.     0x00, 0x00, 0x00,
  257.     0x00, 0x00, 0x00,
  258.     0x00, 0x00, 0x00,
  259.     0x00, 0x00, 0x00,
  260.     0x00, 0x00, 0x00,
  261.     0x00, 0x00, 0x00,
  262.     0x00, 0x00, 0x00,
  263.     0x00, 0x00, 0x00,
  264.     0x00, 0x00, 0x00,
  265.     0x00, 0x00, 0x00,
  266.     0x00, 0x00, 0x00,
  267.     0x00, 0x00, 0x00,
  268.     0x00, 0x00, 0x00,
  269.     0x00, 0x00, 0x00,
  270.     0x00, 0x00, 0x00,
  271.     0x00, 0x00, 0x00,
  272.     0x00, 0x00, 0x00,
  273.     0x00, 0x00, 0x00,
  274.     0x00, 0x00, 0x00,
  275.     0x00, 0x00, 0x00,
  276.     0x00, 0x00, 0x00,
  277.     0x00, 0x00, 0x00,
  278.     0x00, 0x00, 0x00,
  279.     0x00, 0x00, 0x00,
  280.     0x00, 0x00, 0x00,
  281.     0x00, 0x00, 0x00,
  282.     0x00, 0x00, 0x00,
  283.     0x00, 0x00, 0x00,
  284.     0x00, 0x00, 0x00,
  285.     0x00, 0x00, 0x00,
  286.     0x00, 0x00, 0x00,
  287.     0x00, 0x00, 0x00,
  288.     0x00, 0x00, 0x00,
  289.     0x00, 0x00, 0x00,
  290.     0x00, 0x00, 0x00,
  291.     0x00, 0x00, 0x00,
  292.     0x00, 0x00, 0x00,
  293.     0x00, 0x00, 0x00,
  294.     0x00, 0x00, 0x00,
  295.     0x00, 0x00, 0x00,
  296.     0x00, 0x00, 0x00,
  297.     0x00, 0x00, 0x00,
  298.     0x00, 0x00, 0x00,
  299.     0x00, 0x00, 0x00,
  300.     0x00, 0x00, 0x00,
  301.     0x00, 0x00, 0x00,
  302.     0x00, 0x00, 0x00,
  303.     0x00, 0x00, 0x00,
  304.     0x00, 0x00, 0x00,
  305.     0x00, 0x00, 0x00,
  306.     0x00, 0x00, 0x00,
  307.     0x00, 0x00, 0x00,
  308.     0x00, 0x00, 0x00,
  309.     0x00, 0x00, 0x00,
  310.     0x00, 0x00, 0x00,
  311.     0x00, 0x00, 0x00,
  312.     0x00, 0x00, 0x00,
  313.     0x00, 0x00, 0x00,
  314.     0x00, 0x00, 0x00,
  315.     0x00, 0x00, 0x00,
  316.     0x00, 0x00, 0x00,
  317.     0x00, 0x00, 0x00,
  318.     0x00, 0x00, 0x00,
  319.     0x00, 0x00, 0x00,
  320.     0x00, 0x00, 0x00,
  321.     0x00, 0x00, 0x00,
  322.     0x00, 0x00, 0x00,
  323.     0x00, 0x00, 0x00,
  324.     0x00, 0x00, 0x00,
  325.     0x00, 0x00, 0x00,
  326.     0x00, 0x00, 0x00,
  327.     0x00, 0x00, 0x00,
  328.     0x00, 0x00, 0x00,
  329.     0x00, 0x00, 0x00,
  330.     0x00, 0x00, 0x00,
  331.     0x00, 0x00, 0x00,
  332.     0x00, 0x00, 0x00,
  333.     0x00, 0x00, 0x00,
  334.     0x00, 0x00, 0x00,
  335.     0x00, 0x00, 0x00,
  336.     0x00, 0x00, 0x00,
  337.     0x00, 0x00, 0x00,
  338.     0x00, 0x00, 0x00,
  339.     0x00, 0x00, 0x00,
  340.     0x00, 0x00, 0x00,
  341.     0x00, 0x00, 0x00,
  342.     0x00, 0x00, 0x00,
  343.     0x00, 0x00, 0x00,
  344.     0x00, 0x00, 0x00,
  345.     0x00, 0x00, 0x00,
  346.     0x00, 0x00, 0x00,
  347.     0x00, 0x00, 0x00,
  348.     0x00, 0x00, 0x00,
  349.     0x00, 0x00, 0x00,
  350.     0x00, 0x00, 0x00,
  351.     0x00, 0x00, 0x00,
  352.     0x00, 0x00, 0x00,
  353.     0x00, 0x00, 0x00,
  354.     0x00, 0x00, 0x00,
  355.     0x00, 0x00, 0x00,
  356.     0x00, 0x00, 0x00,
  357.     0x00, 0x00, 0x00,
  358.     0x00, 0x00, 0x00,
  359.     0x00, 0x00, 0x00,
  360.     0x00, 0x00, 0x00,
  361.     0x00, 0x00, 0x00,
  362.     0x00, 0x00, 0x00,
  363.     0x00, 0x00, 0x00,
  364.     0x00, 0x00, 0x00,
  365.     0x00, 0x00, 0x00,
  366.     0x00, 0x00, 0x00,
  367.     0x00, 0x00, 0x00,
  368.     0x00, 0x00, 0x00,
  369.     0x00, 0x00, 0x00,
  370.     0x00, 0x00, 0x00,
  371.     0x00, 0x00, 0x00,
  372.     0x00, 0x00, 0x00,
  373.     0x00, 0x00, 0x00,
  374.     0x00, 0x00, 0x00,
  375.     0x00, 0x00, 0x00,
  376.     0x00, 0x00, 0x00,
  377.     0x00, 0x00, 0x00,
  378.     0x00, 0x00, 0x00,
  379.     0x00, 0x00, 0x00,
  380.     0x00, 0x00, 0x00,
  381.     0x00, 0x00, 0x00,
  382.     0x00, 0x00, 0x00,
  383.     0x00, 0x00, 0x00,
  384.     0x00, 0x00, 0x00,
  385.     0x00, 0x00, 0x00,
  386.     0x00, 0x00, 0x00,
  387.     0x00, 0x00, 0x00,
  388.     0x00, 0x00, 0x00,
  389.     0x00, 0x00, 0x00,
  390.     0x00, 0x00, 0x00,
  391.     0x00, 0x00, 0x00,
  392.     0x00, 0x00, 0x00,
  393.     0x00, 0x00, 0x00,
  394.     0x00, 0x00, 0x00,
  395.     0x00, 0x00, 0x00,
  396.     0x00, 0x00, 0x00,
  397.     0x00, 0x00, 0x00,
  398.     0x00, 0x00, 0x00,
  399.     0x00, 0x00, 0x00,
  400.     0x00, 0x00, 0x00,
  401.     0x00, 0x00, 0x00,
  402.     0x00, 0x00, 0x00,
  403.     0x00, 0x00, 0x00,
  404.     0x00, 0x00, 0x00,
  405.     0x00, 0x00, 0x00,
  406.     0x00, 0x00, 0x00,
  407.     0x00, 0x00, 0x00,
  408.     0x00, 0x00, 0x00,
  409.     0x00, 0x00, 0x00,
  410.     0x00, 0x00, 0x00,
  411.     0x00, 0x00, 0x00,
  412.     0x00, 0x00, 0x00,
  413.     0x00, 0x00, 0x00,
  414.     0x00, 0x00, 0x00,
  415.     0x00, 0x00, 0x00,
  416.     0x00, 0x00, 0x00,
  417.     0x00, 0x00, 0x00,
  418.     0x00, 0x00, 0x00,
  419.     0x00, 0x00, 0x00,
  420.     0x00, 0x00, 0x00,
  421.     0x00, 0x00, 0x00,
  422.     0x00, 0x00, 0x00,
  423.     0x00, 0x00, 0x00,
  424.     0x00, 0x00, 0x00,
  425.     0x00, 0x00, 0x00,
  426.     0x00, 0x00, 0x00,
  427.     0x00, 0x00, 0x00,
  428.     0x00, 0x00, 0x00,
  429.     0x00, 0x00, 0x00,
  430.     0x00, 0x00, 0x00,
  431.     0x00, 0x00, 0x00,
  432.     0x00, 0x00, 0x00,
  433.     0x00, 0x00, 0x00,
  434.     0x00, 0x00, 0x00,
  435.     0x00, 0x00, 0x00,
  436.     0x00, 0x00, 0x00,
  437.     0x00, 0x00, 0x00,
  438.     0x00, 0x00, 0x00,
  439.     0x00, 0x00, 0x00,
  440.     0x00, 0x00, 0x00,
  441.     0x00, 0x00, 0x00,
  442.     0x00, 0x00, 0x00,
  443.     0xff, 0xff, 0xff}
  444.   };
  445.  
  446. /* Global variables specific to this driver.                */
  447.  
  448. int rowsize;            /* Number of bytes in a row.        */
  449. struct BANK bank[8];        /* Information about what each bank     */
  450.                 /*   contains (up to 8 banks).        */
  451. unsigned char current_bank = 0,    /* Current bank.            */
  452.     maximum_bank;        /* Maximum bank for this mode.        */
  453.  
  454. SCREEN_PTR const screen_buffer = (SCREEN_PTR)MK_FP( ATI_SEGMENT, 0);
  455.                 /* Pointer to the base of video memory.    */
  456. unsigned char current_pattern[8][8];    /* Current fill pattern stored    */
  457.                     /*  as pixels.            */
  458. SCREEN_PTR current_address,    /* Current address into video memory.    */
  459.        old_address;        /* Previous address.  Used in         */
  460.                  /*   incrementing.            */
  461.  
  462. /*                                    */
  463. /*    Function Protoypes local to the ATI driver.            */
  464. /*                                    */
  465.  
  466. void copy_image( 
  467.     unsigned char const far *from, 
  468.     int from_xsize, 
  469.         unsigned char far *to, 
  470.     int to_xsize,
  471.     int mode
  472.     );
  473. void char_draw( unsigned char c);
  474. void set_pattern( unsigned char *current_pattern, 
  475.           unsigned char const far *pattern);
  476. void update_pattern( void);
  477.  
  478.  
  479. /******************************* INSTALL ********************************/
  480. /*    The Install function is used to prepare the driver to use.  The    */
  481. /*  calls to this function allow the kernal to inquire the mode     */
  482. /*  information, and allow the kernal to install the mode infomation.    */
  483. /*  sets the error code to 'grInvalidMode' for invalid mode numbers    */
  484. /*  and 'grError' for an unrecognized command.                */
  485. /************************************************************************/
  486.  
  487. const char *CopyRight = 
  488.            "ATI VGA Wonder BGI driver (V 1.10) Copyright R. Adsett 1990.";
  489.  
  490.                 /* Names of the drivers modes.  The     */
  491.                 /*  first character is the length of     */
  492.                 /*  the string.                */
  493. char *Name[] = {
  494.         "\x21 ATI VGA Wonder (640 x 400 x 256)",
  495.         "\x21 ATI VGA Wonder (640 x 480 x 256)",
  496.         "\x21 ATI VGA Wonder (800 x 600 x 256)"
  497.         };
  498.  
  499. long install(
  500.     unsigned int mode,    /* Mode to use.                */
  501.     char command        /* Install sub command.            */
  502.     )
  503. {
  504. long ret_code;
  505.  
  506. switch( command )            /* Determine the command to use */
  507.     {
  508.     case 0:                /* Install Device Command.    */
  509.          if((mode & 0xff) >= MAX_MODES)    /* Is the mode requested valid? */
  510.               {                /*  No set an error code.    */
  511.               Stat_Block.stat = grInvalidMode;
  512.           }
  513.      CURRENT_MODE = mode & 0xff;    /* Get mode to use.        */
  514.      switch( CURRENT_MODE)        /* Set up mode specific info.    */
  515.           {
  516.           case ATI256LO:
  517.                Stat_Block.xres = 639;    /* Resolution in this    */
  518.                Stat_Block.yres = 399;    /*   mode.        */
  519.                Stat_Block.xefres = 639;
  520.                Stat_Block.yefres = 399;
  521.            break;
  522.  
  523.           case ATI256MED:
  524.                Stat_Block.xres = 639;    /* Resolution in this    */
  525.                Stat_Block.yres = 479;    /*   mode.        */
  526.                Stat_Block.xefres = 639;
  527.                Stat_Block.yefres = 479;
  528.            break;
  529.  
  530.           case ATI256HI:
  531.                Stat_Block.xres = 799;    /* Resolution in this    */
  532.                Stat_Block.yres = 599;    /*   mode.        */
  533.                Stat_Block.xefres = 799;
  534.                Stat_Block.yefres = 599;
  535.            break;
  536.           }
  537.          ret_code = (unsigned int)&Stat_Block;    /* Return pointer to     */
  538.          break;                    /*  the status block.    */
  539.  
  540.     case 1:                /* Mode Query Command.        */
  541.          ret_code = (long)MAX_MODES << 16; /* Return number of modes.    */
  542.          break;
  543.  
  544.     case 2:                /* Mode Name Command.        */
  545.          if( (mode & 0xff) > MAX_MODES)    /* Is the mode requested valid? */
  546.               {                /*  No set an error code.    */
  547.               Stat_Block.stat = grInvalidMode;
  548.           }
  549.                           /* Return pointer to the name.    */
  550.          ret_code = (unsigned int)Name[mode & 0xff];
  551.          break;
  552.  
  553.     default:                /* Unknown Install Call.    */
  554.          Stat_Block.stat = grError;    /* General error.        */
  555.          break;
  556.     }                    /* End of Install command case.    */
  557. return( ret_code);            /* Return pointer, mode numbers */
  558. }
  559.  
  560. /******************************* INITIALIZE *****************************/
  561. /*    The initialize function is used to enter the graphics mode.    */
  562. /*  Save the current mode so that it can be restored later.        */
  563. /************************************************************************/
  564.  
  565. void init( unsigned int dit_offset, unsigned int dit_segment)
  566. {
  567. struct DIT far *Dev_info;
  568. struct REGPACK mode_regs;
  569. void *deftbl;
  570. static int mode_table[] = { 0x61, 0x62, 0x63 };
  571. static struct BANK bankmed[] = { {0, 102, 0, 255},
  572.                  { 102, 204, 256, 511},
  573.                  { 204, 307, 512, 127},
  574.                  { 307, 409, 128, 383},
  575.                  { 409, 511, 384, 639}
  576.                    };
  577. static struct BANK bankhi[] = { { 0, 81, 0, 735},
  578.                 { 81, 163, 736, 671},
  579.                 { 163, 245, 672, 607},
  580.                 { 245, 327, 608, 543},
  581.                 { 327, 409, 544, 479},
  582.                 { 409, 491, 480, 415},
  583.                 { 491, 573, 416, 351},
  584.                 { 573, 655, 352, 287}
  585.                   };
  586.  
  587. Dev_info = (struct DIT far *)MK_FP( dit_segment, dit_offset);
  588.  
  589. background_colour = Dev_info->background;
  590.                     /* Set the background colour.    */
  591. update_pattern();            /* Set up the pattern for use.    */
  592. deftbl = &(Default_Palette.colora[0]);     /* Load table offset.        */
  593.  
  594. mode_regs.r_ax = 0x1200;        /* Tell the bios to load the     */
  595. mode_regs.r_bx = 0x31;            /*  default palette when it     */
  596. intr( 0x10, &mode_regs);        /*  switches modes.        */
  597.  
  598. if( Dev_info->init != 0xA5)        /* Don't ask me!        */
  599.     {
  600.     mode_regs.r_ax = 0xf00;        /* Get current mode.        */
  601.     intr( 0x10, &mode_regs);
  602.     TEXT_MODE = mode_regs.r_ax & 0xff;
  603.  
  604.                         /* Set asked for mode.        */
  605.     mode_regs.r_ax = mode_table[ CURRENT_MODE] & 0xff;
  606.     intr( 0x10, &mode_regs);
  607.  
  608.     switch( CURRENT_MODE)        /* Set up mode specific info.    */
  609.          {
  610.      case ATI256LO:
  611.           rowsize = 640;        /* Bytes per row.        */
  612.           maximum_bank = 4;        /* Number of banks of memory.    */
  613.                           /* Bank info for this mode.    */
  614.           memcpy( bank, bankmed, sizeof( bankmed));
  615.           break;
  616.  
  617.      case ATI256MED:
  618.           rowsize = 640;           /* Bytes per row.        */
  619.           maximum_bank = 5;        /* Number of banks of memory.    */
  620.                           /* Bank info for this mode.    */
  621.           memcpy( bank, bankmed, sizeof( bankmed));
  622.           break;
  623.  
  624.      case ATI256HI:
  625.           rowsize = 800;           /* Bytes per row.        */
  626.           maximum_bank = 8;        /* Number of banks of memory.    */
  627.                           /* Bank info for this mode.    */
  628.           memcpy( bank, bankhi, sizeof( bankhi));
  629.           break;
  630.  
  631.      }
  632.     }
  633. palette( 0x80ff, 0xff,  0xff, 0xff);
  634. mode_regs.r_es = _DS;            /* Load colour table segment.    */
  635. mode_regs.r_dx = (unsigned int)deftbl;    /* Load table offset.        */
  636. mode_regs.r_bx = 0;            /* Beginning of the table.    */
  637. mode_regs.r_cx = 255;            /* Size of the table.        */
  638. mode_regs.r_ax = 0x1017;        /* Request read all palette    */
  639. intr( 0x10, &mode_regs);        /*  service.            */
  640. }
  641.  
  642. /******************************* CLEAR **********************************/
  643. /*    Clear the screen.  Write zero everywhere.              */
  644. /************************************************************************/
  645.  
  646. void clear( void )
  647. {
  648.  
  649. for( current_bank = 0; current_bank < maximum_bank; current_bank++)
  650.     {
  651.     BANK_SELECT();
  652.     set_mem( screen_buffer, 0, 0);
  653.     }
  654. }
  655.  
  656. /********************************** POST ********************************/
  657. /*    Go to text mode.  Use mode stored previously.            */
  658. /************************************************************************/
  659.  
  660. void post( void )
  661. {
  662. struct REGPACK mode_regs;
  663.  
  664. mode_regs.r_ax = TEXT_MODE;
  665. intr( 0x10, &mode_regs);
  666. }
  667.  
  668. /********************************* MOVE *********************************/
  669. /*    This function is used to move the current pointer (CP). This is    */
  670. /*  a pretty generic routine, library later?                  */
  671. /************************************************************************/
  672.  
  673. void move( int x, int y)
  674. {
  675.  
  676. CP_X = x;                /* Update the current pointer.    */
  677. CP_Y = y;
  678. }
  679.  
  680. /******************************** DRAW **********************************/
  681. /*    Draw a line vector from the CP to the specified coordinate.    */
  682. /*  Update the CP to the new coordinate.                */
  683. /************************************************************************/
  684.  
  685. void draw( int x, int y)
  686. {
  687.  
  688. line( CP_X, CP_Y, x, y);        /* Draw the line.        */
  689. CP_X = x;                /* Update the current pointer    */
  690. CP_Y = y;
  691. }
  692.  
  693. /********************************* VECT *********************************/
  694. /*    Draw a line between the two specified points.            */
  695. /************************************************************************/
  696.  
  697. void vect( int x1, int y1, int x2, int y2)
  698. {
  699.  
  700. line( x1, y1, x2, y2);        /* Draw the line.            */
  701. }
  702.  
  703. /********************************* PATBAR *******************************/
  704. /*    Fill a rectangle with the current filling pattern.  Do not     */
  705. /*  outline.  The coordinates passed are the upper left corner and the    */
  706. /*  lower right corner.                            */
  707. /************************************************************************/
  708.  
  709. void patbar( int x1, int y1, int x2, int y2)
  710. {
  711. int x3, y3;
  712.  
  713. if( x2 < x1)            /* Sometimes the emulation routines get    */
  714.     {                /*   the y coords. backwards.  We'll    */
  715.     x3 = x2; x2 = x1; x1 = x3;    /*   check the x coords. as well just     */
  716.     }                /*   to be sure.            */
  717. if( y2 < y1)
  718.     {
  719.     y3 = y2; y2 = y1; y1 = y3;
  720.     }
  721. for( ; y1 <= y2; y1++)        /* For each line.            */
  722.     {
  723.     int pre_done;
  724.  
  725.     x3 = x1;
  726.     y3 = y1;
  727.     pre_done = 0;
  728.     CALC_ADDR( x3, y3);        /* Calculate start address....        */
  729.     if( (x3 & 7) != 0)
  730.          {
  731.      int size;
  732.  
  733.      pre_done = 8 - x3 & 7;
  734.      size = ((x2-x1+1) < pre_done) ? (x2-x1+1) : pre_done;
  735.          if( current_address + size < current_address)
  736.           {
  737.           int size2;
  738.  
  739.           size2 = -(int)current_address;
  740.               copy_image( ¤t_pattern[y1&7][x3&7], pre_done, 
  741.                  current_address, size2, COPY);
  742.                     /* ... and copy appropriate line of the    */
  743.                 /*  current pattern in.            */
  744.               CALC_ADDR( x3 + size2, y3);   /* Find the beginning.    */
  745.               copy_image( ¤t_pattern[y1&7][x3&7 + size2], pre_done,
  746.                  current_address, size - size2, COPY);
  747.           }
  748.      else
  749.           {
  750.               copy_image( ¤t_pattern[y1&7][x3&7], pre_done, 
  751.                  current_address, size, COPY);
  752.           }
  753.          CALC_ADDR( x3 + pre_done, y3);    /* Calculate start address....    */
  754.      x3 += pre_done;
  755.      }
  756.     if( pre_done < x2-x1+1)
  757.          {
  758.      int size;
  759.  
  760.      size = x2 - x1 + 1 - pre_done;
  761.          if( current_address + size < current_address)
  762.               {
  763.           int size2;
  764.  
  765.           size2 = -(int)current_address;
  766.               copy_image( current_pattern[y1&7], 8, current_address, 
  767.                       size2, COPY);
  768.                     /* ... and copy appropriate line of the    */
  769.                 /*  current pattern in.            */
  770.               CALC_ADDR( x3 + size2, y3);   /* Find the beginning.    */
  771.               copy_image( current_pattern[y1&7], 8, current_address, 
  772.                       size - size2, COPY);
  773.                     /* ... and copy appropriate line of the    */
  774.                 /*  current pattern in.            */
  775.           }
  776.      else
  777.           {
  778.               copy_image( current_pattern[y1&7], 8, current_address, 
  779.                       size, COPY);
  780.                     /* ... and copy appropriate line of the    */
  781.                 /*  current pattern in.            */
  782.           }
  783.      }
  784.     }
  785. }
  786.  
  787. /******************************* PALETTE ********************************/
  788. /*    Set the colour palette entries.  Only the set RGB colour method    */
  789. /*  is supported.                            */
  790. /************************************************************************/
  791.  
  792. void palette( int flag_index, int red_colour,  int blue, int green)
  793. {
  794. int index;
  795. char r, g, b;
  796. struct REGPACK mode_regs;
  797.  
  798. index = flag_index & 0x3fff;        /* Grab colour table index.    */
  799. r = red_colour & 0x3f;            /* Grab colours.        */
  800. g = green & 0x3f;
  801. b = blue & 0x3f;
  802. switch(flag_index & 0xc000)
  803.     {
  804.     case 0x4000:
  805.          /*    unused.                            */
  806.      break;
  807.  
  808.     case 0x0000:            /* Load colour table with colour*/
  809.      b = r & 3;            /*  in red_colour.  It's mapped    */
  810.      g = (r >> 2) & 3;        /*  as 2 bits each for red,     */
  811.      r = (r >> 4) & 3;        /*  green, and blue.  Set up    */
  812.      /*FALLTHROUGH*/        /*  and let setrgb do the work.    */
  813.  
  814.     case 0x8000:            /* Load rgb.            */
  815.      mode_regs.r_bx = index;    /* Entry to load.        */
  816.      mode_regs.r_dx = r << 8;    /* Colour values to set it to.    */
  817.      mode_regs.r_cx = (g << 8) | b;
  818.      mode_regs.r_ax = 0x1010;    /* Request set palette service.    */
  819.      intr( 0x10, &mode_regs);    /* Call the Bios.        */
  820.      break;
  821.          
  822.     case 0xc000:            /*  Load background.        */
  823.          background_colour = r;
  824.      break;
  825.     }
  826. }
  827.  
  828. /****************************** ALLPALETTE ******************************/
  829. /*    The BGI kernal only passes the first 16 entries.  Therefore     */
  830. /*  this function ignores the passed argument and simply restores the    */
  831. /*  default palette.  (At least that way the results are consistent).     */
  832. /************************************************************************/
  833.  
  834. void allpalette( unsigned int pptr_offset, unsigned int pptr_segment)
  835. {
  836. struct REGPACK mode_regs;
  837.  
  838. mode_regs.r_es = _DS;            /* Load colour table segment.    */
  839. mode_regs.r_dx = (unsigned int)&Default_Palette; /* Load table offset.    */
  840. mode_regs.r_dx++;
  841. mode_regs.r_bx = 0;            /* Beginning of the table.    */
  842. mode_regs.r_cx = 255;            /* Size of the table.        */
  843. mode_regs.r_ax = 0x1012;        /* Request set all palette    */
  844. intr( 0x10, &mode_regs);        /*  service.            */
  845. }
  846.  
  847. /******************************* COLOR **********************************/
  848. /*    Sets new foreground (drawing) and fill colours.            */
  849. /************************************************************************/
  850.  
  851. void color( char new_fill_colour, char new_draw_colour )
  852. {
  853.  
  854. new_draw_colour &= 0xff;    /* Mask colours to possible range.    */
  855. new_fill_colour &= 0xff;
  856. current_colour = new_draw_colour;
  857. fill_colour = new_fill_colour;
  858. update_pattern();        /* Update current pattern to reflect    */
  859.                 /*   the new colours.            */
  860. }
  861.  
  862. /******************************* FILLSTYLE ******************************/
  863. /*    Set the current fillstyle.                    */
  864. /************************************************************************/
  865.  
  866. static int current_pattern_no = 0, user_pattern[8];
  867.                 /* Current pattern and user pattern.    */
  868.  
  869. void fillstyle( unsigned char pattern, unsigned int pptr_offset,
  870.     unsigned int pptr_segment)
  871. {
  872. unsigned char far *pptr;
  873. int i;
  874.  
  875. pptr = MK_FP( pptr_segment, pptr_offset);    /* Ptr. to user line    */
  876.                         /*   style.        */
  877. current_pattern_no = pattern;        /* Save current style.        */
  878. if( current_pattern_no == 0xff )    /* User defined line style    */
  879.     {
  880.     set_pattern( (unsigned char *)¤t_pattern, pptr);
  881.                     /* Make pattern accessible to filling     */
  882.                 /*   routine.                */
  883.     for( i = 0; i < 8; i++)    /* Save User pattern for later use.    */
  884.          {
  885.      user_pattern[i] = *(int far *)(pptr + i*sizeof( int));
  886.      }
  887.     }
  888. else
  889.     {
  890.     set_pattern( (unsigned char *)current_pattern, 
  891.                  (unsigned char far *)&def_patterns[pattern]);
  892.                     /* Make pattern accessible to filling     */
  893.                 /*   routine.                */
  894.     }
  895. }
  896.  
  897. void update_pattern( void)    /* Update pattern to take care of new    */
  898. {                /*   colours.                */
  899.  
  900. if( current_pattern_no == 0xff )    /* User defined line style    */
  901.     {
  902.     set_pattern( (unsigned char *)current_pattern, 
  903.                  (unsigned char far *)user_pattern);
  904.                     /* Make pattern accessible to filling     */
  905.                 /*   routine.                */
  906.     }
  907. else
  908.     {
  909.     set_pattern( (unsigned char *)current_pattern, 
  910.                  (unsigned char far *)&def_patterns[current_pattern_no]);
  911.                     /* Make pattern accessible to filling     */
  912.                 /*   routine.                */
  913.     }
  914. }
  915.  
  916. /******************************* LINESTYLE ******************************/
  917. /*    Set the current line style.  This includes drawing pattern and    */
  918. /*  width.                                */
  919. /************************************************************************/
  920.  
  921. void linestyle( char style, int pattern, int width)
  922. {
  923.  
  924. switch( style)            /* Set appropriate line pattern.    */
  925.     {
  926.     case SOLID_LINE:
  927.          current_line_style = 0xffff;
  928.      break;
  929.  
  930.     case DOTTED_LINE:
  931.          current_line_style = 0xCCCC;
  932.      break;
  933.  
  934.     case CENTRE_LINE:
  935.          current_line_style = 0xFC78;
  936.      break;
  937.  
  938.     case DASHED_LINE:
  939.          current_line_style = 0xF8F8;
  940.      break;
  941.  
  942.     case USER_LINE:
  943.          current_line_style = pattern;
  944.      break;
  945.  
  946.     default:
  947.          break;
  948.     }
  949. current_line_width = width;        /* Save the width.        */
  950. }
  951.  
  952. /******************************* TEXTSTYLE ******************************/
  953. /*    Set the text path and size.  Returns x & y size as a long.    */
  954. /************************************************************************/
  955.  
  956. long textstyle( char number, char path, int xsize, int ysize)
  957. {
  958.  
  959. char_path = path;            /* Record path.            */
  960. char_size = xsize >> 3;            /* Convert text size to a    */
  961.                     /*  multiple of 8.        */
  962. if( char_size == 0)            /* Must be at least 1.        */
  963.     char_size = 1;
  964. xsize = ysize = char_size << 3;        /* Compute actual size.        */
  965. return( (((long)xsize) << 16) | ysize);    /* Return actual size.        */
  966. }
  967.  
  968. /******************************** TEXT **********************************/
  969. /*    Draw a text string.                        */
  970. /************************************************************************/
  971.  
  972. void text( int length, unsigned int offset, unsigned int segment)
  973. {
  974. char far * cptr = MK_FP( segment, offset);
  975. int i;
  976.  
  977. for( i = 0; i < length; ++i )         /* For all characters ...    */
  978.     {
  979.     char_draw( *cptr++);        /* Draw it.            */
  980.     }
  981. }
  982.  
  983. /****************************** FLOODFILL *******************************/
  984. /*    Unimplemented. Null function.  Is this really of importance to    */
  985. /*  anyone?                                */
  986. /************************************************************************/
  987.  
  988. void floodfill( int x, int y, unsigned char boundary)
  989. {
  990. }
  991.  
  992. /******************************* BITMAPUTIL *****************************/
  993. /*    Get the address of the bit map utility table.            */
  994. /************************************************************************/
  995.  
  996. void *bitmaputil( void )
  997. {
  998.  
  999. return(&Utility_Table);
  1000. }
  1001.  
  1002. /*                                    */
  1003. /*    The following define the bit map utility functions.        */
  1004. /*                                    */
  1005.  
  1006. void enter_graphics( void )        /* Enter graphics mode function.*/
  1007. {                    /* Null function.        */
  1008. }
  1009.  
  1010. void leave_graphics( void )        /* Leave graphics mode function */
  1011. {                    /* Null function.        */
  1012. }
  1013.  
  1014. int bits_per_pixel( void )        /* Enter graphics mode function */
  1015. {
  1016.  
  1017. return( 8);                /* Always 8 bits/pixel.        */
  1018. }
  1019.  
  1020. void putpix( int x, int y, char colour)    /* Write a pixel function    */
  1021. {
  1022.  
  1023. colour &= 0xff;
  1024. CALC_ADDR( x, y);            /* Calculate address.        */
  1025. POINT( colour);                /* Draw pixel.            */
  1026. }
  1027.  
  1028. char getpix( int x, int y)        /* Read a pixel function    */
  1029. {
  1030.  
  1031. CALC_ADDR( x, y);            /* Calculate address.        */
  1032. return( RD_POINT());            /* Read pixel colour.        */
  1033. }
  1034.  
  1035. void set_page( char page)        /* Set the active drawing page    */
  1036. {                    /* Null function.  Only 1 page.    */
  1037.  
  1038. }
  1039.  
  1040. void set_visual( char page)        /* Set the active display page    */
  1041. {                    /* Null function.  Only 1 page.    */
  1042.  
  1043. }
  1044.  
  1045. void set_write_mode( int mode)        /* Set the current write mode    */
  1046. {
  1047.  
  1048. current_write_mode = mode;        /* Save write mode.        */
  1049. }
  1050.  
  1051.  
  1052. /****************************** RESTOREBITMAP ***************************/
  1053. /*    Copy a bitmap to video memory.                    */
  1054. /************************************************************************/
  1055.  
  1056. void restorebitmap( char mode, unsigned int segment, unsigned int offset,
  1057.         int x1, int y1, int x2, int y2)
  1058. {
  1059. const unsigned char far *buffer;
  1060. int xsize, x3, y3, bump;
  1061.  
  1062. x1 = x2;        /* Bug in doc's. */
  1063. y1 = y2;
  1064.  
  1065. buffer = (const unsigned char far *)MK_FP( segment, offset);
  1066.                     /* Bitmap address.        */
  1067. xsize = *(int far *)buffer + 1;        /* Columns.            */
  1068. buffer += sizeof( int);
  1069. y2 = y1 + *(int far *)buffer + 1;    /* Rows.            */
  1070. bump = xsize + 1;            /* Size of row in memory.  This    */
  1071.                     /* should be agreed on with     */
  1072.                     /* 'savebitmap'.        */
  1073. buffer += sizeof(int);            /* Increment to storage.    */
  1074. for( ;y1 < y2; y1++)            /* For each line...        */
  1075.     {
  1076.     x3 = x1;
  1077.     y3 = y1;
  1078.     CALC_ADDR( x3, y3);            /* Find the beginning.        */
  1079.     if( current_address + xsize < current_address)
  1080.          {
  1081.      int size2;
  1082.  
  1083.      size2 = -(int)current_address;
  1084.          copy_image( buffer, size2, current_address, size2, mode);
  1085.                         /* Copy the line using the    */
  1086.                     /*  appropriate mode.        */
  1087.          CALC_ADDR( x3 + size2, y3);    /* Find the beginning.        */
  1088.          copy_image( buffer + size2, xsize - size2, current_address, 
  1089.                  xsize - size2, mode);
  1090.                         /* Copy the line using the    */
  1091.                     /*  appropriate mode.        */
  1092.      }
  1093.     else
  1094.          {
  1095.          copy_image( buffer, xsize, current_address, xsize, mode);
  1096.                         /* Copy the line using the    */
  1097.                     /*  appropriate mode.        */
  1098.      }
  1099.     buffer += bump;            /* Increment bitmap to the next    */
  1100.     }                    /*  line.            */
  1101. }
  1102.  
  1103. /****************************** SAVEBITMAP ******************************/
  1104. /*    Copy an area of video memory to a bitmap.            */
  1105. /************************************************************************/
  1106.  
  1107. void savebitmap( unsigned int buff_segment, unsigned int buff_offset,
  1108.         int x1, int y1, int x2, int y2)
  1109. {
  1110. unsigned char far *buffer;
  1111. int xsize, x3, y3, bump;
  1112.  
  1113. x1 = x2;        /* Bug in doc's. */
  1114. y1 = y2;
  1115. buffer = (unsigned char far *)MK_FP( buff_segment, buff_offset);
  1116.                     /* Bitmap address.        */
  1117. xsize = *(int far *)buffer + 1;        /* Columns.            */
  1118. buffer += sizeof( int);
  1119. y2 = y1 + *(int far *)buffer + 1;    /* Rows.            */
  1120. bump = xsize +1;            /* Size of row in memory.  This    */
  1121.                     /* should be agreed on with     */
  1122.                     /* 'restorebitmap'.        */
  1123. buffer += sizeof(int);            /* Increment to storage.    */
  1124. for( ;y1 < y2; y1++)            /* For each line...        */
  1125.     {
  1126.     x3 = x1;
  1127.     y3 = y1;
  1128.     CALC_ADDR( x3, y3);            /* Find the beginning.        */
  1129.     if( current_address + xsize < current_address)
  1130.          {
  1131.      int size2;
  1132.  
  1133.      size2 = -(int)current_address;
  1134.          copy_image( current_address, size2, buffer, size2, COPY);
  1135.                         /* Copy the line using the    */
  1136.                     /*  copy mode.            */
  1137.          CALC_ADDR( x3 + size2, y3);    /* Find the beginning.        */
  1138.          copy_image( current_address, xsize - size2, buffer + size2, 
  1139.                  xsize - size2, COPY);
  1140.                         /* Copy the line using the    */
  1141.                     /*  copy mode.            */
  1142.      }
  1143.     else
  1144.          {
  1145.          copy_image( current_address, xsize, buffer, xsize, COPY);
  1146.                         /* Copy the line using the    */
  1147.                     /*  copy mode.            */
  1148.      }
  1149.     buffer += bump;            /* Increment bitmap to the next    */
  1150.     }                    /*  line.            */
  1151. }
  1152.  
  1153. /****************************** SETCLIP *********************************/
  1154. /*    Set the clipping area.    Library?                */
  1155. /************************************************************************/
  1156.  
  1157. void setclip( int x1, int y1, int x2, int y2)
  1158. {
  1159.  
  1160. MINX = x1;                /* Save the clipping limits.    */
  1161. MAXY = y1;
  1162. MAXX = x2;
  1163. MAXY = y2;
  1164. }
  1165.  
  1166. /***************************** GET_PIXEL ********************************/
  1167. /*    Read a pixel colour from the screen.                */
  1168. /************************************************************************/
  1169.  
  1170. char get_pixel( int x, int y)
  1171. {
  1172.  
  1173. CALC_ADDR( x, y);            /* Calculate the address.    */
  1174. return( RD_POINT());            /* Read the pixel.        */
  1175. }
  1176.  
  1177. /***************************** SET_PIXEL ********************************/
  1178. /*    Set a pixel to a specific colour.                */
  1179. /************************************************************************/
  1180.  
  1181. void set_pixel( int x, int y, char colour)
  1182. {
  1183.  
  1184. colour &= 0xff;
  1185. CALC_ADDR( x, y);            /* Calculate address.        */
  1186. POINT( colour);                /* Draw the pixel.        */
  1187. }
  1188.  
  1189. /****************************** TEXTSIZ *********************************/
  1190. /*    Return the pixel size of a string.                */
  1191. /************************************************************************/
  1192.  
  1193. long textsiz( int length, unsigned int offset, unsigned int segment)
  1194. {
  1195. if( char_path == NORMAL_PATH)        /* Horizontal.            */
  1196.     {
  1197.     return( (((long)(length*char_size*8))<<16) | (8*char_size));
  1198.     }
  1199. else                    /* Vertical.            */
  1200.     {
  1201.     return( (((long)(char_size*8))<<16) | (length*8*char_size));
  1202.     }
  1203. }
  1204.  
  1205. /****************************** COLOR_QUERY *****************************/
  1206. /*    Get colour palette & size.                    */
  1207. /************************************************************************/
  1208.  
  1209. long color_query( char command_type)
  1210. {
  1211. int i;
  1212. long ret_val;
  1213.  
  1214.  
  1215. switch( command_type )            /* Act on the input command.    */
  1216.     {
  1217.     case 0:                /* Color palette size query.    */
  1218.          ret_val = ((long)(255)) << 16;
  1219.          ret_val |= 256;
  1220.          break;
  1221.  
  1222.     case 1:                /* Default palette settings.    */
  1223.          ret_val = (unsigned long)&Default_Palette;
  1224.          break;
  1225.  
  1226.     default:                /* Unknown command.        */
  1227.          break;
  1228.     }
  1229. return( ret_val);
  1230. }
  1231.  
  1232. /********************* CHAR_DRAW ****************************************/
  1233. /*    Draw a character.                        */
  1234. /************************************************************************/
  1235. void char_draw( unsigned char c)
  1236. {
  1237. static unsigned char char_bit_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
  1238. const CHAR_TABLE_ENTRY far *current;
  1239. int i, j, k, l, tx, ty;
  1240. unsigned char row_cur;
  1241.  
  1242. if( c > 127) return;        /* Don't do upper 128.            */
  1243. current = char_def + c;        /* Get character definition from ROM.    */
  1244. if( char_path == NORMAL_PATH)    /* Draw horizontal.            */
  1245.     {
  1246.     for( i = 0; i < 8; i++)            /*  For each row...    */
  1247.          {
  1248.          row_cur = (current->row)[i];        /* Def. for this line.    */
  1249.          for( j = 0; j < char_size; j++)    /* Size multiplier.    */
  1250.               {
  1251.           for( k = 0; k < 8; k++)         /*  For each column...    */
  1252.                {
  1253.                if( row_cur & char_bit_mask[k])    /* Column def.    */
  1254.                     {
  1255.                     for( l = 0; l < char_size; l++)    /* Draw 'size'    */
  1256.                          {                /*  points.    */
  1257.                  tx = CP_X;
  1258.                  ty = CP_Y;
  1259.                  DRAW_POINT( tx, ty);
  1260.                      CP_X++;
  1261.                      }
  1262.                 }
  1263.                else            /* Advance 'size' points.    */
  1264.                     {
  1265.                 CP_X += char_size;
  1266.                     }
  1267.                }
  1268.           CP_X -= char_size*8;        /* Back to begining col.*/
  1269.           CP_Y++;                /* Next line.        */
  1270.           }
  1271.          }
  1272.     CP_X += char_size*8;        /* Next character.        */
  1273.     CP_Y -= char_size*8;        /* Charcter top.        */
  1274.     }
  1275. else                /* Draw vertical.            */
  1276.     {
  1277.     for( i = 0; i < 8; i++)            /*  For each row...    */
  1278.          {
  1279.          row_cur = (current->row)[i];        /* Def. for this line.    */
  1280.          for( j = 0; j < char_size; j++)    /* Size multiplier.    */
  1281.               {
  1282.           for( k = 0; k < 8; k++)         /*  For each column...    */
  1283.                {
  1284.                if( row_cur & char_bit_mask[k])    /* Column def.    */
  1285.                     {
  1286.                     for( l = 0; l < char_size; l++)
  1287.                          {
  1288.                  tx = CP_X;
  1289.                  ty = CP_Y;
  1290.                  DRAW_POINT( tx, ty);
  1291.                      CP_Y--;
  1292.                      }
  1293.                 }
  1294.                else            /* Advance 'size' points.    */
  1295.                     {
  1296.                 CP_Y -= char_size;
  1297.                     }
  1298.                }
  1299.           CP_Y += char_size*8;        /* Back to begining col.*/
  1300.           CP_X++;                  /* Next line.        */
  1301.           }
  1302.          }
  1303.     CP_Y -= char_size*8;          /* Next character.        */
  1304.     CP_X -= char_size*8;          /* Charcter top.        */
  1305.     }
  1306. }
  1307.  
  1308. /************************* COPY_IMAGE ***********************************/
  1309. /*    Copy an image line from one area of memory to another.  The     */
  1310. /*  source image is repeated as necessary to fill the destination.      */
  1311. /*  This is sufficient to form the core of a basic set of two parameter    */
  1312. /*  BiTBlT routines except for the fact that no precautions are taken     */
  1313. /*  against overlap.  Could be sped up considerably by recoding in    */
  1314. /*  assembly code.                            */
  1315. /************************************************************************/
  1316.  
  1317. void copy_image( 
  1318.     unsigned char const far *from, 
  1319.     int from_xsize, 
  1320.         unsigned char far *to, 
  1321.     int to_xsize,
  1322.     int mode
  1323.     )
  1324. {
  1325.  
  1326. switch( mode)                /* Copy mode.            */
  1327.     {
  1328.     case COPY:                /* Copy verbatim.        */
  1329.          copy_mem( from, from_xsize, to, to_xsize);
  1330.      break;
  1331.  
  1332.     case XOR:                       /* Copy xor.            */
  1333.          xor_mem( from, from_xsize, to, to_xsize);
  1334.      break;
  1335.  
  1336.     case OR:                       /* Copy or.            */
  1337.          or_mem( from, from_xsize, to, to_xsize);
  1338.      break;
  1339.  
  1340.     case AND:                       /* Copy and.            */
  1341.          and_mem( from, from_xsize, to, to_xsize);
  1342.      break;
  1343.  
  1344.     case NEGATE:                   /* Copy negate.            */
  1345.          neg_mem( from, from_xsize, to, to_xsize);
  1346.      break;
  1347.  
  1348.     default:
  1349.          break;
  1350.     }
  1351. }
  1352.  
  1353. /*************************** SET_PATTERN ********************************/
  1354. /*    Change a bit pattern into a colour image pattern that can be    */
  1355. /*  easily copied.  The bit pattern is an 8x8 pattern.            */
  1356. /************************************************************************/
  1357.  
  1358. void set_pattern( unsigned char *current_pattern, 
  1359.           unsigned char const far *pattern)
  1360. {
  1361. static unsigned char pat_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
  1362. int i, j;
  1363.  
  1364. for( i = 0; i < 8; i++)        /* For each line.            */
  1365.     {
  1366.     for( j = 0; j < 8; j++)    /* For each column.            */
  1367.          {
  1368.      if( (*pattern) & pat_mask[j])    /* Set to fill colour.        */
  1369.           {
  1370.           *current_pattern = fill_colour;
  1371.           }
  1372.      else            /* Or the background colour.        */
  1373.           {
  1374.           *current_pattern = background_colour;
  1375.           }
  1376.      current_pattern++;
  1377.      }
  1378.     pattern++;            /* Next line.                */
  1379.     }
  1380. }
  1381.  
  1382.  
  1383.