Yeah, VESA stopped assigning codes for video modes long ago -- instead they standardized a much better solution: you can query the video card for what modes it supports, and query it about the attributes of each mode. In my own OS, I have a function that I call with a desired width, height, and depth, and it returns the video mode number for it (or the closest match). Then you just set that mode. You'll want to look in the VESA VBE docs for these functions:
INT 0x10, AX=0x4F00: Get Controller Info. This is the one that returns the array of all supported video modes.
INT 0x10, AX=0x4F01: Get Mode Info. Call this for each member of the mode array to find out the details of that mode.
INT 0x10, AX=0x4F02: Set Video Mode. Call this with the mode number you decide to use.
Here's the code I use to determine which mode I want:
UInt16 findMode(int x, int y, int d) { ControllerInfo *ctrl = (ControllerInfo *)0x2000; ModeInfo *inf = (ModeInfo *)0x3000; UInt16 *modes; int i; UInt16 best = 0x13; int pixdiff, bestpixdiff = DIFF(320 * 200, x * y); int depthdiff, bestdepthdiff = 8 >= d ? 8 - d : (d - 8) * 2;
strncpy(ctrl->VbeSignature, "VBE2", 4); intV86(0x10, "ax,es:di", 0x4F00, 0, ctrl); // Get Controller Info if ( (UInt16)v86.tss.eax != 0x004F ) return best;
modes = (UInt16*)REALPTR(ctrl->VideoModePtr); for ( i = 0 ; modes[i] != 0xFFFF ; ++i ) { intV86(0x10, "ax,cx,es:di", 0x4F01, modes[i], 0, inf); // Get Mode Info if ( (UInt16)v86.tss.eax != 0x004F ) continue; // Check if this is a graphics mode with linear frame buffer support if ( (inf->ModeAttributes & 0x90) != 0x90 ) continue; // Check if this is a packed pixel or direct color mode if ( inf->MemoryModel != 4 && inf->MemoryModel != 6 ) continue; // Check if this is exactly the mode we're looking for if ( x == inf->XResolution && y == inf->YResolution && d == inf->BitsPerPixel ) return modes[i]; // Otherwise, compare to the closest match so far, remember if best pixdiff = DIFF(inf->XResolution * inf->YResolution, x * y); depthdiff = inf->BitsPerPixel >= d ? inf->BitsPerPixel - d : (d - inf->BitsPerPixel) * 2; if ( bestpixdiff > pixdiff || (bestpixdiff == pixdiff && bestdepthdiff > depthdiff) ) { best = modes[i]; bestpixdiff = pixdiff; bestdepthdiff = depthdiff; } } if ( x == 640 && y == 480 && d == 1 ) return 0x11; return best; }
|