Page 1 of 4

VESA without the BIOS

Posted: Wed Feb 20, 2008 9:31 pm
by iammisc
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?

Posted: Thu Feb 21, 2008 1:26 am
by Combuster
There's still the v8086 option.

But if you really do *not* want to rely on the bios, you'll have to write your own drivers. For each card.

Posted: Thu Feb 21, 2008 2:49 am
by zaleschiemilgabriel
Here we go again... :) :lol:

Posted: Thu Feb 21, 2008 7:13 am
by jal
zaleschiemilgabriel wrote:Here we go again... :) :lol:
Says he who asked almost that exact same question. Your remark is neither funny nor helpful.


JAL

Re: VESA without the BIOS

Posted: Thu Feb 21, 2008 7:21 am
by jal
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?
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.

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

Posted: Thu Feb 21, 2008 10:21 pm
by iammisc
I guess I'll just settle for the vm86 option although IMO it's kinda an ugly hack.

Posted: Sun Mar 02, 2008 10:53 am
by lukem95
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).

Posted: Tue Mar 04, 2008 7:25 am
by jal
lukem_95 wrote:Jal, can i ask where you got the docs to write that code?
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.
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 think you misported something then, it should work rather straightforward.


JAL

Posted: Tue Mar 04, 2008 2:33 pm
by lukem95
i can't see how i misported it though, unless (god knows how) my outw() code is incorrect (just to check ;))

Code: Select all

void outw(u16int port, u8int value)
{
    __asm__ __volatile__ ( "outw %w0, %1" : : "a" (value), "id" (port) );
}
it seems to half work, and then just die :S

Posted: Tue Mar 04, 2008 3:30 pm
by froggey
lukem_95 wrote:i can't see how i misported it though, unless (god knows how) my outw() code is incorrect (just to check ;))

Code: Select all

void outw(u16int port, u8int value)
{
    __asm__ __volatile__ ( "outw %w0, %1" : : "a" (value), "id" (port) );
}
it seems to half work, and then just die :S
Half work is right ;)
value should be a u16int, currently it's cutting off the high 8 bits

Posted: Tue Mar 04, 2008 4:07 pm
by lukem95
oh my word.

how on earth did i manage to overlook that one :|

Posted: Wed Mar 05, 2008 12:18 am
by Brendan
Hi,
iammisc wrote:I guess I'll just settle for the vm86 option although IMO it's kinda an ugly hack.
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).

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

Posted: Wed Mar 05, 2008 1:44 am
by jal
lukem_95 wrote:how on earth did i manage to overlook that one :|
That would kind of explain why the resolution never got beyond 255 :))).


JAL

Posted: Wed Mar 05, 2008 6:31 am
by bewing
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).
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.

Posted: Wed Mar 05, 2008 6:44 am
by jal
Ok, upon popular demand, I added a Wiki page describing the Bochs VBE hardware interface.


JAL