VESA Video Modes: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
No edit summary
 
No edit summary
Line 5: Line 5:
You'll want to look in the VESA VBE docs for these functions:
You'll want to look in the VESA VBE docs for these functions:


;INT 0x10, AX=0x4F00
;__INT 0x10, AX=0x4F00__: Get Controller Info. This is the one that returns the array of all supported video modes.
: Get Controller Info. This is the one that returns the array of all supported video modes.
<verbatim>
<pre>
struct vbeControllerInfo {
struct vbeControllerInfo {
char signature[4]; // == "VESA"
char signature[4]; // == "VESA"
Line 19: Line 20:
v86_bios(0x10, {ax:0x4f00, es:SEG(vib), di:OFF(vib)},&out);
v86_bios(0x10, {ax:0x4f00, es:SEG(vib), di:OFF(vib)},&out);
if (out.ax!=0x004f) die("something wrong with VBE get info");
if (out.ax!=0x004f) die("something wrong with VBE get info");
</verbatim>
</pre>


;INT 0x10, AX=0x4F01
;__INT 0x10, AX=0x4F01__: Get Mode Info. Call this for each member of the mode array to find out the details of that mode.
: Get Mode Info. Call this for each member of the mode array to find out the details of that mode.


<pre>
<verbatim>


struct vbeModeInfo {
struct vbeModeInfo {
Line 49: Line 51:
short reserved2;
short reserved2;
};
};
</verbatim>
</pre>


;__INT 0x10, AX=0x4F02__: Set Video Mode. Call this with the mode number you decide to use.
;__INT 0x10, AX=0x4F02__: Set Video Mode. Call this with the mode number you decide to use.


!! Will it work with Bochs ?
== Will it work with Bochs ?==


For VBE to work in Bochs you need the "VGABIOS-lgpl" BIOS and have a version of Bochs that was compiled with the "--enable-vbe" option... See [Vesa Information in Bochs| Forum:6311] thread for more info
For VBE to work in Bochs you need the "VGABIOS-lgpl" BIOS and have a version of Bochs that was compiled with the "--enable-vbe" option... See [Vesa Information in Bochs| Forum:6311] thread for more info



!! How to pick the mode i wish ?
==How to pick the mode i wish ?==


Here's a sample code, assuming you have a VirtualMonitor already ... Basically, you will scan the 'modes list' referenced by the vbeInfoBlock.videomodes[] and then call 'get mode info' for each mode. You can then compare width, height and colordepth of each mode with the desired one.
Here's a sample code, assuming you have a VirtualMonitor already ... Basically, you will scan the 'modes list' referenced by the vbeInfoBlock.videomodes[] and then call 'get mode info' for each mode. You can then compare width, height and colordepth of each mode with the desired one.


<pre>
<verbatim>


UInt16 findMode(int x, int y, int d)
UInt16 findMode(int x, int y, int d)
Line 106: Line 109:
return best;
return best;
}
}
</verbatim>
</pre>

----
==See Also==
===Threads===
*[VESA, higher modes|Forum:6379] - Initial Thread, reply by Dreamsmith (aka DaidalosGuy)


[[Category:Video]]
Initial Thread: [VESA, higher modes|Forum:6379], reply by Dreamsmith (aka DaidalosGuy)

Revision as of 18:28, 5 April 2007

Template:Convert

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 your OS, you can have a function that you call with a desired width, height, and depth, and it returns the video mode number for it (or the closest match). Then, 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.
struct vbeControllerInfo {
   char signature[4];             // == "VESA"
   short version;                 // == 0x0300 for VBE 3.0
   short oemString[2];            // isa vbeFarPtr
   unsigned char capabilities[4];
   short videomodes[2];           // isa vbeFarPtr
   short totalMemory;             // as # of 64KB blocks
};

vbeInfoBlock *vib = dos_alloc(512);
v86_bios(0x10, {ax:0x4f00, es:SEG(vib), di:OFF(vib)},&out);
if (out.ax!=0x004f) die("something wrong with VBE get info");
INT 0x10, AX=0x4F01
Get Mode Info. Call this for each member of the mode array to find out the details of that mode.

struct vbeModeInfo {
  word attributes;
  byte winA,winB;
  word granularity;
  word winsize;
  word segmentA, segmentB;
  VBE_FAR(realFctPtr);
  word pitch; // bytes per scanline

  word Xres, Yres;
  byte Wchar, Ychar, planes, bpp, banks;
  byte memory_model, bank_size, image_pages;
  byte reserved0;

  byte red_mask, red_position;
  byte green_mask, green_position;
  byte blue_mask, blue_position;
  byte rsv_mask, rsv_position;
  byte directcolor_attributes;

  dword physbase;  // your LFB address ;)
  dword reserved1;
  short reserved2;
};
__INT 0x10, AX=0x4F02__
Set Video Mode. Call this with the mode number you decide to use.

Will it work with Bochs ?

For VBE to work in Bochs you need the "VGABIOS-lgpl" BIOS and have a version of Bochs that was compiled with the "--enable-vbe" option... See [Vesa Information in Bochs| Forum:6311] thread for more info


How to pick the mode i wish ?

Here's a sample code, assuming you have a VirtualMonitor already ... Basically, you will scan the 'modes list' referenced by the vbeInfoBlock.videomodes[] and then call 'get mode info' for each mode. You can then compare width, height and colordepth of each mode with the desired one.


UInt16 findMode(int x, int y, int d)
{
  struct vbeControllerInfo *ctrl = (ControllerInfo *)0x2000;
  struct vbeModeInfo *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->signature, "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->attributes & 0x90) != 0x90 ) continue;

      // Check if this is a packed pixel or direct color mode
      if ( inf->memory_model != 4 && inf->memory_model != 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->Xres * inf->Yres, x * y);
      depthdiff = (inf->bpp >= d)? inf->bpp - d : (d - inf->bpp) * 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;
}

See Also

Threads

  • [VESA, higher modes|Forum:6379] - Initial Thread, reply by Dreamsmith (aka DaidalosGuy)