home *** CD-ROM | disk | FTP | other *** search
- /*************************** TECMAR DRIVER ******************************/
- /* Tecmar Graphics Master BGI driver. This program acts as a BGI */
- /* for the Tecmar Graphics Master (TGM) in the 640x400x16 mode. This */
- /* only works for a TGM configured to be a colour output device mapped */
- /* at segment 0xA000 and using ONLY that segment. It's a rather */
- /* unusual arrangement even for the TGM but it allows it to coexist */
- /* with other adapters (such as a Hercules), in a dual moniter system. */
- /* In this configuration the memory is mapped as follows. Two pixels */
- /* per byte high order byte holds first pixel and 320 consecutive */
- /* bytes form a line. The lines are arranged in two banks of two */
- /* 'paragraphs' each. Only one bank is accesible at a time. */
- /* */
- /* Offset Bank 0 Bank 1 */
- /* */
- /* +-----------------------+-----------------------+ */
- /* 0 | line 0 | line 2 | */
- /* | | | */
- /* */
- /* | | | */
- /* +-----------------------+-----------------------+ */
- /* 0x8000 | line 1 | line 3 | */
- /* | | | */
- /* */
- /* | | | */
- /* +-----------------------+-----------------------+ */
- /* */
- /* V 0.90 26/07/89 Robert Adsett Original. */
- /* V 1.00 18/05/90 Robert Adsett Release version. */
- /* V 1.10 30/06/90 Robert Adsett Add copyright. Editorial */
- /* changes. */
- /* V 1.11 02/07/90 Robert Adsett Add explicit casts to address */
- /* macros. */
- /* V 1.12 05/07/90 Robert Adsett Use a dummy copy of the current */
- /* screen address to overcome a */
- /* TC++ bug. */
- /* V 1.13 11/07/90 Robert Adsett Was copying one too many rows */
- /* in save/restore bitmap. */
- /* */
- /* LIMITATIONS: */
- /* Block operations are slow. They could be speeded up */
- /* considerably by recoding them in assembly language. */
- /* Flood fill is unimplemented at present. */
- /* Palette setting operations are null functions. The colours */
- /* on the TGM are hardwired and unchangeable. */
- /* Error checking & reporting are almost non-existant. */
- /* Everything that can be emulated is. This seems to be */
- /* reasonably fast so changing this is not a high priority. */
- /* */
- /* KNOWN BUGS: */
- /* Line width is currently ignored. This seems to be taken care */
- /* of by the kernal but should be changed. */
- /************************************************************************/
-
- #include <stdlib.h>
- #include <string.h>
- #include "bgi.h"
- #include "tecmar.h"
-
- /* Generic driver global variables. Should be present in almost */
- /* every driver. */
-
- const CHAR_TABLE_ENTRY far * const char_def =
- (CHAR_TABLE_ENTRY far *)MK_FP( 0xf000, 0xfa6e);
- /* Pointer to character definition */
- /* table in ROM. */
-
- /* Fill pattern definitions. */
- const FILLPATTERN def_patterns[12] = {
- { 0, 0, 0, 0, 0, 0, 0, 0 }, /* No Fill. */
- { 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff }, /* Solid Fill. */
- { 0xff, 0xff, 0, 0, 0xff,
- 0xff, 0, 0}, /* Line Fill. */
- { 1, 2, 4, 8, 0x10, 0x20,
- 0x40, 0x80}, /* Lt Slash fill. */
- { 0xE0, 0xC1, 0x83, 0x07,
- 0x0E, 0x1C, 0x38, 0x70 }, /* Slash Fill. */
- { 0xF0, 0x78, 0x3C, 0x1E,
- 0x0F, 0x87, 0xC3, 0xE1 }, /* Backslash Fill. */
- { 0xA5, 0xD2, 0x69, 0xB4,
- 0x5A, 0x2D, 0x96, 0x4B }, /* Lt Backslash Fill. */
- { 0xFF, 0x88, 0x88, 0x88,
- 0xFF, 0x88, 0x88, 0x88 }, /* Hatch Fill. */
- { 0x81, 0x42, 0x24, 0x18,
- 0x18, 0x24, 0x42, 0x81 }, /* XHatch Fill. */
- { 0xCC, 0x33, 0xCC, 0x33,
- 0xCC, 0x33, 0xCC, 0x33 }, /* Interleave Fill. */
- { 0x80, 0x00, 0x08, 0x00,
- 0x80, 0x00, 0x08, 0x00 }, /* Wide Dot Fill. */
- { 0x88, 0x00, 0x22, 0x00,
- 0x88, 0x00, 0x22, 0x00 } /* Close Dot Fill. */
- };
- /* */
- /* The following structure defines the Bit Manipulation Utility */
- /* function table. */
- /* */
-
- const UTILITIES Utility_Table = { /* Bit Utilities Function Table */
- (NRFPTR) dispatch_enter_graphics, /* Enter graphics mode function */
- (NRFPTR) dispatch_leave_graphics, /* Leave graphics mode function */
- (NRFPTR) dispatch_putpix, /* Write a pixel function */
- (NRFPTR) dispatch_getpix, /* Read a pixel function */
- (NRFPTR) dispatch_bits_per_pixel, /* Bits per pixel value */
- (NRFPTR) dispatch_set_page, /* Set the active drawing page */
- (NRFPTR) dispatch_set_visual, /* Set the active display page */
- (NRFPTR) dispatch_set_write_mode /* Set the current write mode */
- };
-
- int MAXY = 399, MAXX = 640, MINY = 0, /* Clipping limits. */
- MINX = 0;
- unsigned int current_line_style = 0xffff; /* Current line drawing */
- /* style. */
- int current_write_mode = COPY; /* Current drawing mode. */
- int current_line_width = 1; /* Current line width. */
- unsigned char current_colour = 0xff, /* Current drawing, */
- fill_colour = 0xff, /* filling, */
- background_colour = 0; /* and background colour. */
-
- unsigned int CP_X = 0, CP_Y = 0; /* Current Drawing Pointer CP. */
- unsigned int char_size, char_path; /* Current character size and */
- /* drawing path. */
-
- const unsigned int line_style_mask[16] = { /* A set of bit masks */
- 0x8000, /* used to mask bits */
- 0x4000, /* from the current */
- 0x2000, /* line style. */
- 0x1000,
- 0x0800,
- 0x0400,
- 0x0200,
- 0x0100,
- 0x0080,
- 0x0040,
- 0x0020,
- 0x0010,
- 0x0008,
- 0x0004,
- 0x0002,
- 0x0001
- };
-
- STATUS Stat_Block = { /* Device status block. */
- 0, /* Current device status. */
- 0, /* Device Type Identifier. */
- 639, /* Device Full Resolution in X */
- 399, /* Device Full Resolution in Y */
- 639, /* Device Effective X Resolution */
- 399, /* Device Effective Y Resolution */
- 9000, /* Device X Size in inches*1000 */
- 7000, /* Device Y Size in inches*1000 */
- 10000, /* Aspect Ratio * 10000 */
- /* For compatibility the other fields */
- /* set so. */
- 8,
- 8,
- 0x90,
- 0x90
- };
-
- PALETTE Default_Palette = { /* Default palette. Note that this is */
- /* hardwired and unchangeable for the */
- /* TGM. */
- 16, { 0x00, /* Black */
- 0x01, /* Blue */
- 0x02, /* Green */
- 0x03, /* Cyan */
- 0x04, /* Red */
- 0x05, /* Magenta */
- 0x07, /* Light Gray */
- 0x14, /* Brown */
- 0x38, /* Dark Gray */
- 0x39, /* Light Blue */
- 0x3A, /* Light Green */
- 0x3B, /* Light Cyan */
- 0x3C, /* Light Red */
- 0x3D, /* Light Magenta */
- 0x3E, /* Yellow */
- 0x3F } /* White */
- };
-
- /* Global variables specific to this driver. */
-
- /* Determines the bank and paragraph for an */
- /* address. */
- const struct BANK_PARA bank_para[4] = {
- { 31, 0x8000+320, 0x8000, 0},
- { 31, 0x8000, 0x8000, 0x8000},
- { 95, 0x8000, 0x8000, 0},
- { 95, 0x8000, 0x8000-320, 0x8000}
- };
- int current_bank = 31, /* Current bank. */
- bank_para_index; /* Offset into the bank_par structure for this */
- /* address. */
- const unsigned char mask[2] = { 0xf0, 0x0f}; /* Used to ask off */
- /* pixels in a byte. */
-
- unsigned char far * const screen_buffer =
- (unsigned char far *)MK_FP( TECMAR_SEGMENT, 0);
- /* Pointer to the base of video memory. */
- unsigned char current_pattern[8][4]; /* Current fill pattern stored */
- /* as pixels. */
- unsigned char far *current_address; /* Current address into video */
- /* memory. */
- char current_mask; /* Current pixel mask. */
-
-
-
- /* */
- /* Function Protoypes local to the tecmar driver. */
- /* */
-
- void char_draw( unsigned char c);
- void copy_image(
- unsigned char const far *from,
- int from_off,
- int from_xsize,
- unsigned char far *to,
- int to_off,
- int to_xsize,
- int mode
- );
- void set_pattern( unsigned char *current_pattern,
- unsigned char const far *pattern);
- void update_pattern( void);
-
-
- /******************************* 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. */
- /* sets the error code to 'grInvalidMode' for invalid mode numbers */
- /* and 'grError' for an unrecognized command. */
- /************************************************************************/
-
- const char *CopyRight =
- "Tecmar Graphics Master BGI driver (V 1.10) Copyright R. Adsett 1990.";
-
- char Name[] = "\x1F Tecmar Driver (640 x 480 x 4)";
- /* Name of the drivers only mode. The */
- /* first character is the length of */
- /* the string. */
-
- long install(
- unsigned int mode, /* Mode to use. */
- char command /* Install sub command. */
- )
- {
- long ret_code;
-
- switch( command ) /* Determine the command to use */
- {
- case 0: /* Install Device Command. */
- if((mode & 0xff) >= MAX_MODES) /* Is the mode requested valid? */
- { /* No set an error code. */
- Stat_Block.stat = grInvalidMode;
- }
- ret_code = (unsigned int)&Stat_Block; /* Return pointer to */
- break; /* the status block. */
-
- case 1: /* Mode Query Command. */
- ret_code = (long)MAX_MODES << 16; /* Return number of modes. */
- break;
-
- case 2: /* Mode Name Command. */
- if( (mode & 0xff) > MAX_MODES) /* Is the mode requested valid? */
- { /* No set an error code. */
- Stat_Block.stat = grInvalidMode;
- }
- ret_code = (unsigned int)Name; /* Return pointer to the name. */
- break;
-
- default: /* Unknown Install Call. */
- Stat_Block.stat = grError; /* General error. */
- break;
- } /* End of Install command case. */
- return( ret_code); /* Return pointer, mode numbers */
- }
-
- /******************************* INITIALIZE *****************************/
- /* The initialize function is uset to enter the graphics mode. */
- /* Since there is only one graphics mode and no text mode all this */
- /* does is initialize the adapter and clear the screen. */
- /************************************************************************/
-
- /************************************************************************/
- /* These are the initialization parameters required to set up the */
- /* Tecmar in the 640 x 400 x 4 mode. Don't ask me what all these */
- /* values do, I'm taking it on rote. The first column is the port and */
- /* the second is the byte to send out it. (0,0) ends the sequence. */
- /************************************************************************/
-
- static const unsigned int init_6845[][2] = {
- { 0x398, 1},
- { 0x394, 13},
- { 0x395, 0},
- { 0x394, 12},
- { 0x395, 0},
- { 0x394, 11},
- { 0x395, 0},
- { 0x394, 10},
- { 0x395, 32},
- { 0x394, 9},
- { 0x395, 3},
- { 0x394, 8},
- { 0x395, 3},
- { 0x394, 7},
- { 0x395, 56},
- { 0x394, 6},
- { 0x395, 50},
- { 0x394, 5},
- { 0x395, 1},
- { 0x394, 4},
- { 0x395, 64},
- { 0x394, 3},
- { 0x395, 15},
- { 0x394, 2},
- { 0x395, 184},
- { 0x394, 1},
- { 0x395, 160},
- { 0x394, 0},
- { 0x395, 227},
- { 0x399, 0},
- { 0x39a, 31},
- { 0x398, 24},
- { 0, 0}
- };
-
-
- void init( unsigned int dit_offset, unsigned int dit_segment)
- {
- int i;
- struct DIT far *Dev_info;
-
- Dev_info = (struct DIT far *)MK_FP( dit_segment, dit_offset);
-
- Dev_info->background &= 0x0f; /* Mask background colour. */
- background_colour = (Dev_info->background << 4) | Dev_info->background;
- /* Set the background colour. */
- update_pattern(); /* Set up the pattern for use. */
- if( Dev_info->init != 0xA5) /* Don't ask me! */
- {
- for( i = 0; init_6845[i][0] != 0; i++) /* Set up video mode. */
- {
- outportb( init_6845[i][0], init_6845[i][1]);
- }
- clear(); /* Clear the screen. */
- }
- }
-
- /******************************* CLEAR **********************************/
- /* Clear the screen. Write zero everywhere. */
- /************************************************************************/
-
- void clear( void )
- {
-
- outportb( 0x398, 1); /* Turn off screen. */
- outportb( 0x39a, 31); /* Set bank. */
- set_mem( screen_buffer, 0, 0); /* Erase Bank 0. */
- outportb( 0x39a, 95); /* Set bank. */
- set_mem( screen_buffer, 0, 0); /* Erase Bank 1. */
- outportb( 0x39a, current_bank); /* Restore current bank. */
- outportb( 0x398, 24); /* Turn on screen. */
- }
-
- /********************************** POST ********************************/
- /* Go to text mode. A null function for the TGM in this mode. */
- /************************************************************************/
-
- void post( void )
- {
-
- /* Tecmar has no text mode in this configuration. */
- }
-
- /********************************* MOVE *********************************/
- /* This function is used to move the current pointer (CP). This is */
- /* a pretty generic routine, library later? */
- /************************************************************************/
-
- void move( int x, int y)
- {
-
- CP_X = x; /* Update the current pointer. */
- CP_Y = y;
- }
-
- /******************************** DRAW **********************************/
- /* Draw a line vector from the CP to the specified coordinate. */
- /* Update the CP to the new coordinate. */
- /************************************************************************/
-
- void draw( int x, int y)
- {
-
- line( CP_X, CP_Y, x, y); /* Draw the line. */
- CP_X = x; /* Update the current pointer */
- CP_Y = y;
- }
-
- /********************************* VECT *********************************/
- /* Draw a line between the two specified points. */
- /************************************************************************/
-
- void vect( int x1, int y1, int x2, int y2)
- {
-
- line( x1, y1, x2, y2); /* Draw the line. */
- }
-
- /********************************* PATBAR *******************************/
- /* Fill a rectangle with the current filling pattern. Do not */
- /* outline. The coordinates passed are the upper left corner and the */
- /* lower right corner. */
- /************************************************************************/
- /* Dummy copy to counter TC++ BUG!! */
- void far *junk;
- void patbar( int x1, int y1, int x2, int y2)
- {
- int x3, y3;
-
- if( x2 < x1) /* Sometimes the emulation routines get */
- { /* the y coords. backwards. We'll */
- x3 = x2; x2 = x1; x1 = x3; /* check the x coords. as well just */
- } /* to be sure. */
- if( y2 < y1)
- {
- y3 = y2; y2 = y1; y1 = y3;
- }
- for( ; y1 <= y2; y1++) /* For each line. */
- {
- x3 = x1;
- y3 = y1;
- CALC_ADDR( x3, y3); /* Calculate start address.... */
- /* Dummy copy to counter TC++ BUG!! */
- junk = current_address;
- copy_image( current_pattern[y1&7], 0, 8, current_address, x1&1,
- x2-x1+1, COPY); /* ... and copy appropriate line of the */
- /* current pattern in. */
- }
- }
-
- /******************************* PALETTE ********************************/
- /* There is no way to adjust the palette on the TGM. This is a */
- /* null function. */
- /************************************************************************/
-
- void palette( int flag_index, int red_colour, int blue, int green)
- {
- }
-
- /****************************** ALLPALETTE ******************************/
- /* There is no way to adjust the palette on the TGM. This is a */
- /* null function. */
- /************************************************************************/
-
- void allpalette( unsigned int pptr_offset, unsigned int pptr_segment)
- {
- }
-
- /******************************* COLOR **********************************/
- /* Sets new foreground (drawing) and fill colours. */
- /************************************************************************/
-
- void color( char new_fill_colour, char new_draw_colour )
- {
-
- new_draw_colour &= 0xf; /* Mask colours to possible range. */
- new_fill_colour &= 0xf;
- /* Expand them to fill a full char. */
- /* This makes it easier to set a */
- /* a pixel appropriately. */
- current_colour = (new_draw_colour << 4) | new_draw_colour;
- fill_colour = (new_fill_colour << 4) | new_fill_colour;
- update_pattern(); /* Update current pattern to reflect */
- /* the new colours. */
- }
-
- /******************************* FILLSTYLE ******************************/
- /* Set the current fillstyle. */
- /************************************************************************/
-
- static int current_pattern_no = 0, user_pattern[8];
- /* Current pattern and user pattern. */
-
- void fillstyle( unsigned char pattern, unsigned int pptr_offset,
- unsigned int pptr_segment)
- {
- unsigned char far *pptr;
- int i;
-
- pptr = MK_FP( pptr_segment, pptr_offset); /* Ptr. to user line */
- /* style. */
- current_pattern_no = pattern; /* Save current style. */
- if( current_pattern_no == 0xff ) /* User defined line style */
- {
- set_pattern( (unsigned char *)¤t_pattern, pptr);
- /* Make pattern accessible to filling */
- /* routine. */
- for( i = 0; i < 8; i++) /* Save User pattern for later use. */
- {
- user_pattern[i] = *(int far *)(pptr + i*sizeof( int));
- }
- }
- else
- {
- set_pattern( (unsigned char *)current_pattern,
- (unsigned char far *)&def_patterns[pattern]);
- /* Make pattern accessible to filling */
- /* routine. */
- }
- }
-
- void update_pattern( void) /* Update pattern to take care of new */
- { /* colours. */
-
- if( current_pattern_no == 0xff ) /* User defined line style */
- {
- set_pattern( (unsigned char *)current_pattern,
- (unsigned char far *)user_pattern);
- /* Make pattern accessible to filling */
- /* routine. */
- }
- else
- {
- set_pattern( (unsigned char *)current_pattern,
- (unsigned char far *)&def_patterns[current_pattern_no]);
- /* Make pattern accessible to filling */
- /* routine. */
- }
- }
-
- /******************************* LINESTYLE ******************************/
- /* Set the current line style. This includes drawing pattern and */
- /* width. */
- /************************************************************************/
-
- void linestyle( char style, int pattern, int width)
- {
-
- switch( style) /* Set appropriate line pattern. */
- {
- case SOLID_LINE:
- current_line_style = 0xffff;
- break;
-
- case DOTTED_LINE:
- current_line_style = 0xCCCC;
- break;
-
- case CENTRE_LINE:
- current_line_style = 0xFC78;
- break;
-
- case DASHED_LINE:
- current_line_style = 0xF8F8;
- break;
-
- case USER_LINE:
- current_line_style = pattern;
- break;
-
- default:
- break;
- }
- current_line_width = width; /* Save the width. */
- }
-
- /******************************* TEXTSTYLE ******************************/
- /* Set the text path and size. Returns x & y size as a long. */
- /************************************************************************/
-
- long textstyle( char number, char path, int xsize, int ysize)
- {
-
- char_path = path; /* Record path. */
- char_size = xsize >> 3; /* Convert text size to a */
- /* multiple of 8. */
- if( char_size == 0) /* Must be at least 1. */
- char_size = 1;
- xsize = ysize = char_size << 3; /* Compute actual size. */
- return( (((long)xsize) << 16) | ysize); /* Return actual size. */
- }
-
- /******************************** TEXT **********************************/
- /* Draw a text string. */
- /************************************************************************/
-
- void text( int length, unsigned int offset, unsigned int segment)
- {
- char far * cptr = MK_FP( segment, offset);
- int i;
-
- for( i = 0; i < length; ++i ) /* For all characters ... */
- {
- char_draw( *cptr++); /* Draw it. */
- }
- }
-
- /****************************** FLOODFILL *******************************/
- /* Unimplemented. Null function. */
- /************************************************************************/
-
- void floodfill( int x, int y, unsigned char boundary)
- {
- }
-
- /******************************* BITMAPUTIL *****************************/
- /* Get the address of the bit map utility table. */
- /************************************************************************/
-
- void *bitmaputil( void )
- {
-
- return((void *)&Utility_Table);
- }
-
- /* */
- /* The following define the bit map utility functions. */
- /* */
-
- void enter_graphics( void ) /* Enter graphics mode function.*/
- { /* Null function. */
- }
-
- void leave_graphics( void ) /* Leave graphics mode function */
- { /* Null function. */
- }
-
- int bits_per_pixel( void ) /* Enter graphics mode function */
- {
-
- return( 4); /* Always 4 bits/pixel. */
- }
-
- void putpix( int x, int y, char colour) /* Write a pixel function */
- {
-
- colour &= 0xf; /* Propagate colour to high */
- colour |= colour << 4; /* nibble. */
- CALC_ADDR( x, y); /* Calculate address. */
- POINT( colour); /* Draw pixel. */
- }
-
- char getpix( int x, int y) /* Read a pixel function */
- {
-
- CALC_ADDR( x, y); /* Calculate address. */
- return( RD_POINT()); /* Read pixel colour. */
- }
-
- void set_page( char page) /* Set the active drawing page */
- { /* Null function. Only 1 page. */
-
- }
-
- void set_visual( char page) /* Set the active display page */
- { /* Null function. Only 1 page. */
-
- }
-
- void set_write_mode( int mode) /* Set the current write mode */
- {
-
- current_write_mode = mode; /* Save write mode. */
- }
-
-
- /****************************** RESTOREBITMAP ***************************/
- /* Copy a bitmap to video memory. */
- /************************************************************************/
-
- void restorebitmap( char mode, unsigned int segment, unsigned int offset,
- int x1, int y1, int x2, int y2)
- {
- const unsigned char far *buffer;
- int xsize, x3, y3, bump;
-
- x1 = x2;/* Bug. */
- y1 = y2;
-
- buffer = (const unsigned char far *)MK_FP( segment, offset);
- /* Bitmap address. */
- xsize = *(int far *)buffer + 1; /* Columns. */
- buffer += sizeof( int);
- y2 = y1 + *(int far *)buffer + 1; /* Rows. */
- bump = xsize/2 +1; /* Size of row in memory. This */
- /* should be agreed on with */
- /* 'savebitmap'. */
- buffer += sizeof(int); /* Increment to storage. */
- for( ;y1 < y2; y1++) /* For each line... */
- {
- x3 = x1;
- y3 = y1;
- CALC_ADDR( x3, y3); /* Find the beginning. */
- /* Dummy copy to counter TC++ BUG!! */
- junk = current_address;
- copy_image( buffer, 0, xsize, current_address, x1&1, xsize, mode);
- /* Copy the line using the */
- /* appropriate mode. */
- buffer += bump; /* Increment bitmap to the next */
- } /* line. */
- }
-
- /****************************** SAVEBITMAP ******************************/
- /* Copy an area of video memory to a bitmap. */
- /************************************************************************/
-
- void savebitmap( unsigned int buff_segment, unsigned int buff_offset,
- int x1, int y1, int x2, int y2)
- {
- unsigned char far *buffer;
- int xsize, x3, y3, bump;
-
- x1 = x2;/* Bug.*/
- y1 = y2;
- buffer = (unsigned char far *)MK_FP( buff_segment, buff_offset);
- /* Bitmap address. */
- xsize = *(int far *)buffer + 1; /* Columns. */
- buffer += sizeof( int);
- y2 = y1 + *(int far *)buffer + 1; /* Rows. */
- bump = xsize/2 +1; /* Size of row in memory. This */
- /* should be agreed on with */
- /* 'restorebitmap'. */
- buffer += sizeof(int); /* Increment to storage. */
- for( ;y1 < y2; y1++) /* For each line... */
- {
- x3 = x1;
- y3 = y1;
- CALC_ADDR( x3, y3); /* Find the beginning. */
- /* Dummy copy to counter TC++ BUG!! */
- junk = current_address;
- copy_image( current_address, x1&1, xsize, buffer, 0, xsize, COPY);
- /* Copy the line using the */
- /* copy mode. */
- buffer += bump; /* Increment bitmap to the next */
- } /* line. */
- }
-
- /****************************** SETCLIP *********************************/
- /* Set the clipping area. Library? */
- /************************************************************************/
-
- void setclip( int x1, int y1, int x2, int y2)
- {
-
- MINX = x1; /* Save the clipping limits. */
- MAXY = y1;
- MAXX = x2;
- MAXY = y2;
- }
-
- /***************************** GET_PIXEL ********************************/
- /* Read a pixel colour from the screen. */
- /************************************************************************/
-
- char get_pixel( int x, int y)
- {
-
- CALC_ADDR( x, y); /* Calculate the address. */
- return( RD_POINT()); /* Read the pixel. */
- }
-
- /***************************** SET_PIXEL ********************************/
- /* Set a pixel to a specific colour. */
- /************************************************************************/
-
- void set_pixel( int x, int y, char colour)
- {
-
- colour &= 0xf; /* Propagate colour to the high */
- colour |= colour << 4; /* nibble. */
- CALC_ADDR( x, y); /* Calculate address. */
- POINT( colour); /* Draw the pixel. */
- }
-
- /****************************** TEXTSIZ *********************************/
- /* Return the pixel size of a string. */
- /************************************************************************/
-
- long textsiz( int length, unsigned int offset, unsigned int segment)
- {
- if( char_path == NORMAL_PATH) /* Horizontal. */
- {
- return( (((long)(length*char_size*8))<<16) | (8*char_size));
- }
- else /* Vertical. */
- {
- return( (((long)(char_size*8))<<16) | (length*8*char_size));
- }
- }
-
- /****************************** COLOR_QUERY *****************************/
- /* Get colour palette & size. */
- /************************************************************************/
-
- long color_query( char command_type)
- {
- int i;
- long ret_val;
-
- i = 16; /* Number of colours. */
-
- switch( command_type ) /* Act on the input command. */
- {
- case 0: /* Color palette size query. */
- ret_val = ((long)i -1L) << 16;
- ret_val |= i;
- break;
-
- case 1: /* Default palette settings. */
- ret_val = (unsigned long)&Default_Palette;
- break;
-
- default: /* Unknown command. */
- break;
- }
- return( ret_val);
- }
-
- /********************* CHAR_DRAW ****************************************/
- /* Draw a character. */
- /************************************************************************/
- void char_draw( unsigned char c)
- {
- static unsigned char char_bit_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
- const CHAR_TABLE_ENTRY far *current;
- int i, j, k, l, tx, ty;
- unsigned char row_cur;
-
- current = char_def + c; /* Get character definition from ROM. */
- if( char_path == NORMAL_PATH) /* Draw horizontal. */
- {
- for( i = 0; i < 8; i++) /* For each row... */
- {
- row_cur = (current->row)[i]; /* Def. for this line. */
- for( j = 0; j < char_size; j++) /* Size multiplier. */
- {
- for( k = 0; k < 8; k++) /* For each column... */
- {
- if( row_cur & char_bit_mask[k]) /* Column def. */
- {
- for( l = 0; l < char_size; l++) /* Draw 'size' */
- { /* points. */
- tx = CP_X;
- ty = CP_Y;
- DRAW_POINT( tx, ty);
- CP_X++;
- }
- }
- else /* Advance 'size' points. */
- {
- CP_X += char_size;
- }
- }
- CP_X -= char_size*8; /* Back to begining col.*/
- CP_Y++; /* Next line. */
- }
- }
- CP_X += char_size*8; /* Next character. */
- CP_Y -= char_size*8; /* Charcter top. */
- }
- else /* Draw vertical. */
- {
- for( i = 0; i < 8; i++) /* For each row... */
- {
- row_cur = (current->row)[i]; /* Def. for this line. */
- for( j = 0; j < char_size; j++) /* Size multiplier. */
- {
- for( k = 0; k < 8; k++) /* For each column... */
- {
- if( row_cur & char_bit_mask[k]) /* Column def. */
- {
- for( l = 0; l < char_size; l++)
- {
- tx = CP_X;
- ty = CP_Y;
- DRAW_POINT( tx, ty);
- CP_Y--;
- }
- }
- else /* Advance 'size' points. */
- {
- CP_Y -= char_size;
- }
- }
- CP_Y += char_size*8; /* Back to begining col.*/
- CP_X++; /* Next line. */
- }
- }
- CP_Y -= char_size*8; /* Next character. */
- CP_X -= char_size*8; /* Charcter top. */
- }
- }
-
- /************************* COPY_IMAGE ***********************************/
- /* Copy an image line from one area of memory to another. The */
- /* source image is repeated as necessary to fill the destination. */
- /* This is sufficient to form the core of a basic set of two parameter */
- /* BiTBlT routines except for the fact that no precautions are taken */
- /* against overlap. Could be sped up considerably by recoding in */
- /* assembly code. */
- /************************************************************************/
-
- void copy_image(
- unsigned char const far *from,
- int from_off,
- int from_xsize,
- unsigned char far *to,
- int to_off,
- int to_xsize,
- int mode
- )
- {
- int j;
- unsigned char from_mask, to_mask, temp;
- unsigned char const far *temp_from;
-
- from_mask = mask[from_off]; /* Mask appropriately to get */
- to_mask = mask[to_off]; /* the right nibbles. May not */
- /* be on a byte boundary. */
- temp_from = from; /* Pointer to source. */
-
- switch( mode) /* Copy mode. */
- {
- case COPY: /* Copy verbatim. */
- for( j = 0; j < to_xsize; j++) /* Until destination is full... */
- {
- if( !(j % from_xsize)) /* Restart source from start. */
- {
- temp_from = from;
- from_mask = mask[from_off];
- }
- temp = (*temp_from & from_mask); /* Read source... */
- if( from_mask == 0xf0)
- {
- temp |= temp >> 4; /* ... into low nibble, */
- }
- else
- {
- temp |= temp << 4; /* ... and high. */
- }
- *to = (*to & ~to_mask) | (temp & to_mask);
- /* Copy source into */
- /* proper dest. nibble.*/
- to_mask = ~to_mask; /* Increment source */
- from_mask = ~from_mask; /* and destination. */
- if( to_mask == 0xf0) /* Start of new byte. */
- {
- to++;
- }
- if( from_mask == 0xf0)
- {
- temp_from++;
- }
- }
- break;
-
- case XOR: /* Copy xor. */
- for( j = 0; j < to_xsize; j++) /* Until destination is full... */
- {
- if( !(j % from_xsize)) /* Restart source from start. */
- {
- temp_from = from;
- from_mask = mask[from_off];
- }
- temp = (*temp_from & from_mask); /* Read source... */
- if( from_mask == 0xf0)
- {
- temp |= temp >> 4; /* ... into low nibble, */
- }
- else
- {
- temp |= temp << 4; /* ... and high. */
- }
- *to = (*to & ~to_mask) | ((temp ^ *to) & to_mask);
- /* Xor source into */
- /* proper dest. nibble.*/
- to_mask = ~to_mask; /* Increment source */
- from_mask = ~from_mask; /* and destination. */
- if( to_mask == 0xf0) /* Start of new byte. */
- {
- to++;
- }
- if( from_mask == 0xf0)
- {
- temp_from++;
- }
- }
- break;
-
- case OR: /* Copy or. */
- for( j = 0; j < to_xsize; j++) /* Until destination is full... */
- {
- if( !(j % from_xsize)) /* Restart source from start. */
- {
- temp_from = from;
- from_mask = mask[from_off];
- }
- temp = (*temp_from & from_mask); /* Read source... */
- if( from_mask == 0xf0)
- {
- temp |= temp >> 4; /* ... into low nibble, */
- }
- else
- {
- temp |= temp << 4; /* ... and high. */
- }
- *to = (*to & ~to_mask) | ((temp | *to) & to_mask);
- /* Or source into */
- /* proper dest. nibble.*/
- to_mask = ~to_mask; /* Increment source */
- from_mask = ~from_mask; /* and destination. */
- if( to_mask == 0xf0) /* Start of new byte. */
- {
- to++;
- }
- if( from_mask == 0xf0)
- {
- temp_from++;
- }
- }
- break;
-
- case AND: /* Copy and. */
- for( j = 0; j < to_xsize; j++) /* Until destination is full... */
- {
- if( !(j % from_xsize)) /* Restart source from start. */
- {
- temp_from = from;
- from_mask = mask[from_off];
- }
- temp = (*temp_from & from_mask); /* Read source... */
- if( from_mask == 0xf0)
- {
- temp |= temp >> 4; /* ... into low nibble, */
- }
- else
- {
- temp |= temp << 4; /* ... and high. */
- }
- *to = (*to & ~to_mask) | ((temp & *to) & to_mask);
- /* And source into */
- /* proper dest. nibble.*/
- to_mask = ~to_mask; /* Increment source */
- from_mask = ~from_mask; /* and destination. */
- if( to_mask == 0xf0) /* Start of new byte. */
- {
- to++;
- }
- if( from_mask == 0xf0)
- {
- temp_from++;
- }
- }
- break;
-
- case NEGATE: /* Copy negate. */
- for( j = 0; j < to_xsize; j++) /* Until destination is full... */
- {
- if( !(j % from_xsize)) /* Restart source from start. */
- {
- temp_from = from;
- from_mask = mask[from_off];
- }
- temp = (*temp_from & from_mask); /* Read source... */
- if( from_mask == 0xf0)
- {
- temp |= temp >> 4; /* ... into low nibble, */
- }
- else
- {
- temp |= temp << 4; /* ... and high. */
- }
- *to = (*to & ~to_mask) | (~temp & to_mask);
- /* Negate source into */
- /* proper dest. nibble.*/
- to_mask = ~to_mask; /* Increment source */
- from_mask = ~from_mask; /* and destination. */
- if( to_mask == 0xf0) /* Start of new byte. */
- {
- to++;
- }
- if( from_mask == 0xf0)
- {
- temp_from++;
- }
- }
- break;
-
- default:
- break;
- }
- }
-
- /*************************** SET_PATTERN ********************************/
- /* Change a bit pattern into a colour image pattern that can be */
- /* easily copied. The bit pattern is an 8x8 pattern. */
- /************************************************************************/
-
- void set_pattern( unsigned char *current_pattern,
- unsigned char const far *pattern)
- {
- static unsigned char pat_mask[8] = { 128, 64, 32, 16, 8, 4, 2, 1};
- int i, j;
-
- for( i = 0; i < 8; i++) /* For each line. */
- {
- for( j = 0; j < 8; j++) /* For each column. */
- {
- if( *pattern & pat_mask[j]) /* Set to fill colour. */
- {
- *current_pattern = (*current_pattern & ~mask[j&1]) |
- (fill_colour & mask[j&1]);
- }
- else /* Or the background colour. */
- {
- *current_pattern = (*current_pattern & ~mask[j&1]) |
- (background_colour & mask[j&1]);
- }
- if( j&1) /* Next pattern element. */
- {
- current_pattern++;
- }
- }
- pattern++; /* Next line. */
- }
- }
-