home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / BGIDRV.ZIP / DEBUG.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-31  |  33.1 KB  |  1,288 lines

  1.  
  2. /*
  3.  
  4.     DEBUG.C - sample debugging BGI driver
  5.  
  6.     Copyright (c) 1988,89 Borland International
  7.  
  8. */
  9.  
  10.  
  11.  
  12.  
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <dos.h>
  16.  
  17. /* ----------------------------- DEBUG.C ------------------------------ */
  18. /*                                    */
  19. /*    Function Protoypes for the debug driver.            */
  20. /*                                    */
  21.  
  22. void save_regs( void );
  23. void banner( char *str );
  24. void putnum( unsigned number );
  25. void puthex( unsigned number );
  26. void dputs( char far *str );
  27. void crlf( void );
  28.  
  29. void far enter_graphics( void );
  30. void far leave_graphics( void );
  31. void far putpix( void );
  32. void far getpix( void );
  33. void far set_visual( void );
  34. void far set_page( void );
  35. void far set_write_mode( void );
  36.  
  37. typedef void far (*FRFPTR)( void );    /* Pointer to Void/Void Funct    */
  38. typedef void     (*NRFPTR)( void );    /* Pointer to Void/Void Funct    */
  39.  
  40. /*                                    */
  41. /*    The following C structure defines a Device Status Block.    */
  42. /*                                    */
  43.  
  44. typedef struct {
  45.   unsigned char   stat;            /* Current device status.    */
  46.   unsigned char   devtype;        /* Device Type Identifier.    */
  47.   unsigned int      xres;            /* Device Full Resolution in X    */
  48.   unsigned int      yres;            /* Device Full Resolution in Y    */
  49.   unsigned int      xefres;        /* Device Effective X Resolution*/
  50.   unsigned int      yefres;        /* Device Effective Y Resolution*/
  51.   unsigned int      xinch;        /* Device X Size in inches*1000 */
  52.   unsigned int      yinch;        /* Device Y Size in inches*1000 */
  53.   unsigned int      aspec;        /* Aspect Ratio * 10000        */
  54.   unsigned char   chsizx;        /* Standard char size X        */
  55.   unsigned char   chsizy;        /* Standard char size Y        */
  56.   unsigned char   fcolors;        /* Number of foreground colors    */
  57.   unsigned char   bcolors;        /* Number of background colors    */
  58. } STATUS;
  59.  
  60. /*                                    */
  61. /*    The following structure defines a palette record.        */
  62. /*                                    */
  63.  
  64. typedef struct {
  65.   unsigned char length;            /* # of color entries in palette*/
  66.   unsigned char color[16];        /* Up to 16 color entries    */
  67.   } PALETTE;
  68.  
  69. /*                                    */
  70. /*    The following structure defines a utility function table.    */
  71. /*                                    */
  72.  
  73. typedef struct {
  74.   NRFPTR  goto_graph;            /* Enter graphics mode function */
  75.   NRFPTR  exit_graph;            /* Leave graphics mode function */
  76.   NRFPTR  putpix;            /* Write a pixel function    */
  77.   NRFPTR  getpix;            /* Read a pixel function    */
  78.   int      bits_per_pixel;        /* Bits per pixel value        */
  79.   NRFPTR  set_page;            /* Set the active drawing page    */
  80.   NRFPTR  set_visual;            /* Set the active display page    */
  81.   NRFPTR  write_mode;            /* Set the current write mode    */
  82.   } UTILITIES;
  83.  
  84. /*                                    */
  85. /*    This status block declares the debug driver to appear as an    */
  86. /*    EGA card in high resolution mode.                */
  87. /*                                    */
  88.  
  89. STATUS    Stat_Block = {        /* Status block to fake an EGA driver    */
  90.   0,                /* Current device status.        */
  91.   0,                /* Device Type Identifier.        */
  92.   639,                /* Device Full Resolution in X        */
  93.   479,                /* Device Full Resolution in Y        */
  94.   639,                /* Device Effective X Resolution    */
  95.   479,                /* Device Effective Y Resolution    */
  96.   9000,                /* Device X Size in inches*1000        */
  97.   7000,                /* Device Y Size in inches*1000        */
  98.   10000,            /* Aspect Ratio * 10000            */
  99.   8  + 0x80,            /* Standard char size X            */
  100.   8  + 0x80,            /* Standard char size Y            */
  101.   16 + 0x80,            /* Number of foreground colors        */
  102.   16 + 0x80            /* Number of background colors        */
  103.   };
  104.  
  105. /*                                    */
  106. /*    This palette declares the default EGA palette.            */
  107. /*                                    */
  108.  
  109. PALETTE Default_Palette = {    /* Define the palette for above EGA mode*/
  110.   16, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
  111.     0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F    }
  112.   };
  113.  
  114. /*                                    */
  115. /*    The following structure defines the Bit Manipulation Utility    */
  116. /*    function table.                            */
  117. /*                                    */
  118.  
  119. UTILITIES Utility_Table = {        /* Bit Utilities Function Table */
  120.   (NRFPTR) enter_graphics,        /* Enter graphics mode function */
  121.   (NRFPTR) leave_graphics,        /* Leave graphics mode function */
  122.   (NRFPTR) putpix,            /* Write a pixel function    */
  123.   (NRFPTR) getpix,            /* Read a pixel function    */
  124.   4,                    /* Bits per pixel value        */
  125.   (NRFPTR) set_page,            /* Set the active drawing page    */
  126.   (NRFPTR) set_visual,            /* Set the active display page    */
  127.   (NRFPTR) set_write_mode        /* Set the current write mode    */
  128.   };
  129.  
  130. /*                                    */
  131. /*    The following defines the name of the modes for Driver.        */
  132. /*    NOTE: The string must start with a PASCAL style length.        */
  133. /*                                    */
  134.  
  135. char Name[] = "\030Debug Driver (640 x 480)";
  136.  
  137. /*    Driver Local Data Variables                    */
  138.  
  139. char Buffer[80] = { 0 };        /* String output buffer        */
  140.  
  141. unsigned int    CP_X = 0, CP_Y = 0;    /* Current Drawing Pointer CP    */
  142.  
  143. unsigned int  ds = 0;            /* DS on entry to the driver    */
  144. unsigned int  ax = 0, bx = 0, cx = 0, dx = 0;
  145. unsigned int  ah = 0, bh = 0, ch = 0, dh = 0;
  146. unsigned int  al = 0, bl = 0, cl = 0, dl = 0;
  147.  
  148. /* ----------------------------- INSTALL ------------------------------- */
  149. /*                                     */
  150. /*    The Install function is used to prepare the driver to use.     */
  151. /*    The calls to this function allow the kernal to inquire the     */
  152. /*    mode information, and allow the kernal to install the mode     */
  153. /*    infomation.                             */
  154. /*                                     */
  155.  
  156. void install( void )
  157. {
  158.  
  159.   save_regs();                /* Save a copy of current regs    */
  160.  
  161.   banner( "INSTALL" );            /* Announce the function type    */
  162.   switch( al ){                /* Determine the command to use */
  163.  
  164.     case 0:                /* Install Device Command    */
  165.       dputs( "    Install Device:   Mode Number: " );
  166.       putnum( cl );
  167.       dputs( "  AutoDetect Maximum: " );
  168.       putnum( ch );
  169.       crlf();
  170.  
  171.       _ES = _CS;            /* Make ES:BX point to block    */
  172.       _BX = (unsigned int) &Stat_Block; /* BX points to status block    */
  173.       break;
  174.  
  175.     case 1:                /* Mode Query Command        */
  176.       dputs( "    Mode Query Request (1 Mode)\r\n" );
  177.       _CX = 1;                /* Return only 1 mode supported */
  178.       break;
  179.  
  180.     case 2:                /* Mode Name Command        */
  181.       dputs( "    Mode Name Request: Mode " );
  182.       putnum( cx );
  183.       crlf();
  184.  
  185.       _ES = _CS;            /* Make ES:BX point to name    */
  186.       _BX = (unsigned int) Name;    /* BX points to name string    */
  187.       break;
  188.  
  189.     default:                /* Unknown Install Call        */
  190.       dputs( "    ERROR: Unknown Install Command: " );
  191.       puthex( al );
  192.       crlf();
  193.       break;
  194.     }                    /* End of Install command case    */
  195. }
  196.  
  197. /* ----------------------------- INITIALIZE ---------------------------- */
  198. /*                                     */
  199. /*    The initialize function is uset to enter the graphics mode.     */
  200. /*    Once the kernal has established the mode, the Initialize     */
  201. /*    call is used to execute the entry to graphics mode.         */
  202. /*                                     */
  203.  
  204. void init( void )
  205. {
  206.  
  207.   save_regs();                /* Save a copy of current regs    */
  208.  
  209.   banner( "INITIALIZE" );
  210.   dputs( "    Device Status Table at " );
  211.   puthex( _ES );
  212.   dputs( ":" );
  213.   puthex( bx );
  214.   crlf();
  215.  
  216. }
  217.  
  218. /* ----------------------------- CLEAR DEVICE -------------------------- */
  219. /*                                     */
  220. /*    The Clear Device call is used to ready the device for new     */
  221. /*    output. This would be a clear screen on graphics hardware,     */
  222. /*    formfeed on a printer or plotter, and a flush for file I/O.     */
  223. /*                                     */
  224.  
  225. void clear( void )
  226. {
  227.  
  228.   banner( "CLEAR DEVICE" );
  229.  
  230. }
  231.  
  232. /* ----------------------------- POST DEVICE --------------------------- */
  233. /*                                     */
  234. /*    The Post Device function is used to end the graphics output.     */
  235. /*    This would be used to begin printing a page on a printer,     */
  236. /*    set a graphics screen to visable, etc.                 */
  237. /*                                     */
  238.  
  239. void post( void )
  240. {
  241.  
  242.   banner( "POST DEVICE" );
  243.  
  244. }
  245.  
  246. /* ----------------------------- MOVE TO ------------------------------- */
  247. /*                                     */
  248. /*    This function is used to move the current pointer (CP). The     */
  249. /*    Current pointer is the system graphics cursor.             */
  250. /*                                     */
  251.  
  252. void move( void )
  253. {
  254.  
  255.   save_regs();                /* Save a copy of current regs    */
  256.  
  257.   banner( "MOVE" );
  258.   dputs( "    Move to:     X: " );
  259.   putnum( ax );
  260.   dputs( "  Y: " );
  261.   putnum( bx );
  262.   crlf();
  263.  
  264.   CP_X = ax;                /* Update the current pointer    */
  265.   CP_Y = bx;
  266.  
  267. }
  268.  
  269. /* ----------------------------- DRAW TO ------------------------------- */
  270. /*                                     */
  271. /*    Draw To is used to draw a line vector from the CP to the     */
  272. /*    specified coordinate.                         */
  273. /*                                     */
  274.  
  275. void draw( void )
  276. {
  277.  
  278.   save_regs();                /* Save a copy of current regs    */
  279.  
  280.   banner( "DRAW" );
  281.   dputs( "    Draw to:     X: " );
  282.   putnum( ax );
  283.   dputs( "  Y: " );
  284.   putnum( bx );
  285.   crlf();
  286.  
  287.   CP_X = ax;                /* Update the current pointer    */
  288.   CP_Y = bx;
  289.  
  290. }
  291.  
  292. /* ----------------------------- VECT ---------------------------------- */
  293. /*                                     */
  294. /*    Vector is used to draw lines when the beginning and ending     */
  295. /*    point are know. The parameters specify two vertices for         */
  296. /*    drawing the desire line.                     */
  297. /*                                     */
  298.  
  299. void vect( void )
  300. {
  301.  
  302.   save_regs();                /* Save a copy of current regs    */
  303.  
  304.   banner( "VECT" );
  305.   dputs( "    Vector From:  X: " );
  306.   putnum( ax );
  307.   dputs( "  Y: " );
  308.   putnum( bx );
  309.   dputs( "   To:  X: " );
  310.   putnum( cx );
  311.   dputs( "  Y: " );
  312.   putnum( dx );
  313.   crlf();
  314.  
  315. }
  316.  
  317. /* ----------------------------- POLYGON ------------------------------ */
  318. /*                                    */
  319. /*    The polygon command is used to implement all of the possible    */
  320. /*    polygon output syles. The parameters allow specifying a means    */
  321. /*    to draw a polygon using a static array, or by accruing points    */
  322. /*    through the moveto - lineto calls in a capture mode.        */
  323. /*                                    */
  324.  
  325. void polygon( void )
  326. {
  327.   int far *iptr = MK_FP( _ES, _BX );
  328.   int i;
  329.  
  330.   save_regs();
  331.  
  332.   banner( "POLYGON" );
  333.  
  334.   switch( ax ){                /* Determine Polygon action    */
  335.     case 0:                /* Start polygon definition    */
  336.       dputs( "    Start Polygon Definition\r\n" );
  337.       break;
  338.  
  339.     case 1:                /* Close and trace polygon    */
  340.       dputs( "    Close and Trace Polygon\r\n" );
  341.       break;
  342.  
  343.     case 2:                /* Close and fill polygon    */
  344.       dputs( "    Close, Trace, and Fill Polygon\r\n" );
  345.       break;
  346.  
  347.     case 3:                /* Close and fill (no outline)    */
  348.       dputs( "    Close and Fill Polygon (No Outline)\r\n" );
  349.       break;
  350.  
  351.     case 4:                /* Draw points, but no capture    */
  352.       dputs( "    Draw Points without Capture\r\n" );
  353.       break;
  354.  
  355.     case 5:                /* End polygon capture mode    */
  356.       dputs( "    Turn Capture Off\r\n" );
  357.       break;
  358.  
  359.     case 6:                /* Draw polygon from data array */
  360.       dputs( "    Draw Polygon:  " );
  361.       putnum( cx );
  362.       dputs( " Vertices\n\r" );
  363.       for( i=0 ; i<cx ; ++i ){        /* Display the vertex list    */
  364.     dputs( "      " );
  365.     putnum( i );
  366.     dputs( ":  X: " );
  367.     putnum( *iptr++ );
  368.     dputs( "  Y: " );
  369.     putnum( *iptr++ );
  370.     }
  371.       break;
  372.  
  373.     case 7:                /* Fill polygon from data array */
  374.       dputs( "    Fill Polygon:  " );
  375.       putnum( cx );
  376.       dputs( " Vertices\n\r" );
  377.       for( i=0 ; i<cx ; ++i ){        /* Display the vertex list    */
  378.     dputs( "      " );
  379.     putnum( i );
  380.     dputs( ":  X: " );
  381.     putnum( *iptr++ );
  382.     dputs( "  Y: " );
  383.     putnum( *iptr++ );
  384.     }
  385.       break;
  386.  
  387.     default:                /* Unknown polygon command    */
  388.       dputs( "    ERROR: Unknown Polygon Command (" );
  389.       putnum( ax );
  390.       dputs( "\r\n" );
  391.       break;
  392.  
  393.     }
  394.  
  395. }
  396.  
  397. /* ----------------------------- RECT ---------------------------------- */
  398. /*                                     */
  399. /*    This function is used to draw a filled rectangle to the output     */
  400. /*    device. The parameters are the coordinates of opposite corners     */
  401. /*    of the input rectangle. The rectangle call is also capable of     */
  402. /*    producing 3D bars with an additional depth and cap parameter.     */
  403. /*                                     */
  404.  
  405. void bar( void )
  406. {
  407.  
  408.   save_regs();                /* Save a copy of current regs    */
  409.  
  410.   banner( "RECT" );
  411.   dputs( "    Upper Right:  X: " );
  412.   putnum( ax );
  413.   dputs( "  Y: " );
  414.   putnum( bx );
  415.   crlf();
  416.   dputs( "    3D Depth:  " );
  417.   putnum( cx );
  418.   dputs( " Top Flag: (" );
  419.   putnum( dx );
  420.   dputs( ") " );
  421.   dputs( dx ? "Yes\r\n" : "No\r\n" );
  422.  
  423. }
  424.  
  425. /* ----------------------------- PATBAR -------------------------------- */
  426. /*                                     */
  427. /*    The patbar function is used to draw rectangles which are filled  */
  428. /*    with the current drawing pattern. The parameters of PATBAR     */
  429. /*    at the coordinates of the opposing corners of the bar.         */
  430. /*                                     */
  431.  
  432. void patbar( void )
  433. {
  434.  
  435.   save_regs();                /* Save a copy of current regs    */
  436.  
  437.   banner( "PATBAR");
  438.   dputs( "    Upper Left:   X: " );
  439.   putnum( ax );
  440.   dputs( "  Y: " );
  441.   putnum( bx );
  442.  
  443.   dputs( "    Lower Right:  X: " );
  444.   putnum( cx );
  445.   dputs( "  Y: " );
  446.   putnum( dx );
  447.   crlf();
  448.  
  449. }
  450.  
  451. /* ----------------------------- ARC ----------------------------------- */
  452. /*                                     */
  453. /*    The ARC command is used to output elliptical arcs. The input     */
  454. /*    parameters of the arc are the coordinate of the ARC center,     */
  455. /*    the X and Y radius, and the beginning and ending angle.         */
  456. /*                                     */
  457.  
  458. void arc( void )
  459. {
  460.  
  461.   save_regs();                /* Save a copy of current regs    */
  462.  
  463.   banner( "ARC" );
  464.   dputs( "    X Radius: " );
  465.   putnum( cx );
  466.   dputs( "    Y Radius: " );
  467.   putnum( dx );
  468.   crlf();
  469.   dputs( "    Start Angle: " );
  470.   putnum( ax );
  471.   dputs( "    End Angle:   " );
  472.   putnum( bx );
  473.   crlf();
  474.  
  475. }
  476.  
  477. /* ---------------------------- PIESLICE ------------------------------- */
  478. /*                                     */
  479. /*    The sector command is used to output setors. The input         */
  480. /*    parameters of the sector are the coordinate of the center,     */
  481. /*    the X and Y radius, and the beginning and ending angle.         */
  482. /*                                     */
  483.  
  484. void pieslice( void )
  485. {
  486.  
  487.   save_regs();                /* Save a copy of current regs    */
  488.  
  489.   banner( "PIESLICE" );
  490.   dputs( "    X Radius: " );
  491.   putnum( cx );
  492.   dputs( "    Y Radius: " );
  493.   putnum( dx );
  494.   crlf();
  495.   dputs( "    Start Angle: " );
  496.   putnum( ax );
  497.   dputs( "    End Angle:   " );
  498.   putnum( bx );
  499.   crlf();
  500.  
  501. }
  502.  
  503. /* -------------------------- FILLED ELLIPSE --------------------------- */
  504. /*                                     */
  505. /*    The input parameters of the elipse command is the coordinate     */
  506. /*    of the center and the x and y radii.                 */
  507. /*                                     */
  508.  
  509. void filled_ellipse( void )
  510. {
  511.  
  512.   save_regs();                /* Save a copy of current regs    */
  513.  
  514.   banner( "FILLED ELLIPSE" );
  515.   dputs( "    X Radius: " );
  516.   putnum( ax );
  517.   dputs( "    Y Radius: " );
  518.   putnum( bx );
  519.   crlf();
  520.  
  521. }
  522.  
  523. /* ----------------------------- PALETTE ------------------------------- */
  524. /*                                     */
  525. /*    The palette command is the central command for loading the     */
  526. /*    device palette. This function support several modes to allow     */
  527. /*    for the varied palette and color systems.             */
  528. /*                                     */
  529.  
  530. void palette( void )
  531. {
  532.   int flags, index;
  533.  
  534.   save_regs();                /* Save a copy of current regs    */
  535.  
  536.   banner( "PALETTE" );
  537.  
  538.   flags = (ax >> 14) & 0x0003;        /* Get flag bits from command    */
  539.   index = ax & 0x3fff;            /* Mask to get color index    */
  540.  
  541.   switch( flags ){            /* Act according to flags    */
  542.     case 0:                /* Set indexed color palette    */
  543.       dputs( "    Set Indexed Color:  Index: " );
  544.       putnum( index );
  545.       dputs( "   Color Value: " );
  546.       putnum( bx );
  547.       crlf();
  548.       break;
  549.     case 1:                /* Undefine color command    */
  550.       dputs( "ERROR: Undefined Set Color Command (01)\r\n" );
  551.       break;
  552.     case 2:                /* RGB - Index color        */
  553.       dputs( "    Set RGB Color:  Index: " );
  554.       putnum( index );
  555.       dputs( "  R: " );
  556.       putnum( bx );
  557.       dputs( "  G: " );
  558.       putnum( cx );
  559.       dputs( "  B: " );
  560.       putnum( dx );
  561.       crlf();
  562.       break;
  563.     case 3:                /* Background color        */
  564.       dputs( "    Set Background Color:  Color Value: " );
  565.       putnum( bx );
  566.       crlf();
  567.       break;
  568.     }
  569.  
  570. }
  571.  
  572. /* ----------------------------- ALLPALETTE ---------------------------- */
  573. /*                                     */
  574. /*    The all palette command is used to load an entire palette in     */
  575. /*    a single output command. The current BGI limits the size of     */
  576. /*    the allpalette command to be the first 16 colors.         */
  577. /*                                     */
  578.  
  579. void allpalette( void )
  580. {
  581.   unsigned char far *pptr = MK_FP( _ES, _BX );
  582.   int i;
  583.  
  584.   banner( "ALLPALETTE" );
  585.   i = *pptr++;
  586.   dputs( "    Palette Size:  " );
  587.   putnum( i );
  588.   crlf();
  589.  
  590.   while( i-- ){
  591.     dputs( "      " );
  592.     putnum( *pptr++ );
  593.     crlf();
  594.     }
  595.  
  596. }
  597.  
  598. /* ----------------------------- COLOR --------------------------------- */
  599. /*                                     */
  600. /*    The color function takes an index and sets the active fore     */
  601. /*    and background colors for output devices.             */
  602. /*                                     */
  603.  
  604. void color( void )
  605. {
  606.  
  607.   save_regs();                /* Save a copy of current regs    */
  608.  
  609.   banner( "COLOR" );
  610.   dputs( "    Drawing Color:  " );
  611.   putnum( al );
  612.   dputs( "    Filling Color:  " );
  613.   putnum( ah );
  614.   crlf();
  615.  
  616. }
  617.  
  618. /* ----------------------------- FILLSTYLE ----------------------------- */
  619. /*                                     */
  620. /*    The fill style function is used to set the interior style of     */
  621. /*    the filled primatives.    The input to the function is the     */
  622. /*    filled pattern style number, or a flag and a pointer to load     */
  623. /*    an 8x8 bit pattern tile.                     */
  624. /*                                     */
  625.  
  626. void fillstyle( void )
  627. {
  628.  
  629.   static char *fill_name[] = {        /* Names of line styles        */
  630.     "Empty",
  631.     "Solid",
  632.     "Line",
  633.     "Lt Slash",
  634.     "Slash",
  635.     "Bkslash",
  636.     "Ltbkslash",
  637.     "Hatch",
  638.     "Xhatch",
  639.     "Interleave",
  640.     "Wide dot",
  641.     "Close dot",
  642.     "User Defined"
  643.     };
  644.  
  645.   int i;
  646.   unsigned char far *pptr;
  647.  
  648.   save_regs();                /* Save a copy of current regs    */
  649.   pptr = MK_FP( _ES, _BX );
  650.  
  651.   banner( "FILLSTYLE" );
  652.   dputs( "    Fill Style: (" );
  653.   putnum( al );
  654.   dputs( ")  " );
  655.   dputs( (al == 0xff) ? "User Defined" : fill_name[al] );
  656.   dputs( " Fill\r\n" );
  657.  
  658.   if( al == 0xff ){            /* User defined line style    */
  659.     dputs( "    User Defined Fill Pattern:\r\n" );
  660.     dputs( "      " );
  661.     for( i=0 ; i<8 ; ++i ){
  662.       puthex( *pptr++ );
  663.       dputs( " " );
  664.       }
  665.     crlf();
  666.     }
  667.  
  668.  
  669. }
  670.  
  671. /* ----------------------------- LINESTYLE ----------------------------- */
  672. /*                                     */
  673. /*    The line style command is used to set the style of the lines     */
  674. /*    and borders of objects. The input to the fucntion is the line     */
  675. /*    style number, of a flag and a 16 bit pattern for user defined     */
  676. /*    line drawing styles.                         */
  677. /*                                     */
  678.  
  679. void linestyle( void )
  680. {
  681.   static char *line_name[] = {        /* Names of line styles        */
  682.     "Solid",
  683.     "Dotted",
  684.     "Center",
  685.     "Dashed",
  686.     "User Defined"
  687.     };
  688.  
  689.   save_regs();                /* Save a copy of current regs    */
  690.  
  691.   banner( "LINESTYLE" );
  692.   dputs( "    Line Style: (" );
  693.   putnum( al );
  694.   dputs( ")  " );
  695.   dputs( line_name[al] );
  696.   dputs( "Line    Line Width:  " );
  697.   putnum( cx );
  698.   crlf();
  699.  
  700.   if( al == 4 ){            /* User defined line style    */
  701.     dputs( "    User Defined Line Pattern: " );
  702.     puthex( cx );
  703.     crlf();
  704.     }
  705.  
  706. }
  707.  
  708. /* ----------------------------- TEXTSTYLE ----------------------------- */
  709. /*                                     */
  710. /*    The text style command is used to define the output font,     */
  711. /*    text path, and text direction for font rendering.         */
  712. /*                                     */
  713.  
  714. void textstyle( void )
  715. {
  716.  
  717.   save_regs();                /* Save a copy of current regs    */
  718.  
  719.   banner( "TEXTSTYLE" );
  720.   dputs( "    Font Number:  " );
  721.   putnum( al );
  722.   dputs( "    Font Path:    " );
  723.   putnum( ah );
  724.   crlf();
  725.   dputs( "    Character Size:  X:  " );
  726.   putnum( bx );
  727.   dputs( "    Y:  " );
  728.   putnum( cx );
  729.   crlf();
  730.  
  731.   _BX = bx;                /* Return the input as default    */
  732.   _CX = cx;
  733.  
  734. }
  735.  
  736. /* ------------------------------ TEXT --------------------------------- */
  737. /*                                     */
  738. /*    The text output command takes a string and renders the string     */
  739. /*    on the output device. The input to the function is the text     */
  740. /*    and the string length.                         */
  741. /*                                     */
  742.  
  743. void text( void )
  744. {
  745.   char far * cptr = MK_FP( _ES, _BX );
  746.   int i;
  747.  
  748.   save_regs();                /* Save a copy of current regs    */
  749.  
  750.   banner( "TEXT" );
  751.  
  752.   dputs( "    Input Text: \"" );
  753.  
  754. /*    Read sting from the far memory to local memory.            */
  755.  
  756.   for( i=0 ; i<cx ; ++i ) Buffer[i] = *cptr++;
  757.   Buffer[i] = '\0';            /* Null terminate string    */
  758.  
  759.   dputs( Buffer );
  760.   dputs( "\"\r\n" );
  761.  
  762. }
  763.  
  764. /* ---------------------------- FLOODFILL ------------------------------ */
  765. /*                                     */
  766. /*    This function is a standard floodfill command The input to     */
  767. /*    the function is the seed point for the floodfill. The fill     */
  768. /*    is done in the current drawing color and pattern.         */
  769. /*                                     */
  770.  
  771. void floodfill( void )
  772. {
  773.  
  774.   save_regs();                /* Save a copy of current regs    */
  775.  
  776.   banner( "FLOOD FILL" );
  777.   dputs( "    Seed Point:  X: " );
  778.   putnum( ax );
  779.   dputs( "  Y: " );
  780.   putnum( bx );
  781.   crlf();
  782.  
  783. }
  784.  
  785. /* ----------------------------- BITMANIPUTIL ------------------------- */
  786. /*                                    */
  787. /*    This function returns the base of the bit manipulation utility    */
  788. /*    table. The entry does not perform any function.            */
  789. /*                                    */
  790.  
  791. void bitmaputil( void )
  792. {
  793.  
  794.   banner( "BITMAPUTIL" );
  795.   dputs( "    Bit Map Utility Table Base: " );
  796.   puthex( _DS );
  797.   dputs( ":" );
  798.   puthex( (unsigned int) &Utility_Table );
  799.   crlf();
  800.  
  801.   _ES = _DS;                /* ES:BX = table address    */
  802.   _BX = (unsigned int) &Utility_Table;    /* Assign Base of table address */
  803.  
  804. }
  805.  
  806. /* -------------------------------------------------------------------- */
  807. /*                                    */
  808. /*    The following defines the bit map utilities.            */
  809. /*                                    */
  810. /*    These functions are accessed directly from the calling code,    */
  811. /*    and are not process via the normal BGI Interface. Therefore,    */
  812. /*    these routines must preserve the input data, and must be FAR    */
  813. /*    functions.                            */
  814. /*                                    */
  815.  
  816. void far enter_graphics( void )        /* Enter graphics mode function */
  817. {
  818.   unsigned int orgds = _DS;
  819.  
  820.   _DS = _CS;                /* Point Data Seg to Code Seg    */
  821.   banner( "Bit Map Function: Enter Pixel Graphics Mode" );
  822.   _DS = orgds;                /* Restore the original DS    */
  823.  
  824. }
  825.  
  826. void far leave_graphics( void )        /* Leave graphics mode function */
  827. {
  828.   unsigned int orgds = _DS;
  829.  
  830.   _DS = _CS;                /* Point Data Seg to Code Seg    */
  831.   banner( "Bit Map: Leave Pixel Graphics Mode" );
  832.   _DS = orgds;                /* Restore the original DS    */
  833.  
  834. }
  835.  
  836. void far putpix( void )            /* Write a pixel function    */
  837. {
  838.   unsigned int arg   = _AX;
  839.   unsigned int orgds = _DS;
  840.  
  841.   _DS = _CS;                /* Point Data Seg to Code Seg    */
  842.   save_regs();                /* Save a copy of current regs    */
  843.  
  844.   banner( "Bit Map Function: Put Pixel" );
  845.   dputs( "     Pixel Address:  X: " );
  846.   putnum( arg );
  847.   dputs( "  Y: " );
  848.   putnum( bx );
  849.   dputs( "  Value: " );
  850.   putnum( dl );
  851.   crlf();
  852.   _DS = orgds;                /* Restore the original DS    */
  853.  
  854. }
  855.  
  856. void far getpix( void )            /* Read a pixel function    */
  857. {
  858.   unsigned int arg   = _AX;
  859.   unsigned int orgds = _DS;
  860.  
  861.   _DS = _CS;                /* Point Data Seg to Code Seg    */
  862.   save_regs();                /* Save a copy of current regs    */
  863.  
  864.   banner( "Bit Map Function: Get Pixel" );
  865.   dputs( "     Pixel Address:  X: " );
  866.   putnum( arg );
  867.   dputs( "  Y: " );
  868.   putnum( bx );
  869.   crlf();
  870.  
  871.   _DS = orgds;                /* Restore the original DS    */
  872.   _DL = 5;                /* Fake return value        */
  873.  
  874. }
  875.  
  876. void far set_page( void )        /* Set the active drawing page    */
  877. {
  878.   unsigned int arg   = _AL;
  879.   unsigned int orgds = _DS;
  880.  
  881.   _DS = _CS;                /* Point Data Seg to Code Seg    */
  882.   save_regs();                /* Save a copy of current regs    */
  883.  
  884.   banner( "Bit Map Function: Set Active Page" );
  885.   dputs( "     Page Number:  " );
  886.   putnum( arg );
  887.   crlf();
  888.   _DS = orgds;                /* Restore the original DS    */
  889.  
  890. }
  891.  
  892. void far set_visual( void )        /* Set the active display page    */
  893. {
  894.   unsigned int arg   = _AL;
  895.   unsigned int orgds = _DS;
  896.  
  897.   _DS = _CS;                /* Point Data Seg to Code Seg    */
  898.   save_regs();                /* Save a copy of current regs    */
  899.  
  900.   banner( "Bit Map Function: Set Visual Page" );
  901.   dputs( "     Page Number:  " );
  902.   putnum( arg );
  903.   crlf();
  904.   _DS = orgds;                /* Restore the original DS    */
  905.  
  906. }
  907.  
  908. void far set_write_mode( void )        /* Set the current write mode    */
  909. {
  910.   unsigned int arg   = _AX;
  911.   unsigned int orgds = _DS;
  912.  
  913.   _DS = _CS;                /* Point Data Seg to Code Seg    */
  914.   save_regs();                /* Save a copy of current regs    */
  915.  
  916.   banner( "Bit Map Function: Set Write Mode" );
  917.   dputs( "     XOR Write Mode:  (" );
  918.   putnum( arg );
  919.   dputs( ")  " );
  920.   dputs( arg ? "On\r\n" : "Off\r\n" );
  921.   _DS = orgds;                /* Restore the original DS    */
  922.  
  923. }
  924.  
  925.  
  926. /* ---------------------------- RESTOREBITMAP -------------------------- */
  927. /*                                     */
  928. /*    The restore bit map function is used to load a retangular     */
  929. /*    region from the host memory into the graphics memory. The     */
  930. /*    input to the routine is the region to write, a pointer to     */
  931. /*    the source in the host's memory, and the mode to use when        */
  932. /*    writing the region.                         */
  933. /*                                     */
  934.  
  935. void restorebitmap( void )
  936. {
  937.   unsigned int si = _SI;
  938.   unsigned int di = _DI;
  939.  
  940.   save_regs();                /* Save a copy of current regs    */
  941.  
  942.   banner( "RESTOREBITMAP" );
  943.  
  944.   dputs( "    Restore Buffer at  " );
  945.   puthex( _ES );
  946.   dputs( ":" );
  947.   puthex( bx );
  948.   crlf();
  949.  
  950.   dputs( "    Start  X:  " );
  951.   putnum( si );
  952.   dputs( "  Y: " );
  953.   putnum( di );
  954.   dputs( "    End  X:  " );
  955.   putnum( cx );
  956.   dputs( "  Y: " );
  957.   putnum( dx );
  958.   crlf();
  959.  
  960. }
  961.  
  962. /* ---------------------------- SAVEBITMAP ----------------------------- */
  963. /*                                     */
  964. /*    The save bit map function is used to write a rectangular     */
  965. /*    region from the graphics memory to the host memory. The input     */
  966. /*    to the function is the region to be read, and a pointer to     */
  967. /*    a save buffer in the host memory.                 */
  968. /*                                     */
  969.  
  970. void savebitmap( void )
  971. {
  972.   unsigned int si = _SI;
  973.   unsigned int di = _DI;
  974.  
  975.   save_regs();                /* Save a copy of current regs    */
  976.  
  977.   banner( "SAVEBITMAP" );
  978.  
  979.   dputs( "    Save Buffer at  " );
  980.   puthex( _ES );
  981.   dputs( ":" );
  982.   puthex( bx );
  983.   crlf();
  984.  
  985.   dputs( "    Start  X:  " );
  986.   putnum( si );
  987.   dputs( "  Y: " );
  988.   putnum( di );
  989.   dputs( "    End  X:  " );
  990.   putnum( cx );
  991.   dputs( "  Y: " );
  992.   putnum( dx );
  993.   crlf();
  994.  
  995. }
  996.  
  997. /* ---------------------------- SETCLIP -------------------------------- */
  998. /*                                     */
  999. /*    The setclip function defines a clipping rectangle on the     */
  1000. /*    output device.    The input to the function defines the         */
  1001. /*    coordinated of the opposing corners of the clipping rectangle.     */
  1002. /*                                     */
  1003. /*                                     */
  1004.  
  1005. void setclip( void )
  1006. {
  1007.  
  1008.   save_regs();                /* Save a copy of current regs    */
  1009.  
  1010.   banner( "SETCLIP" );
  1011.   dputs( "    Upper Left:  X: " );
  1012.   putnum( ax );
  1013.   dputs( "  Y: " );
  1014.   putnum( bx );
  1015.   dputs( "  Lower Right:  X: " );
  1016.   putnum( cx );
  1017.   dputs( "  Y: " );
  1018.   putnum( dx );
  1019.   crlf();
  1020.  
  1021. }
  1022.  
  1023. /* ---------------------------- GETPIXEL ------------------------------- */
  1024. /*                                     */
  1025. /*    The GetPixel function is used to read a specific pixel value     */
  1026. /*    from the graphics screen. The input is the coordinate of the     */
  1027. /*    pixel to be read. The output is the pixel value.         */
  1028. /*                                     */
  1029.  
  1030. void get_pixel( void )
  1031. {
  1032.  
  1033.   save_regs();                /* Save a copy of current regs    */
  1034.  
  1035.   banner( "GET PIXEL" );
  1036.   dputs( "    Pixel Address:  X: " );
  1037.   putnum( ax );
  1038.   dputs( "  Y: " );
  1039.   putnum( bx );
  1040.   crlf();
  1041.  
  1042.   _DL = 5;                /* Return 5 as fake value    */
  1043.  
  1044. }
  1045.  
  1046. /* ---------------------------- SETPIXEL ------------------------------- */
  1047. /*                                     */
  1048. /*    The SetPixel command is used to write a specific pixel to     */
  1049. /*    the graphics area. The input values are the coordinate of     */
  1050. /*    the pixel to write, and the pixel value to write.         */
  1051. /*                                     */
  1052.  
  1053. void set_pixel( void )
  1054. {
  1055.  
  1056.   save_regs();                /* Save a copy of current regs    */
  1057.  
  1058.   banner( "SET PIXEL" );
  1059.   dputs( "    Pixel Address:  X: " );
  1060.   putnum( ax );
  1061.   dputs( "  Y: " );
  1062.   putnum( bx );
  1063.   dputs( "  Value:  " );
  1064.   putnum( dl );
  1065.   crlf();
  1066.  
  1067. }
  1068.  
  1069. /* ---------------------------- ESCAPE -------------------------------- */
  1070.  
  1071. void escape( void )
  1072. {
  1073.  
  1074.   save_regs();                /* Save a copy of current regs    */
  1075.  
  1076.   banner( "ESCAPE" );
  1077.  
  1078. }
  1079.  
  1080. /* ---------------------------- TEXTSIZE ------------------------------- */
  1081. /*                                     */
  1082. /*    The textsize function allows the kernal to inquire the size     */
  1083. /*    of text strings. The input to the function is a pointer to     */
  1084. /*    text and the length of the string. The output is the horz     */
  1085. /*    and vert dimensions of the string in pixels.             */
  1086. /*                                     */
  1087.  
  1088. void textsiz( void )
  1089. {
  1090.   char far * cptr;
  1091.   int i;
  1092.  
  1093.   save_regs();                /* Save a copy of current regs    */
  1094.   cptr = MK_FP( _ES, _BX );        /* Make a pointer to the text    */
  1095.  
  1096.   banner( "TEXT SIZE" );
  1097.   dputs( "    Input Text: \"" );
  1098.  
  1099. /*    Read sting from the far memory to local memory.            */
  1100.  
  1101.   for( i=0 ; i<cx ; ++i ) Buffer[i] = *cptr++;
  1102.   Buffer[i] = '\0';            /* Null terminate string    */
  1103.  
  1104.   dputs( Buffer );
  1105.   dputs( "\"\r\n" );
  1106.  
  1107.   _BX = cx * 8;                /* Return default size info    */
  1108.   _CX = 8;
  1109.  
  1110. }
  1111.  
  1112. /* ---------------------------- COLOR_QUERY --------------------------- */
  1113. /*                                    */
  1114. /*    This function allows the kernal to inquire the size and base    */
  1115. /*    colors for the current device.                    */
  1116. /*                                    */
  1117.  
  1118. void color_query( void )
  1119. {
  1120.   int i;
  1121.  
  1122.   save_regs();                /* Save a copy of current regs    */
  1123.  
  1124.   i = Stat_Block.fcolors & 0x7f;    /* Get color info w/o flag bit    */
  1125.  
  1126.   banner( "QUERY COLOR" );
  1127.   switch( al ){                /* Act on the input command    */
  1128.     case 0:                /* Color palette size query    */
  1129.       dputs( "    Color Table Size:  (Size: " );
  1130.       putnum( i );
  1131.       dputs( "  Maximum Color: " );
  1132.       putnum( i-1 );
  1133.       dputs( ")\r\n" );
  1134.       _BX = i;                /* Return the table size    */
  1135.       _CX = i - 1;            /* Return the maximum color #    */
  1136.       break;
  1137.  
  1138.     case 1:                /* Default palette settings    */
  1139.       dputs( "    Default Palette Query\r\n" );
  1140.       _ES = _CS;            /* Mask ES:BX point to default    */
  1141.       _BX = (unsigned int) &Default_Palette;
  1142.       break;
  1143.  
  1144.     default:
  1145.       dputs( "    ERROR: Unknown Color Query Command: " );
  1146.       puthex( al );
  1147.       crlf();
  1148.       break;
  1149.     }
  1150.  
  1151. }
  1152.  
  1153. /* ---------------------------- SETWINDOW ------------------------------ */
  1154. /*                                     */
  1155. /*    The setwindow function defines a VDC space on the output device  */
  1156. /*    The input to the function defines the VDC's to be set to the     */
  1157. /*    current clipping viewport.                     */
  1158. /*                                     */
  1159. /*                                     */
  1160.  
  1161. void setwindow( void )
  1162. {
  1163.  
  1164.   save_regs();                /* Save a copy of current regs    */
  1165.  
  1166.   banner( "SETWINDOW" );
  1167.   dputs( "    Upper Left:  X: " );
  1168.   putnum( ax );
  1169.   dputs( "  Y: " );
  1170.   putnum( bx );
  1171.   dputs( "  Lower Right:  X: " );
  1172.   putnum( cx );
  1173.   dputs( "  Y: " );
  1174.   putnum( dx );
  1175.   crlf();
  1176.  
  1177. }
  1178.  
  1179. /* ----------------------------- BANNER ------------------------------- */
  1180. /*                                    */
  1181. /*    This function sends a string to the console via a direct    */
  1182. /*    DOS Function 9. The string is place inside a standard banner    */
  1183. /*    before being sent to the console.                */
  1184. /*                                    */
  1185.  
  1186. void banner( char *string )
  1187. {
  1188.   static char header[] = ">>> DEBUG: ";
  1189.  
  1190.   dputs( header );
  1191.   dputs( string );
  1192.   crlf();
  1193.  
  1194. }
  1195.  
  1196.  
  1197. /* ----------------------------- PUTNUM ------------------------------- */
  1198. /*                                    */
  1199. /*    This function converts a number to a decimal ASCII string.    */
  1200. /*    The string is then sent to the console via a DPUTS command.    */
  1201. /*                                    */
  1202.  
  1203. void putnum( unsigned number )        /* Output Decimal Number    */
  1204. {
  1205.   static char numstr[10] = "XXXXXXXX";    /* String for conversion space    */
  1206.  
  1207.   itoa( number, numstr, 10 );        /* Convert to decimal string    */
  1208.   dputs( numstr );            /* Send number to console    */
  1209.  
  1210. }
  1211.  
  1212.  
  1213. /* ----------------------------- PUTHEX ------------------------------- */
  1214. /*                                    */
  1215. /*    This function converts a number to a hexidecimal ASCII string.    */
  1216. /*    The string is then sent to the console via a DPUTS command.    */
  1217. /*                                    */
  1218.  
  1219. void puthex( unsigned number )        /* Output Hexidecimal Number    */
  1220. {
  1221.   static char hextbl[] = "0123456789ABCDEF";
  1222.   static char numstr[] = "XXXX";       /* String space for conversion  */
  1223.  
  1224.   numstr[3] = hextbl[ number & 0x000f ];
  1225.   number >>= 4;
  1226.  
  1227.   numstr[2] = hextbl[ number & 0x000f ];
  1228.   number >>= 4;
  1229.  
  1230.   numstr[1] = hextbl[ number & 0x000f ];
  1231.   number >>= 4;
  1232.  
  1233.   numstr[0] = hextbl[ number & 0x000f ];
  1234.  
  1235.   dputs( numstr );            /* Send number to console    */
  1236.  
  1237. }
  1238.  
  1239.  
  1240. /* ----------------------------- DPUTS -------------------------------- */
  1241. /*                                    */
  1242. /*    This function send a string to the console using DOS.        */
  1243. /*                                    */
  1244.  
  1245. void dputs( char far *str )        /* Output string to console    */
  1246. {
  1247.   char far *cptr = str;            /* Point at input string    */
  1248.  
  1249.   while( *cptr ){            /* Send NULL terminated string    */
  1250.     _AH = 2;                /* DOS Charater output function */
  1251.     _DL = *cptr++;            /* Pick up character to send    */
  1252.     geninterrupt( 0x21 );        /* Enter DOS to send character    */
  1253.     }
  1254.  
  1255. }
  1256.  
  1257. /* ----------------------------- CRLF --------------------------------- */
  1258. /*                                    */
  1259. /*    This function send a Carrage Return and Line Feed to the    */
  1260. /*    console.                            */
  1261. /*                                    */
  1262.  
  1263. void crlf( void )            /* goto new line on screen    */
  1264. {
  1265.   static char str[] = "\r\n";        /* New line string to DOS    */
  1266.  
  1267.   dputs( str );                /* Send string to console    */
  1268.  
  1269. }
  1270.  
  1271. /* ----------------------------- SAVEREGS ----------------------------- */
  1272. /*                                    */
  1273. /*    This function saves a copy of all of the input registers.    */
  1274. /*    This function is needed because C does hidden things with    */
  1275. /*    registers, which would require constant PUSH's and POP's.    */
  1276. /*                                    */
  1277.  
  1278. void save_regs( void )            /* Save registers into memory    */
  1279. {
  1280.  
  1281.   ax = _AX;    al = _AL;    ah = _AH;
  1282.   bx = _BX;    bh = _BH;    bl = _BL;
  1283.   cx = _CX;    ch = _CH;    cl = _CL;
  1284.   dx = _DX;    dh = _DH;    dl = _DL;
  1285.  
  1286. }
  1287.  
  1288.