home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <dos.h>
- #include <conio.h>
- #include <alloc.h>
-
- #define NORMAL 0x7 /* Normal video attribute */
- #define BOLD 0x8 /* Bold video attribute */
- #define UNDERLINED 0xA /* Underlined video attribute */
- #define REVERSE 0x70 /* Reverse video attribute */
- #define SCREEN 0x10 /* BIOS video interrupt number */
- #define RETRACE 0x3da /* Video Retrace port address for CGA */
- #define ASCII 0 /* ASCII character set */
- #define UK 1 /* UK character set */
- #define SPECIAL 2 /* Special character set, graphics chars */
-
- /****************************************************************************/
- /* Function prototypes */
-
- void VidInit( void ); /* Initialize the video system */
- void SetVattr( unsigned char ); /* Set the video attribute */
- void AddVattr( unsigned char ); /* Add attribute to current video attribute*/
- void SubVattr( unsigned char ); /* Sub attribute from current vid attribute*/
- void BrkAtt( unsigned char ); /* Break attribute into extra and base */
- unsigned char AddAtt( void ); /* Add extra and base attributes to get */
- /* a resulting displayable video attribute*/
- void ChrWrite( unsigned char ); /* Write character to the screen */
- void SetScroll(int , int ); /* Set the scrolling region */
- void ScrollDown( void ); /* Move down a row scrolling if necessary */
- void ScrollUp( void ); /* Move up a row scrolling if necessary */
- void IndexDown( void ); /* Scroll the screen down */
- void IndexUp( void ); /* Scroll the screen up */
- void SetCurs(int , int ); /* Set the cursor to absolute coordinates */
- void SetRelCurs(int , int ); /* Set the cursor to relative coordinates */
- void PosCurs( void ); /* Position the cursor to cursx,cursy */
- void ModeLine( void ); /* Display the Mode line */
- void ClearScreen( void ); /* Clear the terminal screen */
- void ClearEOS( void ); /* Clear from cursor to end of screen */
- void ClearBOS( void ); /* Clear from cursor to top of screen */
- void ClearEOL( void ); /* Clear from cursor to end of line */
- void ClearBOL( void ); /* Clear from cursor to start of line */
- void ClearBox( unsigned char, /* Clear a box on the video screen */
- unsigned char, unsigned char,
- unsigned char, unsigned char);
- void MarCharSet( int ); /* Map a character set */
- void SetCharSet( int, unsigned char ); /* Set a character set */
- void SaveCursor( void ); /* Save the cursor description */
- void RestoreCursor( void ); /* Restore the cursor description */
- void SetCursorVisibility( int ); /* Set the cursor visibility mode */
- void SetBackGround( int ); /* Set background video attribute */
- void SetColor( void ); /* Set the screen colors */
- void InitTabs( void ); /* Initialize the tab settings */
- void DoTab( void ); /* Perform a tab */
- void SetTabStop( void ); /* Set a tab stop at cursor position */
- void ClearTabStop( void ); /* Clear a tab stop at the cursor position*/
- void ClearAllTabs( void ); /* Clear all the defined tab stops */
- void SetScreenWidth( int ); /* Set the logical width of the screen */
- void StartScreen( int, int ); /* Start a screen access */
- void EndScreen( void ); /* End a screen access */
- void WriteOneChar( unsigned char, /* Write one character to the screen */
- int, int );
- int VTprintf( int, int, int, /* Printf for Emulator to row and column */
- char *, ... ); /* in regular or reverse video */
- void SaveScreen( void ); /* Save contents of video memory */
- void RestoreScreen( void ); /* Restore contents of video memory */
-
- static void interrupt10( unsigned,/* Issue a BIOS video interrupt */
- unsigned , unsigned , unsigned );
-
-
- /****************************************************************************/
- /* Global Data */
-
- unsigned char retracemode = 0; /* Flag indicating No Video refresh wait */
- unsigned char forecolor; /* Foreground color */
- unsigned char backcolor; /* Background color */
-
- unsigned char vidmode; /* Screen video mode */
-
- /****************************************************************************/
- /* External variables */
-
- extern unsigned originmode; /* Origin mode, relative or absolute */
- extern unsigned insertmode; /* Insert mode, off or on */
- extern unsigned autowrap; /* Automatic wrap mode, off or on */
- extern unsigned newline; /* Newline mode, off or on, GLOBAL data!*/
- extern unsigned cursorvisible; /* Cursor visibility, on or hidden */
- extern unsigned reversebackground;/* Reverse background attribute, on or off*/
- extern unsigned screenwid; /* Absolute screen width */
-
- extern char modeline[]; /* Text of mode line */
-
- /***************************************************************************/
- /* Local static data */
-
- static unsigned char screentop; /* Absolute top of screen */
- static unsigned char screenbot; /* Absolute bottom of screen */
- static unsigned char scrolltop; /* Top row of scrolling region */
- static unsigned char scrollbot; /* Bottom row of scrolling region */
-
- static int cursx; /* X cursor position */
- static int cursy; /* Y cursor position */
-
- static unsigned scroff; /* Screen memory offset */
- static unsigned scrseg; /* Screen memory segment */
- static unsigned scrchars; /* Number of chars written to video memory */
- static unsigned char tvmode; /* Flag to indicate control program present*/
- char far *screen; /* Pointer to video screen */
- static unsigned savebp; /* Static storage for BP through int 0x10 */
-
- static unsigned char video_state; /* State of video, reversed or normal */
- static unsigned char scbattr; /* Video attribute of empty video cell */
- static unsigned char curattr; /* Video attribute of displayable chars */
- static unsigned char baseattr; /* Base attribute for video attributes */
- static unsigned char extrattr; /* Extra attribute for video attributes */
-
- static unsigned char att_reverse; /* Reverse attribute bits */
- static unsigned char att_normal; /* Normal attribute bits */
- static unsigned char att_low_mask = 0x6; /* Low attribute mask */
- static unsigned char att_underline = 0x1; /* Underlined attribute bit */
- static unsigned char att_intensity = 0x8; /* Bold attribute bit */
- static unsigned char att_blink = 0x80; /* Blinking attribute bit */
-
-
- static unsigned columns; /* Columns on logical terminal screen */
- static unsigned lines; /* Lines on logical terminal screen */
-
- static char tabs[132]; /* active tab stops */
- static char deftabs[132]; /* default tab stops, 9,17,26 .... */
-
- static int G0 = ASCII; /* Character set G0 */
- static int G1 = ASCII; /* Character set G1 */
- static int *GL = &G0; /* Pointer to current mapped character set*/
-
- static char special_chars[32] = { /* Special characters */
- 32,4,176,9,12,13,10,248,241,18,11,217,191,218,192,197,
- 196,196,196,196,196,195,180,193,194,179,243,242,227,216,156,7
- } ;
-
- static struct SaveCursorStruct { /* Structure to save cursor description */
- int cursx; /* X cursor position, column */
- int cursy; /* Y cursor position, row */
- int *GL; /* pointer to mapped character set */
- int G0; /* character set G0 */
- int G1; /* character set G1 */
- int mode; /* origin mode */
- } save = { 1, 1, &G0, ASCII, ASCII , 0 } ;
-
- /* Pointer to memory allocated to hold */
- static char far *screen_save = NULL; /* the contents of video memory */
-
- /****************************************************************************/
- /****************************************************************************/
-
-
- /* V I D I N I T -- Initialize the video system */
-
- void VidInit( ) {
-
- char far *bptr;
- /* Obtain video information from BIOS */
- _AH = 0x0F; /* Use function F of interrupt 10 */
- savebp = _BP; /* Precautionary save of register BP */
- geninterrupt( 0x10 ); /* Issue BIOS video interrupt */
- _BP = savebp; /* Restore saved BP register */
- vidmode = _AL; /* Save the video mode */
- columns = _AH; /* Save the number of columns */
- lines = 25; /* Lines = 25, (sorry no 43,50 lines */
- screenbot = lines - 1; /* Bottom of screen is 24 */
- screentop = 1; /* Top of screen is line 1 */
-
- tvmode = 0; /* Assume no control program present */
-
-
-
- if (GetVidSetup() == 0) { /* If no video parameters are saved */
- /* then determine default values */
-
- /* First determine if snow is a problem */
- if (vidmode != 7) /* Assume video adapter is snowy if */
- retracemode = 1; /* it is not a MonoChrome */
-
- /* First query Video BIOS to see if */
- _AX = 0x1A00; /* VGA is present, no "snow" problem on VGA*/
- savebp = _BP; /* Precautionary save of register BP */
- geninterrupt( 0x10 ); /* Issue BIOS video interrupt */
- _BP = savebp; /* Restore saved BP register */
- if (_AL == 0x1A) /* If VGA is detected */
- retracemode = 0; /* No snow protection needed */
- else { /* Else look for an EGA */
- _CL = 0xC; /* Test the Video BIOS to see if */
- _BX = 0xFF10; /* an EGA can be detected */
- _AX = 0x1200; /* EGA's don't have "snow" problem either*/
- savebp = _BP; /* Precautionary save of register BP */
- geninterrupt( 0x10 ); /* Issue BIOS video interrupt */
- _BP = savebp; /* Restore saved BP register */
- if (_CL < 0xC) { /* If EGA is detected */
- bptr = MK_FP(0x40,0x87);/* Check BIOS data to see if the */
- if ( (*bptr & 0x8) == 0)/* EGA is the active adapter */
- retracemode = 0; /* No snow protection required */
- }
- }
-
- /* Determine the default screen attributes*/
- _AH = 0x8; /* Issue function 8 or interrupt 10 */
- _BH = 0x0; /* for page 0 */
- savebp = _BP; /* Precautionary save of register BP */
- geninterrupt( 0x10 ); /* Get video attribute at cursor pos */
- _BP = savebp; /* Restore saved BP register */
- scbattr = _AH; /* Save this attribute */
-
- forecolor = scbattr & 0xf;/* Save values for determined colors */
- backcolor = scbattr >> 4;
- }
-
-
- else { /* If saved values were available */
-
- /* Set the screen color to saved value */
- scbattr = ( backcolor << 4 ) | forecolor;
-
- if (vidmode == 7) /* Do not let retracemode be set on */
- retracemode = 0; /* if video is a MonoChrome */
- }
-
- att_normal = scbattr;
- BrkAtt(scbattr); /* Break the attribute into base,extra */
- /* Reverse the foreground and background*/
- baseattr = ( baseattr >> 4 | baseattr << 4);
- att_reverse = AddAtt(); /* Put the attributes back together */
- /* in order to get reverse attribute */
-
- /* Clear screen to established attribute*/
- interrupt10( 0x0600,scbattr << 8,
- 0 ,(lines << 8) | (columns - 1 ));
-
- /* Clear the top line setting it to reverse*/
- interrupt10( 0x0600,att_reverse << 8 ,0,columns - 1);
- vtprintf(0,0,1,modeline); /* Display the mode line in reverse */
-
-
- if (screen_save == NULL) { /* If first time to be initialized */
- /* Attempt to allocate screen mem */
- if ( (screen_save = farmalloc( lines * columns * 2 )) == NULL)
- badexit("No memory available for video screen save buffer");
- }
-
- }
-
-
- /* S E T V A T T R -- Set the video attribute */
-
- void SetVattr(unsigned char attr) {
-
- video_state = 0; /* Reset the video state */
- BrkAtt(scbattr); /* Break apart the default screen attribute*/
-
- switch (attr) { /* See what video attribute is requested */
- case BLINK: /* Blinking characters */
- extrattr = att_blink;
- break;
- case REVERSE: /* Reversed video characters */
- video_state = 1;
- baseattr = ( baseattr >> 4 | baseattr << 4);
- break;
- case UNDERLINED: /* Underlined characters */
- if (vidmode == 0x7) /* Monochrome can underline */
- extrattr = att_underline;
- else { /* others can't use reverse video */
- video_state = 1;
- baseattr = ( baseattr >> 4 | baseattr << 4);
- }
- break;
- case BOLD: /* High intensity, bold, characters */
- extrattr = att_intensity;
- break;
- case NORMAL: /* Normal characters */
- default:
- extrattr = 0;
- break;
- }
- curattr = AddAtt(); /* Put the video attributes back together */
-
- }
-
-
-
- /* A D D V A T T R -- Add an attribute bit to the current video attribute */
-
- void AddVattr(unsigned char attr) {
-
- BrkAtt(curattr); /* Break apart the current video attribute*/
-
- switch (attr) { /* See what attribute wants to be added */
- case BLINK: /* Blinking attribute */
- extrattr |= att_blink;
- break;
- case BOLD: /* High intensity, bold, attribute */
- extrattr |= att_intensity;
- break;
- case REVERSE: /* Reversed attribute */
- if (video_state == 0) {
- video_state = 1;
- baseattr = ( baseattr >> 4 | baseattr << 4);
- }
- break;
- case UNDERLINED: /* Underlined characters */
- if (vidmode == 0x7) /* Monochrom can underline */
- extrattr = att_underline;
- /* others cant use reversed video */
- else if (video_state == 0) {
- video_state = 1;
- baseattr = ( baseattr >> 4 | baseattr << 4);
- }
- break;
- default:
- break;
- }
- curattr = AddAtt(); /* Put the video attributes back together */
- }
-
- /* S U B V A T T R -- Remove attribute bit to the current video attribute */
-
- void SubVattr(unsigned char attr) {
-
- BrkAtt(curattr); /* Break apart the current video attribute*/
-
- switch (attr) { /* See what video attribute to remove */
- case BLINK: /* Remove the blinking attribute */
- extrattr &= ~att_blink;
- break;
- case BOLD: /* Remove the high intensity, bold */
- extrattr &= ~att_intensity;
- break;
- case REVERSE: /* Remove reversed attribute */
- if (video_state == 1) {
- video_state = 0;
- baseattr = ( baseattr >> 4 | baseattr << 4);
- }
- break;
- case UNDERLINED: /* Remove underlined attribute */
- if (vidmode == 0x7) /* Monochrome could have underlined */
- extrattr &= ~att_underline;
- /* others couldn't remove reverse attribute*/
- else if (video_state == 1) {
- video_state = 0;
- baseattr = ( baseattr >> 4 | baseattr << 4);
- }
- break;
- default:
- break;
- }
- curattr = AddAtt(); /* Put the video attributes back together */
- }
-
-
-
- /* B R K A T T R -- Break an attribute into its video components */
-
- void BrkAtt(unsigned char attribute) {
-
- extrattr = 0; /* Clear extra attributes */
- baseattr = attribute; /* Start specified base attribute */
-
- if (vidmode == 0x7) { /* If a Monochrome monitor */
- if (attribute & att_low_mask){ /* Any Low mask attributes on? */
- baseattr |= att_normal; /* if yes then set normal bits on */
- }
- else { /* else check other attributes */
- if (attribute & att_underline){ /* Underline attribute ? */
- extrattr |= att_underline; /* yes then set underline bit */
- if (attribute & 0x70) /* Reverse video ? */
- baseattr &= ~att_underline; /* If yes then clear underline */
- else /* monochrome can't do both */
- baseattr |= att_normal; /* Else set normal bits on */
- }
- }
- }
-
- if (baseattr & att_intensity) /* If bold attribute is on */
- extrattr |= att_intensity; /* then set intensity bit */
-
- if (baseattr & att_blink) /* If blink attribute is on */
- extrattr |= att_blink; /* then set blink bit */
-
- /* Turn off blink,bold in base attribute */
- baseattr &= ~(att_intensity + att_blink);
- }
-
-
- /* A D D A T R -- Build video attribute from base and extra attributes */
-
- unsigned char AddAtt() {
-
- if (extrattr & att_underline) /* If underline is requested */
- baseattr &= ~att_low_mask; /* Clear low mask */
-
- return(baseattr | extrattr); /* return the or'ed attributes */
- }
-
-
- /* C H R W R I T E -- Write a character to a row and column of the screen */
-
- void ChrWrite( unsigned char chr ) {
- unsigned char c[2], attr[2];
- int row, ws;
-
- if (*GL == ASCII) /* Check character set being used */
- ; /* if regular ASCII then char is OK */
- else if (*GL == SPECIAL) { /* if using the special character */
- if (chr > 94 && chr < 128) /* then translate graphics characters */
- chr = special_chars[ chr - 95];
- }
- else if (*GL == UK) { /* If using the UK character set */
- if (chr == '#') /* then watch for the number sign */
- chr = '£'; /* translating it to British pound */
- }
-
-
- /* NOTE: Inserting a character using this technique is *very* slow */
- /* for snowy CGA systems */
- if (insertmode) { /* If insert mode, scoot rest of line over */
- StartScreen(cursy,cursx-1);/* Start direct video memory access */
-
- c[0] = *screen; /* Save character at current position */
- attr[0] = *(screen + 1); /* Save attribute at current position */
- ws = 1;
- for (row = cursx; row < columns; row ++) {
-
- c[ws] = *(screen + 2); /* Save character at next position */
- attr[ws] = *(screen + 3); /* Save attribute at next position */
- ws ^= 1; /* Flop save char,attribute array index */
- *(screen + 2) = c[ws]; /* Write saved character and attribute */
- *(screen + 3) = attr[ws];
- screen += 2; /* Increment to next character position */
- scrchars++; /* Increment the number of chars written */
- }
- EndScreen(); /* Update screen in control programs */
- }
-
-
- if (cursx > screenwid) { /* If trying to go beyond the screen width */
- if (autowrap) { /* when autowrap is on */
- ScrollUp(); /* scroll the screen up */
- SetCurs(1,0); /* set cursor to column 1 of next line */
- }
- else
- cursx = screenwid; /* else put the cursor on right margin */
- }
-
- WriteOneChar(chr, cursy, cursx - 1);
-
- ++cursx; /* Increment the cursor X position */
- PosCurs(); /* Move the cursor to the new position */
-
- }
-
-
- /* S E T S C R O L L -- Establish the scrolling boundaries */
-
- void SetScroll( register int top, register int bottom) {
-
- if (top == 0) /* If the top scroll boundary is 0 */
- top = 1; /* interpret this as the top screen row */
- if (bottom == 0) /* If the bottom scroll boundary is 0 */
- bottom = screenbot; /* interpret this as bottom screen row */
-
- /* Set scrolling region if valid coords */
- if (top > 0 && top <= screenbot && bottom >= top && bottom <= screenbot){
- scrolltop = top; /* save top boundary */
- scrollbot = bottom; /* save bottom boundary */
- SetCurs(1,1); /* this also homes the cursor */
- }
- }
-
-
-
-
- /* S C R O L L D O W N -- Move up a row scrolling if necessary */
-
- void ScrollDown( )
- {
-
- if (cursy == scrolltop) /* If on the top of the scrolling region */
- IndexDown(); /* scroll the rest of the region down */
- else { /* Else */
- --cursy; /* just decrement cursor Y position */
- PosCurs(); /* and request the reposition */
- }
- }
-
-
- /* S C R O L L U P -- Move down a row scrolling if necessary */
-
- void ScrollUp( )
- {
-
- if (cursy == scrollbot) /* If on the bottom of the scrolling region*/
- IndexUp(); /* scroll the rest of the region down */
- else { /* Else */
- ++cursy; /* just increment the cursor Y position */
- PosCurs(); /* and request the reposition */
- }
- }
-
-
- /* I N D E X D O W N -- Scroll the screen down */
-
- void IndexDown( )
- {
- register unsigned attr;
-
- attr = scbattr << 8; /* Get the attribute for new line */
- /* Call the BIOS to scroll the region */
- interrupt10( 0x0701,attr,scrolltop << 8,(scrollbot << 8) | (columns - 1) );
- PosCurs(); /* Position the cursor */
- }
-
- /* I N D E X U P -- Scroll the screen up */
-
- void IndexUp( )
- {
- register unsigned attr;
-
- attr = scbattr << 8; /* Get the attribute for new line */
- /* Call the BIOS to scroll the region */
- interrupt10( 0x0601,attr,scrolltop << 8,(scrollbot << 8) | (columns - 1));
- PosCurs(); /* Position the cursor */
- }
-
-
- /* S E T C U R S -- Set absolute cursor position on the logical screen */
-
- void SetCurs(register int col, register int row)
- {
- if (col == 0) /* If called with X coordinate = zero */
- col = cursx; /* then default to current coordinate */
- if (row == 0) /* If called with Y coordinate = zero */
- row = cursy; /* then default to current coordinate */
-
- if (originmode) { /* If origin mode is relative */
- row += (scrolltop - 1); /* adjust the row */
- if (row < scrolltop || row > scrollbot)
- return; /* Can not position cursor out of scroll */
- /* region in relative cursor mode */
- }
- /* Can only position the cursor if it lies */
- /* within the logical screen limits */
- if (col <= screenwid && row <= screenbot ) {
- cursx = col; /* Set the X cursor coordinate, column */
- cursy = row; /* Set the Y cursor coordinate, row */
- PosCurs(); /* Request the physical positioning */
- }
- }
-
-
- /* S E T R E L C U R S -- Set relative curs pos on the logical screen */
-
- void SetRelCurs(register int col, register int row)
- {
-
- if (col == 0) /* If called with X coordinate = zero */
- col = cursx; /* then default to current X coordinate */
- else /* Else */
- col = cursx + col; /* add col value to X cursor position */
- /* Note: col can be negative */
-
- if (row == 0) /* If called with Y coordinate = zero */
- row = cursy; /* then default to current Y coordinate */
- else /* Else */
- row = cursy + row; /* add row value to Y cursor position */
- /* Note: row can be negative */
-
- if (originmode) { /* If origin mode is relative */
- row += (scrolltop - 1); /* adjust the row */
- if (row < scrolltop || row > scrollbot)
- return; /* Can not position cursor out of scroll */
- } /* region in relative cursor mode */
-
- /* Can only position the cursor if it lies */
- /* within the logical screen limits */
- if (col > 0 && col <= screenwid && row > 0 && row <= screenbot){
- cursy = row; /* Set the X cursor coordinate, column */
- cursx = col; /* Set the Y cursor coordinate, row */
- PosCurs(); /* Request the physical positioning */
- }
- }
-
- /* P O S C U R S -- Position the cursor on the physical screen */
-
- void PosCurs()
- {
- register int col = cursx;
- register int row = cursy;
-
- if (col <= columns) /* Check validity of requested column */
- ; /* ok if column is within screen bounds */
- else
- col = columns; /* else put cursor on the right bound */
-
- if (row <= lines) /* Check validity of requested row */
- ; /* ok if row is within screen bounds */
- else
- row = lines; /* else put cursor on the bottom */
-
- if (cursorvisible) /* Only position the cursor if its visible */
- interrupt10(0x0200,0,0,(row << 8) | --col );
- }
-
-
-
- /* C L E A R S C R E E N -- Clear the screen setting it to a normal attr */
-
- void ClearScreen()
- {
- ClearBox(1, screentop, columns, screenbot, scbattr);
- }
-
- /* C L E A R E O S -- Clear from the cursor to the end of screen */
-
- void ClearEOS()
- {
- ClearEOL(); /* First clear to the End of the Line */
- if (cursy < screenbot) /* Then clear every line below it */
- clearbox(1,cursy + 1,columns, screenbot, scbattr);
- }
-
- /* C L E A R B O S -- Clear from the cursor to the beggining of screen */
-
- void ClearBOS()
- {
- ClearBOL(); /* First clear to the Beginning of the Line */
- if (cursy > screentop) /* Then clear every line above it */
- ClearBox(1,screentop,columns, cursy - 1, scbattr);
- }
-
- /* C L E A R E O L -- Clear to the end of the current line */
-
- void ClearEOL()
- {
- ClearBox(cursx, cursy, columns, cursy, scbattr );
- }
-
-
- /* C L E A R B O L -- Clear to the beginning of the current line */
-
- void ClearBOL()
- {
- ClearBOX(1, cursy, cursx, cursy, scbattr );
- }
-
-
- /* C L E A R B O X -- Clear a window on the screen with the specified attr */
-
- void ClearBox( unsigned char left, unsigned char top,
- unsigned char right, unsigned char bottom, unsigned char attr )
- {
- /* Use BIOS scroll window function to clear*/
- interrupt10( 0x0600,attr << 8, /* a window to a specified attribute */
- (top << 8) | (--left),(bottom << 8) | --right);
- }
-
-
- /* M A P C H A R S E T -- Map an established character set to current */
-
- void MapCharSet( int charset ) {
-
- if (charset == 0) /* If mapping G0 character set */
- GL = &G0; /* Point the current char set,GL to G0 */
- else if (charset == 1) /* If mapping G1 character set */
- GL = &G1; /* Point the current char set,GL, to G1 */
- }
-
-
- /* S E T C H A R S E T -- Establish a character set */
-
- void SetCharSet( int gset, unsigned char set) {
- int *charset;
-
- if (gset == 0) /* Check to see what character set is */
- charset = &G0; /* going to be set */
- else if (gset == 1)
- charset = &G1;
- else
- return; /* If not valid set then return */
-
- switch(set) {
- case 'B': /* 'B' maps the character set to ASCII */
- *charset = ASCII; /* this is the normal character set */
- break;
- case 'A': /* 'A' maps the character set to UK */
- *charset = UK; /* only difference between UK and ASCII */
- break; /* is the pound sign, # = £ */
- case '0': /* '0' maps the character set to SPECIAL */
- *charset = SPECIAL; /* this character set is the 'graphics' */
- break; /* character set used for line drawing */
- default:
- }
- }
-
- /* S A V E C U R S O R -- Save the cursor description into memory */
-
- void SaveCursor() {
-
- save.cursx = cursx; /* Save the X cursor position */
- save.cursy = cursy; /* Save the Y cursor position */
- save.GL = GL; /* Save the current mapped character set */
- save.G0 = G0; /* Save G0 character set */
- save.G1 = G1; /* Save G1 character set */
- save.mode = originmode; /* Also save the origin mode */
- }
-
-
- /* R E S T O R E C U R S O R -- Restore the cursor description from memory */
-
- void RestoreCursor() {
-
- cursx = save.cursx; /* Restore the saved X cursor position */
- cursy = save.cursy; /* Restore the saved Y cursor position */
- GL = save.GL; /* Restore the saved mapped character set */
- G0 = save.G0; /* Restore the saved G0 character set */
- G1 = save.G1; /* Restore the saved G1 character set */
- originmode = save.mode; /* Also restore the saved origin mode */
- PosCurs(); /* Then reposition the cursor */
- }
-
-
- /* S E T C U R S O R V I S I B I L I T Y -- Show/Hide the cursor */
-
- void SetCursorVisibility( int mode ) {
-
- if (mode) { /* If invisible cursor is specified, then */
- cursorvisible = 1; /* the cursor will not appear on the */
- SetCurs(0,0); /* terminal screen */
- }
- else { /* Else the cursor will be shown at the */
- cursorvisible = 0; /* current cursor position */
- interrupt10(0x0200,0,0,lines << 8 );
- }
- }
-
-
- /* S E T B A C K G R O U N D -- Set the background attribute */
-
- void SetBackGround( int mode ) {
- int reverse_screen = 0; /* Flag to indicate screen is to be reversed*/
- register int i;
-
-
- if (mode) { /* If reversed background is specified, */
- if (reversebackground != 1) { /* only reverse the screen if it is */
- reverse_screen = 1; /* not already set to reverse */
- reversebackground = 1;
- }
- }
- else { /* Else if normal background is specified */
- if (reversebackground != 0) { /* only reverse the screen if it is */
- reverse_screen = 1; /* currently set to reverse */
- reversebackground = 0;
- }
- }
-
- if (reverse_screen) { /* If reverse screen flag is set */
- /* first save the contents of screen */
-
- StartScreen(0,0);
-
- for (i = 0; i < lines * columns; i++){
- screen++;
- BrkAtt(*screen); /* Break attribute apart and reverse it */
- baseattr = ( baseattr >> 4 | baseattr << 4);
- *screen++ = AddAtt(); /* Put attribute together as displayable */
- }
- scrchars = i;
- EndScreen();
-
- BrkAtt(scbattr); /* reverse the default character attr */
- baseattr = ( baseattr >> 4 | baseattr << 4);
- scbattr = AddAtt();
- BrkAtt(curattr); /* reverse the current character attr */
- baseattr = ( baseattr >> 4 | baseattr << 4);
- curattr = AddAtt();
- }
- }
-
-
-
- /* S E T C O L O R -- Set the screen color */
-
- void SetColor() {
- register int i;
- unsigned char attr;
-
- BrkAtt(att_normal); /* Break apart the current screen color */
- attr = baseattr; /* Save this attribute */
-
- /* Create the new screen attribute */
- att_normal = curattr = scbattr = ( (backcolor << 4) | forecolor);
- BrkAtt(att_normal); /* and the new reverse attribute */
- baseattr = ( baseattr >> 4 | baseattr << 4);
- att_reverse = AddAtt();
-
- StartScreen(0,0);
-
- for (i = 0; i < lines * columns; i++){
- screen++;
- BrkAtt(*screen); /* Break attribute apart and reverse it */
- if (baseattr == attr) { /* If this chars base attributes are the */
- baseattr = att_normal; /* old screen color then this is a normal */
- } /* character so set it to new normal attr */
- else /* Else set this character to new reverse */
- baseattr = att_reverse;
- *screen++ = AddAtt(); /* Put attribute together as displayable */
- }
- scrchars = i;
- EndScreen();
- }
-
-
- /* I N I T T A B S -- Initialize Tab stops to default settings */
-
- void InitTabs() {
- register int i;
-
- for( i = 1; i < 131; i++) { /* Set tabs for mod 8 = 0 positions */
- if ( i % 8 ) /* 9, 17, 26 .... */
- deftabs[i+1] = tabs[i+1] = 0; /* Zero indicates no tab here */
- else
- deftabs[i+1] = tabs[i+1] = 1; /* One indicates a tab stop */
- }
- }
-
-
- /* D O T A B -- Perform a tab */
-
- void DoTab() {
- register int i;
- /* Look for next tab stop */
- for (i = cursx + 1; i <= screenwid; i++) {
- if ( tabs[i] == 1 ) { /* If a tab stop is found */
- SetCurs(i,cursy); /* request cursor position here */
- return; /* and finished */
- }
- }
- }
-
- /* S E T T A B S T O P -- set a tab stop at the current cursor position */
-
- void SetTabStop() {
-
- tabs[cursx] = 1; /* Mark current cursor position as tab stop*/
- }
-
- /* C L E A R T A B S T O P -- clear a tab stop at the current curs position */
-
- void ClearTabStop() {
-
- tabs[cursx] = 0; /* Clear current cursor position tab stop */
- }
-
- /* C L E A R A L L T A B S -- clear all tab stops */
-
- void ClearAllTabs() {
- /* Clear all of the tab stop marks */
- memset(tabs,'\0',sizeof(tabs));
- }
-
-
- /* S E T S C R E E N W I D T H -- set the screen width */
-
- void SetScreenWidth(int width) {
-
- if (width == 132) /* When the screen is set to 132 columns */
- screenwid = 132; /* set the logical right boundary */
- else if (width == 80) /* Else if the screen width is 80 */
- screenwid = 80; /* set the logical right boundary */
-
- /* Setting the screen width also */
- ClearScreen(); /* Clears the screen */
- originmode = 0; /* Sets the origin mode to absolute */
- SetScroll(0,0); /* Resets the scrolling region */
- SetCurs(1,1); /* Sets the cursor to the home position */
- }
-
-
- /* S T A R T S C R E E N -- Start a direct screen addressing "transaction" */
-
- void StartScreen( register int row, register int col ) {
- unsigned vscroff, vscrseg;
-
- if ( vidmode == 7 ) { /* If in Monochrome video mode */
- scrseg = 0xb000; /* Assume video segment of B000 */
- }
- else { /* If other mode then assumme */
- scrseg = 0xb800; /* video memory segment is B800 */
- }
-
- scroff =((row*columns)+col)*2;/* Calculate offset from beginning of */
- /* screen memory */
- scrchars = 0; /* Initialize count of characters written */
-
- savebp = _BP; /* Save reg BP, in case old BIOS trashes it */
- /* Query the address of video memory for */
- _ES = scrseg; /* this process under Windows, DesQview, ... */
- _DI = 0; /* ES:DI = assumed screen address */
- _AH = 0xFE; /* Issue Video interrupt function FE */
- geninterrupt(0x10); /* in order to check for control program */
- vscroff = _DI; /* ES:DI now holds actual address of screen*/
- vscrseg = _ES;
- _BP = savebp; /* Restore register BP */
-
- tvmode = 0; /* Assume no control program */
- if (vscroff != 0 || vscrseg != scrseg) {
- scrseg = vscrseg; /* If address of screen is different from*/
- scroff += vscroff; /* assumed address then a control program*/
- tvmode = 1; /* is present and has remapped the screen*/
- }
- else if (retracemode == 0)
- ; /* No refresh wait for these situations */
- else {
- /* Wait till screen is refreshing */
- while( (inportb(RETRACE) & 0x8) != 0 )
- ; /* Wait till refresh is through */
- while( (inportb(RETRACE) & 0x8) == 0 )
- ;
- outportb(0x3d8,0x25); /* Turn off the screen refresh */
- }
- /* Construct a far pointer to video memory*/
- (void far *)screen = MK_FP(scrseg,scroff);
-
- }
-
-
- /* E N D S C R E E N -- End a direct screen addressing "transaction" */
-
- void EndScreen( ) {
- /* Values to turn the screen back on */
- static unsigned char modeset[] = /* after video refresh is turned off */
- { 0x2C,0x28,0x2D,0x29,0x2A,0x2E,0x1E,0x29,
- } ;
- /* If control program video update required*/
- if (tvmode == 1 && scrchars > 0) {
- _ES = scrseg; /* Point ES:DI to beginning of video memory*/
- _DI = scroff; /* to update */
- _CX = scrchars; /* CX holds the number of chars to update */
- _AH = 0xFF; /* Use function FF of BIOS video interrupt */
- geninterrupt(0x10); /* to copy video buffer to screen */
- }
- else if (retracemode == 0)
- ; /* Situations screen was not turned off */
- else { /* Else if screen is off turn it back on */
- outportb(0x3d8, modeset[vidmode]);
- }
- }
-
-
- /* W R I T E O N E C H A R -- writes on character to video memory */
- /* NOTE: this function does not shut down video refresh in order */
- /* to avoid snow on CGA, so it is *much* faster than using StartScreen */
- /* and an EndScreen transaction for one character screen writes. */
-
- void WriteOneChar(unsigned char c, register int row, register int col ) {
- unsigned vscroff, vscrseg;
- int retrace_wait = 0;
-
- if ( vidmode == 7 ) { /* If in Monochrome video mode */
- scrseg = 0xb000; /* Assume video segment of B000 */
- }
- else { /* If other mode then assumme */
- scrseg = 0xb800; /* video memory segment is B800 */
- }
-
- scroff =((row*columns)+col)*2;/* Calculate offset from beginning of */
- /* screen memory */
- savebp = _BP; /* Save reg BP, in case old BIOS trashes it */
- /* Query the address of video memory for */
- _ES = scrseg; /* this process under Windows, DesQview, ... */
- _DI = 0; /* ES:DI = assumed screen address */
- _AH = 0xFE; /* Issue Video interrupt function FE */
- geninterrupt(0x10); /* in order to check for control program */
- vscroff = _DI; /* ES:DI now holds actual address of screen*/
- vscrseg = _ES;
- _BP = savebp; /* Restore register BP */
-
- tvmode = 0; /* Assume no control program */
- if (vscroff != 0 || vscrseg != scrseg) {
- scrseg = vscrseg; /* If address of screen is different from*/
- scroff += vscroff; /* assumed address then a control program*/
- tvmode = 1; /* is present and has remapped the screen*/
- }
- else if (retracemode == 0)
- ; /* No refresh wait for these situations */
- else {
- retrace_wait = 1; /* Else assume snowy CGA */
- }
- /* Construct a far pointer to video memory*/
- (void far *)screen = MK_FP(scrseg,scroff);
-
- if ( retrace_wait == 0 ) { /* If no snow then */
- *screen++ = c; /* write character into screen memory */
- *screen = curattr; /* write attribute into screen memory */
- }
- else { /* Else if snowy CGA then try and sneak */
- if (inportb(RETRACE) & 0x8) { /* the character and attribute into */
- *screen++ = c; /* video memory in between video */
- *screen = curattr; /* refreshes */
- }
- else {
- while (inportb(RETRACE) & 0x8)
- ;
- while (inportb(RETRACE) & 0x1)
- ;
- *screen++ = c;
- *screen = curattr;
- }
- }
-
- if (tvmode == 1) { /* If control program video update required*/
- _ES = scrseg; /* Point ES:DI to beginning of video memory*/
- _DI = scroff; /* to update */
- _CX = 1; /* CX holds the number of chars to update */
- _AH = 0xFF; /* Use function FF of BIOS video interrupt */
- geninterrupt(0x10); /* to copy video buffer to screen */
- }
- }
-
-
- /* S A V E S C R E E N -- Save the contents of the video screen */
-
- void SaveScreen() {
-
- StartScreen(0,0); /* Start the video direct access */
- movedata(scrseg, scroff, /* Move the video memory to save buffer */
- FP_SEG(screen_save), FP_OFF(screen_save),
- lines * columns * 2 );
- scrchars = 0; /* Zero characters were written to screen */
- EndScreen(); /* End the screen access */
- interrupt10(0x0200,0,0,lines << 8 ); /* Hide the cursor */
- }
-
- /* R E S T O R E S C R E E N -- Restore contents of the video screen */
-
- void RestoreScreen() {
-
- StartScreen(0,0); /* Start the video direct access */
- /* Move the save buffer to video memory */
- movedata(FP_SEG(screen_save), FP_OFF(screen_save),
- scrseg, scroff,
- lines * columns * 2 );
- scrchars = lines * columns; /* Number of chars written to screen */
- EndScreen(); /* End the screen access */
- PosCurs(); /* Reposition the cursor */
- }
-
-
- /* V T P R I N T F -- print a formatted string to the video screen */
-
- int vtprintf( int row, int col, int reverse, char *strformat, ... )
- {
- unsigned attr;
- va_list argptr;
- char str[132];
- char *sptr = str;
- int it;
-
- if (reverse) { /* If reversed attribute specified */
- attr = att_reverse;
- }
- else { /* Else use normal attribute */
- attr = att_normal;
- }
-
- va_start( argptr, format ); /* Start variable length argument list */
- StartScreen(row,col); /* Start a screen update */
- scrchars = vsprintf( str, strformat, argptr ); /* Format the string */
- while (*sptr != '\0') { /* Move the formatted string */
- *screen++ = *sptr++; /* to video memory */
- *screen++ = attr;
- }
- EndScreen(); /* End the screen update */
- va_end(argptr); /* End the va_start */
- return(scrchars); /* Return number of characters written */
- }
-
-
-
- /* I N T E R R U P T 1 0 -- Call on the BIOS video software interrupt */
-
- void interrupt10(unsigned ax,unsigned bx,unsigned cx,unsigned dx){
- register unsigned savesi; /* Force compiler to save contents of */
- register unsigned savedi; /* SI and DI registers on the stack */
- static unsigned savebp;
-
- savebp = _BP; /* Save BP since some BIOS'es may destroy it*/
- _CX = cx; /* Load contents of register parameters */
- _DX = dx;
- _BX = bx;
- _AX = ax;
- geninterrupt(0x10); /* Issue Video interrupt */
- _BP = savebp; /* Restore BP register */
- }