From f3c90b3ef2baf12b95cde32771ba99d3b431308b Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Wed, 5 Feb 2025 20:01:21 +0000 Subject: [PATCH] Fix PTIMER speed, which fixes 1 minute of being frozen on the win2k bootscreen --- src/video/nv/nv3/subsystems/nv3_ptimer.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/video/nv/nv3/subsystems/nv3_ptimer.c b/src/video/nv/nv3/subsystems/nv3_ptimer.c index 30dd96f23..b182644ec 100644 --- a/src/video/nv/nv3/subsystems/nv3_ptimer.c +++ b/src/video/nv/nv3/subsystems/nv3_ptimer.c @@ -59,22 +59,21 @@ void nv3_ptimer_interrupt(uint32_t num) // Ticks the timer. void nv3_ptimer_tick(double real_time) { - // do not divide by zero + // prevent a divide by zero if (nv3->ptimer.clock_numerator == 0 || nv3->ptimer.clock_denominator == 0) return; // get the current time - // Due to timer system limitations, the timer system is not capable of running at 100 megahertz. Therefore, we have to scale it down and then scale up the level of changes - // to the state. // See Envytools. We need to use the frequency as a source. - // But we need to figure out how many cycles actually occurred because this counts up every cycle... + // We need to figure out how many cycles actually occurred because this counts up every cycle... + // However it seems that their formula is wrong. I can't be bothered to figure out what's going on and, based on documentation from NVIDIA, + // timer_0 is meant to roll over every 4 seconds. Multiplying by 10 basically does the job. // Convert to microseconds - double freq_base = (real_time / 1000000.0f) / ((double)1.0 / nv3->nvbase.memory_clock_frequency); - - double current_time = freq_base * ((double)nv3->ptimer.clock_numerator * NV3_86BOX_TIMER_SYSTEM_FIX_QUOTIENT) / (double)nv3->ptimer.clock_denominator; // *10.0? + double freq_base = (real_time / 1000000.0f) / ((double)1.0 / nv3->nvbase.memory_clock_frequency) * 10.0f; + double current_time = freq_base * ((double)nv3->ptimer.clock_numerator) / (double)nv3->ptimer.clock_denominator; // *10.0? // truncate it nv3->ptimer.time += (uint64_t)current_time;