Path: utzoo!utgpu!watmath!att!mcdchg!ditka!qiclab!jamesd From: jamesd@qiclab.UUCP (James Deibele) Newsgroups: comp.sys.ibm.pc Subject: Re: determining cga, ega, vga Message-ID: <3201@qiclab.UUCP> Date: 16 Nov 89 15:08:01 GMT References: <5695@lindy.Stanford.EDU> Reply-To: jamesd@qiclab.UUCP (James Deibele) Organization: Qic Laboratories, Portland, Oregon. Lines: 294 In article <5695@lindy.Stanford.EDU> GG.DAR@forsythe.stanford.edu (Aaron Reizes) writes: >How do I determine the type of video adapter installed, >CGA, EGA, or VGA? So far I haven't found any easy way to be sure >which I am dealing with? The code below is swiped from the C Gazette, who charge $21 a year for 4 issues. Seems like a pretty reasonable deal to me (I have no connection with them except as a satisfied customer). The C Gazette 1341 Ocean Avenue #257 Santa Monica, CA 90401 USA (213) 473-7414 -------This is from the C Gazette, Volume 4, #1 --------- /****************** CRTTYPE.C ************************ * Identifies monitor type either by printing a * message about the CRT or by returning a unique * identification byte. Version 2.1 * * Usage: unsigned int crttype (void) * * Macros: * DRIVER -- #define it to have driver code * VERBOSE - #define it to print messages * * (c) 1989 Andrew Binstock * Use freely if authorship is acknowledged. * * Validated for Microsoft 5.1, Turbo C 2.0, Watcom 7.0 * Note: loop optimization must be disabled *******************************************************/ #include #include #include #define MSC 1 /* set MSC to 1 for Microsoft compilation */ #if MSC #define MK_FP(seg,ofs) ((void far *) \ (((unsigned long)(seg) << 16) | (unsigned)(ofs))) #include #pragma loop_opt(off) /* Disable loop optimization */ #endif #define DRIVER 1 /* If != 0, run test driver */ #define VERBOSE 1 /* If != 0, print identification info to stdout */ #if VERBOSE #define say(m, i) prnt(m, i) static void prnt (char *, int); #else #define say(m, i) #endif #define MDA 0x0100 #define HERCULES 0x0200 #define CGA 0x0400 #define EGA 0x0800 #define MCGA 0x1000 #define VGA 0x2000 #define UNKNOWN 0xFF00 #define MONO 0x00 #define COLOR 0x01 #define PLUS 0x02 /* Used for identifying CGA */ #define CRTC_COLOR_INDEX_REG 0x3D4 /* Port for CRTC index register */ #define CRTC_COLOR_DATA_REG 0x3D5 /* Port for CRTC data register */ /* Used for identifying MDA */ #define CRTC_MONO_INDEX_REG 0x3B4 /* Port for CRTC index register */ #define CRTC_MONO_DATA_REG 0x3B5 /* Port for CRTC data register */ /* Used for identifying Hercules */ #define CRTC_STATUS_PORT 0x3BA /* Port for CRTC retrace status */ union REGS regs; unsigned int crttype (void) { unsigned int monitor_type = 0; unsigned char far * peeker ; unsigned char hold_a_byte; int i; regs.h.ah = 0x1A; /* Service 1A, sub-service 0 */ regs.h.al = 0x00; /* of int 10h will identify a */ int86(0x10, ®s, ®s); /* VGA or MCGA */ if (regs.h.al == 0x1A) /* true only for VGA, MCGA */ { say ("VGA found: ", -1); if (regs.h.bl != 0) say ("Currently active system is %s \n", regs.h.bl); if (regs.h.bh != 0) say ("Currently inactive system is %s \n", regs.h.bh); return (regs.h.bl < 0x0A ? VGA : MCGA); } regs.h.ah = 0x12; /* Next, test for EGA */ regs.h.bl = 0x10; int86 (0x10, ®s, ®s); if (regs.h.bl != 0x10) /* It's an EGA */ { monitor_type |= EGA; say ("EGA with %s monitor", (regs.h.bh == 0 ? 'C' : 'M'));/* Color or */ /* monochr. */ say ("and %s Kb of video RAM\n", (regs.h.bl + 1) * 64); /* RAM size */ switch (regs.h.cl) /* CL contains monitor info */ { /* found at BIOS location */ case 2: /* 0040:0088; these values */ case 3: /* are the only valid ones */ case 8: /* for an enhanced EGA. */ case 9: monitor_type |= PLUS; say ("Enhanced Display Found", -1); break; } /* Let's see if the EGA is active. Since we */ /* can't read EGA status, we have to look in */ /* the BIOS area at 0487h, bit 3: 0 = active */ peeker = MK_FP (0x0040, 0x0087); say ("EGA %s active", (*peeker & 0x08) == 0 ? 'Y' : 'N'); return (monitor_type | (regs.h.bh == 0 ? COLOR : MONO)); } /* Not VGA, MCGA, EGA, so let's try CGA, after quick test for mono */ regs.h.ah = 0x0F; /* Get the current mode */ int86 (0x10, ®s, ®s); /* if it's a 7 (mono alpha) */ if (regs.h.al != 0x07) /* go to mono test, since CGA */ { /* cannot be in mode 7 */ outp (CRTC_COLOR_INDEX_REG, 0x0F); /* Get value of reg. 15 */ hold_a_byte = inp (CRTC_COLOR_DATA_REG); /* Read and save it. */ outp (CRTC_COLOR_DATA_REG, 0x63); /* Write an unlikely value */ for (i = 0; i < 100; i++) ; /* Wait a bit... */ if (inp (CRTC_COLOR_DATA_REG) == 0x63) /* Read it back and check it*/ { /* If the same in and out, */ outp (CRTC_COLOR_DATA_REG, hold_a_byte); /* it is a CGA. */ say ("CGA found", -1); /* Say so, reset reg. 15*/ return (CGA | COLOR); /* and go home. */ } else { /* otherwise, reset reg. 15 */ outp (CRTC_COLOR_DATA_REG, hold_a_byte); /* and announce the */ say ("Unknown CGA model", -1); /* difficulty. */ return (UNKNOWN | COLOR); } } /* Let's see if a mono adapter is found */ /* Same as CGA technique but to mono port */ outp (CRTC_MONO_INDEX_REG, 0x0F); /* Announce interest in reg. 15 */ hold_a_byte = inp (CRTC_MONO_DATA_REG); /* Read and save it. */ outp (CRTC_MONO_DATA_REG, 0x63); /* Write an improbable value */ for (i = 0; i <100; i++) ; /* Wait a bit... */ if (inp (CRTC_MONO_DATA_REG) != 0x63) /* Read it back and check it; */ { /* If it's not same in and out, */ outp (CRTC_MONO_DATA_REG, hold_a_byte);/* it's not an MDA - so */ say ("Unknown monitor type", -1); /* say so, restore reg 15 and */ return (UNKNOWN | MONO); /* go home. */ } /* We have MDA if we're here. */ outp (CRTC_MONO_DATA_REG, hold_a_byte); /* Restore reg 15 from */ /* previous test */ /* So it's mono, but is it a Hercules ? */ hold_a_byte = inp (CRTC_STATUS_PORT); /* Get the setting */ hold_a_byte &= 0x80; /* Isolate bit 7 */ for ( i = 0; i < 1000; i++) /* Test bit 7, 1000 times */ { if ((inp (CRTC_STATUS_PORT) & 0x80) /* If the value changes */ != hold_a_byte) /* it'a Hercules */ { monitor_type = HERCULES; break; } } if (monitor_type != HERCULES) /* If no Hercules then it's a */ { /* plain MDA monitor. Say so */ say ("Monochrome CRT, no Hercules", -1); /* and go home. */ return (MDA | MONO); } /* What kind of Hercules is it? */ hold_a_byte = inp (CRTC_STATUS_PORT); /* Get a fresh reading */ hold_a_byte &= 0x70; /* Keep bits 4-6 */ switch (hold_a_byte) /* and test the value */ { case 0x50: say ("In Color Card found", -1); return (monitor_type | COLOR); case 0x10: say ("Graphics Plus Card found", -1); return (monitor_type | PLUS); case 0x00: say ("Regular Graphics Card found", -1); return (monitor_type | MONO); } say ("Unknown Hercules", -1); return (UNKNOWN | MONO); /* Unknown Hercules model */ } #if VERBOSE static void prnt(char * literal, int msg) { static char * display_name [] = { "Not Found", /* 00h */ "MDA with monochrome display", /* 01h */ "CGA with color display", /* 02h */ "reserved", /* 03h */ "EGA with color display", /* 04h */ "EGA with monochrome display", /* 05h */ "Professional graphics display", /* 06h */ "VGA with analog monochrome", /* 07h */ "VGA with analog color display", /* 08h */ "reserved", /* 09h */ "MCGA with digital color display", /* 0Ah */ "MCGA with analog monochrome display", /* 0Bh */ "MCGA with analog color display" /* 0Ch */ }; if (msg == -1) { puts (literal); return; } if ( msg >= 0x00 && msg <= 0x0C ) { printf (literal, display_name[msg]); return; } if ( msg == 'Y' || msg == 'N' ) { printf (literal, msg == 'Y' ? "is" : "is not"); return; } if (msg == 'C' || msg == 'M') { printf (literal, (msg == 'C' ? "color" : "monochrome")); return; } if (msg == 64 || msg == 128 || msg == 192 || msg == 256) { char p [4]; printf (literal, itoa (msg, p, 10)); return; } } #endif #ifdef DRIVER void main(void) { printf ("\nMonitor ID is %x", crttype()); } #endif -- James Deibele jamesd@qiclab BBSs: (503) 760-1473 or (503) 761-7451 TECHBooks: The Computer Book Specialists --- Voice: (503) 646-8257 12600 SW 1st Beaverton, OR 97005 --- Book reviewers wanted for computer science & electronics - contact us for more information.