Ian wrote:I had a poke around with vf3 with the status bits. Once the game is loaded the status bit doesn't seem to matter at all. Ie can just return 0 and the game runs at normal speed. So everything must be synced at startup with that particular routine
Right. By the way, do you have your Pro-1000 SDK disassemblies? I've lost them. I'm starting to develop a couple theories and will poke around a little more at home, maybe re-organize my notes on fvipers2 (that is the game into which I've traced the furthest).
Idea 1
The pingpong memory (0x8e000000 according to the API headers) is puzzling to me. If it's a double buffer that swaps, then what prevents it from swapping when a flush is issued immediately after other regions are written? It is absolutely possible that the Real3D keeps tracks of which memory banks are "dirty" and then performs a different action for flush depending on what regions were last modified. Evidence in favor of this is the fact that regardless of whether games flush after each region is written (some games prefer to do this after all memory is updated), they seem to like to flush after every texture upload (IIRC). In this model, "flush" is a "do work" command.
Evidence against this would be the timing routine itself. No memory is written when the flush is performed and the game tries to time the results. Memory is set up ahead of time, and the appropriate flushes are performed then. Nothing is dirty when the flush command is issued in the timing routine I posted, yet something clearly happens.
Idea 2
Maybe rendering happens at fixed points in the frame. Namely, rendering kicks off some time after VBL starts. In this approach, maybe there is a fixed window of time immediately after VBL in which the memory can be written, after which rendering will kick off. Maybe rendering only kicks off if a flush command has been issued. But the point is that it always begins at a given time point. The timing value then represents a sort of window period during which the games are allowed to make updates. If they miss the window, they have to wait until the next frame. If a flush is not issued and the timeout window is missed, or the flush is issued too late, the Real3D will not begin rendering because doing so would make it late the next frame around.
This is essentially what Supermodel currently assumes and what the timing logic is trying to do. It's trying to wait some fixed time after VBL to kick off rendering. Frustratingly, we haven't found the right timing or maybe there is a subtlety we're missing. Or maybe, the flush command acts as a "keep track of what memory regions are dirty", though that makes little sense from a hardware point of view.
At any rate, fvipers2 should help. I have a clear example of frames being missed and the delay routine responsible for that during attract mode. If I can understand how the 3 timing routines work (timing calibration at start up + 2 timing related routines at the beginning and end of the main loop), I think I might be able to crack this.