|VESA, higher modes..
|Page 1 of 1|
|Author:||vbbrett [ Thu Jul 15, 2004 8:31 pm ]|
|Post subject:||VESA, higher modes..|
I read a tutorial on how to initialize VESA graphics at a resolution of 320x200x256. That is too small for me. How would I enter a higher mode such as 640x480, or even 1024x768? Using the same VESA standard? Not much is documented on the higher modes.
I've written my kernel from the ground up starting at the bootsector. So, if a switch requires real mode, I'm up for it!
|Author:||Dreamsmith [ Thu Jul 15, 2004 11:36 pm ]|
|Post subject:||Re:VESA, higher modes..|
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 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;
|Page 1 of 1||All times are UTC - 6 hours|
|Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group