Metropoli BBS
VIEWER: debug.c MODE: TEXT (ASCII)
/*

    DEBUG.C - sample debugging BGI driver

    Copyright (c) 1988,89 Borland International

*/




#include <stdlib.h>
#include <string.h>
#include <dos.h>

/* ----------------------------- DEBUG.C ------------------------------ */
/*                                                                      */
/*      Function Protoypes for the debug driver.                        */
/*                                                                      */

void save_regs( void );
void banner( char *str );
void putnum( unsigned number );
void puthex( unsigned number );
void dputs( char far *str );
void crlf( void );

void far enter_graphics( void );
void far leave_graphics( void );
void far putpix( void );
void far getpix( void );
void far bits_per_pixel( void );
void far set_visual( void );
void far set_page( void );
void far set_write_mode( void );

typedef void far (*FRFPTR)( void );     /* Pointer to Void/Void Funct   */
typedef void     (*NRFPTR)( void );     /* Pointer to Void/Void Funct   */

/*                                                                      */
/*      The following C structure defines a Device Status Block.        */
/*                                                                      */

typedef struct {
  unsigned char   stat;                 /* Current device status.       */
  unsigned char   devtype;              /* Device Type Identifier.      */
  unsigned int    xres;                 /* Device Full Resolution in X  */
  unsigned int    yres;                 /* Device Full Resolution in Y  */
  unsigned int    xefres;               /* Device Effective X Resolution*/
  unsigned int    yefres;               /* Device Effective Y Resolution*/
  unsigned int    xinch;                /* Device X Size in inches*1000 */
  unsigned int    yinch;                /* Device Y Size in inches*1000 */
  unsigned int    aspec;                /* Aspect Ratio * 10000         */
  unsigned char   chsizx;               /* Standard char size X         */
  unsigned char   chsizy;               /* Standard char size Y         */
  unsigned char   fcolors;              /* Number of foreground colors  */
  unsigned char   bcolors;              /* Number of background colors  */
} STATUS;

/*                                                                      */
/*      The following structure defines a palette record.               */
/*                                                                      */

typedef struct {
  unsigned char length;                 /* # of color entries in palette*/
  unsigned char color[16];              /* Up to 16 color entries       */
  } PALETTE;

/*                                                                      */
/*      The following structure defines a utility function table.       */
/*                                                                      */

typedef struct {
  NRFPTR  goto_graph;                   /* Enter graphics mode function */
  NRFPTR  exit_graph;                   /* Leave graphics mode function */
  NRFPTR  putpix;                       /* Write a pixel function       */
  NRFPTR  getpix;                       /* Read a pixel function        */
  NRFPTR  bits_per_pixel;               /* Bits per pixel value         */
  NRFPTR  set_page;                     /* Set the active drawing page  */
  NRFPTR  set_visual;                   /* Set the active display page  */
  NRFPTR  write_mode;                   /* Set the current write mode   */
  } UTILITIES;

/*                                                                      */
/*      This status block declares the debug driver to appear as an     */
/*      EGA card in high resolution mode.                               */
/*                                                                      */

STATUS  Stat_Block = {          /* Status block to fake an EGA driver   */
  0,                            /* Current device status.               */
  0,                            /* Device Type Identifier.              */
  639,                          /* Device Full Resolution in X          */
  479,                          /* Device Full Resolution in Y          */
  639,                          /* Device Effective X Resolution        */
  479,                          /* Device Effective Y Resolution        */
  9000,                         /* Device X Size in inches*1000         */
  7000,                         /* Device Y Size in inches*1000         */
  10000,                        /* Aspect Ratio * 10000                 */
  8  + 0x80,                    /* Standard char size X                 */
  8  + 0x80,                    /* Standard char size Y                 */
  16 + 0x80,                    /* Number of foreground colors          */
  16 + 0x80                     /* Number of background colors          */
  };

/*                                                                      */
/*      This palette declares the default EGA palette.                  */
/*                                                                      */

PALETTE Default_Palette = {     /* Define the palette for above EGA mode*/
  16, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
        0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F  }
  };

/*                                                                      */
/*      The following structure defines the Bit Manipulation Utility    */
/*      function table.                                                 */
/*                                                                      */

UTILITIES Utility_Table = {             /* Bit Utilities Function Table */
  (NRFPTR) enter_graphics,              /* Enter graphics mode function */
  (NRFPTR) leave_graphics,              /* Leave graphics mode function */
  (NRFPTR) putpix,                      /* Write a pixel function       */
  (NRFPTR) getpix,                      /* Read a pixel function        */
  (NRFPTR) bits_per_pixel,              /* Bits per pixel function      */
  (NRFPTR) set_page,                    /* Set the active drawing page  */
  (NRFPTR) set_visual,                  /* Set the active display page  */
  (NRFPTR) set_write_mode               /* Set the current write mode   */
  };

/*                                                                      */
/*      The following defines the name of the modes for Driver.         */
/*      NOTE: The string must start with a PASCAL style length.         */
/*                                                                      */

char Name[] = "\030Debug Driver (640 x 480)";

/*      Driver Local Data Variables                                     */

char Buffer[80] = { 0 };                /* String output buffer         */

unsigned int    CP_X = 0, CP_Y = 0;     /* Current Drawing Pointer CP   */

unsigned int  ds = 0;                   /* DS on entry to the driver    */
unsigned int  ax = 0, bx = 0, cx = 0, dx = 0;
unsigned int  ah = 0, bh = 0, ch = 0, dh = 0;
unsigned int  al = 0, bl = 0, cl = 0, dl = 0;

/* ----------------------------- INSTALL ------------------------------- */
/*                                                                       */
/*      The Install function is used to prepare the driver to use.       */
/*      The calls to this function allow the kernal to inquire the       */
/*      mode information, and allow the kernal to install the mode       */
/*      infomation.                                                      */
/*                                                                       */

void install( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "INSTALL" );                  /* Announce the function type   */
  switch( al ){                         /* Determine the command to use */

    case 0:                             /* Install Device Command       */
      dputs( "    Install Device:   Mode Number: " );
      putnum( cl );
      dputs( "  AutoDetect Maximum: " );
      putnum( ch );
      crlf();

      _ES = _CS;                        /* Make ES:BX point to block    */
      _BX = (unsigned int) &Stat_Block; /* BX points to status block    */
      break;

    case 1:                             /* Mode Query Command           */
      dputs( "    Mode Query Request (1 Mode)\r\n" );
      _CX = 1;                          /* Return only 1 mode supported */
      break;

    case 2:                             /* Mode Name Command            */
      dputs( "    Mode Name Request: Mode " );
      putnum( cx );
      crlf();

      _ES = _CS;                        /* Make ES:BX point to name     */
      _BX = (unsigned int) Name;        /* BX points to name string     */
      break;

    default:                            /* Unknown Install Call         */
      dputs( "    ERROR: Unknown Install Command: " );
      puthex( al );
      crlf();
      break;
    }                                   /* End of Install command case  */
}

/* ----------------------------- INITIALIZE ---------------------------- */
/*                                                                       */
/*      The initialize function is uset to enter the graphics mode.      */
/*      Once the kernal has established the mode, the Initialize         */
/*      call is used to execute the entry to graphics mode.              */
/*                                                                       */

void init( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "INITIALIZE" );
  dputs( "    Device Status Table at " );
  puthex( _ES );
  dputs( ":" );
  puthex( bx );
  crlf();

}

/* ----------------------------- CLEAR DEVICE -------------------------- */
/*                                                                       */
/*      The Clear Device call is used to ready the device for new        */
/*      output. This would be a clear screen on graphics hardware,       */
/*      formfeed on a printer or plotter, and a flush for file I/O.      */
/*                                                                       */

void clear( void )
{

  banner( "CLEAR DEVICE" );

}

/* ----------------------------- POST DEVICE --------------------------- */
/*                                                                       */
/*      The Post Device function is used to end the graphics output.     */
/*      This would be used to begin printing a page on a printer,        */
/*      set a graphics screen to visable, etc.                           */
/*                                                                       */

void post( void )
{

  banner( "POST DEVICE" );

}

/* ----------------------------- MOVE TO ------------------------------- */
/*                                                                       */
/*      This function is used to move the current pointer (CP). The      */
/*      Current pointer is the system graphics cursor.                   */
/*                                                                       */

void move( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "MOVE" );
  dputs( "    Move to:     X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  crlf();

  CP_X = ax;                            /* Update the current pointer   */
  CP_Y = bx;

}

/* ----------------------------- DRAW TO ------------------------------- */
/*                                                                       */
/*      Draw To is used to draw a line vector from the CP to the         */
/*      specified coordinate.                                            */
/*                                                                       */

void draw( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "DRAW" );
  dputs( "    Draw to:     X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  crlf();

  CP_X = ax;                            /* Update the current pointer   */
  CP_Y = bx;

}

/* ----------------------------- VECT ---------------------------------- */
/*                                                                       */
/*      Vector is used to draw lines when the beginning and ending       */
/*      point are know. The parameters specify two vertices for          */
/*      drawing the desire line.                                         */
/*                                                                       */

void vect( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "VECT" );
  dputs( "    Vector From:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  dputs( "   To:  X: " );
  putnum( cx );
  dputs( "  Y: " );
  putnum( dx );
  crlf();

}

/* ----------------------------- POLYGON ------------------------------ */
/*                                                                      */
/*      The polygon command is used to implement all of the possible    */
/*      polygon output syles. The parameters allow specifying a means   */
/*      to draw a polygon using a static array, or by accruing points   */
/*      through the moveto - lineto calls in a capture mode.            */
/*                                                                      */

void polygon( void )
{
  int far *iptr = MK_FP( _ES, _BX );
  int i;

  save_regs();

  banner( "POLYGON" );

  switch( ax ){                         /* Determine Polygon action     */
    case 0:                             /* Start polygon definition     */
      dputs( "    Start Polygon Definition\r\n" );
      break;

    case 1:                             /* Close and trace polygon      */
      dputs( "    Close and Trace Polygon\r\n" );
      break;

    case 2:                             /* Close and fill polygon       */
      dputs( "    Close, Trace, and Fill Polygon\r\n" );
      break;

    case 3:                             /* Close and fill (no outline)  */
      dputs( "    Close and Fill Polygon (No Outline)\r\n" );
      break;

    case 4:                             /* Draw points, but no capture  */
      dputs( "    Draw Points without Capture\r\n" );
      break;

    case 5:                             /* End polygon capture mode     */
      dputs( "    Turn Capture Off\r\n" );
      break;

    case 6:                             /* Draw polygon from data array */
      dputs( "    Draw Polygon:  " );
      putnum( cx );
      dputs( " Vertices\n\r" );
      for( i=0 ; i<cx ; ++i ){          /* Display the vertex list      */
        dputs( "      " );
        putnum( i );
        dputs( ":  X: " );
        putnum( *iptr++ );
        dputs( "  Y: " );
        putnum( *iptr++ );
        }
      break;

    case 7:                             /* Fill polygon from data array */
      dputs( "    Fill Polygon:  " );
      putnum( cx );
      dputs( " Vertices\n\r" );
      for( i=0 ; i<cx ; ++i ){          /* Display the vertex list      */
        dputs( "      " );
        putnum( i );
        dputs( ":  X: " );
        putnum( *iptr++ );
        dputs( "  Y: " );
        putnum( *iptr++ );
        }
      break;

    default:                            /* Unknown polygon command      */
      dputs( "    ERROR: Unknown Polygon Command (" );
      putnum( ax );
      dputs( "\r\n" );
      break;

    }

}

/* ----------------------------- RECT ---------------------------------- */
/*                                                                       */
/*      This function is used to draw a filled rectangle to the output   */
/*      device. The parameters are the coordinates of opposite corners   */
/*      of the input rectangle. The rectangle call is also capable of    */
/*      producing 3D bars with an additional depth and cap parameter.    */
/*                                                                       */

void bar( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "RECT" );
  dputs( "    Upper Right:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  crlf();
  dputs( "    3D Depth:  " );
  putnum( cx );
  dputs( " Top Flag: (" );
  putnum( dx );
  dputs( ") " );
  dputs( dx ? "Yes\r\n" : "No\r\n" );

}

/* ----------------------------- PATBAR -------------------------------- */
/*                                                                       */
/*      The patbar function is used to draw rectangles which are filled  */
/*      with the current drawing pattern. The parameters of PATBAR       */
/*      at the coordinates of the opposing corners of the bar.           */
/*                                                                       */

void patbar( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "PATBAR");
  dputs( "    Upper Left:   X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );

  dputs( "    Lower Right:  X: " );
  putnum( cx );
  dputs( "  Y: " );
  putnum( dx );
  crlf();

}

/* ----------------------------- ARC ----------------------------------- */
/*                                                                       */
/*      The ARC command is used to output elliptical arcs. The input     */
/*      parameters of the arc are the coordinate of the ARC center,      */
/*      the X and Y radius, and the beginning and ending angle.          */
/*                                                                       */

void arc( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "ARC" );
  dputs( "    X Radius: " );
  putnum( cx );
  dputs( "    Y Radius: " );
  putnum( dx );
  crlf();
  dputs( "    Start Angle: " );
  putnum( ax );
  dputs( "    End Angle:   " );
  putnum( bx );
  crlf();

}

/* ---------------------------- PIESLICE ------------------------------- */
/*                                                                       */
/*      The sector command is used to output setors. The input           */
/*      parameters of the sector are the coordinate of the center,       */
/*      the X and Y radius, and the beginning and ending angle.          */
/*                                                                       */

void pieslice( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "PIESLICE" );
  dputs( "    X Radius: " );
  putnum( cx );
  dputs( "    Y Radius: " );
  putnum( dx );
  crlf();
  dputs( "    Start Angle: " );
  putnum( ax );
  dputs( "    End Angle:   " );
  putnum( bx );
  crlf();

}

/* -------------------------- FILLED ELLIPSE --------------------------- */
/*                                                                       */
/*      The input parameters of the elipse command is the coordinate     */
/*      of the center and the x and y radii.                             */
/*                                                                       */

void filled_ellipse( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "FILLED ELLIPSE" );
  dputs( "    X Radius: " );
  putnum( ax );
  dputs( "    Y Radius: " );
  putnum( bx );
  crlf();

}

/* ----------------------------- PALETTE ------------------------------- */
/*                                                                       */
/*      The palette command is the central command for loading the       */
/*      device palette. This function support several modes to allow     */
/*      for the varied palette and color systems.                        */
/*                                                                       */

void palette( void )
{
  int flags, index;

  save_regs();                          /* Save a copy of current regs  */

  banner( "PALETTE" );

  flags = (ax >> 14) & 0x0003;          /* Get flag bits from command   */
  index = ax & 0x3fff;                  /* Mask to get color index      */

  switch( flags ){                      /* Act according to flags       */
    case 0:                             /* Set indexed color palette    */
      dputs( "    Set Indexed Color:  Index: " );
      putnum( index );
      dputs( "   Color Value: " );
      putnum( bx );
      crlf();
      break;
    case 1:                             /* Undefine color command       */
      dputs( "ERROR: Undefined Set Color Command (01)\r\n" );
      break;
    case 2:                             /* RGB - Index color            */
      dputs( "    Set RGB Color:  Index: " );
      putnum( index );
      dputs( "  R: " );
      putnum( bx );
      dputs( "  G: " );
      putnum( cx );
      dputs( "  B: " );
      putnum( dx );
      crlf();
      break;
    case 3:                             /* Background color             */
      dputs( "    Set Background Color:  Color Value: " );
      putnum( bx );
      crlf();
      break;
    }

}

/* ----------------------------- ALLPALETTE ---------------------------- */
/*                                                                       */
/*      The all palette command is used to load an entire palette in     */
/*      a single output command. The current BGI limits the size of      */
/*      the allpalette command to be the first 16 colors.                */
/*                                                                       */

void allpalette( void )
{
  unsigned char far *pptr = MK_FP( _ES, _BX );
  int i;

  banner( "ALLPALETTE" );
  i = *pptr++;
  dputs( "    Palette Size:  " );
  putnum( i );
  crlf();

  while( i-- ){
    dputs( "      " );
    putnum( *pptr++ );
    crlf();
    }

}

/* ----------------------------- COLOR --------------------------------- */
/*                                                                       */
/*      The color function takes an index and sets the active fore       */
/*      and background colors for output devices.                        */
/*                                                                       */

void color( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "COLOR" );
  dputs( "    Drawing Color:  " );
  putnum( al );
  dputs( "    Filling Color:  " );
  putnum( ah );
  crlf();

}

/* ----------------------------- FILLSTYLE ----------------------------- */
/*                                                                       */
/*      The fill style function is used to set the interior style of     */
/*      the filled primatives.  The input to the function is the         */
/*      filled pattern style number, or a flag and a pointer to load     */
/*      an 8x8 bit pattern tile.                                         */
/*                                                                       */

void fillstyle( void )
{

  static char *fill_name[] = {          /* Names of line styles         */
    "Empty",
    "Solid",
    "Line",
    "Lt Slash",
    "Slash",
    "Bkslash",
    "Ltbkslash",
    "Hatch",
    "Xhatch",
    "Interleave",
    "Wide dot",
    "Close dot",
    "User Defined"
    };

  int i;
  unsigned char far *pptr;

  save_regs();                          /* Save a copy of current regs  */
  pptr = MK_FP( _ES, _BX );

  banner( "FILLSTYLE" );
  dputs( "    Fill Style: (" );
  putnum( al );
  dputs( ")  " );
  dputs( (al == 0xff) ? "User Defined" : fill_name[al] );
  dputs( " Fill\r\n" );

  if( al == 0xff ){                     /* User defined line style      */
    dputs( "    User Defined Fill Pattern:\r\n" );
    dputs( "      " );
    for( i=0 ; i<8 ; ++i ){
      puthex( *pptr++ );
      dputs( " " );
      }
    crlf();
    }


}

/* ----------------------------- LINESTYLE ----------------------------- */
/*                                                                       */
/*      The line style command is used to set the style of the lines     */
/*      and borders of objects. The input to the fucntion is the line    */
/*      style number, of a flag and a 16 bit pattern for user defined    */
/*      line drawing styles.                                             */
/*                                                                       */

void linestyle( void )
{
  static char *line_name[] = {          /* Names of line styles         */
    "Solid",
    "Dotted",
    "Center",
    "Dashed",
    "User Defined"
    };

  save_regs();                          /* Save a copy of current regs  */

  banner( "LINESTYLE" );
  dputs( "    Line Style: (" );
  putnum( al );
  dputs( ")  " );
  dputs( line_name[al] );
  dputs( "Line    Line Width:  " );
  putnum( cx );
  crlf();

  if( al == 4 ){                        /* User defined line style      */
    dputs( "    User Defined Line Pattern: " );
    puthex( cx );
    crlf();
    }

}

/* ----------------------------- TEXTSTYLE ----------------------------- */
/*                                                                       */
/*      The text style command is used to define the output font,        */
/*      text path, and text direction for font rendering.                */
/*                                                                       */

void textstyle( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "TEXTSTYLE" );
  dputs( "    Font Number:  " );
  putnum( al );
  dputs( "    Font Path:    " );
  putnum( ah );
  crlf();
  dputs( "    Character Size:  X:  " );
  putnum( bx );
  dputs( "    Y:  " );
  putnum( cx );
  crlf();

  _BX = bx;                             /* Return the input as default  */
  _CX = cx;

}

/* ------------------------------ TEXT --------------------------------- */
/*                                                                       */
/*      The text output command takes a string and renders the string    */
/*      on the output device. The input to the function is the text      */
/*      and the string length.                                           */
/*                                                                       */

void text( void )
{
  char far * cptr = MK_FP( _ES, _BX );
  int i;

  save_regs();                          /* Save a copy of current regs  */

  banner( "TEXT" );

  dputs( "    Input Text: \"" );

/*      Read sting from the far memory to local memory.                 */

  for( i=0 ; i<cx ; ++i ) Buffer[i] = *cptr++;
  Buffer[i] = '\0';                     /* Null terminate string        */

  dputs( Buffer );
  dputs( "\"\r\n" );

}

/* ---------------------------- FLOODFILL ------------------------------ */
/*                                                                       */
/*      This function is a standard floodfill command The input to       */
/*      the function is the seed point for the floodfill. The fill       */
/*      is done in the current drawing color and pattern.                */
/*                                                                       */

void floodfill( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "FLOOD FILL" );
  dputs( "    Seed Point:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  crlf();

}

/* ---------------------------- GETPIXEL  ------------------------------ */
/*                                                                       */
/*      This function is used to read a pixel from the screen.           */
/*      The function input is the coordinates of the pixel to be         */
/*      read.  The output from the function is the color of the          */
/*      pixel that was read.                                             */
/*                                                                       */

void getpixel( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "GET PIXEL" );
  dputs( "     Pixel Address:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  crlf();

}

/* ---------------------------- SETPIXEL  ------------------------------ */
/*                                                                       */
/*      This function is used to plot a pixel on the screen.             */
/*      the function input is the coordinates of the pixel to be         */
/*      plotted and the color value of the pixel.                        */
/*                                                                       */

void setpixel( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "SET PIXEL" );
  dputs( "     Pixel Address:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  dputs( "  Value: " );
  putnum( dl );
  crlf();

}

/* ----------------------------- BITMAPUTIL --------------------------- */
/*                                                                      */
/*      This function returns the base of the bit manipulation utility  */
/*      table. The entry does not perform any function.                 */
/*                                                                      */

void bitmaputil( void )
{

  banner( "BITMAPUTIL" );
  dputs( "    Bit Map Utility Table Base: " );
  puthex( _DS );
  dputs( ":" );
  puthex( (unsigned int) &Utility_Table );
  crlf();

  _ES = _DS;                            /* ES:BX = table address        */
  _BX = (unsigned int) &Utility_Table;  /* Assign Base of table address */

}

/* -------------------------------------------------------------------- */
/*                                                                      */
/*      The following defines the bit map utilities.                    */
/*                                                                      */
/*      These functions are accessed directly from the calling code,    */
/*      and are not process via the normal BGI Interface. Therefore,    */
/*      these routines must preserve the input data, and must be FAR    */
/*      functions.                                                      */
/*                                                                      */

void far enter_graphics( void )         /* Enter graphics mode function */
{
  unsigned int orgds = _DS;

  _DS = _CS;                            /* Point Data Seg to Code Seg   */
  banner( "Bit Map Function: Enter Pixel Graphics Mode" );
  _DS = orgds;                          /* Restore the original DS      */

}

void far leave_graphics( void )         /* Leave graphics mode function */
{
  unsigned int orgds = _DS;

  _DS = _CS;                            /* Point Data Seg to Code Seg   */
  banner( "Bit Map: Leave Pixel Graphics Mode" );
  _DS = orgds;                          /* Restore the original DS      */

}

void far putpix( void )                 /* Write a pixel function       */
{
  unsigned int arg   = _AX;
  unsigned int orgds = _DS;

  _DS = _CS;                            /* Point Data Seg to Code Seg   */
  save_regs();                          /* Save a copy of current regs  */

  banner( "Bit Map Function: Put Pixel" );
  dputs( "     Pixel Address:  X: " );
  putnum( arg );
  dputs( "  Y: " );
  putnum( bx );
  dputs( "  Value: " );
  putnum( dl );
  crlf();
  _DS = orgds;                          /* Restore the original DS      */

}

void far getpix( void )                 /* Read a pixel function        */
{
  unsigned int arg   = _AX;
  unsigned int orgds = _DS;

  _DS = _CS;                            /* Point Data Seg to Code Seg   */
  save_regs();                          /* Save a copy of current regs  */

  banner( "Bit Map Function: Get Pixel" );
  dputs( "     Pixel Address:  X: " );
  putnum( arg );
  dputs( "  Y: " );
  putnum( bx );
  crlf();

  _DS = orgds;                          /* Restore the original DS      */
  _DL = 5;                              /* Fake return value            */

}

void far bits_per_pixel( void )         /* returns the bits per pixel   */
{
  #define PIXEL_BITS 4

  save_regs();                          /* Save a copy of current regs  */
  banner( "Bit Map Function: Bits Per Pixel" );
  crlf();

  _AX = PIXEL_BITS;
}

void far set_page( void )               /* Set the active drawing page  */
{
  unsigned int arg   = _AL;
  unsigned int orgds = _DS;

  _DS = _CS;                            /* Point Data Seg to Code Seg   */
  save_regs();                          /* Save a copy of current regs  */

  banner( "Bit Map Function: Set Active Page" );
  dputs( "     Page Number:  " );
  putnum( arg );
  crlf();
  _DS = orgds;                          /* Restore the original DS      */

}

void far set_visual( void )             /* Set the active display page  */
{
  unsigned int arg   = _AL;
  unsigned int orgds = _DS;

  _DS = _CS;                            /* Point Data Seg to Code Seg   */
  save_regs();                          /* Save a copy of current regs  */

  banner( "Bit Map Function: Set Visual Page" );
  dputs( "     Page Number:  " );
  putnum( arg );
  crlf();
  _DS = orgds;                          /* Restore the original DS      */

}

void far set_write_mode( void )         /* Set the current write mode   */
{
  unsigned int arg   = _AX;
  unsigned int orgds = _DS;

  _DS = _CS;                            /* Point Data Seg to Code Seg   */
  save_regs();                          /* Save a copy of current regs  */

  banner( "Bit Map Function: Set Write Mode" );
  dputs( "     XOR Write Mode:  (" );
  putnum( arg );
  dputs( ")  " );
  dputs( arg ? "On\r\n" : "Off\r\n" );
  _DS = orgds;                          /* Restore the original DS      */

}


/* ---------------------------- RESTOREBITMAP -------------------------- */
/*                                                                       */
/*      The restore bit map function is used to load a retangular        */
/*      region from the host memory into the graphics memory. The        */
/*      input to the routine is the region to write, a pointer to        */
/*      the source in the host's memory, and the mode to use when        */
/*      writing the region.                                              */
/*                                                                       */

void restorebitmap( void )
{
  unsigned int si = _SI;
  unsigned int di = _DI;

  save_regs();                          /* Save a copy of current regs  */

  banner( "RESTOREBITMAP" );

  dputs( "    Restore Buffer at  " );
  puthex( _ES );
  dputs( ":" );
  puthex( bx );
  crlf();

  dputs( "    Start  X:  " );
  putnum( si );
  dputs( "  Y: " );
  putnum( di );
  dputs( "    End  X:  " );
  putnum( cx );
  dputs( "  Y: " );
  putnum( dx );
  crlf();

}

/* ---------------------------- SAVEBITMAP ----------------------------- */
/*                                                                       */
/*      The save bit map function is used to write a rectangular         */
/*      region from the graphics memory to the host memory. The input    */
/*      to the function is the region to be read, and a pointer to       */
/*      a save buffer in the host memory.                                */
/*                                                                       */

void savebitmap( void )
{
  unsigned int si = _SI;
  unsigned int di = _DI;

  save_regs();                          /* Save a copy of current regs  */

  banner( "SAVEBITMAP" );

  dputs( "    Save Buffer at  " );
  puthex( _ES );
  dputs( ":" );
  puthex( bx );
  crlf();

  dputs( "    Start  X:  " );
  putnum( si );
  dputs( "  Y: " );
  putnum( di );
  dputs( "    End  X:  " );
  putnum( cx );
  dputs( "  Y: " );
  putnum( dx );
  crlf();

}

/* ---------------------------- SETCLIP -------------------------------- */
/*                                                                       */
/*      The setclip function defines a clipping rectangle on the         */
/*      output device.  The input to the function defines the            */
/*      coordinated of the opposing corners of the clipping rectangle.   */
/*                                                                       */
/*                                                                       */

void setclip( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "SETCLIP" );
  dputs( "    Upper Left:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  dputs( "  Lower Right:  X: " );
  putnum( cx );
  dputs( "  Y: " );
  putnum( dx );
  crlf();

}

/* ---------------------------- GETPIXEL ------------------------------- */
/*                                                                       */
/*      The GetPixel function is used to read a specific pixel value     */
/*      from the graphics screen. The input is the coordinate of the     */
/*      pixel to be read. The output is the pixel value.                 */
/*                                                                       */

void get_pixel( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "GET PIXEL" );
  dputs( "    Pixel Address:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  crlf();

  _DL = 5;                              /* Return 5 as fake value       */

}

/* ---------------------------- SETPIXEL ------------------------------- */
/*                                                                       */
/*      The SetPixel command is used to write a specific pixel to        */
/*      the graphics area. The input values are the coordinate of        */
/*      the pixel to write, and the pixel value to write.                */
/*                                                                       */

void set_pixel( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "SET PIXEL" );
  dputs( "    Pixel Address:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  dputs( "  Value:  " );
  putnum( dl );
  crlf();

}

/* ---------------------------- ESCAPE -------------------------------- */

void escape( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "ESCAPE" );

}

/* ---------------------------- TEXTSIZE ------------------------------- */
/*                                                                       */
/*      The textsize function allows the kernal to inquire the size      */
/*      of text strings. The input to the function is a pointer to       */
/*      text and the length of the string. The output is the horz        */
/*      and vert dimensions of the string in pixels.                     */
/*                                                                       */

void textsiz( void )
{
  char far * cptr;
  int i;

  save_regs();                          /* Save a copy of current regs  */
  cptr = MK_FP( _ES, _BX );             /* Make a pointer to the text   */

  banner( "TEXT SIZE" );
  dputs( "    Input Text: \"" );

/*      Read sting from the far memory to local memory.                 */

  for( i=0 ; i<cx ; ++i ) Buffer[i] = *cptr++;
  Buffer[i] = '\0';                     /* Null terminate string        */

  dputs( Buffer );
  dputs( "\"\r\n" );

  _BX = cx * 8;                         /* Return default size info     */
  _CX = 8;

}

/* ---------------------------- COLOR_QUERY --------------------------- */
/*                                                                      */
/*      This function allows the kernal to inquire the size and base    */
/*      colors for the current device.                                  */
/*                                                                      */

void color_query( void )
{
  int i;

  save_regs();                          /* Save a copy of current regs  */

  i = Stat_Block.fcolors & 0x7f;        /* Get color info w/o flag bit  */

  banner( "QUERY COLOR" );
  switch( al ){                         /* Act on the input command     */
    case 0:                             /* Color palette size query     */
      dputs( "    Color Table Size:  (Size: " );
      putnum( i );
      dputs( "  Maximum Color: " );
      putnum( i-1 );
      dputs( ")\r\n" );
      _BX = i;                          /* Return the table size        */
      _CX = i - 1;                      /* Return the maximum color #   */
      break;

    case 1:                             /* Default palette settings     */
      dputs( "    Default Palette Query\r\n" );
      _ES = _CS;                        /* Mask ES:BX point to default  */
      _BX = (unsigned int) &Default_Palette;
      break;

    default:
      dputs( "    ERROR: Unknown Color Query Command: " );
      puthex( al );
      crlf();
      break;
    }

}

/* ---------------------------- SETWINDOW ------------------------------ */
/*                                                                       */
/*      The setwindow function defines a VDC space on the output device  */
/*      The input to the function defines the VDC's to be set to the     */
/*      current clipping viewport.                                       */
/*                                                                       */
/*                                                                       */

void setwindow( void )
{

  save_regs();                          /* Save a copy of current regs  */

  banner( "SETWINDOW" );
  dputs( "    Upper Left:  X: " );
  putnum( ax );
  dputs( "  Y: " );
  putnum( bx );
  dputs( "  Lower Right:  X: " );
  putnum( cx );
  dputs( "  Y: " );
  putnum( dx );
  crlf();

}

/* ----------------------------- BANNER ------------------------------- */
/*                                                                      */
/*      This function sends a string to the console via a direct        */
/*      DOS Function 9. The string is place inside a standard banner    */
/*      before being sent to the console.                               */
/*                                                                      */

void banner( char *string )
{
  static char header[] = ">>> DEBUG: ";

  dputs( header );
  dputs( string );
  crlf();

}


/* ----------------------------- PUTNUM ------------------------------- */
/*                                                                      */
/*      This function converts a number to a decimal ASCII string.      */
/*      The string is then sent to the console via a DPUTS command.     */
/*                                                                      */

void putnum( unsigned number )          /* Output Decimal Number        */
{
  static char numstr[10] = "XXXXXXXX";  /* String for conversion space  */

  itoa( number, numstr, 10 );           /* Convert to decimal string    */
  dputs( numstr );                      /* Send number to console       */

}


/* ----------------------------- PUTHEX ------------------------------- */
/*                                                                      */
/*      This function converts a number to a hexidecimal ASCII string.  */
/*      The string is then sent to the console via a DPUTS command.     */
/*                                                                      */

void puthex( unsigned number )          /* Output Hexidecimal Number    */
{
  static char hextbl[] = "0123456789ABCDEF";
  static char numstr[] = "XXXX";       /* String space for conversion  */

  numstr[3] = hextbl[ number & 0x000f ];
  number >>= 4;

  numstr[2] = hextbl[ number & 0x000f ];
  number >>= 4;

  numstr[1] = hextbl[ number & 0x000f ];
  number >>= 4;

  numstr[0] = hextbl[ number & 0x000f ];

  dputs( numstr );                      /* Send number to console       */

}


/* ----------------------------- DPUTS -------------------------------- */
/*                                                                      */
/*      This function send a string to the console using DOS.           */
/*                                                                      */

void dputs( char far *str )             /* Output string to console     */
{
  char far *cptr = str;                 /* Point at input string        */

  while( *cptr ){                       /* Send NULL terminated string  */
    _AH = 2;                            /* DOS Charater output function */
    _DL = *cptr++;                      /* Pick up character to send    */
    geninterrupt( 0x21 );               /* Enter DOS to send character  */
    }

}

/* ----------------------------- CRLF --------------------------------- */
/*                                                                      */
/*      This function send a Carrage Return and Line Feed to the        */
/*      console.                                                        */
/*                                                                      */

void crlf( void )                       /* goto new line on screen      */
{
  static char str[] = "\r\n";           /* New line string to DOS       */

  dputs( str );                         /* Send string to console       */

}

/* ----------------------------- SAVEREGS ----------------------------- */
/*                                                                      */
/*      This function saves a copy of all of the input registers.       */
/*      This function is needed because C does hidden things with       */
/*      registers, which would require constant PUSH's and POP's.       */
/*                                                                      */

void save_regs( void )                  /* Save registers into memory   */
{

  ax = _AX;     al = _AL;       ah = _AH;
  bx = _BX;     bh = _BH;       bl = _BL;
  cx = _CX;     ch = _CH;       cl = _CL;
  dx = _DX;     dh = _DH;       dl = _DL;

}


[ RETURN TO DIRECTORY ]