home *** CD-ROM | disk | FTP | other *** search
- /* autogrph.c */
-
- /* identify type of video adapter being used (graphics types, only) and
- return the identification code for that adapter. This module is designed
- to be compiled alone, and the object code bound into the auxgraph library
- file.
-
- calling unsigned video_test ();
-
- returns disp_a + disp_b << 8 for primary and secondary displays, respectively.
- Returned codes as given below.
- */
-
- /* copyright 1990, 1991 Robert C. Becker, Lantern Systems */
-
- #include <stdio.h>
- #include <dos.h>
- #include <bios.h>
- #include <conio.h>
-
- /* do some fancy bit setting to make detecting mono vs. color easier */
- /* 7 6 5 4 3 2 1 0 */
- /* +--------+--------+--------+--------+--------+--------+--------+--------+ */
- /* |Herc=1 | mono=1 | | | Adapter ID code 0 - 0F | */
- /* | | | | | | */
- /* +--------+--------+--------+--------+--------+--------+--------+--------+ */
-
- /* these are the returned video adapter ID code numbers */
-
- #define VIDEO 0x10 /* video interrupt number */
- #define NOGRAPHICS 0 /* no supported graphics modes available */
- #define CGA 1 /* CGA */
- #define MEGA 0x42 /* EGA monochrome */
- #define CEGA 3 /* EGA color */
- #define PGC 4 /* PGC: not supported */
- #define MVGA 0x45 /* VGA monochrome */
- #define CVGA 6 /* VGA color */
- #define EMCGA 7 /* MCGA w/EGA color display */
- #define MMCGA 0x48 /* Mono MCGA */
- #define CMCGA 9 /* Color MCGA */
- #define ATT 0x0A /* ATT PC6300: not known if DEB is present */
- #define HGC 0x0CB /* Hercules graphics card */
- #define HGCPLUS 0x0CC /* Hercules Plus card */
- #define INCOLOR 0x8D /* Hercules InColor card */
-
- unsigned video_test ();
- static int ps2_test ();
- static int ega_test ();
- static void cga_test ();
- static int herc_test ();
- static int att_test ();
-
- static unsigned disp_a, disp_b, ega_mry;
- static unsigned ps2vid[] = { NOGRAPHICS, NOGRAPHICS, CGA, NOGRAPHICS, CEGA, MEGA,
- PGC, MVGA, CVGA, NOGRAPHICS, EMCGA, CMCGA, CMCGA };
-
- static unsigned ega_config[] = { CGA, CEGA, MEGA }; /* only need 3 of 6: order is same for last 3 configs */
-
- static char attlogo[] = "OLIVETTI";
- static char far *romid;
- static char romstr [10];
-
- static char copyright [] = "copyright 1990, 1991 Robert C. Becker, Lantern Systems";
-
- static union REGS regs;
-
- /*---------------------------------------*/
-
- unsigned video_test ()
- {
- int j;
-
- disp_a = disp_b = NOGRAPHICS; /* initialize: no supported video graphics modes */
-
- if (ps2_test () > 1) return ( disp_a + (disp_b << 8) );
- /* done: VGA interrupt answered all questions */
-
- if ( !ega_test () ) /* returns 1 if EGA: if EGA, no CGA possible */
- if ( !att_test () ) cga_test ();
-
- /* The value of the adapter returned by ega_test () is one of CEGA, CGA, MEGA.
- The CGA value is returned because an EGA adapter using a CGA monitor can't reproduce
- the high resolution graphics modes. Also, because the adapter port adr's are
- programmable and change when using mono modes, we can't look for Herc cards if we
- have a mono EGA adapter since the ports overlap. We test first for an ATT graphics
- adapter because it is basically a CGA adapter and will pass the CGA test. By testing
- first for the ATT card, we can separate them. */
-
- /* if either display is MONO, No Herc cards possible */
- /* this includes the InColor card which uses the mono address space */
- if (( disp_a & 0x40 ) || ( disp_b & 0x40 )) return ( disp_a + (disp_b << 8) );
- if ( j = herc_test () )
- {
- if ( disp_a == NOGRAPHICS )
- disp_a = j;
- else
- disp_b = j; /* never get here if disp_b already assigned */
- } /* (another type of mono display would be present) */
-
- /* a complete video test would also determine which adapter is presently the
- primary display. We don't care here, because we are going to take the highest
- resolution display and switch to it for graphics */
-
- return ( disp_a + (disp_b << 8) );
- }
-
- /*---------------------------------------*/
-
- int ps2_test () /* test for PS/2 VGA or MCGA */
- { /* returns # of displays found: 0 for none/unsupported */
- int i = 0;
-
- regs.x.ax = 0x1A00; /* get video display configuration */
- int86 (VIDEO, ®s, ®s);
- if (regs.h.al != 0x1a) return (0); /* unsupported command */
- if (regs.h.bl > 0 && regs.h.bl <= 0x0C ) /* active display */
- {
- ++i; /* found one display */
- disp_a = ps2vid [regs.h.bl]; /* type number */
- }
- if (regs.h.bh > 0 && regs.h.bh <= 0x0C ) /* inactive display */
- {
- disp_b = ps2vid [regs.h.bh]; /* type number */
- return ( ++i); /* found a display */
- }
- return (i);
- }
-
- /*---------------------------------------*/
-
- int ega_test () /* test for EGA display */
- {
- unsigned i;
-
- regs.x.ax = 0x1200; /* code for Alternate Select */
- regs.h.bl = 0x10; /* code for return EGA information */
- int86 (VIDEO, ®s, ®s);
-
- if (regs.h.bl == 0x10 ) return ( 0 ); /* No EGA present */
- i = regs.h.cl > 1; /* bit 0 = don't care */
- i = (i > 2) ? i - 3: i; /* fold repeated pattern into 1st three types */
- ega_mry = regs.h.bl; /* EGA memory code */
-
- /* we have an EGA adapter, but find out how it is configured. Need to
- know if it is EGA color, CGA color, or BW graphics */
-
- if (disp_a == NOGRAPHICS ) /* no prior active display identified */
- {
- disp_a = ega_config[ i ];
- return ( 1 ); /* return EGA found: do not test for CGA */
- }
- if ( disp_b == NOGRAPHICS ) /* no prior secondary display identified */
- {
- disp_b = ega_config[ i ];
- return ( 1 ); /* this is the alternative adapter: done searching */
- }
- }
-
- /*---------------------------------------*/
- void cga_test ()
- {
- unsigned cur_pos;
- int i, j;
-
- /* test for CGA by testing for 6845 CRTC chip at 0x3d4 */
- outp ( 0x3d4, 0x0F ); /* select cursor position low byte reg */
- cur_pos = inp (0x3d5); /* read current value of cursor low reg */
- outp (0x3d5, 0x66); /* arbitrary value */
-
-
- for (i = 0; i < 100; ++i) j = inp (0x3d5); /* kill time */
-
- if (inp (0x3d5) == 0x66 ) /* have CGA */
- {
- outp ( 0x3d5, cur_pos ); /* restore cursor position */
- if (disp_a != NOGRAPHICS )
- {
- disp_b = CGA;
- return;
- }
- disp_a = CGA; /* if we got here, then there is no other primary display */
- outp ( 0x3d5, cur_pos); /* restore cursor position */
- }
- return;
- }
-
- /*---------------------------------------*/
-
- int herc_test ()
- {
- unsigned st, st1, i;
-
- st = inp (0x3ba) & 0x70; /* read Herc/MDA status reg. Get Herc ID bits */
- if ( st == 0x50 ) /* InColor card */
- return (INCOLOR);
- if ( st == 0x10 ) /* Herc Plus card */
- return (HGCPLUS);
- st = (inp (0x3ba) ); /* read status port */
- for (i = 0x3fff; i > 0; --i) /* not a good idea to use clock speed dependent loops */
- {
- if ( (st ^ inp (0x3ba) ) & 0x80 ) /* test for changes in vert retrace bit (80h) */
- return ( HGC ); /* bit 7 changes: must be ordinary Herc card */
- }
- return ( NOGRAPHICS ); /* bit 7 does not change -> MDA card */
- }
-
- /*---------------------------------------*/
-
-
- static int att_test ()
- {
- char *str;
- int i;
-
- FP_SEG (romid) = 0x0fc00;
- FP_OFF (romid) = 0x0050;
- str = romstr;
- for (i = 0; i < 8; ++i, ++str, ++romid) *str = *romid;
- *str = '\0'; /* terminate string */
-
- /* printf ("ROM ID string = %s\n", romstr); */
- if ( !strcmp (romstr, attlogo) ) /* BIOS ROM logo matches */
- {
- if (disp_a != NOGRAPHICS )
- {
- disp_b = ATT;
- return (1);
- }
- disp_a = ATT; /* if we got here, then there is no other primary display */
- return (1);
- }
- return (0); /* not ATT */
- }
-
-
- /*---------------------------------------*/
-