//------------------------------------------------------------------- // vesainfo.cpp // // This program uses the Linux 'vm86()' system-call to execute // some SVGA firmware procedures (supplied by the manufacturer // of any VESA-compliant video display controller) which offer // information about the capabilities of your graphics system; // in particular, a list of the supported VESA graphics modes. // // compile with: $ g++ vesainfo.cpp int86.cpp -o vesainfo // // Reference: // "VESA BIOS Extension (VBE) Core Functions Standard, version // 3.0", Video Electronics Standards Association (1998). // // programmer: ALLAN CRUSE // written on: 10 JUN 2005 // revised on: 29 AUG 2005 //------------------------------------------------------------------- #include // for printf(), perror() #include // for gethostname() #include // for exit() #include // for strncpy() #include "int86.h" // for init8086(), int86() typedef struct { unsigned char VbeSignature[4]; unsigned char VbeVersion[2]; unsigned short OemStringPtr[2]; unsigned char Capabilities[4]; unsigned short VideoModePtr[2]; unsigned short TotalMemory; unsigned char OemSoftwareRev[2]; unsigned short OemVendorNamePtr[2]; unsigned short OemProductNamePtr[2]; unsigned char Reserved[222]; unsigned char OemData[256]; } VbeInfoBlk; typedef struct { unsigned short ModeAttributes; unsigned char WinAAttributes; unsigned char WinBAttributes; unsigned short WinGranularity; unsigned short WinSize; unsigned short WinASegment; unsigned short WinBSegment; unsigned short WinFuncPtr[2]; unsigned short BytesPerScanLine; unsigned short XResolution; unsigned short YResolution; unsigned char XCharSize; unsigned char YCharSize; unsigned char NumberOfPlanes; unsigned char BitsPerPixel; unsigned char NumberOfBanks; unsigned char MemoryModel; unsigned char BankSize; unsigned char NumberOfImagePages; unsigned char Reserved; unsigned char RedMaskSize; unsigned char RedFieldPosition; unsigned char GreenMaskSize; unsigned char GreenFieldPosition; unsigned char BlueMaskSize; unsigned char BlueFieldPosition; unsigned char RsvdMaskSize; unsigned char RsvdFieldPosition; unsigned char DirectColorModeInfo; unsigned long PhysBasePtr; unsigned long Reserved1; unsigned short Reserved2; unsigned short LinBytesPerScanLine; unsigned char BnkNumberOfImagePages; unsigned char LinNumberOfImagePages; unsigned char LinRedMaskSize; unsigned char LinRedFieldPosition; unsigned char LinGreenMaskSize; unsigned char LinGreenFieldPosition; unsigned char LinBlueMaskSize; unsigned char LinBlueFieldPosition; unsigned char LinRsvdMaskSize; unsigned char LinRsvdFieldPosition; unsigned long MaxPixelClock; unsigned char Reserved3[189]; } ModeInfoBlock; struct vm86plus_struct vm; int main( int argc, char **argv ) { // get the hostname for this workstation (will identify output) char hostname[ 64 ] = ""; gethostname( hostname, 64 ); //------------------------------------------------------------- // Here we execute VESA BIOS function 0. // // expects: AX = 4F00h // ES:DI = address for information block // (initial dword is 'VBE2' if 512 butes) // // returns: AX = 004F (success) or 014F (failure) //------------------------------------------------------------- init8086(); // setup simulated 8086 execution environment VbeInfoBlk *vbe = (VbeInfoBlk*)0x00010000; strncpy( (char*)vbe, "VBE2", 4 ); // plant the signature vm.regs.eax = 0x4F00; // VESA 'Get VbeInfoBlk' service vm.regs.es = 0x1000; // segment-address for structure vm.regs.edi = 0x0000; // offset-address for structure int86( 0x10, vm ); // execute software interrupt if ( vm.regs.eax != 0x004F ) { fprintf( stderr, "VbeInfoBlk not found\n" ); exit(1); } unsigned char *cp; unsigned short *wp; printf( "\n\nVESA BIOS Extensions Information\n\n" ); printf( "\tVbeSignature: %s \n", vbe->VbeSignature ); cp = vbe->VbeVersion; printf( "\tVbeVersion: %d.%d \n", cp[1], cp[0] ); wp = (unsigned short*)vbe->OemStringPtr; printf( "\tOemStringPtr: %04X:%04X ", wp[1], wp[0] ); cp = (unsigned char*)( 16L * wp[1] + wp[0] ); printf( "\'%s\' \n", cp ); cp = (unsigned char *)vbe->Capabilities; printf( "\tCapabilities: " ); for (int i = 0; i < 4; i++) printf( "%02X ", cp[i] ); printf( "\n" ); wp = vbe->VideoModePtr; printf( "\tVideoModePtr: %04X:%04X \n", wp[1], wp[0] ); printf( "\tTotalMemory: %d KB \n", vbe->TotalMemory * 64 ); cp = vbe->OemSoftwareRev; printf( "\tOemSoftwareRev: %d.%d \n", cp[1], cp[0] ); wp = vbe->OemVendorNamePtr; printf( "\tOemVendorNamePtr: %04X:%04X ", wp[1], wp[0] ); cp = (unsigned char*)( 16L * wp[1] + wp[0] ); printf( "\'%s\' \n", cp ); wp = vbe->OemProductNamePtr; printf( "\tOemProductNamePtr: %04X:%04X ", wp[1], wp[0] ); cp = (unsigned char*)( 16L * wp[1] + wp[0] ); printf( "\'%s\' \n", cp ); printf( "\nList of VESA video modes supported " ); printf( "on workstation \'%s\': \n", hostname ); wp = (unsigned short *)vbe->VideoModePtr; short *vp = (short*)( 16L * wp[1] + wp[0] ); int nmodes; // number of supported modes for (nmodes = 0; nmodes < 64; nmodes++) { if ( vp[ nmodes ] == ~0 ) break; if ( ( nmodes % 12 ) == 0 ) printf( "\n " ); printf( " %04X ", vp[ nmodes ] ); } printf( "\n" ); //------------------------------------------------------------- // Here we repeatedly execute VESA BIOS function 1. // // expects: AX = 4F01h // BX = vesa mode-number // ES:DI = address for information block // // returns: AX = 004F (success) or 014F (failure) //------------------------------------------------------------- ModeInfoBlock *mi; for (int i = 0; i < nmodes; i++) { mi = (ModeInfoBlock*)(0x00010200 + 256*i); memset( (void*)mi, 0x00, 256 ); vm.regs.eax = 0x4F01; // VESA 'Get ModeInfoBlk' vm.regs.ecx = vp[i]; // which vesa mode-number vm.regs.es = 0x1000; // segment-address for info vm.regs.edi = 512 + 256*i; // offset-address for info int86( 0x10, vm ); // execute software interrupt printf( "\nmode 0x%04X: ", vp[i] ); printf( "%2d-bpp ", mi->BitsPerPixel ); printf( "%4dx%-4d ", mi->XResolution, mi->YResolution ); printf( "MemoryModel=%d ", mi->MemoryModel ); printf( "NumberOfPlanes=%d ", mi->NumberOfPlanes ); if ( mi->ModeAttributes & (1<<3) ) printf( "color " ); else printf( "monochrome " ); if ( mi->ModeAttributes & (1<<4) ) printf( "graphics " ); else printf( "text " ); } printf( "\n\n" ); }