Page 2 of 2

Re: How to use VESA linear frame buffer

Posted: Wed Jan 28, 2015 1:33 am
by freecrac
Hello,
i never used Bochs or Qemu, but starting with VBE version 2.0, VESA will no longer define new VESA mode
numbers and it will no longer be mandatory to support these old mode numbers.
And so we have to get the modenumber from the modetable that comes within the VBE bios.

Code: Select all

     RES_X =  1920           ; horizontal resolution
     RES_Y =  1200           ; vertical resolution
;----------------------------
.DATA
VBEINFO   DB 512 dup (0)     ; Buffer for VBE 4F00 Vbe Info Block
MODEINFO  DB 256 dup (0)     ; Buffer for VBE 4F01 Mode Info Block
;----------------------------
.code
          mov      ax, @DATA           ; segment address of the data segment
          mov      ds, ax
          mov      es, ax

          mov      di, OFFSET VBEINFO  ; get the Vbe Info Block
	       mov      ax, 4F00h           ; es:di 512 byte
	       int    10h                   : Function 00h - Return VBE Controller Information
	       cmp      ax, 4Fh
	       jnz ERROR       ; need instructions for output an Error message + terminate program

	       mov      dl, [di+5]          ; major version number of VBE
	       cmp      dl, 2               ; version 2?
	       jb  ERROR

; Get the VBE modenumber from the VBE modetable

          lfs      si, [di+0Eh]        ; VbeFarPtr to VideoModeList
GETMode:  mov      cx, fs:[si]         ; get the mode number
          add      si, 2
          cmp      cx, 0FFFFh          ; end of modelist ?
          jz  ERROR

          add      cx, 4000h           ; mode number + linear acess
          mov      di, OFFSET MODEINFO
          mov      ax, 4F01h           ; get the Mode Info Block
          int    10h                   ; Function 01h - Return VBE Mode Information
          cmp      ax, 4Fh
          jnz ERROR

; Now we have to find the mode number wich operate with our desired resolution

          cmp     WORD PTR[di+12h], RES_X ; horizontal resolution in pixels
          jnz GETMode
          cmp     WORD PTR[di+14h], RES_Y ; vertical resolution in pixels
          jnz GETMode
          cmp     BYTE PTR[di+19h], 8     ; bits per pixel
          jnz GETMode
          test    WORD PTR[di], 80h       ; Linear frame buffer mode
          jz  GETMode
          cmp     DWORD PTR[di+28h], 0    ; physical address for flat memory frame buffer
          jz  GETMode

; Set the VBE mode

          mov      ax, 4F02h
          mov      bx, cx               ; modenumber             
          int    10h
          cmp      ax, 4Fh
          jnz ERROR
And for to calculate an address of a pixel, or the size of the screen, we have to use the LinBytesPerScanLine(MODEINFO+32h), because the scanline can be longer as the horizontal resolution, with a part outside of the visible view.

More details can be found inside of the public document "vbe3.pdf" from vesa.org (need register/login).
Some other usefull documents from vesa.org are: "EEDIDguideV1.pdf" and "EEDIDverifGuideRa.pdf".

Dirk