VESA Video Modes: Difference between revisions
[unchecked revision] | [unchecked revision] |
Content deleted Content added
m Bot: Replace deprecated source tag with syntaxhighlight |
|||
(5 intermediate revisions by 4 users not shown) | |||
Line 1:
Under legacy BIOS
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.
<
struct VbeInfoBlock {
char VbeSignature[4];
uint16_t VbeVersion;
uint16_t OemStringPtr[2];
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>
In assembly(nasm):
<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.
<
struct vbe_mode_info_structure {
} __attribute__ ((packed));
</syntaxhighlight>
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.
<
uint16_t findMode(int x, int y, int d)
{
Line 123 ⟶ 257:
return best;
}
</syntaxhighlight>
== Common Mistakes ==
|