VESA without the BIOS
VESA without the BIOS
I want to implement graphics support in my OS. Now I know you can use the BIOS in real mode or the protected mode entry point in protected mode. However, the protected mode entry point is completely optional. Is there any way to enter a VESA graphics mode without even relying on the BIOS. Is there some documentation where I can get more information?
Is this even possible?
Is this even possible?
Re: VESA without the BIOS
VESA is a BIOS specification (at least, I assume you mean VBE, the VESA BIOS extensions). So without BIOS, there's no VESA. And yes, there's plenty of documentation, and Google is your friend.iammisc wrote:Is there any way to enter a VESA graphics mode without even relying on the BIOS. Is there some documentation where I can get more information?
That said, as long as you are using Bochs or Qemu for an emulator, you can use the Bochs VGA BIOS backdoor that the Bochs VBE uses. That's as simple as:
Code: Select all
class CVesaDriver
{
public:
void SetVideoMode(unsigned short width, unsigned short height, unsigned short depth);
void ExitVideoMode();
private:
void WriteCommand(unsigned short index, unsigned short value);
enum VBE_IOPORTS {
VBE_DISPI_IOPORT_INDEX = 0x01CE, VBE_DISPI_IOPORT_DATA = 0x01CF
};
enum VBE_COMMANDS {
VBE_DISPI_INDEX_ID, VBE_DISPI_INDEX_XRES, VBE_DISPI_INDEX_YRES,
VBE_DISPI_INDEX_BPP, VBE_DISPI_INDEX_ENABLE, VBE_DISPI_INDEX_BANK,
VBE_DISPI_INDEX_VIRT_WIDTH, VBE_DISPI_INDEX_VIRT_HEIGHT,
VBE_DISPI_INDEX_X_OFFSET, VBE_DISPI_INDEX_Y_OFFSET
};
enum VBE_FLAGS {
VBE_DISPI_DISABLED, VBE_DISPI_ENABLED, VBE_DISPI_GETCAPS,
VBE_DISPI_8BIT_DAC = 0x20, VBE_DISPI_LFB_ENABLED = 0x40, VBE_DISPI_NOCLEARMEM = 0x80
};
} VesaDriver;
void CVesaDriver::SetVideoMode(unsigned short width, unsigned short height, unsigned short depth)
{
WriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
WriteCommand(VBE_DISPI_INDEX_XRES, width);
WriteCommand(VBE_DISPI_INDEX_YRES, height);
WriteCommand(VBE_DISPI_INDEX_BPP, depth);
WriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED );
}
void CVesaDriver::ExitVideoMode()
{
this->WriteCommand(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
}
void CVesaDriver::WriteCommand(unsigned short index, unsigned short value)
{
WriteIoWord(VBE_DISPI_IOPORT_INDEX, index);
WriteIoWord(VBE_DISPI_IOPORT_DATA, value);
}
JAL
Jal, can i ask where you got the docs to write that code?
i saw it, ported it and found that it seemed to half work, and was looking for some docs to try and get it up and running. i failed to find any however.
for me the code set the x dimension to 256 and set depth to 32bpp (no matter what i set as the values) and the rest of the commands it gave a warning as unknown commands. i think im using the most up to date video bios to (the VBE one, not cirrus).
i saw it, ported it and found that it seemed to half work, and was looking for some docs to try and get it up and running. i failed to find any however.
for me the code set the x dimension to 256 and set depth to 32bpp (no matter what i set as the values) and the rest of the commands it gave a warning as unknown commands. i think im using the most up to date video bios to (the VBE one, not cirrus).
From another thread in this forum. Googling for e.g. VBE_DISP_IOPORT_INDEX, you'll find e.g. this (the Bochs VBE sources), but also this, which is the closest thing to a description I could find.lukem_95 wrote:Jal, can i ask where you got the docs to write that code?
I think you misported something then, it should work rather straightforward.for me the code set the x dimension to 256 and set depth to 32bpp (no matter what i set as the values) and the rest of the commands it gave a warning as unknown commands. i think im using the most up to date video bios to (the VBE one, not cirrus).
JAL
i can't see how i misported it though, unless (god knows how) my outw() code is incorrect (just to check )
it seems to half work, and then just die :S
Code: Select all
void outw(u16int port, u8int value)
{
__asm__ __volatile__ ( "outw %w0, %1" : : "a" (value), "id" (port) );
}
Half work is rightlukem_95 wrote:i can't see how i misported it though, unless (god knows how) my outw() code is incorrect (just to check )
it seems to half work, and then just die :SCode: Select all
void outw(u16int port, u8int value) { __asm__ __volatile__ ( "outw %w0, %1" : : "a" (value), "id" (port) ); }
value should be a u16int, currently it's cutting off the high 8 bits
Hi,
Instead I make my boot loader/s set a "default" video mode during boot (based on some boot variables). If the user wants to change video modes they need to change the boot variables and then reboot the computer (or, get a "native" video driver for the OS).
This method is easier (for me) to implement and leads to a better end product in the long term (but it's a bit crappy in the "short" term, when there aren't any native video drivers).
Cheers,
Brendan
I don't like vm86 either. Not using vm86 mode means I can treat segment registers as constants and never save/load them (which can be expensive due to protection checks).iammisc wrote:I guess I'll just settle for the vm86 option although IMO it's kinda an ugly hack.
Instead I make my boot loader/s set a "default" video mode during boot (based on some boot variables). If the user wants to change video modes they need to change the boot variables and then reboot the computer (or, get a "native" video driver for the OS).
This method is easier (for me) to implement and leads to a better end product in the long term (but it's a bit crappy in the "short" term, when there aren't any native video drivers).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
But what if some userapp is naughty and modifies one? (To a legal value -- otherwise it would GPF, of course.) You can't allow that to propogate into other userapps, can you? I thought I should force the segment registers back to default on each task switch, just as a precaution.Brendan wrote: Not using vm86 mode means I can treat segment registers as constants and never save/load them (which can be expensive due to protection checks).