VOGONS


First post, by bradr

User metadata
Rank Newbie
Rank
Newbie

I thought I read somewhere that the VGA's CRTC latches the start address register at the start of vertical retrace but I can't find that reference any more - anyone know for sure?

ie: if the start address is changed immediately after vertical retrace will it affect the frame that's about to be drawn - or the one after?

Reply 1 of 4, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

That is what I recall as well, but there's a lot of clones and who really knows at which point the start address register is latched.

But safe to say, it is latched in the blanking area for sure.

So at least if you change the address after vertical retrace, maybe even when screen is being drawn, you can be sure that the previous screen is being drawn and on next frame the address set is latched.

I think you might want to test that, but many games just assume something and usually it has worked.
I've thought a test screen where the timing is tested, and the user can be asked what is seen on screen to calibrate this.

There are even a game that auto-detect the vertical retrace polarity by measuring their pulse widhts, I've not seen that one before being taken into account, but it will then use the correct edge of vertical retrace signal.

Reply 2 of 4, by bradr

User metadata
Rank Newbie
Rank
Newbie

Thanks Japael,

The reason I ask is that in the emulator I'm writing I had working as follows:

1. Wait till the end of display area (because I need to see any palette switches before passing everything to opengl shader)
2. At the end of the display area draw the screen - and here I was using whatever the start address happened to be at the time.

Mostly it rendered ok, but in Lemmings the mouse cursor would flicker - missing every 5th frame. That coincides with Lemmings running at 1 game frame per 5 video frames. I noticed the start address was being updated just after vertical retrace and the mouse cursor getting drawn just after that. If the start address is latched at vertical retrace then I think this means Lemmings is actually updating the start address and drawing the mouse for the frame after the one that's about to be drawn.

Anyway, for now I've latched the start address and delayed it by one frame and the flicker is gone.

Reply 3 of 4, by xjas

User metadata
Rank l33t
Rank
l33t

Was just talking about this relating to my own code on another forum. Scali posted some good info here.

twitch.tv/oldskooljay - playing the obscure, forgotten & weird - most Tuesdays & Thursdays @ 6:30 PM PDT. Bonus streams elsewhen!

Reply 4 of 4, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

I've made a little test program to determine when it is latched.
I've only tested on one system so far, so other systems may behave differently.

It looks like the start address register is latched pretty close to (or exactly at) the moment when the vertical retrace bit (bit3) in port 3da goes high.
I also found a reference to this here :http://read.seas.harvard.edu/cs261/hwref/ibm-vga.txt

So in my Athlon system there is a motherboard integrated VGA chipset, I suppose it's Trident 8500 maybe.

The program I made first sets up mode 13h (320x200, 256 colors) and draws a pattern of boxes to the screen, to visually determine the starting address.
The program sits in a tight loop that writes successive values to start address high and low registers while polling status of port 3da.
There is actually two loops, one loop is run while 3da bit 3 is high and another one runs while 3da bit 3 is low, but the loops are otherwise identical.
I can then selected when to reset the address counter to start from zero, at either when bit 3 went high or low, and also measure how long those loops ran by storing the address counter for later printing.

It seems that the PC can run the loop so that the address counts from 0 to 13451 in a single frame. It does not make difference if it counts from rising edge to rising edge, or from falling edge to falling edge of port 3da bit 3.
As we know, mode 13h runs at approximately 70Hz, so with this method the start address is written and status register read roughly at 940 thousand times per second, or about 1060 ns per loop.
Measuring the timing, the vertical retrace bit is high for 60 to 61 counts and low for the rest, about 13481 counts.

So when the loop is set up so that start address counter is reset to 0 when rising edge of port 3da bit 3 is detected, the screen ends up at being drawn starting from address 13540.
As the loop only goes to 13541 before resetting to zero, and I might have a off-by-one bugs there somewhere, like actually 13541 is the cycle it is reset back to zero, it does mean that the address is already latched when rising edge is detected.

And when the loop is set up so that start address counter is reset to 0 when falling edge of port 3da bit 3 is detected, the screen ends up at being drawn starting from address 13479, while the first high reading of port 3da bit 3 is detected at count 13481. Again, the screen jitters between two start addresses and there can be off-by-one errors, it appears that address was latched right at or before when rising edge is detected.

A better measurement of the port 3da bit 3 with a tighter loop that only polls for the status indicates that the bit is high for 181 counts and low for 40443 counts during a video frame. Again, approximating that the frame rate is 70Hz, the measurements indicate that 181 counts is approximately 63.65 microseconds, while standard VGA timing would assume that 2 lines of vsync is 63.56us. Thus it would appear that the vertical retrace bit really is the vsync signal.

And finally, when measuring the mode 13h vsync period with PIT, I got 17104 or 17105 ticks, that's about 69.76 Hz.