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

  1. /***************************** NN9 DRIVER *******************************/
  2. /*    Revolution 1024 x 8 BGI driver.  This program acts as a BGI     */
  3. /*  driver for the Revolution 1024 x 8.  For this card the memory is     */
  4. /*  mapped as follows.  One pixel per byte, laid out linearly in 64K     */
  5. /*  pages (banks).  Only one bank (out of 16) is accesible at a time.    */
  6. /*    The resolution of this card is 1024 x 768 x 256.  However on    */
  7. /*  the system I have to test the first column does not display so it     */
  8. /*  is really only 1023 x 768 x 256.                    */
  9. /*                                    */
  10. /*    V 1.00  30/06/90  Robert Adsett                  */
  11. /*                This is the release version.  Some    */
  12. /*                features are not fully implemented yet    */
  13. /*                but it seems solid enough.        */
  14. /*    V 1.01    11/07/90  Robert Adsett Was copying one too many rows    */
  15. /*                    in save/restore bitmap.        */
  16. /*                                    */
  17. /*  LIMITATIONS:                            */
  18. /*    Flood fill is unimplemented at present.                */
  19. /*    Error checking & reporting are almost non-existant.        */
  20. /*    Everything that can be emulated is.  This seems to be         */
  21. /*   reasonably fast so changing this is not a high priority.        */
  22. /*    Does not use the 7220 for any operations that it could be used    */
  23. /*   for. (Including snow relief on changing palette colours.)        */
  24. /*                                    */
  25. /*  KNOWN BUGS:                                */
  26. /*    Line width is currently ignored.  This seems to be taken care    */
  27. /*   of by the kernal but should be changed.                */
  28. /************************************************************************/
  29.  
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include "bgi.h"
  33. #include "nn9.h"
  34.  
  35. /*    Generic driver global variables.  Should be present in almost    */
  36. /*  every driver.                            */
  37.  
  38. const CHAR_TABLE_ENTRY far * const char_def = 
  39.             (CHAR_TABLE_ENTRY far *)MK_FP( 0xf000, 0xfa6e);
  40.                 /* Pointer to character definition    */
  41.                 /*  table in ROM.            */
  42.  
  43.                 /* Fill pattern definitions.        */
  44. const FILLPATTERN def_patterns[12] = {
  45.         { 0, 0, 0, 0, 0, 0, 0, 0 },     /* No Fill.        */
  46.         { 0xff, 0xff, 0xff, 0xff, 
  47.           0xff, 0xff, 0xff, 0xff },    /* Solid Fill.        */
  48.         { 0xff, 0xff, 0, 0, 0xff, 
  49.           0xff, 0, 0},            /* Line Fill.        */
  50.         { 1, 2, 4, 8, 0x10, 0x20,
  51.           0x40, 0x80},            /* Lt Slash fill.    */
  52.         { 0xE0, 0xC1, 0x83, 0x07, 
  53.           0x0E, 0x1C, 0x38, 0x70 },    /* Slash Fill.        */
  54.         { 0xF0, 0x78, 0x3C, 0x1E, 
  55.           0x0F, 0x87, 0xC3, 0xE1 },    /* Backslash Fill.    */
  56.         { 0xA5, 0xD2, 0x69, 0xB4, 
  57.           0x5A, 0x2D, 0x96, 0x4B },    /* Lt Backslash Fill.    */
  58.         { 0xFF, 0x88, 0x88, 0x88, 
  59.           0xFF, 0x88, 0x88, 0x88 },    /* Hatch Fill.        */
  60.         { 0x81, 0x42, 0x24, 0x18, 
  61.           0x18, 0x24, 0x42, 0x81 },    /* XHatch Fill.        */
  62.         { 0xCC, 0x33, 0xCC, 0x33, 
  63.           0xCC, 0x33, 0xCC, 0x33 },    /* Interleave Fill.    */
  64.         { 0x80, 0x00, 0x08, 0x00, 
  65.           0x80, 0x00, 0x08, 0x00 },     /* Wide Dot Fill.    */
  66.         { 0x88, 0x00, 0x22, 0x00, 
  67.           0x88, 0x00, 0x22, 0x00 }    /* Close Dot Fill.    */
  68.            };
  69. /*                                    */
  70. /*    The following structure defines the Bit Manipulation Utility    */
  71. /*    function table.                            */
  72. /*                                    */
  73.  
  74. const UTILITIES Utility_Table = {    /* Bit Utilities Function Table */
  75.   (NRFPTR) dispatch_enter_graphics,    /* Enter graphics mode function */
  76.   (NRFPTR) dispatch_leave_graphics,    /* Leave graphics mode function */
  77.   (NRFPTR) dispatch_putpix,        /* Write a pixel function    */
  78.   (NRFPTR) dispatch_getpix,        /* Read a pixel function    */
  79.   (NRFPTR) dispatch_bits_per_pixel,    /* Bits per pixel value        */
  80.   (NRFPTR) dispatch_set_page,        /* Set the active drawing page    */
  81.   (NRFPTR) dispatch_set_visual,        /* Set the active display page    */
  82.   (NRFPTR) dispatch_set_write_mode    /* Set the current write mode    */
  83.   };
  84.  
  85. int MAXY = 767, MAXX = 1022, MINY = 0,     /* Clipping limits.        */
  86.     MINX = 0;
  87. unsigned int current_line_style = 0xffff;    /* Current line drawing    */
  88.                         /*  style.        */
  89. int current_write_mode = COPY;        /* Current drawing mode.    */
  90. int current_line_width = 1;        /* Current line width.        */
  91. unsigned char current_colour = 0xff,     /* Current drawing,        */
  92.           fill_colour = 0xff,    /*  filling,            */
  93.               background_colour = 0;    /*  and background colour.    */
  94.  
  95. unsigned int    CP_X = 0, CP_Y = 0;    /* Current Drawing Pointer CP.    */
  96. unsigned int    char_size, char_path;    /* Current character size and    */
  97.                     /*  drawing path.        */
  98.  
  99. const unsigned int line_style_mask[16] = {    /* A set of bit masks    */
  100.                     0x8000,    /*  used to mask bits    */
  101.                     0x4000,    /*  from the current    */
  102.                     0x2000,    /*  line style.        */
  103.                     0x1000,
  104.                     0x0800,
  105.                     0x0400,
  106.                     0x0200,
  107.                     0x0100,
  108.                     0x0080,
  109.                     0x0040,
  110.                     0x0020,
  111.                     0x0010,
  112.                     0x0008,
  113.                     0x0004,
  114.                     0x0002,
  115.                     0x0001
  116.                     };
  117.  
  118. STATUS    Stat_Block = {        /* Device status block.            */
  119.   0,                /* Current device status.        */
  120.   0,                /* Device Type Identifier.        */
  121.   1022,                /* Device Full Resolution in X        */
  122.   767,                /* Device Full Resolution in Y        */
  123.   1022,                /* Device Effective X Resolution    */
  124.   767,                /* Device Effective Y Resolution    */
  125.   9000,                /* Device X Size in inches*1000        */
  126.   7000,                /* Device Y Size in inches*1000        */
  127.   10000,            /* Aspect Ratio * 10000            */
  128.                   /* For compatibility the other fields     */
  129.                 /*  set so.                */
  130.   8,
  131.   8,
  132.   0x90,
  133.   0x90
  134.   };
  135.  
  136. NN9PALETTE Default_Palette = {    /* Default palette.              */
  137.   16, { 0x00, 0x00, 0x00,    /* In this case set during startup.    */
  138.       0x00, 0x00, 0x0f,    0x00, 0x0f, 0x00,    0x00, 0x00, 0x03,
  139.     0x00, 0x00, 0x04,    0x00, 0x00, 0x05,    0x00, 0x00, 0x07,
  140.     0x00, 0x00, 0x14,    0x00, 0x00, 0x38,    0x00, 0x00, 0x39,
  141.     0x00, 0x00, 0x3A,    0x00, 0x00, 0x3B,    0x00, 0x00, 0x3C,
  142.     0x00, 0x00, 0x3D,    0x00, 0x00, 0x3E,    0x00, 0x00, 0x3F,
  143.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  144.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  145.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  146.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  147.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  148.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  149.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  150.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  151.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  152.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  153.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  154.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  155.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  156.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  157.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  158.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  159.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  160.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  161.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  162.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  163.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  164.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  165.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  166.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  167.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  168.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  169.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  170.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  171.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  172.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  173.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  174.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  175.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  176.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  177.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  178.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  179.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  180.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  181.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  182.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  183.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  184.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  185.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  186.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  187.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  188.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  189.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  190.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  191.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  192.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  193.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  194.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  195.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  196.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  197.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  198.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  199.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  200.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  201.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  202.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  203.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  204.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  205.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  206.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  207.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  208.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  209.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  210.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  211.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  212.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  213.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  214.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  215.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  216.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  217.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  218.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  219.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  220.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  221.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0x00, 0x00, 0x00,
  222.     0x00, 0x00, 0x00,    0x00, 0x00, 0x00,    0xff, 0xff, 0xff}
  223.   };
  224.  
  225. /* Global variables specific to this driver.                */
  226.  
  227. unsigned char current_bank = 0;        /* The bank currently mapped    */
  228.                     /*  into memory.        */
  229.  
  230. SCREEN_PTR const screen_buffer = (SCREEN_PTR)MK_FP( NN9_SEGMENT, 0);
  231.                 /* Pointer to the base of video memory.    */
  232. unsigned char current_pattern[8][8];    /* Current fill pattern stored    */
  233.                     /*  as pixels.            */
  234. SCREEN_PTR current_address,    /* Current address into video memory.    */
  235.        old_address;        /* Previous address.  Used in         */
  236.                  /*   incrementing.            */
  237.  
  238. /*                                    */
  239. /*    Function Protoypes local to the ATI driver.            */
  240. /*                                    */
  241.  
  242. void copy_image( 
  243.     unsigned char const far *from, 
  244.     int from_xsize, 
  245.         unsigned char far *to, 
  246.     int to_xsize,
  247.     int mode
  248.     );
  249. void char_draw( unsigned char c);
  250. void set_pattern( unsigned char *current_pattern, 
  251.           unsigned char const far *pattern);
  252. void update_pattern( void);
  253.  
  254.  
  255. /******************************* INSTALL ********************************/
  256. /*    The Install function is used to prepare the driver to use.  The    */
  257. /*  calls to this function allow the kernal to inquire the mode     */
  258. /*  information, and allow the kernal to install the mode infomation.    */
  259. /*  sets the error code to 'grInvalidMode' for invalid mode numbers    */
  260. /*  and 'grError' for an unrecognized command.                */
  261. /************************************************************************/
  262.  
  263. const char *CopyRight = 
  264.    "Revolution Number Nine BGI driver (V 1.00) Copyright R. Adsett 1990.";
  265.  
  266.                 /* Names of the drivers modes.  The     */
  267.                 /*  first character is the length of     */
  268.                 /*  the string.                */
  269. char *Name[] = {
  270.         "\x29 NN9 Revolution 1024x8 (1024 x 768 x 256)"
  271.         };
  272.  
  273. long install(
  274.     unsigned int mode,    /* Mode to use.                */
  275.     char command        /* Install sub command.            */
  276.     )
  277. {
  278. long ret_code;
  279.  
  280. switch( command )            /* Determine the command to use */
  281.     {
  282.     case 0:                /* Install Device Command.    */
  283.          if((mode & 0xff) >= MAX_MODES)    /* Is the mode requested valid? */
  284.               {                /*  No set an error code.    */
  285.               Stat_Block.stat = grInvalidMode;
  286.           }
  287.          ret_code = (unsigned int)&Stat_Block;    /* Return pointer to     */
  288.          break;                    /*  the status block.    */
  289.  
  290.     case 1:                /* Mode Query Command.        */
  291.          ret_code = (long)MAX_MODES << 16; /* Return number of modes.    */
  292.          break;
  293.  
  294.     case 2:                /* Mode Name Command.        */
  295.          if( (mode & 0xff) > MAX_MODES)    /* Is the mode requested valid? */
  296.               {                /*  No set an error code.    */
  297.               Stat_Block.stat = grInvalidMode;
  298.           }
  299.                           /* Return pointer to the name.    */
  300.          ret_code = (unsigned int)Name[mode & 0xff];
  301.          break;
  302.  
  303.     default:                /* Unknown Install Call.    */
  304.          Stat_Block.stat = grError;    /* General error.        */
  305.          break;
  306.     }                    /* End of Install command case.    */
  307. return( ret_code);            /* Return pointer, mode numbers */
  308. }
  309.  
  310. /******************************* INITIALIZE *****************************/
  311. /*    The initialize function is used to enter the graphics mode.    */
  312. /*  Save the current mode so that it can be restored later.        */
  313. /************************************************************************/
  314.  
  315. void init( unsigned int dit_offset, unsigned int dit_segment)
  316. {
  317. struct DIT far *Dev_info;
  318.  
  319. Dev_info = (struct DIT far *)MK_FP( dit_segment, dit_offset);
  320.  
  321. background_colour = Dev_info->background;
  322.                     /* Set the background colour.    */
  323. update_pattern();            /* Set up the pattern for use.    */
  324.  
  325. if( Dev_info->init != 0xA5)        /* Don't ask me!        */
  326.     {
  327.     }
  328. palette( 0x80ff, 0xff,  0xff, 0xff);    /* Last Palette entry is bright    */
  329.                     /*  white.  Set the rest to the    */
  330.                     /*  EGA defaults.        */
  331.  
  332. palette( 0x8000, 0x00,  0x00, 0x00);    /* Black.            */
  333. palette( 0x8001, 0x00,  0x00, 0x7f);    /* Blue.            */
  334. palette( 0x8002, 0x00,  0x7f, 0x00);    /* Green.            */
  335. palette( 0x8003, 0x00,  0x7f, 0x7f);    /* Cyan.            */
  336. palette( 0x8004, 0x7f,  0x00, 0x00);    /* Red.                */
  337. palette( 0x8005, 0x7f,  0x00, 0x7f);    /* Magenta.            */
  338. palette( 0x8006, 0x7f,  0x7f, 0x00);    /* Broen.            */
  339. palette( 0x8007, 0x9f,  0x9f, 0x9f);    /* LightGray.            */
  340. palette( 0x8008, 0x5f,  0x5f, 0x5f);    /* DarkGray.            */
  341. palette( 0x8009, 0x00,  0x00, 0xff);    /* LighBlue.            */
  342. palette( 0x800a, 0x00,  0xff, 0x00);    /* LightGreen.            */
  343. palette( 0x800b, 0x00,  0xff, 0xff);    /* LightCyan.            */
  344. palette( 0x800c, 0xff,  0x00, 0x00);    /* LightRed.            */
  345. palette( 0x800d, 0xff,  0x00, 0xff);    /* LightMagenta.        */
  346. palette( 0x800e, 0xff,  0xff, 0x00);    /* Yellow.            */
  347. palette( 0x800f, 0xff,  0xff, 0xff);    /* White.            */
  348. palette( 0x80ff, 0xff,  0xff, 0xff);    /* White.            */
  349.  
  350.     /*  Get a copy of the default palette.                */
  351. copy_mem( MK_FP( NN9_PALETTE, 0), 256, &(Default_Palette.colora[0]), 256);
  352. copy_mem( MK_FP( NN9_PALETTE, 0x1000), 256, &(Default_Palette.colora[256]), 
  353.           256);
  354. copy_mem( MK_FP( NN9_PALETTE, 0x2000), 256, &(Default_Palette.colora[512]), 
  355.           256);
  356. }
  357.  
  358. /******************************* CLEAR **********************************/
  359. /*    Clear the screen.  Write zero everywhere.              */
  360. /************************************************************************/
  361.  
  362. void clear( void )
  363. {
  364.  
  365. for( current_bank = 0; current_bank < BANKS; current_bank++)
  366.     {
  367.     BANK_SELECT();
  368.     set_mem( screen_buffer, 0, 0);
  369.     }
  370. }
  371.  
  372. /********************************** POST ********************************/
  373. /*    Go to text mode.  Use mode stored previously.            */
  374. /************************************************************************/
  375.  
  376. void post( void )
  377. {
  378. }
  379.  
  380. /********************************* MOVE *********************************/
  381. /*    This function is used to move the current pointer (CP). This is    */
  382. /*  a pretty generic routine, library later?                  */
  383. /************************************************************************/
  384.  
  385. void move( int x, int y)
  386. {
  387.  
  388. CP_X = x;                /* Update the current pointer.    */
  389. CP_Y = y;
  390. }
  391.  
  392. /******************************** DRAW **********************************/
  393. /*    Draw a line vector from the CP to the specified coordinate.    */
  394. /*  Update the CP to the new coordinate.                */
  395. /************************************************************************/
  396.  
  397. void draw( int x, int y)
  398. {
  399.  
  400. line( CP_X, CP_Y, x, y);        /* Draw the line.        */
  401. CP_X = x;                /* Update the current pointer    */
  402. CP_Y = y;
  403. }
  404.  
  405. /********************************* VECT *********************************/
  406. /*    Draw a line between the two specified points.            */
  407. /************************************************************************/
  408.  
  409. void vect( int x1, int y1, int x2, int y2)
  410. {
  411.  
  412. line( x1, y1, x2, y2);        /* Draw the line.            */
  413. }
  414.  
  415. /********************************* PATBAR *******************************/
  416. /*    Fill a rectangle with the current filling pattern.  Do not     */
  417. /*  outline.  The coordinates passed are the upper left corner and the    */
  418. /*  lower right corner.                            */
  419. /************************************************************************/
  420.  
  421. void patbar( int x1, int y1, int x2, int y2)
  422. {
  423. int x3, y3;
  424.  
  425. if( x2 < x1)            /* Sometimes the emulation routines get    */
  426.     {                /*   the y coords. backwards.  We'll    */
  427.     x3 = x2; x2 = x1; x1 = x3;    /*   check the x coords. as well just     */
  428.     }                /*   to be sure.            */
  429. if( y2 < y1)
  430.     {
  431.     y3 = y2; y2 = y1; y1 = y3;
  432.     }
  433. for( ; y1 <= y2; y1++)        /* For each line.            */
  434.     {
  435.     int pre_done;
  436.  
  437.     x3 = x1;
  438.     y3 = y1;
  439.     pre_done = 0;
  440.     CALC_ADDR( x3, y3);        /* Calculate start address....        */
  441.     if( (x3 & 7) != 0)
  442.          {
  443.      int size;
  444.  
  445.      pre_done = 8 - (x3 & 7);
  446.      size = ((x2-x1+1) < pre_done) ? (x2-x1+1) : pre_done;
  447.          copy_image( ¤t_pattern[y1&7][x3&7], pre_done, 
  448.                  current_address, size, COPY);
  449.          CALC_ADDR( x3 + pre_done, y3);    /* Calculate start address....    */
  450.      x3 += pre_done;
  451.      }
  452.     if( pre_done < x2-x1+1)
  453.          {
  454.      int size;
  455.  
  456.      size = x2 - x1 + 1 - pre_done;
  457.          copy_image( current_pattern[y1&7], 8, current_address, 
  458.                       size, COPY);
  459.                     /* ... and copy appropriate line of the    */
  460.                 /*  current pattern in.            */
  461.      }
  462.     }
  463. }
  464.  
  465. /******************************* PALETTE ********************************/
  466. /*    Set the colour palette entries.  Only the set RGB colour method    */
  467. /*  is supported.                            */
  468. /************************************************************************/
  469.  
  470. void palette( int flag_index, int red_colour,  int blue, int green)
  471. {
  472. int index;
  473. unsigned char r, g, b;
  474. SCREEN_PTR pal;
  475.  
  476. pal = MK_FP( NN9_PALETTE, 0);
  477. index = flag_index & 0xff;        /* Grab colour table index.    */
  478. r = red_colour & 0xff;            /* Grab colours.        */
  479. g = green & 0xff;
  480. b = blue & 0xff;
  481. switch(flag_index & 0xc000)
  482.     {
  483.     case 0x4000:
  484.          /*    unused.                            */
  485.      break;
  486.  
  487.     case 0x0000:            /* Load colour table with colour*/
  488.      b = r & 3;            /*  in red_colour.  It's mapped    */
  489.      g = (r >> 2) & 3;        /*  as 2 bits each for red,     */
  490.      r = (r >> 4) & 3;        /*  green, and blue.  Set up    */
  491.      /*FALLTHROUGH*/        /*  and let setrgb do the work.    */
  492.  
  493.     case 0x8000:            /* Load rgb.            */
  494.      *(pal + index) = r;
  495.      *(pal + 0x1000 + index) = g;
  496.      *(pal + 0x2000 + index) = b;
  497.      break;
  498.          
  499.     case 0xc000:            /*  Load background.        */
  500.          background_colour = r;
  501.      break;
  502.     }
  503. }
  504.  
  505. /****************************** ALLPALETTE ******************************/
  506. /*    The BGI kernal only passes the first 16 entries.  Therefore     */
  507. /*  this function ignores the passed argument and simply restores the    */
  508. /*  default palette.  (At least that way the results are consistent).     */
  509. /************************************************************************/
  510.  
  511. void allpalette( unsigned int pptr_offset, unsigned int pptr_segment)
  512. {
  513.  
  514. copy_mem( &(Default_Palette.colora[0]), 256, MK_FP( NN9_PALETTE, 0), 256);
  515. copy_mem( &(Default_Palette.colora[256]), 256, MK_FP( NN9_PALETTE, 0x1000),
  516.           256);
  517. copy_mem( &(Default_Palette.colora[512]), 256, MK_FP( NN9_PALETTE, 0x2000),
  518.           256);
  519. }
  520.  
  521. /******************************* COLOR **********************************/
  522. /*    Sets new foreground (drawing) and fill colours.            */
  523. /************************************************************************/
  524.  
  525. void color( char new_fill_colour, char new_draw_colour )
  526. {
  527.  
  528. new_draw_colour &= 0xff;    /* Mask colours to possible range.    */
  529. new_fill_colour &= 0xff;
  530. current_colour = new_draw_colour;
  531. fill_colour = new_fill_colour;
  532. update_pattern();        /* Update current pattern to reflect    */
  533.                 /*   the new colours.            */
  534. }
  535.  
  536. /******************************* FILLSTYLE ******************************/
  537. /*    Set the current fillstyle.                    */
  538. /************************************************************************/
  539.  
  540. static int current_pattern_no = 0, user_pattern[8] = {0};
  541.                 /* Current pattern and user pattern.    */
  542.  
  543. void fillstyle( unsigned char pattern, unsigned int pptr_offset,
  544.     unsigned int pptr_segment)
  545. {
  546. unsigned char far *pptr;
  547. int i;
  548.  
  549. pptr = MK_FP( pptr_segment, pptr_offset);    /* Ptr. to user line    */
  550.                         /*   style.        */
  551. current_pattern_no = pattern;        /* Save current style.        */
  552. if( current_pattern_no == 0xff )    /* User defined line style    */
  553.     {
  554.     set_pattern( (unsigned char *)¤t_pattern, pptr);
  555.                     /* Make pattern accessible to filling     */
  556.                 /*   routine.                */
  557.     for( i = 0; i < 8; i++)    /* Save User pattern for later use.    */
  558.          {
  559.      user_pattern[i] = *(int far *)(pptr + i*sizeof( int));
  560.      }
  561.     }
  562. else
  563.     {
  564.     set_pattern( (unsigned char *)current_pattern, 
  565.                  (unsigned char far *)&def_patterns[pattern]);
  566.                     /* Make pattern accessible to filling     */
  567.                 /*   routine.                */
  568.     }
  569. }
  570.  
  571. void update_pattern( void)    /* Update pattern to take care of new    */
  572. {                /*   colours.                */
  573.  
  574. if( current_pattern_no == 0xff )    /* User defined line style    */
  575.     {
  576.     set_pattern( (unsigned char *)current_pattern, 
  577.                  (unsigned char far *)user_pattern);
  578.                     /* Make pattern accessible to filling     */
  579.                 /*   routine.                */
  580.     }
  581. else
  582.     {
  583.     set_pattern( (unsigned char *)current_pattern, 
  584.                  (unsigned char far *)&def_patterns[current_pattern_no]);
  585.                     /* Make pattern accessible to filling     */
  586.                 /*   routine.                */
  587.     }
  588. }
  589.  
  590. /******************************* LINESTYLE ******************************/
  591. /*    Set the current line style.  This includes drawing pattern and    */
  592. /*  width.                                */
  593. /************************************************************************/
  594.  
  595. void linestyle( char style, int pattern, int width)
  596. {
  597.  
  598. switch( style)            /* Set appropriate line pattern.    */
  599.     {
  600.     case SOLID_LINE:
  601.          current_line_style = 0xffff;
  602.      break;
  603.  
  604.     case DOTTED_LINE:
  605.          current_line_style = 0xCCCC;
  606.      break;
  607.  
  608.     case CENTRE_LINE:
  609.          current_line_style = 0xFC78;
  610.      break;
  611.  
  612.     case DASHED_LINE:
  613.          current_line_style = 0xF8F8;
  614.      break;
  615.  
  616.     case USER_LINE:
  617.          current_line_style = pattern;
  618.      break;
  619.  
  620.     default:
  621.          break;
  622.     }
  623. current_line_width = width;        /* Save the width.        */
  624. }
  625.  
  626. /******************************* TEXTSTYLE ******************************/
  627. /*    Set the text path and size.  Returns x & y size as a long.    */
  628. /************************************************************************/
  629.  
  630. long textstyle( char number, char path, int xsize, int ysize)
  631. {
  632.  
  633. char_path = path;            /* Record path.            */
  634. char_size = xsize >> 3;            /* Convert text size to a    */
  635.                     /*  multiple of 8.        */
  636. if( char_size == 0)            /* Must be at least 1.        */
  637.     char_size = 1;
  638. xsize = ysize = char_size << 3;        /* Compute actual size.        */
  639. return( (((long)xsize) << 16) | ysize);    /* Return actual size.        */
  640. }
  641.  
  642. /******************************** TEXT **********************************/
  643. /*    Draw a text string.                        */
  644. /************************************************************************/
  645.  
  646. void text( int length, unsigned int offset, unsigned int segment)
  647. {
  648. char far * cptr = MK_FP( segment, offset);
  649. int i;
  650.  
  651. for( i = 0; i < length; ++i )         /* For all characters ...    */
  652.     {
  653.     char_draw( *cptr++);        /* Draw it.            */
  654.     }
  655. }
  656.  
  657. /****************************** FLOODFILL *******************************/
  658. /*    Unimplemented. Null function.  Is this really of importance to    */
  659. /*  anyone?                                */
  660. /************************************************************************/
  661.  
  662. void floodfill( int x, int y, unsigned char boundary)
  663. {
  664. }
  665.  
  666. /******************************* BITMAPUTIL *****************************/
  667. /*    Get the address of the bit map utility table.            */
  668. /************************************************************************/
  669.  
  670. void *bitmaputil( void )
  671. {
  672.  
  673. return(&Utility_Table);
  674. }
  675.  
  676. /*                                    */
  677. /*    The following define the bit map utility functions.        */
  678. /*                                    */
  679.  
  680. void enter_graphics( void )        /* Enter graphics mode function.*/
  681. {                    /* Null function.        */
  682. }
  683.  
  684. void leave_graphics( void )        /* Leave graphics mode function */
  685. {                    /* Null function.        */
  686. }
  687.  
  688. int bits_per_pixel( void )        /* Enter graphics mode function */
  689. {
  690.  
  691. return( 8);                /* Always 8 bits/pixel.        */
  692. }
  693.  
  694. void putpix( int x, int y, char colour)    /* Write a pixel function    */
  695. {
  696.  
  697. colour &= 0xff;
  698. CALC_ADDR( x, y);            /* Calculate address.        */
  699. POINT( colour);                /* Draw pixel.            */
  700. }
  701.  
  702. char getpix( int x, int y)        /* Read a pixel function    */
  703. {
  704.  
  705. CALC_ADDR( x, y);            /* Calculate address.        */
  706. return( RD_POINT());            /* Read pixel colour.        */
  707. }
  708.  
  709. void set_page( char page)        /* Set the active drawing page    */
  710. {                    /* Null function.  Only 1 page.    */
  711.  
  712. }
  713.  
  714. void set_visual( char page)        /* Set the active display page    */
  715. {                    /* Null function.  Only 1 page.    */
  716.  
  717. }
  718.  
  719. void set_write_mode( int mode)        /* Set the current write mode    */
  720. {
  721.  
  722. current_write_mode = mode;        /* Save write mode.        */
  723. }
  724.  
  725.  
  726. /****************************** RESTOREBITMAP ***************************/
  727. /*    Copy a bitmap to video memory.                    */
  728. /************************************************************************/
  729.  
  730. void restorebitmap( char mode, unsigned int segment, unsigned int offset,
  731.         int x1, int y1, int x2, int y2)
  732. {
  733. const unsigned char far *buffer;
  734. int xsize, x3, y3, bump;
  735.  
  736. x1 = x2;        /* Bug in doc's. */
  737. y1 = y2;
  738.  
  739. buffer = (const unsigned char far *)MK_FP( segment, offset);
  740.                     /* Bitmap address.        */
  741. xsize = *(int far *)buffer + 1;        /* Columns.            */
  742. buffer += sizeof( int);
  743. y2 = y1 + *(int far *)buffer + 1;    /* Rows.            */
  744. bump = xsize;                /* Size of row in memory.  This    */
  745.                     /* should be agreed on with     */
  746.                     /* 'savebitmap'.        */
  747. buffer += sizeof(int);            /* Increment to storage.    */
  748. for( ;y1 < y2; y1++)            /* For each line...        */
  749.     {
  750.     x3 = x1;
  751.     y3 = y1;
  752.     CALC_ADDR( x3, y3);            /* Find the beginning.        */
  753.     copy_image( buffer, xsize, current_address, xsize, mode);
  754.                         /* Copy the line using the    */
  755.                     /*  appropriate mode.        */
  756.     buffer += bump;            /* Increment bitmap to the next    */
  757.     }                    /*  line.            */
  758. }
  759.  
  760. /****************************** SAVEBITMAP ******************************/
  761. /*    Copy an area of video memory to a bitmap.            */
  762. /************************************************************************/
  763.  
  764. void savebitmap( unsigned int buff_segment, unsigned int buff_offset,
  765.         int x1, int y1, int x2, int y2)
  766. {
  767. unsigned char far *buffer;
  768. int xsize, x3, y3, bump;
  769.  
  770. x1 = x2;        /* Bug in doc's. */
  771. y1 = y2;
  772. buffer = (unsigned char far *)MK_FP( buff_segment, buff_offset);
  773.                     /* Bitmap address.        */
  774. xsize = *(int far *)buffer + 1;        /* Columns.            */
  775. buffer += sizeof( int);
  776. y2 = y1 + *(int far *)buffer + 1;    /* Rows.            */
  777. bump = xsize;                /* Size of row in memory.  This    */
  778.                     /* should be agreed on with     */
  779.                     /* 'restorebitmap'.        */
  780. buffer += sizeof(int);            /* Increment to storage.    */
  781. for( ;y1 < y2; y1++)            /* For each line...        */
  782.     {
  783.     x3 = x1;
  784.     y3 = y1;
  785.     CALC_ADDR( x3, y3);            /* Find the beginning.        */
  786.     copy_image( current_address, xsize, buffer, xsize, COPY);
  787.                         /* Copy the line using the    */
  788.                     /*  copy mode.            */
  789.     buffer += bump;            /* Increment bitmap to the next    */
  790.     }                    /*  line.            */
  791. }
  792.  
  793. /****************************** SETCLIP *********************************/
  794. /*    Set the clipping area.    Library?                */
  795. /************************************************************************/
  796.  
  797. void setclip( int x1, int y1, int x2, int y2)
  798. {
  799.  
  800. MINX = x1;                /* Save the clipping limits.    */
  801. MAXY = y1;
  802. MAXX = x2;
  803. MAXY = y2;
  804. }
  805.  
  806. /***************************** GET_PIXEL ********************************/
  807. /*    Read a pixel colour from the screen.                */
  808. /************************************************************************/
  809.  
  810. char get_pixel( int x, int y)
  811. {
  812.  
  813. CALC_ADDR( x, y);            /* Calculate the address.    */
  814. return( RD_POINT());            /* Read the pixel.        */
  815. }
  816.  
  817. /***************************** SET_PIXEL ********************************/
  818. /*    Set a pixel to a specific colour.                */
  819. /************************************************************************/
  820.  
  821. void set_pixel( int x, int y, char colour)
  822. {
  823.  
  824. colour &= 0xff;
  825. CALC_ADDR( x, y);            /* Calculate address.        */
  826. POINT( colour);                /* Draw the pixel.        */
  827. }
  828.  
  829. /****************************** TEXTSIZ *********************************/
  830. /*    Return the pixel size of a string.                */
  831. /************************************************************************/
  832.  
  833. long textsiz( int length, unsigned int offset, unsigned int segment)
  834. {
  835. if( char_path == NORMAL_PATH)        /* Horizontal.            */
  836.     {
  837.     return( (((long)(length*char_size*8))<<16) | (8*char_size));
  838.     }
  839. else                    /* Vertical.            */
  840.     {
  841.     return( (((long)(char_size*8))<<16) | (length*8*char_size));
  842.     }
  843. }
  844.  
  845. /****************************** COLOR_QUERY *****************************/
  846. /*    Get colour palette & size.                    */
  847. /************************************************************************/
  848.  
  849. long color_query( char command_type)
  850. {
  851. long ret_val;
  852.  
  853.  
  854. switch( command_type )            /* Act on the input command.    */
  855.     {
  856.     case 0:                /* Color palette size query.    */
  857.          ret_val = ((long)(255)) << 16;
  858.          ret_val |= 256;
  859.          break;
  860.  
  861.     case 1:                /* Default palette settings.    */
  862.          ret_val = (unsigned long)&Default_Palette;
  863.          break;
  864.  
  865.     default:                /* Unknown command.        */
  866.          break;
  867.     }
  868. return( ret_val);
  869. }
  870.  
  871. /********************* CHAR_DRAW ****************************************/
  872. /*    Draw a character.                        */
  873. /************************************************************************/
  874. void char_draw( unsigned char c)
  875. {
  876. static unsigned char char_bit_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
  877. const CHAR_TABLE_ENTRY far *current;
  878. int i, j, k, l, tx, ty;
  879. unsigned char row_cur;
  880.  
  881. if( c > 127) return;        /* Don't do upper 128.            */
  882. current = char_def + c;        /* Get character definition from ROM.    */
  883. if( char_path == NORMAL_PATH)    /* Draw horizontal.            */
  884.     {
  885.     for( i = 0; i < 8; i++)            /*  For each row...    */
  886.          {
  887.          row_cur = (current->row)[i];        /* Def. for this line.    */
  888.          for( j = 0; j < char_size; j++)    /* Size multiplier.    */
  889.               {
  890.           for( k = 0; k < 8; k++)         /*  For each column...    */
  891.                {
  892.                if( row_cur & char_bit_mask[k])    /* Column def.    */
  893.                     {
  894.                     for( l = 0; l < char_size; l++)    /* Draw 'size'    */
  895.                          {                /*  points.    */
  896.                  tx = CP_X;
  897.                  ty = CP_Y;
  898.                  DRAW_POINT( tx, ty);
  899.                      CP_X++;
  900.                      }
  901.                 }
  902.                else            /* Advance 'size' points.    */
  903.                     {
  904.                 CP_X += char_size;
  905.                     }
  906.                }
  907.           CP_X -= char_size*8;        /* Back to begining col.*/
  908.           CP_Y++;                /* Next line.        */
  909.           }
  910.          }
  911.     CP_X += char_size*8;        /* Next character.        */
  912.     CP_Y -= char_size*8;        /* Charcter top.        */
  913.     }
  914. else                /* Draw vertical.            */
  915.     {
  916.     for( i = 0; i < 8; i++)            /*  For each row...    */
  917.          {
  918.          row_cur = (current->row)[i];        /* Def. for this line.    */
  919.          for( j = 0; j < char_size; j++)    /* Size multiplier.    */
  920.               {
  921.           for( k = 0; k < 8; k++)         /*  For each column...    */
  922.                {
  923.                if( row_cur & char_bit_mask[k])    /* Column def.    */
  924.                     {
  925.                     for( l = 0; l < char_size; l++)
  926.                          {
  927.                  tx = CP_X;
  928.                  ty = CP_Y;
  929.                  DRAW_POINT( tx, ty);
  930.                      CP_Y--;
  931.                      }
  932.                 }
  933.                else            /* Advance 'size' points.    */
  934.                     {
  935.                 CP_Y -= char_size;
  936.                     }
  937.                }
  938.           CP_Y += char_size*8;        /* Back to begining col.*/
  939.           CP_X++;                  /* Next line.        */
  940.           }
  941.          }
  942.     CP_Y -= char_size*8;          /* Next character.        */
  943.     CP_X -= char_size*8;          /* Charcter top.        */
  944.     }
  945. }
  946.  
  947. /************************* COPY_IMAGE ***********************************/
  948. /*    Copy an image line from one area of memory to another.  The     */
  949. /*  source image is repeated as necessary to fill the destination.      */
  950. /*  This is sufficient to form the core of a basic set of two parameter    */
  951. /*  BiTBlT routines except for the fact that no precautions are taken     */
  952. /*  against overlap.  Could be sped up considerably by recoding in    */
  953. /*  assembly code.                            */
  954. /************************************************************************/
  955.  
  956. void copy_image( 
  957.     unsigned char const far *from, 
  958.     int from_xsize, 
  959.         unsigned char far *to, 
  960.     int to_xsize,
  961.     int mode
  962.     )
  963. {
  964.  
  965. switch( mode)                /* Copy mode.            */
  966.     {
  967.     case COPY:                /* Copy verbatim.        */
  968.          copy_mem( from, from_xsize, to, to_xsize);
  969.      break;
  970.  
  971.     case XOR:                       /* Copy xor.            */
  972.          xor_mem( from, from_xsize, to, to_xsize);
  973.      break;
  974.  
  975.     case OR:                       /* Copy or.            */
  976.          or_mem( from, from_xsize, to, to_xsize);
  977.      break;
  978.  
  979.     case AND:                       /* Copy and.            */
  980.          and_mem( from, from_xsize, to, to_xsize);
  981.      break;
  982.  
  983.     case NEGATE:                   /* Copy negate.            */
  984.          neg_mem( from, from_xsize, to, to_xsize);
  985.      break;
  986.  
  987.     default:
  988.          break;
  989.     }
  990. }
  991.  
  992. /*************************** SET_PATTERN ********************************/
  993. /*    Change a bit pattern into a colour image pattern that can be    */
  994. /*  easily copied.  The bit pattern is an 8x8 pattern.            */
  995. /************************************************************************/
  996.  
  997. /*static*/ unsigned char pat_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
  998. void set_pattern( unsigned char *current_pattern, 
  999.           unsigned char const far *pattern)
  1000. {
  1001. int i, j;
  1002.  
  1003. for( i = 0; i < 8; i++)        /* For each line.            */
  1004.     {
  1005.     for( j = 0; j < 8; j++)    /* For each column.            */
  1006.          {
  1007.      if( (*pattern) & pat_mask[j])    /* Set to fill colour.        */
  1008.           {
  1009.           *current_pattern = fill_colour;
  1010.           }
  1011.      else            /* Or the background colour.        */
  1012.           {
  1013.           *current_pattern = background_colour;
  1014.           }
  1015.      current_pattern++;
  1016.      }
  1017.     pattern++;            /* Next line.                */
  1018.     }
  1019. }
  1020.  
  1021.  
  1022.