/* * This is a sample program to query a video adapters capabilities * conforming to Vesa Super VGA BIOS Extension Standard #VS891001 * * This program is compiled under Microsoft C version 5.0 (or equivalent). * Any memory model may be used. * (Note the "%Fs" format to display the (far) OEM string) * * The command used to compile this is: * cl /AS /Os /Gs /G0 /Zp vesatest.c * * Program written by Mark D. Niemiec of Tecmar Inc. * This program is in the public domain. */ #include typedef unsigned char uchar; typedef unsigned int uint; #define lobyte(n) ((n) & 0xFF) #define hibyte(n) ((n) >> 8 & 0xFF) /* * VGA BIOS extension functions */ #define SUPERVGA 0x4F #define GetSuperVGAInfo 0x00 #define GetModeInfo 0x01 /* * VGA information block returned by GetSuperVGAInfo call */ struct VgaInfoBlock { char VESASignature[4]; /* 0: 4 signature bytes: must be 'VESA' */ uint VESAVersion; /* 4: VESA version number */ char far *OEMStringPtr; /* 6: Pointer to OEM string */ long Capabilities; /* 10: Capabilities of the video environment */ int far *VideoModePtr; /* 14: list of supported Super VGA modes */ char VIBfiller[256-18]; /* 18: fill to 256 bytes */ }; struct VgaInfoBlock far vib; /* NOTE: Since 'vib' is a static variable, it is pre-initialized to zero */ /* * Mode information returned by GetModeInfo call */ struct ModeInfoBlock { uint ModeAttributes; /* 0: mode attributes */ uchar WinAAttributes; /* 2: Window A attributes */ uchar WinBAttributes; /* 3: Window B attributes */ uint WinGranularity; /* 4: Window granularity */ uint WinSize; /* 6: Window size */ uint WinASegment; /* 8: Window A start segment */ uint WinBSegment; /* 10: Window B start segment */ uint WinFuncPtr[2]; /* 12: (far) pointer to window function */ uint BytesPerScanLine; /* 14: bytes per scan line */ uint XResolution; /* 16: horizontal resolution */ uint YResolution; /* 18: vertical resolution */ uchar XCharSize; /* 19: character cell width */ uchar YCharSize; /* 20: character cell height */ uchar NumberOfPlanes; /* 21: number of memory planes */ uchar BitsPerPixel; /* 22: bits per pixel */ uchar NumberOfBanks; /* 23: number of banks */ uchar MemoryModel; /* 24: memory model type */ uchar BankSize; /* 25: bank size in KB */ char MIBfiller[256-26]; /* 26: fill to 256 bytes */ }; struct ModeInfoBlock far mib; /* NOTE: Since 'mib' is a static variable, it is pre-initialized to zero */ /* * Known memory models */ uchar *models[] = { "Text", /* 0 = text */ "CGA", /* 1 = CGA graphics */ "Herc", /* 2 = Hercules graphics */ "EGA", /* 3 = EGA/VGA planar graphics */ "VGA", /* 4 = VGA packed-pixel graphics */ "256" /* 5 = non-chain-4 256 color */ }; /* 6-F = VESA TBD; 10-FF = OEM */ /* * Column headings */ char headings[] = "\n\ Mode Attr Window WindowA WindowB Mapping Bytes Resolution Char BPP Banks Type\n\ Grn Siz Seg att Seg att Function /line Cell Planes\n\n"; /* * Main procedure */ void main(int argc, char **argv) { extern void queryvesa(void); queryvesa(); exit(0); } /* * Inquire about VESA information */ void queryvesa(void) { extern void vesainfo(void); extern int same(char far *, char *, int); int status; status = int10(SUPERVGA<<8|GetSuperVGAInfo, 0, 0, 0, &vib); if(lobyte(status) != SUPERVGA) { printf("VGA BIOS extensions not installed\n"); } else if(hibyte(status) != 0) { printf("Get Super VGA Information call returned error %d\n", hibyte(status)); } else if(!same(vib.VESASignature,"VESA",4)) { printf("VESA signature was expected, '%4.4s' was found\n", vib.VESASignature); } else { vesainfo(); } } /* * See if two strings (one far and one normal) are equal */ int same(char far *p, char *q, int n) { while(--n >= 0) { if(*p++ != *q++) return(0); } return(1); } /* * Display VESA information */ void vesainfo(void) { extern void querymode(int); int far *modes; printf("Super VGA BIOS extension version %d.%02d is installed\n", hibyte(vib.VESAVersion), lobyte(vib.VESAVersion)); printf( vib.OEMStringPtr==NULL ? "No OEM String is present" : "OEM string is '%Fs'\n", vib.OEMStringPtr); printf("Device capabilities are %lX\n", vib.Capabilities); printf(headings); for(modes=vib.VideoModePtr; *modes!=-1; ) querymode(*modes++); } /* * Inquire about mode information */ void querymode(int mode) { extern void dispmode(void), dispextmode(void); int status; printf("%04X", mode); status = int10(SUPERVGA<<8|GetModeInfo, 0, mode, 0, (struct ModeInfoBlock far *)&mib); if(lobyte(status) != SUPERVGA) { printf(": Get Mode Information call is not available\n"); } else if(hibyte(status) != 0) { printf(": Get Mode Information call returned error %d\n", hibyte(status)); } else { dispmode(); if(mib.ModeAttributes & 0x02) dispextmode(); } printf("\n"); } /* * Display mandatory mode information */ void dispmode(void) { printf(" %s%s%s%s", mib.ModeAttributes&0x01 ? "I" : " ", /* initializable */ mib.ModeAttributes&0x04 ? "B" : " ", /* BIOS fns. */ mib.ModeAttributes&0x08 ? "C" : "M", /* color/mono */ mib.ModeAttributes&0x10 ? "G" : "T"); /* graphics/text */ printf("%4d%4d", mib.WinGranularity, /* window granularity */ mib.WinSize); /* window size */ printf( mib.WinAAttributes&0x01 ? " %04X %s%s" : " ", mib.WinASegment, /* window A segment */ mib.WinAAttributes&0x02 ? "R" : " ", /* window A readable */ mib.WinAAttributes&0x04 ? "W" : " "); /* window A writable */ printf( mib.WinBAttributes&0x01 ? " %04X %s%s" : " ", mib.WinBSegment, /* window B segment */ mib.WinBAttributes&0x02 ? "R" : " ", /* window B readable */ mib.WinBAttributes&0x04 ? "W" : " "); /* window B writable */ printf(" %04X:%04X", mib.WinFuncPtr[1], mib.WinFuncPtr[0]); /* mapping function */ printf("%5d", mib.BytesPerScanLine); /* bytes/scan line */ } /* * Display extended mode information */ void dispextmode(void) { printf("%5dx%-4d", mib.XResolution, /* screen width */ mib.YResolution); /* screen height */ printf("%3dx%-2d", mib.XCharSize, /* character width */ mib.YCharSize); /* character height */ printf("%2d", mib.BitsPerPixel); /* bits/pixel */ printf("%2d", mib.NumberOfPlanes); /* number of planes */ printf( mib.BankSize!=0 ? "%2dx%-3d" : "%2d ", mib.NumberOfBanks, /* number of banks */ mib.BankSize); /* bank size */ if(mib.MemoryModel < 6) printf(" %s", models[mib.MemoryModel]); /* model type */ else printf(" %02X", mib.MemoryModel); /* model number */ } /* * Call video BIOS * (Note: es and di may be passed separately, or together via a far pointer) */ #include int10(int ax, int bx, int cx, int dx, int di, int es) { union REGS r; struct SREGS s; r.x.ax = ax; r.x.bx = bx; r.x.cx = cx; r.x.dx = dx; r.x.di = di; s.es = es; int86x(0x10, &r, &r, &s); return(r.x.ax); }