Nik had it working once, I think. Without having looked at how Daytona 2 measures clock speed, I suspect there are a few things at play here. I actually wrote a CPU timing routine that works on Model 3 and to start with, that one might be a better one to test against because we know exactly how that one is supposed to work. Daytona 2 almost certainly does something similar because, well, how else would you do it? Here is
my code (edited for clarity):
- Code: Select all
uint32_t tb0 = ppc_get_tbl();
prev_second = rtc_get_time().second;
while (!quit)
{
// Whenever the second rolls over, compute refresh rate and CPU frequency
struct RTCTime t = rtc_get_time();
if (t.second != prev_second)
{
uint32_t tb = ppc_get_tbl();
prev_second = t.second;
// Compute CPU clock speed assuming a 1:1 processor/bus clock multiplier.
// Time base registers tick every 4 bus cycles.
double mhz = 4.0 * (tb - tb0) / 1e6;
tilegen_printf_at(2, 6, "CPU: %1.3f MHz", mhz);
tb0 = tb;
}
}
Pretty simple, right? We need something that counts the passage of real time: the real-time clock module. This is a CMOS device that returns a "wall clock time" and date in seconds. All you need to do is wait one second of real wall clock time and then count the number of ticks elapsed according to the PowerPC's time base register, which ticks every 4 *bus* cycles. I think on all Model 3 systems, the bus frequency is 66 MHz but the CPU is 66 (Step 1.0), 100 (Step 1.5), or 166 (Step 2.x) MHz. So the number of CPU clock cycles per time base tick differs. On Step 1.0, it's just 1 tick = 4 bus cycles = 4 CPU cycles.
So what's going on with Daytona 2? Well, I don't know for sure, but let's think about it. We emulate the CMOS clock by returning the real wall clock time. So if you increase the frequency to 166 MHz and the frame rate dips below 60 FPS, the game will see that fewer than 166 million CPU cycles were executed in one actual second. So that's one potential problem. Nik also wrote code to further scale the time base ticks to the emulated frequency so that they always matched the correct frequency. The emulator ticks the time base register such that after emulating N cycles (where N is the frequency we set in Supermodel, I think 50 MHz by default), the time base register should look as though the *true* number of cycles (e.g., 166 million for Daytona 2) has elapsed.
It *should* be possible to get Supermodel to report the correct clock frequency even when running at a lower simulated frequency because of this multiplier. I vaguely recall Nik saying it didn't quite work for some reason but I don't know why. I think a better place to start would be my timing program. If anyone's interested, I could supply the ROM set and the necessary entry for Games.xml to get it up and running. Even without it, you could probably just print the difference in TBL after each second and see if makes sense from a timing perspective. You'll probably first want to undo the effect of that extra scaling value Nik multiplies by somewhere in the PowerPC core (set it to 1). I'll need to look into that at some point for frame timing because you guys are right -- it should just work.