home *** CD-ROM | disk | FTP | other *** search
- /*
- LISTING 1 - AN EXAMPLE FEATURES TABLE
- */
-
- /*
- This code contains a C language Features Table which contains the location
- and copyright string that uniquely identify a machine. In addition to the
- copyrights, the bit fields for the FEATURES and VIDEO_FEATURES variables
- are defined. Note that this code is compiled with the Lattice C Compiler
- version 2.15, using -md -n options. Copyright (c) 1986 Dan Jacobs and
- Joel Rosenblum for public, unrestricted use.
- */
-
- /* bit flags for FEATURES */
-
- #define IBMPC 0x0100 /* IBM PC, XT, Portable, */
- #define IBMPCAT 0x0200 /* IBM AT */
- #define IBMCOMPAT 0x0400 /* IBM PC BIOS Compatible */
- #define IBM_CONVERT 0x0800 /* IBM Convertible */
- #define GENERIC 0x1000 /* Assumed Generic PC */
- #define NO_DMA 0x2000 /* Machine has no DMA */
- #define WANG 0x4000 /* Wang PC Special Case*/
- #define TIPROF 0x8000 /* TI Professional PC Special Case */
- #define CPU_88 0x0001 /* 8088, 8086 Processor */
- #define CPU_186 0x0002 /* 80188, 80186 Processor */
- #define CPU_286 0x0004 /* 80286 Processor */
- #define CPU_V20 0x0008 /* V20, V30 Processor */
- #define NDP 0x0010 /* 8087, 80287 Math Co-processor */
-
- /* bit flags for VIDEO_FEATURES */
-
- #define CGA 0x0001 /* IBM Color Graphics Adapter */
- #define MONO 0x0002 /* IBM Monochrome Adapter */
- #define HERCULES 0x0004 /* Hercules Monochrome Adapter Card */
- #define PGA 0x0008 /* IBM Professional Graphics Adapter */
- #define EGA_MONO 0x0010 /* w/Monochrome Monitor */
- #define EGA_COLOR 0x0020 /* w/Color Monitor */
- #define EGA_HIGH 0x0040 /* w/High Resolution Color Monitor */
- #define UNKNOWN 0x0080 /* Unknown Graphics Type */
- #define ANSI 0x0100 /* ANSI.SYS installed */
-
- /* Additional bit fields may also be defined, please see TABLE 1 for suggestions */
-
- struct machine_info {
- char *logo; /* Unique copyright string */
- long addr; /* String memory location */
- /* Note: actually (char *) must be (long) to pass lattice C */
- int type; /* Machine attributes */
- } feature_table[] = {
-
- /* copyright notice, physical address, pctype */
-
- { "IBM", 0xFE00EL, IBMPC|IBMCOMPAT}, /* All IBMs */
- { "COMPAQ", 0xFFFEAL, IBMCOMPAT}, /* All COMPAQs */
- { "Corona", 0xFE00F, IBMCOMPAT}, /* Old Version Corona */
- { "Corona", 0xFE01A, IBMCOMPAT}, /* Version 3.10 ROM Corona (also Phillips) */
- { "M.P.C.", 0xFDB2D, IBMCOMPAT}, /* New Columbia */
- { "Columbia", 0xFF768, IBMCOMPAT}, /* Old Columbia */
- { "Eagle PC", 0xFFFAA, IBMCOMPAT}, /* Eagle PC */
- { "Eagle PC", 0xFF810, IBMCOMPAT}, /* Eagle PC Plus */
- { "Zenith", 0xFB000, IBMCOMPAT}, /* Zenith Data Systems */
- { "Zenith", 0xFC2FF, GENERIC}, /* Zenith 100 */
- { "MITSUBISHI", 0xFC02A, IBMCOMPAT}, /* Sperry PC and Leading Edge */
- { "TVS", 0xFE003, IBMCOMPAT}, /* Televideo */
- { "OSM", 0xFFFF5, IBMCOMPAT}, /* OSM Rom Version 3.6 or later */
- { "OLIVETTI", 0xFC050, IBMCOMPAT}, /* AT&T-IS PC6300 and Xerox */
- /* NOTE: AT&T is not supporting V1.0 ROMs */
- { "WANG", 0xFFFC2, WANG|GENERIC}, /* WANG professional */
- { "ADDS", 0xFC050, IBMCOMPAT}, /* Applied Data Digital Systems Model PC/I */
- { "CROS", 0xFE000, IBMCOMPAT}, /* Seattle Telecom Turbo Boards */
- { "PCPI", 0xFE00F, IBMCOMPAT}, /* Personal Computer Products */
- { "TAVA", 0xFE018, IBMCOMPAT}, /* Tava PC */
- { "Tandy", 0xFC02B, IBMCOMPAT|NO_DMA}, /* Tandy 1000 has no DMA unless memory upgrade board installed */
- { "Tandon", 0xFC013, IBMCOMPAT}, /* Tandy 1200 */
- { "Texas", 0xFE022, TIPROF}, /* TI Professional V1.23 & V2.11 SYSROM */
- { "American", 0xFE004, IBMCOMPAT}, /* American PC lookalike */
- { "STD", 0xFE00EL, IBMCOMPAT}, /* STD Turbo Boards in IBMs */
- { "STD", 0xFFFEAL, IBMCOMPAT}, /* STD Turbo Boards in COMPAQs */
- { "TOMCAT", 0xFE028, IBMCOMPAT}, /* Tomcat AT clone */
- { "WYSE", 0xFC003, IBMCOMPAT}, /* WYSE PC BIOS Version 1.08 */
- { "Hewlett-Packard", 0xF0024, IBMCOMPAT}, /* Hewlett-Packard Vectra AT Compatible */
- { "Morrow", 0xFE073, IBMCOMPAT}, /* Morrow Pivot II & Zenith 171 Desktops */
-
- /* Additional machines are added to the list starting here */
-
- { NULL, NULL, 0}
- };
-
- -------------------------------------------------------------------------------
-
- /*
- LISTING 2 - DETERMINING MACHINE COMPATIBILITY
- */
-
- /*
- This code shows how the Features Table is used to set up
- the bit flags in the FEATURES variable. Once FEATURES
- is set for the current machine, your other program
- modules can use it to determine what section of code
- should be executed to yield the best program performance.
-
- Copyright (c) 1986 Dan Jacobs and Joel Rosenblum
-
- Compiled using Lattice C ver 2.15, using -md -n options
- */
-
- unsigned int video_features; /* global variable which holds video attributes */
-
- unsigned int set_features()
- {
- char *cp; /* Pointer */
- struct machine_info *p; /* Features Table Structure */
- unsigned int feature; /* FEATURES bit field variable */
-
- /* Assume the PC is generic to start */
- feature = GENERIC; /* default to generic */
-
- /*
- A psuedo code example of how to override the automatic set of FEATURES
- assuming that either a slash option or an DOS environment variable is
- set. Your actual code will depend upon how you do the parsing. See
- the section on "using the machine's copyright notice to determine
- compatibility" in our text.
-
- begin pseudo code example --
-
- if ((/IBM entered on command line) |
- (compatibility = IBM is in the environment)) {
- feature = IBMCOMPAT;
- goto cpu_test;
- }
- -- end psudo code example */
-
- for (p = feature_table; p->addr != NULL; p++) /* if next table entry is NULL, then end loop */
- if (strncmp((char *) p->addr, p->logo, strlen(p->logo)) == 0) {
- feature = p->type;
- break;
- }
-
- if (feature & IBMPC) { /* IBM Personal Computers */
- cp = (char *) 0xFFFFE; /* physical address 0FFFF:E */
- switch (*cp) {
- case 0xF9: /* IBM Convertible */
- feature |= IBM_CONVERT;
- break;
- case 0xFC: /* IBM AT */
- feature |= IBMPCAT | CPU_286;
- break;
- case 0xFD: /* IBM PC JR */
- feature |= NO_DMA;
- break;
- case 0xFE: /* IBM XT or Portable */
- case 0xFF: /* IBM PC */
- break;
- default:
- break; /* unknown IBM type */
- }
- }
-
- /* add the cpu type to FEATURES -- see listing 3 */
- feature = cputest(feature);
-
- /* check for numeric data processor -- see listing 4 */
- feature = test_ndp(feature);
-
- /* add the video display type to VIDEO_FEATURES -- see listing 6 */
- video_features = video_test(feature);
-
- /* check if ANSI.SYS is present -- see listing 7 */
- if (check_ansi()) {
- video_features |= ANSI;
- } else {
- putch(0x0D); /* this cleans up any garbage left on the screen */
- putch(' '); /* by the ansi check if ANSI.SYS is not present */
- putch(' ');
- putch(' ');
- putch(' ');
- putch(0x0A);
- putch(0x0D);
- }
-
- return (feature);
- }
-
- _______________________________________________________________________________
-
- /*
- LISTING 5B - ILLUSTRATION OF TIMING DELAYS, C CALLING ROUTINE
- */
-
- /*
- This driver provides an example of how to use cal.asm for
- delay calibrate routines. The routine will print the delay
- according to the speed of the processor. The closer you
- make the loops to your actual code, the more accurate the
- calculation will be. You should then adjust your actual
- program delay proportional to the results of this test.
- */
-
- #include <stdio.h>
-
- static char id[] = "#PROGRAM: calibrate driver (hzm)";
-
- /*
- * Global variables:
- */
-
- int us500;
- int ms2;
- /*
- * init -- calibrate the delay counters
- */
-
- static
- init()
- {
- us500 = delaycal(500);
- ms2 = delaycal(2000);
- printf("%d loops equals 500 microseconds.\n", us500);
- printf("%d loops equals 2 milliseconds.\n", ms2);
- }
-
- /*
- * delay1 -- delay for .5 sec (= 1000 * 500 usec)
- */
-
- static
- delay1()
- {
- char before[4];
- char after[4];
- int i;
-
- printf("\nNow, delay 1000 * 500 usec...\n");
- dostime(&before);
- for (i = 0; i < 1000; i++) del500u();
- dostime(&after);
- printf(" Start: %02d:%02d:%02d.%02d\n",
- before[1], before[0], before[3], before[2]);
- printf(" End: %02d:%02d:%02d.%02d\n",
- after[1], after[0], after[3], after[2]);
- }
-
- /*
- * delay2 -- delay for 4.0 sec (= 2000 * 2000 usec)
- */
-
- static
- delay2()
- {
- char before[4];
- char after[4];
- int i;
-
- printf("\nNow, delay 2000 * 2000 usec...\n");
- dostime(&before);
- for (i = 0; i < 2000; i++) del2m();
- dostime(&after);
- printf(" Start: %02d:%02d:%02d.%02d\n",
- before[1], before[0], before[3], before[2]);
- printf(" End: %02d:%02d:%02d.%02d\n",
- after[1], after[0], after[3], after[2]);
- }
-
- /*
- * driver main program:
- */
-
- main(argc, argv)
- int argc; char *argv[];
- {
- init();
- delay1();
- delay2();
- exit(0);
- }
-
- -------------------------------------------------------------------------------
-
- /*
- LISTING 7 - TEST FOR PRESENCE OF ANSI.SYS
- */
-
- /*
- This code contains the check for the presence of ANSI.SYS. If
- found, the appropriate bit in VIDEO_FEATURES is set. This code
- is called from listing 2 and is compatible with the Lattice C
- Compiler.
-
- Copyright (c) 1986 Dan Jacobs and Joel Rosenblum
-
- Compiled using Lattice C ver 2.15, using -md -n options
- */
-
- #include "dos.h"
-
- #define FAIL 1
- #define OK 0
-
- #define ANSI 1
- #define NOT_ANSI 0
-
- int line, line2, column, column2;
- union REGS in, out; /* defined in dos.h file of Lattice C Compiler */
-
- /****************************************************************************
-
- NAME
- check_ansi
-
- SYNOPSIS
- Checks to see if ANSI.SYS is installed on your machine
- by doing an ansi "report cursor position" call twice
- in a row to make sure each call returns a value, and
- that the values match for two successive calls. For
- further information on ANSI.SYS, see the IBM DOS
- technical reference.
-
- RETURN VALUE
- 1 if ansi.sys is installed
- 0 otherwise
-
- *****************************************************************************/
-
- check_ansi()
- {
-
- dump_key_buffer();
- cputs("\x1B[6n"); /* report cursor position command */
- if (get_line_column()) {
- dump_key_buffer();
- return NOT_ANSI; /* no cursor position came in */
- }
- line2 = line; /* save the reported values */
- column2 = column;
-
- dump_key_buffer();
- cputs("\x1B[6n"); /* try it one more time */
- if (get_line_column()) {
- dump_key_buffer();
- return NOT_ANSI;
- }
-
- dump_key_buffer();
-
- if (line2 != line || column2 != column) return NOT_ANSI;
-
- return ANSI;
- }
-
- /***************************************************************************
-
- NAME
- get_line_column
-
- SYNOPSIS
- checks to see if there are two keystokes
- the keyboard buffer (K.B.) and if so,
- them in the global variables line
- column.
-
- ****************************************************************************/
-
- get_line_column()
-
- {
- if (!(line = check_key())) return FAIL;
- if (!(column = check_key())) return FAIL;
- return OK;
- }
-
- /***************************************************************************
-
- NAME
- check_key
-
- SYNOPSIS
- returns keystroke left in K.B. if a keystroke exists there
-
- ****************************************************************************/
-
-
- check_key()
- {
- int c;
-
- for (c = 0; c < 100; c++)
- ; /* do nothing but wait */
-
- in.h.dl = 0xFF;
- in.h.ah = 0x6;
- c = intdos(&in, &out);
-
- if (c & 0x40) return 0;
- return (int)out.h.al;
- }
-
- /***************************************************************************
-
- NAME
- dump_key_buffer
-
- SYNOPSIS
- clears K.B.
-
- ****************************************************************************/
-
-
- dump_key_buffer()
- {
- in.h.dl = 0xFF;
- in.h.al = 0x06;
- in.h.ah = 0x0C;
- intdos(&in, &out);
- }
-
- -------------------------------------------------------------------------------
-
- /*
- LISTING 8 - EXAMPLE VIDEO CHARACTER OUTPUT ROUTINE
- */
-
- /*
- This code contains a C language example that uses the bit
- fields contained within the FEATURES variable to determine
- if it is possible to display the IBM extended character
- set on the machine. We assume these characters may be
- displayed if the machine is IBMCOMPAT. Note that this
- may be called from other modules in your program without
- regard to hardware considerations.
-
- Copyright (c) 1986 Dan Jacobs and Joel Rosenblum
-
- Compiled using Lattice C ver 2.15, using -md -n options
- */
-
- extern unsigned int features; /* see definition */
-
- /* position of characters in box_char */
- #define TOP_LEFT 0
- #define TOP_SIDE 1
- #define TOP_RIGHT 2
- #define SIDES 3
- #define BOTTOM_LEFT 4
- #define BOTTOM_SIDE 5
- #define BOTTOM_RIGHT 6
-
- char box_char[2][7] = {
- {0xDA, 0xC4, 0xBF, 0xB3, 0xC0, 0xC4, 0xD9}, /* expanded char codes */
- {0x2B, 0x2D, 0x2B, 0x7C, 0x2B, 0x2D, 0x2D} /* replacement char codes
- to use when no extended
- codes can be used */
- };
-
- /*****************************************************************************
-
- NAME
- draw_box
-
- SYNOPSIS
- Draws a box of size, length, and width at the row
- and column specified. Notice how the characters
- used for the box are changed based on the
- availability of the extended set. (Those
- characters only exist on IBM compatibles).
-
- *****************************************************************************/
-
- draw_box(row, column, length, depth)
- int row, column, length, depth;
- {
- int i;
- int char_set; /* tells which row of box_char to use based
- on the the IBMCOMPAT bit in features, use row
- 0, which contains extended chars, if IBMCOMPAT
- otherwise, use row 1 which contains standard
- ASCII replacements for the extended set */
-
- char_set = features & IBMCOMPAT ? 0 : 1;
-
- move_cursor(row, column); /* First, draw left corner */
-
- /* Move_curser is in listing 9. It moves the cursor to row, column
- by determining the machine's video features contained in the bit
- flags in FEATURES. You notice that your program does not need
- to worry about the details of how to move the cursor depending
- upon which machine is used. That leaves you free to solve more
- important problems */
-
-
- putchars(box_char[char_set][TOP_LEFT], 1);
-
- /* Putchars is a routine which puts the char passed in the first arg
- out to the screen the number of times specified by the second arg.
- Putchar also decides which method it will use to output that char
- based on the type of equiptment installed on your machine. See
- listing 9 for move_cursor detail */
-
- move_cursor(row, column+1); /* now the top side */
- putchars(box_char[char_set][TOP_SIDE], length-2);
-
- move_cursor(row, column+length-1); /* next top right corner */
- putchars(box_char[char_set][TOP_RIGHT], 1);
-
- for(i = 1; i < length-1; i++) { /* Vertical sides */
- move_cursor(row+i, column);
- putchars(box_char[char_set][SIDES], 1);
- move_cursor(row+i, column+length-1);
- putchars(box_char[char_set][SIDES], 1);
- }
-
- move_cursor(row+length-1, column); /* bottom left corner */
- putchars(box_char[char_set][BOTTOM_LEFT], 1);
-
- move_cursor(row+length-1, column+1 ); /* bottom side */
- putchars(box_char[char_set][BOTTOM_SIDE], length-2);
-
- move_cursor(row+length-1, column+length-1); /* bottom right corner */
- putchars(box_char[char_set][BOTTOM_RIGHT], 1);
-
- }
-
- -------------------------------------------------------------------------------
-
- /*
- LISTING 9 - EXAMPLE VIDEO CURSOR POSITIONING ROUTINE
- */
-
- /*
- This routine handles the details of cursor positioning based on
- the bits set in the variables FEATURES and VIDEO_FEATURES. It
- is called from the draw_box routine in listing 8, and illustrates
- how common machine dependent routines should be written. Note
- a similar type of routine should exist in your program to handle
- bit-mapped graphics-related calls.
-
- Compiled using Lattice C ver 2.15, using -md -n options
- */
-
- extern unsigned int features; /* global variable which holds machine features */
- extern unsigned int video_features; /* global variable which holds video-related features */
-
-
- char *screen_buff; /* pointer to buffer of 2000 (80*25) chars which is big
- enough to hold the ASCII charactures for a complete
- video page */
- char *screen_pos; /* pointer into screen_buff at current cursor position */
-
- char page_no; /* previously set video page number */
-
- char string[80]; /* string to use for ASCII calls */
-
- /****************************************************************************
-
- NAME
- move_cursor
-
- SYNOPSIS
- moves the cursor to row, column on the video display
- note that the routine decides which method to use
- based on bits set in both FEATURES and VIDEO_FEATURES
-
-
- *****************************************************************************/
-
- move_cursor(row, column)
- int row, column;
- {
- union REGS inregs, outregs; /* defined in dos.h */
-
- if (features & IBMCOMPAT) { /* use int 10 video bios */
- inregs.h.ah = 2; /* set cursor position */
- inregs.h.dl = column;
- inregs.h.dh = row;
- inregs.h.bh = page_no; /* page number */
- int86(0x10, &inregs, &outregs); /* do bios int 10 */
- } else if (video_features & ANSI) { /* need to do ansi calls */
- sprintf(string, "\x1B[%d;%df$", ++row, ++column);
- dos_puts(string); /* dos_puts is a routine that calls dos and
- prints string using function 9, print string */
- } else { /* dos generic mode */
- screen_pos = screen_buff + row * 80 + column;
- }
-
- /* NOTE: In DOS generic mode we keep a buffer (screen_buff)
- big enough to hold one video page of ASCII text. In all
- of the calls that write to video, we move the chars into
- screen_buf at the pheudo cursor position, screen_pos.
- When we have completed updating the memory-based page,
- we write the ASCII chars from the memory buffer to the
- actual screen using standard dos calls */
- }
-
-