VBE 2.0+ Set Display Start for Page Flipping

Started by
8 comments, last by Thoover 8 years, 8 months ago

Ok, hello again GameDEV - It's been a few years since I was last here.

Anyways,

I am in middle of writing a VBE driver for my kernel, currently I have a double buffer which does stop the flashing, but even at low resolutions I am unable to copy the entire buffer into active video memory within the refresh time. (at 640X480X8 it takes 2.5 refresh cycles which causes tearing)

In Real-Mode I have set the display resolution, enabled LFB, and grabbed the PMode Interface Table - and passed all information to the Kernel.

The issue that I have been facing is when trying to use the SetDisplayStart, no matter my input on DX/CX I end up with the same results.

Currently my video memory has at offset 0 color 0x83 640*480 times and just after this we have color 0x28 640*480 times.

The Current VBE Mode info contains:

BytesPerLine = 0x280 (640)

LinBytesPerScanLine = 0x280

I am calling SetDisplayStart the following way (Intel ASM):


FlipPage:
pusha
 
mov eax, DWORD [SecondBuffer]
test eax, eax
jz .NotSecond
 
mov dx, 0
mov cx, 0
mov DWORD [SecondBuffer], 0
jmp .flipme
 
.NotSecond:
mov dx, WORD [Height]
mov cx, 0
mov DWORD [SecondBuffer], 1
.flipme:
 
;Now Lets Page Flip
xor bx, bx
mov ax, 0x4F07
xchg bx, bx
call DWORD [VBE_FUNCTION7]
test ah, ah
jnz ERROR
cmp al, 0x4F
jne ERROR
 
popa
ret

And no matter how DX/CX is filled the result is always (or Y out of range panic from Bochs):

[attachment=28809:2015-08-20-014835_642x555_scrot.png]

and yes even with DX and CX = 0 this is the result.

So I'm hoping beyond all hope someone here has done this before (as the internet seems to have no reference other than what is in the VBE Specifications...)

I know we are going back to the mid/early 90's here, but I cannot write a driver per card (most have no Info) so I'm stuck with VBE support and software rendering.

Advertisement

I recall there being bitplanes in some modes, not a nice contiguous buffer, and the pattern looks like that. Sometimes you needed to write to some io ports to choose one. The fun part was activating all planes and clearing memory much faster. You might want to find more information on how the video memory corresponds to pixels in that mode?

Or if you have too much time to waste: try different patterns, like setting 4x the amount of memory to 1 color, then drawing exactly one line, then try drawing every fourth byte of the line and moving the pattern 1 byte or line or 1k bytes, or try changing single pixels at many positions, to find out where it ends up on screen?

Though you may be better off getting text mode to run first or one of the standard VGA modes like 640x480x16colors or 320x200x256colors, not one of the more complicated vendor-dependent SVGA modes.

I recall there being bitplanes in some modes, not a nice contiguous buffer, and the pattern looks like that. Sometimes you needed to write to some io ports to choose one. The fun part was activating all planes and clearing memory much faster. You might want to find more information on how the video memory corresponds to pixels in that mode?

Or if you have too much time to waste: try different patterns, like setting 4x the amount of memory to 1 color, then drawing exactly one line, then try drawing every fourth byte of the line and moving the pattern 1 byte or line or 1k bytes, or try changing single pixels at many positions, to find out where it ends up on screen?

Though you may be better off getting text mode to run first or one of the standard VGA modes like 640x480x16colors or 320x200x256colors, not one of the more complicated vendor-dependent SVGA modes.

I have no problem with LFB (in fact in all my systems it is purely flat) The problem comes only when trying to page flip, I can draw all day onto the screen perfectly.

In fact I just enabled the SSE and started moving 128 Bytes of memory at a time instead of 4, which made my double buffer fast enough to work (even at 1024x768x32bpp), though I would still like a buffer in video ram to switch to.

Have you tried doing a GetDisplayStart first, then adding (or subtracting) your screen height to the returned DX, and then passing back the CX and DX values to SetDisplayStart?

Also, take a look at the "Protected Mode considerations" chapter of the VBE dcoument. It seems to say something specific about function 07h. In PM, the CX and DX values are actually a memory address, not the scan line&pixel position as in RM.

I miss VESA. :)

Have you tried doing a GetDisplayStart first, then adding (or subtracting) your screen height to the returned DX, and then passing back the CX and DX values to SetDisplayStart?

Also, take a look at the "Protected Mode considerations" chapter of the VBE dcoument. It seems to say something specific about function 07h. In PM, the CX and DX values are actually a memory address, not the scan line&pixel position as in RM.

I miss VESA. smile.png

GetDisplayStart returns CX = DX = 0

Also only the sub functions of Function 7 that were added in VBE 3.0 use memory locations, the older ones still use legacy values (If I understand the Spec sheet correctly)

I don't know why I cannot copy out the PDF so I'll tell you its page labled 51 (59 in the PDF), second full paragraph - http://www.petesqbsite.com/sections/tutorials/tuts/vbe3.pdf

Years since i played around with VBE. I think tonemgub is on to something. Looks like for 32-bit protected mode one should set the start address of the display in CX and the DX registers. Look at the gray register box for the functions for Input (32 bit). 16-bit still use the direct x,y positions.

"For the VBE 2.0 32-bit protected mode version, the value passed in DX:CX is the 32 bit offset in
display memory, aligned to a plane boundary. For planar modes this means the value is the byte
offset in memory, but in 8+ bits per pixel modes this is the offset from the start of memory divided
by 4."

"If a value that is out of range is programmed, unpredictable results will occur."

@spinningcubes | Blog: Spinningcubes.com | Gamedev notes: GameDev Pensieve | Spinningcubes on Youtube

Well, I'll try it out soon, I'm stuck somewhere else for now, but IIRC I have tried memory offsets with the same result.

But again I'll test it out in a few days to a week once IPC is fully functioning.

Thanks for your replies, I'll post updates.

P.S. I have also been told that the issue may be in Bochs' VBE, so I'll try other "platforms" - lack of better term - including Physical HW


Also only the sub functions of Function 7 that were added in VBE 3.0 use memory locations, the older ones still use legacy values (If I understand the Spec sheet correctly)

I found that info about 7h using memory addresses here: http://www.phatcode.net/res/221/files/vbe20.pdf . Sorry, I thought you were using the same document. Heck, I didn't even know there was a 3.0 version. smile.png All PM BIOS VESA functions use memory addresses, IIRC.


Function 07h protected mode calls have a different format.
AX = 4F07h
BL = 00h Set Display CRTC Start
   = 80h Set Display CRTC Start during Vertical Retrace
CX = Bits 0-15 of display start address
DX = Bits 16-31 of display start address

I don't know the reason why GetDisplayStart is returning 0 for you. If you change it to something else with SetDisplayStart, does it return the new values?

Have you also tried posting this on the osdev forums at osdev.org?

Have you also tried posting this on the osdev forums at osdev.org?

Yep, http://forum.osdev.org/viewtopic.php?f=13&t=29536 - the third post by me is the same (or nearly) as the first post here.


I don't know the reason why GetDisplayStart is returning 0 for you. If you change it to something else with SetDisplayStart, does it return the new values?

Yes it returns the new value (if not way out of memory range - Bochs panics on Y position out of range)

This topic is closed to new replies.

Advertisement