VESA Video Modes: Difference between revisions

m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(6 intermediate revisions by 4 users not shown)
Line 1:
Under legacy BIOS you(and canCSM-capable access the video card functions using the standardized VESA/VBE functions. On modernUEFI systems with UEFI (in lack oflegacy BIOS mode), you'll have to use [[GOP]] (Graphics Output Protocol) tocan access the video card infunctions ausing the standardized way. As of 2020 VESA/VBE is considered obsoletefunctions.
 
In UEFI mode, instead, one uses the [[GOP]] (Graphics Output Protocol) to access the video card in a standardized way.
 
== VESA Functions ==
You'll want to look in the VESA VBE docs for these functions:
Line 6 ⟶ 9:
;INT 0x10, AX=0x4F00
: Get Controller Info. This is the one that returns the array of all supported video modes.
<sourcesyntaxhighlight lang="c">
struct VbeInfoBlock {
char VbeSignature[4]; // == "VESA"
uint16_t VbeVersion; // == 0x0300 for VBE 3.0
uint16_t OemStringPtr[2]; // isa vbeFarPtr
uint8_t Capabilities[4];
uint16_t VideoModePtr[2]; // isa vbeFarPtr
uint16_t TotalMemory; // as # of 64KB blocks
uint8_t Reserved[492];
} __attribute__((packed));
 
Line 19 ⟶ 23:
v86_bios(0x10, {ax:0x4f00, es:SEG(vib), di:OFF(vib)}, &out);
if (out.ax!=0x004f) die("Something wrong with VBE get info");
</syntaxhighlight>
</source>
 
In assembly(nasm):
;INT 0x10, AX=0x4F01, CX=mode, ES+DI=256 byte buffer
<syntaxhighlight lang="asm">
struc VesaInfoBlock ; VesaInfoBlock_size = 512 bytes
.Signature resb 4 ; must be 'VESA'
.Version resw 1
.OEMNamePtr resd 1
.Capabilities resd 1
 
.VideoModesOffset resw 1
.VideoModesSegment resw 1
 
.CountOf64KBlocks resw 1
.OEMSoftwareRevision resw 1
.OEMVendorNamePtr resd 1
.OEMProductNamePtr resd 1
.OEMProductRevisionPtr resd 1
.Reserved resb 222
.OEMData resb 256
endstruc
 
Main:
push ds
pop es
mov di, VesaInfoBlockBuffer
call get_vesa_info
jmp $
 
; in:
; es:di - 512-byte buffer
; out:
; cf - set on error
get_vesa_info:
clc
mov ax, 0x4f00
int 0x10
cmp ax, 0x004f
jne .failed
ret
.failed:
stc
ret
 
ALIGN(4)
 
VesaInfoBlockBuffer: istruc VesaInfoBlock
at VesaInfoBlock.Signature, db "VESA"
times 508 db 0
iend
</syntaxhighlight>
 
'''INT 0x10, AX=0x4F01, CX=mode, ES:DI=256 byte buffer'''
: Get Mode Info. Call this for each member of the mode array to find out the details of that mode. The 256 byte buffer will be filled by the mode info block.
 
<sourcesyntaxhighlight lang="c">
struct vbe_mode_info_structure {
uint16uint16_t attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer.
uint8uint8_t window_a; // deprecated
uint8uint8_t window_b; // deprecated
uint16uint16_t granularity; // deprecated; used while calculating bank numbers
uint16uint16_t window_size;
uint16uint16_t segment_a;
uint16uint16_t segment_b;
uint32uint32_t win_func_ptr; // deprecated; used to switch banks from protected mode without returning to real mode
uint16uint16_t pitch; // number of bytes per horizontal line
uint16uint16_t width; // width in pixels
uint16uint16_t height; // height in pixels
uint8uint8_t w_char; // unused...
uint8uint8_t y_char; // ...
uint8uint8_t planes;
uint8uint8_t bpp; // bits per pixel in this mode
uint8uint8_t banks; // deprecated; total number of banks in this mode
uint8uint8_t memory_model;
uint8uint8_t bank_size; // deprecated; size of a bank, almost always 64 KB but may be 16 KB...
uint8uint8_t image_pages;
uint8uint8_t reserved0;
 
uint8uint8_t red_mask;
uint8uint8_t red_position;
uint8uint8_t green_mask;
uint8uint8_t green_position;
uint8uint8_t blue_mask;
uint8uint8_t blue_position;
uint8uint8_t reserved_mask;
uint8uint8_t reserved_position;
uint8uint8_t direct_color_attributes;
 
uint32uint32_t framebuffer; // physical address of the linear frame buffer; write here to draw to the screen
uint32uint32_t off_screen_mem_off;
uint16uint16_t off_screen_mem_size; // size of memory in the framebuffer but not being displayed on the screen
uint8uint8_t reserved1[206];
} __attribute__ ((packed));
</syntaxhighlight>
</source>
 
In assembly(nasm):
<syntaxhighlight lang="asm">
struc VesaModeInfoBlock ; VesaModeInfoBlock_size = 256 bytes
.ModeAttributes resw 1
.FirstWindowAttributes resb 1
.SecondWindowAttributes resb 1
.WindowGranularity resw 1 ; in KB
.WindowSize resw 1 ; in KB
.FirstWindowSegment resw 1 ; 0 if not supported
.SecondWindowSegment resw 1 ; 0 if not supported
.WindowFunctionPtr resd 1
.BytesPerScanLine resw 1
 
; Added in Revision 1.2
.Width resw 1 ; in pixels(graphics)/columns(text)
.Height resw 1 ; in pixels(graphics)/columns(text)
.CharWidth resb 1 ; in pixels
.CharHeight resb 1 ; in pixels
.PlanesCount resb 1
.BitsPerPixel resb 1
.BanksCount resb 1
.MemoryModel resb 1 ; http://www.ctyme.com/intr/rb-0274.htm#Table82
.BankSize resb 1 ; in KB
.ImagePagesCount resb 1 ; count - 1
.Reserved1 resb 1 ; equals 0 in Revision 1.0-2.0, 1 in 3.0
 
.RedMaskSize resb 1
.RedFieldPosition resb 1
.GreenMaskSize resb 1
.GreenFieldPosition resb 1
.BlueMaskSize resb 1
.BlueFieldPosition resb 1
.ReservedMaskSize resb 1
.ReservedMaskPosition resb 1
.DirectColorModeInfo resb 1
 
; Added in Revision 2.0
.LFBAddress resd 1
.OffscreenMemoryOffset resd 1
.OffscreenMemorySize resw 1 ; in KB
.Reserved2 resb 206 ; available in Revision 3.0, but useless for now
endstruc
 
Main:
; after getting VesaInfoBlock:
push word [VesaInfoBlockBuffer + VesaInfoBlock.VideoModesSegment]
pop es
mov di, VesaModeInfoBlockBuffer
mov bx, [VesaInfoBlockBuffer + VesaInfoBlock.VideoModesOffset] ; get video modes list address
mov cx, [bx] ; get first video mode number
cmp cx, 0xffff ; vesa modes list empty
je .NoModes
call get_vesa_mode_info
.NoModes:
jmp $
 
 
; in:
; cx - VESA mode number
; es:di - 256-byte buffer
; out:
; cf - set on error
get_vesa_mode_info:
clc
mov ax, 0x4f01
int 0x10
cmp ax, 0x004f
jne .failed
ret
.failed:
stc
ret
 
ALIGN(4)
 
VesaModeInfoBlockBuffer: istruc VesaModeInfoBlock
times VesaModeInfoBlock_size db 0
iend
</syntaxhighlight>
 
'''INT 0x10, AX=0x4F02, BX=mode, ES:DI=CRTCInfoBlock'''
Line 79 ⟶ 213:
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.
 
<sourcesyntaxhighlight lang="c">
uint16_t findMode(int x, int y, int d)
{
Line 123 ⟶ 257:
return best;
}
</syntaxhighlight>
</source>
 
== Common Mistakes ==