Removed scaling hack in KeInterruptTime and KeTickCount + added yield in system_events routine

This fixes the stuttering in Halo 2, Metal slug 3, JSRF and restores PDO, PSO to the same state as in master
This commit is contained in:
ergo720 2023-03-07 15:28:37 +01:00 committed by RadWolfie
parent e7bca5e1bf
commit 750d202fa8
3 changed files with 7 additions and 39 deletions

View File

@ -86,41 +86,14 @@ void SleepPrecise(std::chrono::steady_clock::time_point targetTime)
}
}
// NOTE: the pit device is not implemented right now, so we put these here
static void pit_interrupt()
{
LARGE_INTEGER CurrentTicks;
uint64_t Delta;
uint64_t Microseconds;
unsigned int IncrementScaling;
static uint64_t Error = 0;
static uint64_t UnaccountedMicroseconds = 0;
// This keeps track of how many us have elapsed between two cycles, so that the xbox clocks are updated
// with the proper increment (instead of blindly adding a single increment at every step)
QueryPerformanceCounter(&CurrentTicks);
Delta = CurrentTicks.QuadPart - pit_last_qpc;
pit_last_qpc = CurrentTicks.QuadPart;
Error += (Delta * SCALE_S_IN_US);
Microseconds = Error / HostQPCFrequency;
Error -= (Microseconds * HostQPCFrequency);
UnaccountedMicroseconds += Microseconds;
IncrementScaling = (unsigned int)(UnaccountedMicroseconds / 1000); // -> 1 ms = 1000us -> time between two xbox clock interrupts
UnaccountedMicroseconds -= (IncrementScaling * 1000);
xbox::KiClockIsr(IncrementScaling);
}
// NOTE: the pit device is not implemented right now, so we put this here
static uint64_t pit_next(uint64_t now)
{
constexpr uint64_t pit_period = 1000;
uint64_t next = pit_last + pit_period;
if (now >= next) {
pit_interrupt();
xbox::KiClockIsr();
pit_last = get_now();
return pit_period;
}
@ -183,6 +156,7 @@ xbox::void_xt NTAPI system_events(xbox::PVOID arg)
if (elapsed_us >= nearest_next) {
break;
}
std::this_thread::yield();
_mm_pause();
}
}

View File

@ -129,10 +129,7 @@ xbox::void_xt xbox::KiTimerUnlock()
KiTimerMtx.Mtx.unlock();
}
xbox::void_xt xbox::KiClockIsr
(
unsigned int ScalingFactor
)
xbox::void_xt xbox::KiClockIsr()
{
KIRQL OldIrql;
LARGE_INTEGER InterruptTime;
@ -145,7 +142,7 @@ xbox::void_xt xbox::KiClockIsr
// Update the interrupt time
InterruptTime.u.LowPart = KeInterruptTime.LowPart;
InterruptTime.u.HighPart = KeInterruptTime.High1Time;
InterruptTime.QuadPart += (CLOCK_TIME_INCREMENT * ScalingFactor);
InterruptTime.QuadPart += CLOCK_TIME_INCREMENT;
KeInterruptTime.High2Time = InterruptTime.u.HighPart;
KeInterruptTime.LowPart = InterruptTime.u.LowPart;
KeInterruptTime.High1Time = InterruptTime.u.HighPart;
@ -161,7 +158,7 @@ xbox::void_xt xbox::KiClockIsr
// Update the tick counter
OldKeTickCount = KeTickCount;
KeTickCount += ScalingFactor;
++KeTickCount;
// Because this function must be fast to continuously update the kernel clocks, if somebody else is currently
// holding the lock, we won't wait and instead skip the check of the timers for this cycle

View File

@ -56,10 +56,7 @@ namespace xbox
void_xt KiTimerUnlock();
void_xt KiClockIsr
(
IN unsigned int ScalingFactor
);
void_xt KiClockIsr();
xbox::void_xt NTAPI KiCheckTimerTable
(