Page 1 of 1

VESA programming

Posted: Thu Jul 12, 2007 1:14 pm
by salil_bhagurkar
I recently made some code for VESA. I set the mode 0x13c/0x144 which is 1024 x 768 and 32 bits per pixel... My bank changing function is through a bios call (interrupt). I load a bitmap image from the hard disk that is 1024 x 768.

But the drawing is pretty slow. It takes 300 milliseconds to draw the whole image. I figured out that this mode should take 12 bios calls.
My bios calls involve a transition from protected mode to real mode to execute interrupt and then back to protected mode. A normal bios call
takes negligible time and 12 bios calls should'nt take any significant time. So what is making it slow... Is it the RAM? Should i be using the DMA?

Posted: Thu Jul 12, 2007 2:09 pm
by LaurensR1983
Well for what operations exactly are you using the interrupts and on what moments? Are you using a virtual 8086 monitor?

Like if you use interrupts a lot, the entire switching between real and protected mode could take up some time I guess.

(Although I'm pretty new to this, but that seems logical to me)

Posted: Thu Jul 12, 2007 4:17 pm
by Dex
I work it out to 48 times to load.

Re: VESA programming

Posted: Thu Jul 12, 2007 4:54 pm
by pcmattman
salil_bhagurkar wrote:I recently made some code for VESA. I set the mode 0x13c/0x144 which is 1024 x 768 and 32 bits per pixel... My bank changing function is through a bios call (interrupt). I load a bitmap image from the hard disk that is 1024 x 768.

But the drawing is pretty slow. It takes 300 milliseconds to draw the whole image. I figured out that this mode should take 12 bios calls.
My bios calls involve a transition from protected mode to real mode to execute interrupt and then back to protected mode. A normal bios call
takes negligible time and 12 bios calls should'nt take any significant time. So what is making it slow... Is it the RAM? Should i be using the DMA?
Don't use bank switching, an LFB is much faster in comparison.

Posted: Sun Jul 15, 2007 10:49 am
by salil_bhagurkar
Well i use physical mode switching to issue bios interrupts. I figured out that issuing 48 bios calls doesn't take any time(negligible).
I changed the 'memcpy' code to an assembly equivalent and the speed changed considerably...
Hello pcmattman could you tell me how do you program an LFB?

Posted: Sun Jul 15, 2007 11:29 am
by Dex
First your card need to suport LFB (most vesa2 do ), Then you load the modeinfo
Example (from realmode)

Code: Select all

	mov   ax,4f01h					     ; set vesa screen mode information
	mov   di,Mode_Info
	mov   cx,0x4112 				     ; mode number
	and   cx,0xfff
	int   10h 
Into a date structure like this:

Code: Select all

;====================================================;
; VESA MODE INFORMATION                              ;
;====================================================;
Mode_Info:
ModeInfo_ModeAttributes		rw	1
ModeInfo_WinAAttributes		rb	1
ModeInfo_WinBAttributes		rb	1
ModeInfo_WinGranularity		rw	1
ModeInfo_WinSize		rw	1
ModeInfo_WinASegment		rw	1
ModeInfo_WinBSegment		rw	1
ModeInfo_WinFuncPtr		rd	1
ModeInfo_BytesPerScanLine	rw	1
ModeInfo_XResolution		rw	1
ModeInfo_YResolution		rw	1
ModeInfo_XCharSize		rb	1
ModeInfo_YCharSize		rb	1
ModeInfo_NumberOfPlanes		rb	1
ModeInfo_BitsPerPixel		rb	1
ModeInfo_NumberOfBanks		rb	1
ModeInfo_MemoryModel		rb	1
ModeInfo_BankSize		rb	1
ModeInfo_NumberOfImagePages	rb	1
ModeInfo_Reserved_page		rb	1
ModeInfo_RedMaskSize		rb	1
ModeInfo_RedMaskPos		rb	1
ModeInfo_GreenMaskSize		rb	1
ModeInfo_GreenMaskPos		rb	1
ModeInfo_BlueMaskSize		rb	1
ModeInfo_BlueMaskPos		rb	1
ModeInfo_ReservedMaskSize	rb	1
ModeInfo_ReservedMaskPos	rb	1
ModeInfo_DirectColorModeInfo	rb	1
; VBE 2.0 extensions
ModeInfo_PhysBasePtr		rd	1
ModeInfo_OffScreenMemOffset	rd	1
ModeInfo_OffScreenMemSize	rw	1
; VBE 3.0 extensions
ModeInfo_LinBytesPerScanLine	rw	1
ModeInfo_BnkNumberOfPages	rb	1
ModeInfo_LinNumberOfPages	rb	1
ModeInfo_LinRedMaskSize		rb	1
ModeInfo_LinRedFieldPos		rb	1
ModeInfo_LinGreenMaskSize	rb	1
ModeInfo_LinGreenFieldPos	rb	1
ModeInfo_LinBlueMaskSize	rb	1
ModeInfo_LinBlueFieldPos	rb	1
ModeInfo_LinRsvdMaskSize	rb	1
ModeInfo_LinRsvdFieldPos	rb	1
ModeInfo_MaxPixelClock		rd	1
; Reserved
ModeInfo_Reserved		rb	190
;====================================================;
; VESA MODE INFORMATION END                          ;
;====================================================;
Once this this is filled, you can use the address in "ModeInfo_PhysBasePtr" to write to screen as if you were using mode 13h in Dos
eg: (from pmode )

Code: Select all

mov   edi,[ModeInfo_PhysBasePtr]
mov   dword[es:edi], 0x00cccccc  ;color
If es is 0 based, then this will put a pixel in the top left hand corner, in PM.
Note, this is without paging enabled. and note the 4 in the mode number.
Also some cards use 32 bpp and some 24bit so you will need to test this to see "ModeInfo_BitsPerPixel" , The above is without any checks.

Posted: Sun Jul 15, 2007 11:53 am
by salil_bhagurkar
I found that Bochs supports 0x144 (1024 x 768 32 bpp LFB)
I switched to mode: 0x4144 (LFB bit set)
Switching is successful.
I got a screen pointer of 0xe0000000
When i write to the pointer i get nothing on screen...

Code: Select all

int init_vbe()
{
	u32 *i,x=0;
	availableModes();
	init_mode(0x4000+0x144)
	i=ModeInfoBlock->phys_base;
	while(++x<1024*768*4)	{
		*i++=0x00cccccc;
	}
	while(1);
	return NULL;
}

Posted: Sun Jul 15, 2007 12:19 pm
by salil_bhagurkar
Wait... thats not the problem... I am getting a GPF on accessing 0xe0000000... Whats the problem?

Heres my GDT:

Code: Select all

gdt:

gdt_null:
        dd 0
        dd 0

SYS_CODE_SEL	equ	$-gdt
gdt_code:
        dw 0FFFFh
        dw 0
        db 0
        db 0x9A
        db 0xFC
        db 0

SYS_DATA_SEL	equ	$-gdt
gdt_data:
        dw 0FFFFh
        dw 0
        db 0
        db 0x92
        db 0xFC
        db 0

REAL_CODE_SEL	equ	$-gdt
gdt3:	dw 0xFFFF
	dw 0
	db 0
	db 0x9A
	db 0
	db 0

Posted: Sun Jul 15, 2007 4:48 pm
by Dex
I do not use emulator, but on a real PC, for that size you would need to enable A20.
Is your enabled ?. On real PC you would just get the bottom half black, but emulator may give GPF ?

Posted: Mon Jul 16, 2007 7:56 am
by JAAman
Dex wrote: I do not use emulator, but on a real PC, for that size you would need to enable A20.
Is your enabled ?. On real PC you would just get the bottom half black, but emulator may give GPF ?
no, you wont get a GPF for that (the point to an emulator is that it works exactly like a real computer)
iirc bochs defaults to a20 already enabled on startup


as to your problem, a quick glance at 3.4.5 tells me maybe your nybbles are backwards -- shouldnt 0xFC be 0xCF?

bits 16-19, 2nd DD (bits 0-3 of byte 8): segment limit
bits 20 avl
bits 21 reserved in PMode (L in LMode) -- should be 0
bits 22 D/B -- should be 1
bits 23 G -- should be 1

FC = 1111 1100

bit 0-3 (16-19 of DD): upper portion of segment limit: 1100 -- shouldnt this be 1111 (F)? with 1100, 0xE000 0000 is beyond segment limit

bit 5(21): reserved -- should be 0 -- its not


edit:
your code selector has the same problem

Posted: Mon Jul 16, 2007 8:14 am
by Dex
JAAman wrote: no, you wont get a GPF for that (the point to an emulator is that it works exactly like a real computer)
iirc bochs defaults to a20 already enabled on startup
But if it does "defaults to a20 already enabled on startup" than it does not " works exactly like a real computer" as no real PC does that ;)

Posted: Mon Jul 16, 2007 8:26 am
by JAAman
actually, many real PCs do

many BIOSs (both real and emulated) do default to enabled

actually it is enabled on all 386+ CPUs at startup (if it wasnt, the CPU wouldnt be able to read the BIOS code), some BIOSs (most older ones) disable it, but many newer ones leave it enabled (they figure the OS is just going to enable it again, why disable it -- even DOS normally enables it immediately, and its unlikely you will ever find any software that cannot handle it being enabled

Posted: Mon Jul 16, 2007 11:06 am
by salil_bhagurkar
Yes thats right... I figured it out too... I changed the GDT and the modes are working fine... But still I don't get complete speed...
I guess that is the maximum RAM speed that my PC can give...
If i use DMA for LFB would i get better speed?

Are there any ways i could change the LFB address, prepare the image and change it back to make the speed invisibe to the user?

How do operating systems using VESA manage to get much better speeds? (I have puppy linux... it has great graphics speed in the same VESA modes....)

Posted: Mon Jul 16, 2007 1:51 pm
by Dex
You will find all the info you need here
VESA BIOS EXTENSION (VBE) Core Functions Standard
And believe it or not, it's free this time!

@JAAman, Well the A20 is not enabled by default on any of my PC's. :wink: