aboutsummaryrefslogtreecommitdiff
path: root/src/core/arm/nce/patcher.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-30 01:55:20 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-30 02:31:58 -0400
commit0218eacfd560d0ce48b3ffe64d279ee85bbf1347 (patch)
treecbe764aa642b55cae06e94f15bd0e16f234e6052 /src/core/arm/nce/patcher.cpp
parent08be623a271d13b66497a98265f6832e9aa2c0d0 (diff)
nx2: run the guest counter at 31.25 MHz for Switch 2 titles
The Switch 2 counter runs at 31.25 MHz and its SDK converts ticks with that constant: Mario Kart World's sdk builds 31,250,000 in nn::os::GetSystemTickFrequency, TickManager::ConvertToTimeSpan and TickManager::ConvertToTick (19.2 MHz appears nowhere). Eglantine counted at the Switch 1 rate for every title, so every tick-based time in a Switch 2 game was off by 1.63x: elapsed times read short, and a deadline of one 60 Hz frame converted to ticks waited ~27 ms. The wall clock now has a guest counter frequency, set at boot: 31.25 MHz for Switch 2 programs, 19.2 MHz otherwise, EDEN_NX2_CNTFRQ=<Hz> to force one. CNTPCT reads, CNTFRQ_EL0, svcGetSystemTick, thread tick counts and the time services' tick conversions follow it, and the CNTPCT spin detection keeps its ~1.7 us threshold. Mario Kart World, title screen and attract demo, 180 s, same build: frame times unchanged (17-19 ms once warm), process CPU time 848 s instead of 930 s.
Diffstat (limited to 'src/core/arm/nce/patcher.cpp')
-rw-r--r--src/core/arm/nce/patcher.cpp3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/core/arm/nce/patcher.cpp b/src/core/arm/nce/patcher.cpp
index f21d7cacdc..72c3497f03 100644
--- a/src/core/arm/nce/patcher.cpp
+++ b/src/core/arm/nce/patcher.cpp
@@ -627,7 +627,7 @@ void Patcher::WriteMsrHandler(ModuleDestLabel module_dest, oaknut::XReg src_reg,
}
void Patcher::WriteCntfrqHandler(ModuleDestLabel module_dest, oaknut::XReg dest_reg, oaknut::VectorCodeGenerator& cg) {
- cg.MOV(dest_reg, Common::WallClock::CNTFRQ);
+ cg.MOV(dest_reg, Common::g_wall_clock.GetGuestCNTFRQ());
// Jump back to the instruction after the emulated MRS.
if (&cg == &c_pre)
@@ -642,6 +642,7 @@ void Patcher::WriteCntpctHandler(ModuleDestLabel module_dest, oaknut::XReg dest_
#else
static Common::WallClock clock(true, 1);
#endif
+ clock.SetGuestCNTFRQ(Common::g_wall_clock.GetGuestCNTFRQ());
const auto factor = clock.GetGuestCNTFRQFactor();
const auto raw_factor = std::bit_cast<std::array<u64, 2>>(factor);