Page 1 of 2

VESA without BIOS

Posted: Sun Apr 21, 2019 9:06 am
by iProgramInCpp
Is there a standardized way to implement VESA graphics without the use of BIOS?

VGA 640x480x16 (colors) is way too slow.

Do I really have to write a vm86 thing? Or do I really have to write a driver for every available graphics card?

What can I do?

Re: VESA without BIOS

Posted: Sun Apr 21, 2019 9:27 am
by deleted8917
It is very difficult to use VESA without BIOS interrupts. Even more if you're in long mode.
You have to write a driver, but not for every single card in the world, basic VGA graphics like plotting pixels are standard in a some way, but with higher resolutions it start to become more difficult.
There's a VESA tutorial, but still needing BIOS interrupts to get VESA information.
You should look VGA Resources.
This is something really painful, more if you use GRUB (which enables protected mode for you)
GRUB can also switch to a video mode for you.

(I'm not an expert, so correct me if I'm wrong)

Re: VESA without BIOS

Posted: Sun Apr 21, 2019 10:36 am
by Korona
VBE is a software interface. It is tied to the BIOS.

Mode setting requires GPU-specific drivers (i.e., one driver per GPU brand/generation) for any resolution larger than the ones supported by VGA.

Re: VESA without BIOS

Posted: Sun Apr 21, 2019 12:56 pm
by alexfru
iProgramInCpp wrote:Is there a standardized way to implement VESA graphics without the use of BIOS?
There isn't.
iProgramInCpp wrote:VGA 640x480x16 is way too slow.
You can speed it up by minimizing accesses to the video memory and VGA ports, avoiding redraws of the same pixels and RGB-plane switches. Still, it won't be very fast (my last experiments showed that you could update the entire screen at a rate of about 30 FPS tops). And you don't do any video, transparency/blending/animation effects (including redrawing widgets while dragging a window around the screen).

The worst thing here is that the CPU appears to be blocked while doing VGA, meaning many fewer CPU cycles are left for anything else. It's very much like running a web browser on an old computer with a single core CPU. If only there was... VGA DMA. OTOH, if you boot more cores than one (and most systems have at least two or four these days) and schedule stuff on all of them, it may not feel as slow.

You could also keep one core in real or virtual 8086 mode.
iProgramInCpp wrote:Do I really have to write a vm86 thing?
You don't. You can set up the graphics mode early on, before you switch to protected mode permanently.
iProgramInCpp wrote:Or do I really have to write a driver for every available graphics card?
You obviously can't. 64-bit Windows has a mini PC emulator to run the VESA BIOS code without leaving 64-bit mode. It's not a small or trivial solution/workaround.
iProgramInCpp wrote:What can I do?
Don't paint yourself into a corner. Set the mode while it's still easy to do, that is, before you start the kernel.

Re: VESA without BIOS

Posted: Sun Apr 21, 2019 3:37 pm
by no92
Hi,
alexfru wrote:
iProgramInCpp wrote:Is there a standardized way to implement VESA graphics without the use of BIOS?
There isn't.
Well, there is UEFI's GOP (It is BIOS' successor, but it isn't BIOS. So yes, there is.) Given that nearly every new computer shipped in the past ~5 years has UEFI, it's a good bet for the future.

Cheers, Leo

Re: VESA without BIOS

Posted: Sun Apr 21, 2019 7:15 pm
by bzt
iProgramInCpp wrote:VGA 640x480x16 is way too slow.
It is not. See The Incredible Machine for example.
iProgramInCpp wrote:What can I do?
Be more specific. First, what do you mean by 640x480x16?

- 16 colours? Then no VESA (nor BIOS as a matter of fact) needed, you can program the VGA registers directly with IN/OUT (you will need proper SEQ and CRTC values calculated from the timings for the desired mode). The svgalib under Linux does this. Another example is modex.c, which sets 320x240x256, a resolution not available via standard BIOS. Programming VGA registers should work on all VGA compatible video cards, but not on newer video cards (most notably on UEFI machines, where VGA register emulation is probably not available any more). If VGA 16 colour is what you meant, then don't switch planes for every pixel, only once per refresh.

- 16 bits? That uses a linear frame buffer, so there's no hardware slow-down at all. In this case video mode switching has nothing to do with refresh speed. You can't set a 16 bit mode without BIOS, unless you have a native driver. Technically BIOS is a set of drivers which provides you a common real mode interface for every peripheral.

Because both 640x480x16 (colours, 0x12) and 640x480x16 (bits, 0x111) are standard SVGA modes, you can set them up with exactly the same way, with exactly the same "Set Video Mode" BIOS function, no VESA BIOS (AH=0x4F) function needed. The only difference is, 16 bits mode is specific to every video chip, there's no common register set therefore no common IN/OUT alternative.

Cheers,
bzt

Re: VESA without BIOS

Posted: Mon Apr 22, 2019 12:03 am
by iProgramInCpp
bzt wrote: - 16 bits? That uses a linear frame buffer, so there's no hardware slow-down at all. In this case video mode switching has nothing to do with refresh speed. You can't set a 16 bit mode without BIOS, unless you have a native driver. Technically BIOS is a set of drivers which provides you a common real mode interface for every peripheral.

Because both 640x480x16 (colours, 0x12) and 640x480x16 (bits, 0x111) are standard SVGA modes, you can set them up with exactly the same way, with exactly the same "Set Video Mode" BIOS function, no VESA BIOS (AH=0x4F) function needed. The only difference is, 16 bits mode is specific to every video chip, there's no common register set therefore no common IN/OUT alternative.
What are the VGA CRTC registers required to program the 640x480 16-bit color video modes?

edit: just realized:
bzt wrote: The only difference is, 16 bits mode is specific to every video chip, there's no common register set therefore no common IN/OUT alternative.
But any registers specific to the VGA?

Re: VESA without BIOS

Posted: Mon Apr 22, 2019 9:32 am
by bzt
iProgramInCpp wrote:What are the VGA CRTC registers required to program the 640x480 16-bit color video modes?
There's no such thing. VGA does not support 16 bit modes (only palette indexed modes).
For a packed pixel mode, such as the 16 bits mode, you'll need SVGA (or WGA or XGA etc.) which does not have a standardized register set. You could try to set vendor specific registers and values, but documentation is hard to come by. The values for some cards (Trident, Oak, Tseng, S3, Sis, Radeon128 etc.) are listed in the svgalib's source, but those cards are pretty old. For example the Cirrus Logic card does not really support 16 bits (r5g6b5), only 15 bits (r5g5b5), and the register values for that mode on that card can be found here.
iProgramInCpp wrote:But any registers specific to the VGA?
Yes, and I've already linked OSDev wiki on VGA Hardware, read that. It's the link which reads "VGA registers". The aforementioned svgalib's vgaregs.h can be useful too. Please note those are only good if you're dealing with indexed VGA modes. As soon as you switch to packed pixel format, you'll need SVGA at least, and for that VESA BIOS is your best bet.

Cheers,
bzt

Re: VESA without BIOS

Posted: Tue Apr 23, 2019 3:29 am
by mallard
bzt wrote:It is not. See The Incredible Machine for example.
Slight nitpick; that game actually runs at 640x400, allowing it to double-buffer within the standard 256KB VGA memory, which certainly affects (perceived) performance.

I've previously posted the available options for "better-than-VGA" graphics in protected mode. Personally, I use the x86 emulator route (via the excellent designed-for-exactly-this-purpose libx86emu).

Re: VESA without BIOS

Posted: Tue Apr 23, 2019 5:31 am
by bzt
mallard wrote:Slight nitpick; that game actually runs at 640x400, allowing it to double-buffer within the standard 256KB VGA memory, which certainly affects (perceived) performance.
Irrelevant, because
a) double buffer or not, it's using the same 4 bitplanes for colours, so you still have to switch planes for 640x400 (which is the slow part, specially if you switch for every pixel)
b) iProgramInCpp meant 16 bits, not 16 colours.
mallard wrote:I've previously posted the available options for "better-than-VGA" graphics in protected mode. Personally, I use the x86 emulator route (via the excellent designed-for-exactly-this-purpose libx86emu).
Not sure if that worths the effort, as only works on legacy BIOS machines, not on UEFI, but good for you that you have implemented an x86 emulator.

Cheers,
bzt

Re: VESA without BIOS

Posted: Tue Apr 23, 2019 5:52 am
by Octocontrabass
bzt wrote:Not sure if that worths the effort, as only works on legacy BIOS machines, not on UEFI, but good for you that you have implemented an x86 emulator.
It will work on some UEFI machines. All you need is a chipset with legacy VGA support and a legacy option ROM. (These requirements are also met by some non-x86 computers.)

Re: VESA without BIOS

Posted: Tue Apr 23, 2019 6:14 am
by mallard
bzt wrote:a) double buffer or not, it's using the same 4 bitplanes for colours, so you still have to switch planes for 640x400 (which is the slow part, specially if you switch for every pixel)
Sure, but double-buffering does help avoid visual artifacts from updating bitplanes one-at-a-time, which means the code can switch bitplanes less often. If, for example, you draw a full-screen image one-bitplane-at-a-time you'll get noticeable colour-change artifacts, particularly on the hardware that was available when that game was released!
bzt wrote:Not sure if that worths the effort, as only works on legacy BIOS machines, not on UEFI, but good for you that you have implemented an x86 emulator.
It works on any PC that can boot Windows 7 (which requires that VBE be usable even when booting from UEFI!) and can, with a little extra work, be made to work on any PC that has a video card with an option ROM (i.e. a card that works in a BIOS-boot system) regardless of whether there's a system BIOS or not. That includes non-x86 systems.

Re: VESA without BIOS

Posted: Tue Apr 23, 2019 10:48 am
by iProgramInCpp
Thank you for the advice!
I've managed to get the 640x480 4-bit color mode to work faster because of double-buffering now.
Yes, I know, it's totally unrelated to the subject. Hopefully your replies can help other people out..

Re: VESA without BIOS

Posted: Fri Apr 26, 2019 1:09 am
by rdos
When I wrote my graphics driver 10+ years ago, I decided I would not support any bit-plane mode or other strangeness, only linear framebuffer in different configurations. I originally did have support for setting up LFB modes with BIOS, but with UEFI and screens with native resolutions, it's almost always best to setup the native resolution. This is either done at boot time (with VBE) or the UEFI GOP.

Re: VESA without BIOS

Posted: Mon Apr 29, 2019 3:23 pm
by MrLolthe1st
Hi, i'm think, that using standartized VBE with LFB - is best way, you can do.
Firstly, all BIOSes, i'd seen, gives all modes to me, and one of that modes was is native display resolution.
Secondly, drawing with CPU and MMX, SSE, AVX and other instructions is very fast (I'm saying about double-buffering: you drawing in buffer, and sometimes it buffer flushing to LFB, by copying it with MMX/SSE/AVX registers: and it is so fast, as you can see). With waiting CRT back way, i've got a 60FPS redrawing.
And last position is: Windows 10 uses VBE, if you don't have any display drivers.