VOGONS


First post, by OPLx

User metadata
Rank Member
Rank
Member

I was recently look up some information on the VGA registers and came across something that I'm a bit confused about. In Mode 0x1 (40x25 text mode) the CRTC horizontal registers are as follows:

Horizontal Total: 0x2D
Horizontal Display End: 0x27
Start Horizontal Blanking: 0x28
End Horizontal Blanking: 0x90
Start Horizontal Retrace: 0x2A
End Horizontal Retrace: 0xA0

There are a total of 0x32 character clocks per scan line and the part that's perplexing me is the value for the End Horizontal Retrace. Since it uses the lower 5 bits of the result of the Start Horizontal Retrace added to the desired with, the lower 5 bits are all zeros. This would seem to imply that (based on my calculations) that the width of the horizontal retrace period is 0x40 characters, but this value exceeds the horizontal total. I'm used to seeing Horizontal Retrace period values generally falling within the Start Horizontal Blanking and End Horizontal Blanking range, so I'm curious as to what actually VGA hardware does when the retrace period exceeds the Horizontal Total. I can't seem to find make sense of the relation of what the lower 5 bits of the End Horizontal Retrace value are and how the Sequencer's Clocking Mode (master clock divided by 2) affects how the lower 5 bits are calculated. I would have though that (perhaps) it should be something along the lines of 0x30 rather than 0x0.

Reply 1 of 2, by superfury

User metadata
Rank l33t++
Rank
l33t++

It's a simple AND mask being applied to filter out the lower bits of the counter, before matching the end registers. That's 5 bits fior
Also, the horizontal total is actually 5 more than what's specified(done by hardware). So the value written is wanted total minus 5 (so x-5 for a setting of x, 0x00 being 5 clocks and with 0xFF being 260 horizontal character clocks).
The retrace/blanking end stop their retrace/blanking whenever they are matching all buts but the lower 5, which can be on the current scanline, but also on the next scanline. It can be also be forced out of range for even longer periods(of multiple scanlines) if you're willing to have a very small screen, at least theoretically. Like setting it to 0x1F and horizontal total to lower than (0x1F-5)=0x1B to prevent it from matching.
Also, only the end of the retrace/blanking match the lower 5/6 bits only. The start registers match fully(a range of 0-255 character clock number, which also may be out of range). It ends the first time the horizontal character clock counter's bits match(5-bit for horizontal retrace end and 6-bits for horizontal blanking end).
Look at UniPCemu's CRTC timing for the exact way this masks(hardware/vga/vga_crtcontroller.c, function get_display_x).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 2 of 2, by OPLx

User metadata
Rank Member
Rank
Member

Thank you for your explanation. Since I don't have an actual CRT monitor (using an LCD one), I'm not necessarily seeing the actual effects some of these timings have. Your explanation gave me a better idea of how the timing values work.