Page 1 of 1
VBE problems with linear framebuffer
Posted: Sun Aug 21, 2016 9:03 am
by max
Hey guys,
when selecting the right video mode I check that:
- Mode attributes bit 0 (0x1) is set, so it's supported by hardware
- Mode attributes bit 7 (0x80) is set, so linear framebuffer is supported
- Memory model is 0x6, so direct color model
Then, when setting the mode, I make sure to set the bit 14 (0x4000) to enable a flat framebuffer.
This works in VirtualBox and VMWare, but when running in Parallels Desktop, only the top 20-or-so lines of pixels are displayed on screen. Did I forget to check anything other than that?
Greets
Re: VBE problems with linear framebuffer
Posted: Sun Aug 21, 2016 9:45 am
by Ch4ozz
This is what I do and it works perfectly on Qemu, VMWare, VBox, Bochs and real hardware too:
Code: Select all
uint32_t i;
for(i = 0; i < 0xFFFF; i++)
{
regs.ax = 0x4F01;
regs.cx = i | 0x4000;
regs.es = 0;
regs.di = ((uint32_t)modeInfo & 0x0000FFFF);
INT32(0x10, ®s);
if (regs.ax != 0x004F || (modeInfo->attributes & 0x91) != 0x91)
continue;
if(modeInfo->bpp != 32)
continue;
if(modeInfo->memory_model != VESA_MODEL_DIRECT)
continue;
//...
}
//...
regs.ax = 0x4F01;
regs.cx = best_res_mode | 0x4000;
regs.es = 0;
regs.di = ((uint32_t)modeInfo & 0x0000FFFF);
INT32(0x10, ®s);
regs.ax = 0x4F02;
regs.bx = best_res_mode | 0x4000;
INT32(0x10, ®s);
if (regs.ax != 0x004F)
goto _VesaFailed;
Dont forget that pixel width can be different (!= 4).
Thats why I filter all bpp's != 32 bit
EDIT: Check this list:
0: mode supported if set
1: optional information available if set
2: BIOS output supported if set
3: set if color, clear if monochrome
4: set if graphics mode, clear if text mode
5: (VBE2) non-VGA mode
6: (VBE2) No bank swiotching supported
7: (VBE2) Linear framebuffer mode supported
Re: VBE problems with linear framebuffer
Posted: Sun Aug 21, 2016 12:17 pm
by max
Hi,
thanks for your help. Why do you set the video mode with command 0x4F01? Shouldn't that be 0x4F02? Setting with 0x4F01 doesn't work at all for me...
I also tried putting the address in CX instead of BX, but still have the same issue :/ My implementation looks like this:
Code: Select all
/**
*
*/
bool loadModeInfo(uint16_t mode, ModeInfoBlock* target) {
g_vm86_registers out;
g_vm86_registers regs;
g_far_pointer modeInfoBlockFp = G_LINEAR_TO_FP((uint32_t ) target);
regs.ax = 0x4F01;
regs.cx = mode;
regs.es = G_FP_SEG(modeInfoBlockFp);
regs.di = G_FP_OFF(modeInfoBlockFp);
g_call_vm86(0x10, ®s, &out);
return (out.ax == 0x4F);
}
/**
*
*/
bool setVideoMode(uint32_t mode, bool flatFrameBuffer) {
g_vm86_registers out;
g_vm86_registers regs;
regs.ax = 0x4F02;
regs.bx = mode;
if (flatFrameBuffer) {
regs.bx |= 0x4000;
}
g_call_vm86(0x10, ®s, &out);
return (out.ax == 0x4F);
}
Greets
Re: VBE problems with linear framebuffer
Posted: Sun Aug 21, 2016 12:36 pm
by Ch4ozz
max wrote:Hi,
thanks for your help. Why do you set the video mode with command 0x4F01? Shouldn't that be 0x4F02? Setting with 0x4F01 doesn't work at all for me...
I also tried putting the address in CX instead of BX, but still have the same issue :/ My implementation looks like this:
Greets
Dont worry, Im also using 0x4F02 to set the video mode, but I crawl all possible modes to find the best one and to avoid memcpying it all the time I just save the mode and query the saved id info again
Edited the post above and added the 4 lines to switch mode too now
Anyways, try this in loadModeInfo:
Not sure if that changed anything when I coded the driver, but Im sure I kept it for a reason
Re: VBE problems with linear framebuffer
Posted: Sun Aug 21, 2016 12:57 pm
by max
Okay I've now found the difference between Parallels Desktop and VirtualBox...
In the mode attribute field, Parallels has bit 5 set for each video mode that is returned. Specification says this about this:
VBE 2.0 specification wrote:Bit D5 is used to indicate if the mode is compatible with the VGA hardware registers and I/O ports. If
this bit is set, then the mode is NOT VGA compatible and no assumptions should be made about the
availability of any VGA registers. If clear, then the standard VGA I/O ports and frame buffer address
defined in WinASegment and/or WinBSegment can be assumed.
There's no mode without bit 5 that I could use instead.. Anyone know if this issue could be related to that? I'd assume that all the VBE stuff should work normally even though not VGA-compatible..
EDIT: hmm I just noticed that, in addition, the lfb address value is returned with zero, even though the set-video call was successful. :/
Re: VBE problems with linear framebuffer
Posted: Sun Aug 21, 2016 3:43 pm
by BrightLight
Ch4ozz: you set bit 14 (0x4000) when calling VBE function 0x4F01. That works on Bochs, QEMU and VirtualBox, but it triple-faults my real laptop. I've done the same mistake long ago and it took me a while to discover this small bug. The numbers you pass to function 0x4F01 shouldn't have any bits set other that the plain mode number, from the array returned by function 0x4F00.
Just saying, in case you're not aware that this breaks compatibility on some HW.
Re: VBE problems with linear framebuffer
Posted: Sun Aug 21, 2016 5:12 pm
by Ch4ozz
omarrx024 wrote:Ch4ozz: you set bit 14 (0x4000) when calling VBE function 0x4F01. That works on Bochs, QEMU and VirtualBox, but it triple-faults my real laptop. I've done the same mistake long ago and it took me a while to discover this small bug. The numbers you pass to function 0x4F01 shouldn't have any bits set other that the plain mode number, from the array returned by function 0x4F00.
Just saying, in case you're not aware that this breaks compatibility on some HW.
Huh okay, thanks though.
It actually works on my tested laptop (Lenovo T400)
Gonna remove it then
max wrote:Okay I've now found the difference between Parallels Desktop and VirtualBox...
In the mode attribute field, Parallels has bit 5 set for each video mode that is returned. Specification says this about this:
VBE 2.0 specification wrote:Bit D5 is used to indicate if the mode is compatible with the VGA hardware registers and I/O ports. If
this bit is set, then the mode is NOT VGA compatible and no assumptions should be made about the
availability of any VGA registers. If clear, then the standard VGA I/O ports and frame buffer address
defined in WinASegment and/or WinBSegment can be assumed.
There's no mode without bit 5 that I could use instead.. Anyone know if this issue could be related to that? I'd assume that all the VBE stuff should work normally even though not VGA-compatible..
EDIT: hmm I just noticed that, in addition, the lfb address value is returned with zero, even though the set-video call was successful. :/
No idea here, sorry
Re: VBE problems with linear framebuffer
Posted: Mon Aug 22, 2016 2:59 am
by Octacone
Take a look at this:
Re: VBE problems with linear framebuffer
Posted: Mon Aug 22, 2016 10:19 am
by Ch4ozz
Got another idea, do you check the VBE version?
If its not VBE 2 or higher you have to use the hardcoded VESA 1 table