Frame timing

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: Frame timing

Postby Ian » Thu Aug 24, 2017 3:12 pm

What clock speed are you testing at?
Does that even effect things at all ?
I assume the games were linked with some library that handled all these functions automatically for the programmers
Ian
 
Posts: 1126
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing

Postby Bart » Thu Aug 24, 2017 3:23 pm

I've been testing at 100 MHz with Fighting Vipers 2. I think it does matter but it might tolerate some reduction in clock power. I think I said it needed the equivalent of 100 scanlines of time as measured at 100 MHz? That's about a third of the frame. If my theory is correct and it does its processing during the active frame, it would then theoretically still run at about a third of the clock speed plus some percentage margin for DMA transfer code and what-not.
User avatar
Bart
Site Admin
 
Posts: 2001
Joined: Thu Sep 01, 2011 2:13 pm
Location: New York City

Re: Frame timing

Postby Bart » Mon Aug 28, 2017 10:47 am

So I found that the number of "scanlines" worth of time that need to elapse before the Real3D status bit is flipped needs to be almost a full frame for Fighting Vipers 2 to work properly. Texture glitches still occur if it only occupies 100 scanlines (about 25% of the entire frame duration), albeit significantly reduced. You'll still see them stream in late, however. I don't know where the exact threshold is and it doesn't really matter because I think it's becoming clear here that the Real3D flush command is processed by the Real3D at some specific point in the frame (VBL start, most likely).

The downside of this is that the game must be run at 100MHz now. The reason for this is that the timer registers are basically a multiple of the PowerPC clock speed. For Step 1.0, where CPU frequency == bus clock, every 4 bus cycles == every 4 CPU cycles == one timer cycle. For Step 1.5, the bus clock multiplier is 1.5 (66MHz bus clock, 100 MHz CPU clock), so the timer ticks every 6 CPU clocks.

Nik had once toyed with the idea of scaling the timer so that it always fooled the system into thinking it was running a CPU at the correct speed. So if you want to downclock the PowerPC from 100MHz to 50MHz, you now want each cycle to act as though two cycles have actually elapsed. The timer should tick every 3 cycles in that case and maybe this would fix the game. The current frame timing, broken though it is, does rely on precise calibration he performed and I think he was having trouble getting this idea to work and abandoned. Theoretically, it seems sound.

Don't want to get ahead of myself. I've only tested FV2 and LA Machineguns. I don't have the other ROM sets I need to test here yet. Both games have improved. Although there is still garbage 2D data for a couple frames in LA Machineguns, the mission briefings move much more quickly. I'll shoot an email to Charles MacDonald tonight and see if he has any thoughts as to what's going on with the System 24 tilegen IRQs. My theory is that it is triggering both VBL start and end IRQs (or that the tilegen triggers one, and the Real3D triggers another that is timed a few lines off) and that the games actually listen for VBL end. If I had the actual board with me to test on, this would be so easy to figure out! I would just have to print out the difference in timer value between IRQ 1 and 2. But it's probably not essential for getting frame timing fixed for now. This is the kind of stuff the MAME guys will eventually want to know :)
User avatar
Bart
Site Admin
 
Posts: 2001
Joined: Thu Sep 01, 2011 2:13 pm
Location: New York City

Re: Frame timing

Postby Ian » Mon Aug 28, 2017 11:34 am

About the 2d tile gen corruption.
I noticed sometimes the tilegen takes more than a whole frames worth of time to update the memory. I think .. there is some value passed to WriteRegister() which I think it says, don't draw anything during this period.

I think .. it whens 0x6e is passed to

case 0x10: // IRQ acknowledge
IRQ->Deassert(data&0xFF);

So data is 0x6e.

Might be worth looking at
Ian
 
Posts: 1126
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing

Postby Bart » Mon Aug 28, 2017 5:43 pm

As far as I can tell this is just another IRQ ack. But given that there already exists an IRQ ack register on the IRQ controller itself, this one is a bit odd. If it only controlled the IRQs that the tilegen raises, it would make sense. It could just be that the tilegen has to be told to stop sending IRQs. But why it would set a value like 0x6e is odd. Now, Harry mentioned he was able to get rid of garbled graphics using his approach to frame timing, which involves spacing some of the IRQs out. I'll definitely try to look into it. My plan is to test more games next and start refactoring RunMainboardFrame() to be a bit more sensible.

It may turn out that my recent "findings" are total BS and completely break a bunch of other games :)
User avatar
Bart
Site Admin
 
Posts: 2001
Joined: Thu Sep 01, 2011 2:13 pm
Location: New York City

Re: Frame timing

Postby Ian » Tue Aug 29, 2017 1:50 am

Honestly I've no idea what it is doing, but if you look at what is written games will always write
data as
2,4,8 every frame.
Or sometimes 1,4,8

Then during these longer sequences 0x6e will get written. But only during these longer periods.
Ian
 
Posts: 1126
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing

Postby Bart » Tue Aug 29, 2017 11:29 am

So I tried to rewrite the main board frame function in Model3.cpp according to how I think things work. Results for Fighting Vipers 2 were nice but mixed in other games. Magical Truck Adventure's scrolling text looked correct but I need to go back and check to make sure it's actually still broken in the latest SVN. I seem to recall adding some magic offset in Render2D.cpp, which is probably not correct anymore. The girl's dress was not fixed, however, so I'm still not quite there yet.

Scud Race Plus's intro looks significantly better but there is some flicker. Timing isn't dead-on yet.

I also noticed that the Daytona 2 PE title screen was flickering. So today, I dug into Daytona 2 a little bit. It seems to use the same DEC-calibration logic that Fighting Vipers 2 does! It also uses a significantly more complicated system library that makes the IRQ handlers seem more complicated than they really are. I discovered that Daytona 2 (and this is probably true of most games) separates transfers to tilegen VRAM into two separate batches: name table data (which can be updated each frame) and the rest (patterns, scroll, mask, palette -- which often needs not be updated). I suspect the flame effect during the title and track loading screens is accomplished by changing patterns rather than name table entries but not 100% sure.

Just for my own reference, I'm going to post the main loop from dayto2pe with a few comments. I haven't been checking for where Real3D transfers occur and am focusing on the tilegen:

Code: Select all
;
; dayto2pe: part of the boot-up sequence and main program loop
;

;...
0x00018A30: 0x4807B961  bl  0x00094390
0x00018A34: 0x2C030000  cmpi  cr0,0,r3,0x0
0x00018A38: 0x4181008C  bt  cr0[gt],0x00018AC4  ; jumps to service menu
0x00018A3C: 0x4807BEC5  bl  0x00094900
0x00018A40: 0x4807C025  bl  0x00094A64
0x00018A44: 0x480796D5  bl  0x00092118
0x00018A48: 0x480003F5  bl  0x00018E3C
0x00018A4C: 0x48000475  bl  0x00018EC0
0x00018A50: 0x480779FD  bl  0x0009044C
0x00018A54: 0x48063205  bl  0x0007BC58
0x00018A58: 0x48065541  bl  0x0007DF98
0x00018A5C: 0x4BFEC6A5  bl  sub5100             ; DEC calibration
0x00018A60: 0x48033EE9  bl  0x0004C948
0x00018A64: 0x48033F89  bl  0x0004C9EC
0x00018A68: 0x48003B51  bl  0x0001C5B8
0x00018A6C: 0x48000089  bl  0x00018AF4
0x00018A70: 0x3C600010  li  r3,0x00100000       ; <-- top of main loop
0x00018A74: 0x88635007  lbz r3,0x5007(r3)
0x00018A78: 0x2C030000  cmpi  cr0,0,r3,0x00
0x00018A7C: 0x40820048  bf  cr0[eq],0x00018AC4  ; jumps to service menu
0x00018A80: 0x38600000  li  r3,0x00000000
0x00018A84: 0x3C400073  li  r2,0x00730000
0x00018A88: 0x906279B4  stw r3,0x79B4(r2)
0x00018A8C: 0x480356AD  bl  0x0004E138
0x00018A90: 0x4BFF5275  bl  0x0000DD04
0x00018A94: 0x48006955  bl  0x0001F3E8
0x00018A98: 0x3C600050  li  r3,0x00500000
0x00018A9C: 0x480069A1  bl  0x0001F43C          ; tilegen patterns, scroll table, mask table
0x00018AA0: 0x48063031  bl  0x0007BAD0          ; null function (does nothing, returns immediately)
0x00018AA4: 0x38600000  li  r3,0x00000000
0x00018AA8: 0x3C400011  li  r2,0x00110000
0x00018AAC: 0x986287EC  stb r3,-0x7814(r2)
0x00018AB0: 0x4BFF53D9  bl  0x0000DE88          ; VBL (delay loop here?), followed by tilegen name table
0x00018AB4: 0x48000051  bl  0x00018B04          ; another VBL (delay loop here?)
0x00018AB8: 0x4BFFFFB8  b 0x00018A70


Need to find those delay loops again. I'm guessing it'll look a lot like how Fighting Vipers 2's looked. Hopefully this will yield some insight into what point in the frame the game thinks it is in when it writes to the tilegen. The tilegen functions are actually back-to-back. That call to 7BAD0 in between them is stubbed out. However, the second tilegen call seems to invoke one of those sync functions. I haven't found where they are yet and will look at that next. They proved quite informative in FV2 when studied in context.
User avatar
Bart
Site Admin
 
Posts: 2001
Joined: Thu Sep 01, 2011 2:13 pm
Location: New York City

Re: Frame timing

Postby Ian » Tue Aug 29, 2017 12:04 pm

I discovered that Daytona 2 (and this is probably true of most games) separates transfers to tilegen VRAM into two separate batches: name table data (which can be updated each frame) and the rest (patterns, scroll, mask, palette -- which often needs not be updated).


This is what scud is doing in the rolling start. Only we aren't drawing at the correct time, so we get updates of the scrolling from frame 1, but the colour or whatever it is updates from frame 2.
Ian
 
Posts: 1126
Joined: Tue Feb 23, 2016 9:23 am

Re: Frame timing

Postby Bart » Tue Aug 29, 2017 12:27 pm

Ian wrote:
I discovered that Daytona 2 (and this is probably true of most games) separates transfers to tilegen VRAM into two separate batches: name table data (which can be updated each frame) and the rest (patterns, scroll, mask, palette -- which often needs not be updated).


This is what scud is doing in the rolling start. Only we aren't drawing at the correct time, so we get updates of the scrolling from frame 1, but the colour or whatever it is updates from frame 2.


This could turn out to be as simple as getting IRQ timing correct relative to the status bit flip. I think what also happens right now is that we actually run VBL first followed by the active frame. Even if the timing of the status bit change is correct, the pattern uploads might happen at the very end of RunMainBoardFrame() and we draw the frame right after, which is incorrect. It really should be drawn at start of active frame, which currently is smack dab in the *middle* of RunMainBoardFrame(), if that makes sense.
User avatar
Bart
Site Admin
 
Posts: 2001
Joined: Thu Sep 01, 2011 2:13 pm
Location: New York City

Re: Frame timing

Postby Bart » Tue Aug 29, 2017 8:38 pm

This is infuriating! I got so close that I almost submitted a commit but then discovered LA Machineguns broke. ARGH!

The ping pong bit can't be flipped *too close* to the VBL IRQ. I thought that maybe the VBL IRQ is actually generated at the VSync pulse (which is contrary to Charles' document that says it happens on the last active line) and that the Real3D samples the ping pong request at the last display line. That gives 11 scanlines of time between when the status bit should flip and IRQ 02 being generated. Worked lovely in most games: Scud Race Plus exhibits some tearing in the 2D cinematic and the 'Rolling Start' glitch has lessened (though not disappeared), the girl's dress in Magical Truck looks fine, Dirt Devils attract mode runs at full speed, no flicker on the Daytona 2 title screen. Downsides were that Virtual On had to get to 200% during it's "Initialization" screen to boot but otherwise ran fine, and Magical Truck's initial progress bar wrapped the screen. I even had Sega Rally 2 DX running at full speed (albeit with flickering, invalid frames, which were probably moreso the result of the patch being applied than an actual timing glitch).

But then LA Machineguns wants MORE time between the status bit flip and IRQ 02 than I can possibly account for. I can probably find a value that satisfies all games but it doesn't make sense. It gets stuck easily on that initial ROM check looking screen. Bump the clock from 100MHz to 166MHz and it progresses but then gets stuck in attract mode. Argh!

Will have to keep looking... I may need to take a look at what the heck VON2 is doing at boot-up. Magical Truck is probably using the same kind of logic for its status bar.
User avatar
Bart
Site Admin
 
Posts: 2001
Joined: Thu Sep 01, 2011 2:13 pm
Location: New York City

PreviousNext

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 5 guests