640x480x16 Performance?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: 640x480x16 Performance?

Post by alexfru »

rkennedy9064 wrote:
Korona wrote:Today, it might be easier to just use VMX or SVM to do that.
I'm not familiar with VMX and SVM. What do those stand for? Also thanks for the tips on write-combining. I wasn't aware of that. I'll have to look into that more.
Those are hardware-assisted virtualization technologies from intel and AMD in their x86-64 CPUs.

The implication is that one would be able to run 16-bit real mode BIOS code in a VM simply because once the CPU is switched into 64-bit/long mode, there's no other way to execute 16-bit real mode directly (other than switching all the way back to that mode or 32-bit protected mode and use its virtual 8086 submode).
Also, there used to be problems with running 16-bit real mode code in early implementations (AFAIR, real mode was not even supported in VMX). I don't know to what extent that is rectified now.

This isn't easy to pull off. I wouldn't go there.

I think, these days using UEFI and its services for accessing disks and screen (GOP=Graphics Output Protocol) is better than the old BIOS+VGA combo.
Unless, of course, that is exactly what you want for some reason.
rkennedy9064
Member
Member
Posts: 36
Joined: Wed Sep 01, 2010 3:54 pm

Re: 640x480x16 Performance?

Post by rkennedy9064 »

Thanks for the explanation. That does seem like overkill for my needs. Right now I don't have any UEFI related code, everything is still BIOS. I'm mainly just implementing different modes as a learning experience/practice. I have 320x200, 320x240 and 640x480 with support for switching between them and drawing basic shapes like triangles. Was mainly just looking for possible ways to improve the speed of 640x480 mode. I'm going to look into the multiple suggestions and see if I can get something working.
User avatar
thomtl
Member
Member
Posts: 66
Joined: Mon Sep 03, 2018 2:25 am

Re: 640x480x16 Performance?

Post by thomtl »

I have actually implemented VBE with SVM, and while it's certainly not an easy task it's not impossible either. I don't know if it works on VT-x(with help of the extension that allows you to run in real mode ofc) but I presume it would work thesame.
Also if you do plan on doing this I would seriously disadvise doing it without the extensions that allow you to use another paging level to map host physical to guest physical(NPT for AMD and EPT for Intel) without having to manually keep track of shadow paging maps(yes you can run with shadow paging in real mode for AMD, they have paged real mode for that; However I don't think the Intel extension for it exists without EPT though).

All in all while it's not that best idea(and was only implemented by me for the meme of seeing if I could) if you do want to do this I can recommend doing this over V8086 mode, having tried to implement both and only succeeded at one.
(If you want an impression of how many LOC an SVM implementation is, mine is around 1000)

- thom_tl
rkennedy9064
Member
Member
Posts: 36
Joined: Wed Sep 01, 2010 3:54 pm

Re: 640x480x16 Performance?

Post by rkennedy9064 »

klange wrote: We have an article on the wiki that explains how to set the display mode and find the the address of the framebuffer to map. Linear framebuffers are especially useful because once you have one, you no longer need to care all that much about the video device unless you want to modeset again. If/when you look at UEFI, you'll find that it has an API for setting up a linear framebuffer at boot. Grub also can do this on most BIOS machines. Any other graphics card driver you write for a real card (or other emulated cards like VMware's SVGA implementation, which is different from the BGA shared by Bochs/VirtualBox/QEMU) will also provide the same kinda of framebuffer interface.
I started looking into the Bochs Graphics Adapter with qemu and have a question about the version of it. I see that it says to use the most recent version with Qemu, you need the -std-vga option, which qemu says isn't a valid option. I've tried -vga std, -std vmware, -device VGA and -device bochs-display, but they all return 0xB0C0 for the version. I also tried writing 0xB0C5 to set the version, but it still returns 0xB0C0 after writing. The only option that actually returned 0xB0C5 for the version was -device ati-vga. Should those other options be able to support the newest Bochs Graphics Adapter? My Qemu version is QEMU emulator version 4.2.0 (v4.2.0-11797-g2890edc853-dirty), so I would think it would support the newest version.
klange
Member
Member
Posts: 679
Joined: Wed Mar 30, 2011 12:31 am
Libera.chat IRC: klange
Discord: klange

Re: 640x480x16 Performance?

Post by klange »

rkennedy9064 wrote:I started looking into the Bochs Graphics Adapter with qemu and have a question about the version of it. I see that it says to use the most recent version with Qemu, you need the -std-vga option, which qemu says isn't a valid option. I've tried -vga std, -std vmware, -device VGA and -device bochs-display, but they all return 0xB0C0 for the version. I also tried writing 0xB0C5 to set the version, but it still returns 0xB0C0 after writing. The only option that actually returned 0xB0C5 for the version was -device ati-vga. Should those other options be able to support the newest Bochs Graphics Adapter? My Qemu version is QEMU emulator version 4.2.0 (v4.2.0-11797-g2890edc853-dirty), so I would think it would support the newest version.
The actual response of the version value is specific to bochs. You can pretty safely ignore it. Everything has supported the 0xB0C5 feature set for many years now. Since this is software, and not actual hardware, you need not worry about supporting older versions.
rkennedy9064
Member
Member
Posts: 36
Joined: Wed Sep 01, 2010 3:54 pm

Re: 640x480x16 Performance?

Post by rkennedy9064 »

Okay thanks. Just wanted to make sure I wasn't missing something.
iProgramInCpp
Member
Member
Posts: 81
Joined: Sun Apr 21, 2019 7:39 am

Re: 640x480x16 Performance?

Post by iProgramInCpp »

bzt wrote:Oh, you mean 16 colors (4 bits) and not 16 bits (64k colors)? Then alexfru is right.

I'd highly recommend against that mode. But If you insist, the only way to make it fast is to have a copy of the screen in RAM. Then
- when you modify a pixel, you create a list of boxes, areas that has changed. Updating a window can mark the entire window area, no need to check every pixel
- on vertical retrace, you "flush" the screen, you iterate through that list 4 times: first you switch to plane 0, then you update every pixel's 1st bit in the list by copying the area from the RAM screen to the VGA screen. Then you switch to plane 1, and copy the 2nd bits, etc.
- when done, you clear the list

This minimizes the number of plane switches (which is slow), and updates video RAM when it is not used (during a vertical retrace). Also you can calculate the screen offsets of the boxes once and reuse them for all 4 plane writes.

If I were you, I'd rather consider using SVGA mode at least (or even better VESA). If you don't use the VESA 2.0 extensions, some modes have fixed mode values. and you can set them with INT 10h/AH=0. But you really should use VESA (INT 10h/AH=4F) instead, that's more supported and also provides linear frame buffer access (no need for switch banks). Bank switch is necessary as the VGA has a 64k MMIO at 0xA0000, but a 640x480x16 (16 bits, not colors) resolution requires a little bit more than 600k of memory, so you have to map a certain 64k of that 600k at 0xA0000. Linear frame buffers use an address other than 0xA0000 (typically 0xE000000) and they are contiguous, meaning you can only access those from protected mode, but in return you can use the entire 600k as-is.

Cheers,
bzt
What is vertical retrace, is it an interrupt? If so, how can I enable it? It looks to make VGA memory access faster than while the VGA is drawing. And is SVGA inaccessible without int 10h or writing a graphics driver, just like VESA?
Hey! I'm developing two operating systems:

NanoShell --- A 32-bit operating system whose GUI takes inspiration from Windows 9x and early UNIX desktop managers.
Boron --- A portable SMP operating system taking inspiration from the design of the Windows NT kernel.
rkennedy9064
Member
Member
Posts: 36
Joined: Wed Sep 01, 2010 3:54 pm

Re: 640x480x16 Performance?

Post by rkennedy9064 »

iProgramInCpp wrote:
bzt wrote:Oh, you mean 16 colors (4 bits) and not 16 bits (64k colors)? Then alexfru is right.

I'd highly recommend against that mode. But If you insist, the only way to make it fast is to have a copy of the screen in RAM. Then
- when you modify a pixel, you create a list of boxes, areas that has changed. Updating a window can mark the entire window area, no need to check every pixel
- on vertical retrace, you "flush" the screen, you iterate through that list 4 times: first you switch to plane 0, then you update every pixel's 1st bit in the list by copying the area from the RAM screen to the VGA screen. Then you switch to plane 1, and copy the 2nd bits, etc.
- when done, you clear the list

This minimizes the number of plane switches (which is slow), and updates video RAM when it is not used (during a vertical retrace). Also you can calculate the screen offsets of the boxes once and reuse them for all 4 plane writes.

If I were you, I'd rather consider using SVGA mode at least (or even better VESA). If you don't use the VESA 2.0 extensions, some modes have fixed mode values. and you can set them with INT 10h/AH=0. But you really should use VESA (INT 10h/AH=4F) instead, that's more supported and also provides linear frame buffer access (no need for switch banks). Bank switch is necessary as the VGA has a 64k MMIO at 0xA0000, but a 640x480x16 (16 bits, not colors) resolution requires a little bit more than 600k of memory, so you have to map a certain 64k of that 600k at 0xA0000. Linear frame buffers use an address other than 0xA0000 (typically 0xE000000) and they are contiguous, meaning you can only access those from protected mode, but in return you can use the entire 600k as-is.

Cheers,
bzt
What is vertical retrace, is it an interrupt? If so, how can I enable it? It looks to make VGA memory access faster than while the VGA is drawing. And is SVGA inaccessible without int 10h or writing a graphics driver, just like VESA?
In a raster graphics display, the vertical blanking interval (VBI), also known as the vertical interval or VBLANK, is the time between the end of the final visible line of a frame or field and the beginning of the first visible line of the next frame. It is present in analog television, VGA, DVI and other signals. It's bit 3 of the Input Status 1 register. This is Intels description of it according to their docs.
Vertical Retrace/Video.
0 = VSYNC inactive (Indicates that a vertical retrace interval is not taking place).
1 = VSYNC active (Indicates that a vertical retrace interval is taking place).

Note:
VGA pixel generation is not locked to the display output but is loosely coupled. A VSYNC
indication may not occur during the actual VSYNC going to the display but during the
VSYNC that is generated as part of the VGA pixel generation. The exact relationship will vary
with the VGA display operational mode. This status bit will remain active when the VGA is
disabled and the device is running in high resolution modes (non-VGA) to allow for
applications that (now incorrectly) use these status registers bits. In this case, the status will
come from the pipe that the VGA is assigned to.

Bits 4 and 5 of the Vertical Retrace End Register (CR11) previously could program this bit to
generate an interrupt at the start of the vertical retrace interval. This ability to generate
interrupts at the start of the vertical retrace interval is a feature that is largely unused by
legacy software. Interrupts are not supported through the VGA register bits.
As for SVGA I'm pretty sure nothing is standard, so you need to know the graphics card you're programming on. I'm not 100% sure for that part though, so someone else can confirm that.
tom9876543
Member
Member
Posts: 170
Joined: Wed Jul 18, 2007 5:51 am

Re: 640x480x16 Performance?

Post by tom9876543 »

rkennedy9064, I'm not sure why you are wasting time with out-dated graphics modes.
For 32bit x86, BIOS+VESA is a reasonable target for your OS.
It is much more sensible to setup graphics with VESA to get 1024x768x32bit linear frame buffer.
The future is obviously UEFI and you should be aiming to write graphics code that will be compatible with UEFI GOP.
16 colors aka 4bit color sure ain't compatible with UEFI.
Post Reply