From 73be2f3e01e22c7a695edf98b6d511b1f0a3eba7 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:09:42 -0500 Subject: [PATCH] tweak dmas to be more accurate (actually less?) --- src/CP15.cpp | 33 +++++++++++++++++++++++++++------ src/DMA.cpp | 17 ++++++++++------- src/NDS.cpp | 20 +++++++------------- src/NDS.h | 2 +- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/CP15.cpp b/src/CP15.cpp index 747f2955..e89275c8 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -454,7 +454,8 @@ bool ARMv5::ICacheLookup(const u32 addr) // BIST test State register (See arm946e-s Rev 1 technical manual, 2.3.15 "Register 15, test State Register") if (CP15BISTTestStateRegister & CP15_BIST_TR_DISABLE_ICACHE_LINEFILL) [[unlikely]] return false; - + + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; WriteBufferDrain(); FetchAddr[16] = addr; QueueFunction(&ARMv5::ICacheLookup_2); @@ -688,6 +689,8 @@ bool ARMv5::DCacheLookup(const u32 addr) // BIST test State register (See arm946e-s Rev 1 technical manual, 2.3.15 "Register 15, test State Register") if (CP15BISTTestStateRegister & CP15_BIST_TR_DISABLE_DCACHE_LINEFILL) [[unlikely]] return false; + + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; WriteBufferDrain(); // checkme? FetchAddr[16] = addr; @@ -2214,10 +2217,12 @@ void ARMv5::CodeRead32(u32 addr) // bus reads can only overlap with dcache streaming by 6 cycles if (DCacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = DCacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; if (PU_Map[addr>>12] & 0x30) WriteBufferDrain(); else @@ -2346,10 +2351,12 @@ void ARMv5::DRead8_2() // checkme: does dcache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } - + + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; if (PU_Map[addr>>12] & 0x30) WriteBufferDrain(); else @@ -2460,10 +2467,12 @@ void ARMv5::DRead16_2() // checkme: does cache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } - + + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; if (PU_Map[addr>>12] & 0x30) WriteBufferDrain(); else @@ -2575,10 +2584,12 @@ void ARMv5::DRead32_2() // checkme: does cache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } - + + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; if (PU_Map[addr>>12] & 0x30) WriteBufferDrain(); else @@ -2676,15 +2687,17 @@ void ARMv5::DRead32S_2() // checkme: does cache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } - + + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; if (PU_Map[addr>>12] & 0x30) // checkme WriteBufferDrain(); else WriteBufferCheck<1>(); - + QueueFunction(&ARMv5::DRead32S_3); } @@ -2809,12 +2822,14 @@ void ARMv5::DWrite8_2() // checkme: does cache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } if (!(PU_Map[addr>>12] & (0x30))) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; WriteBufferCheck<2>(); QueueFunction(&ARMv5::DWrite8_3); } @@ -2922,12 +2937,14 @@ void ARMv5::DWrite16_2() // checkme: does cache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } if (!(PU_Map[addr>>12] & 0x30)) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; WriteBufferCheck<2>(); QueueFunction(&ARMv5::DWrite16_3); } @@ -3040,12 +3057,14 @@ void ARMv5::DWrite32_2() // checkme: does cache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } if (!(PU_Map[addr>>12] & 0x30)) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; WriteBufferCheck<2>(); QueueFunction(&ARMv5::DWrite32_3); } @@ -3153,12 +3172,14 @@ void ARMv5::DWrite32S_2() // checkme: does cache trigger this? if (ICacheStreamPtr < 7) { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; u64 time = ICacheStreamTimes[6] - 6; // checkme: minus 6? if (NDS.ARM9Timestamp < time) NDS.ARM9Timestamp = time; } if (!(PU_Map[addr>>12] & 0x30)) // non-bufferable { + if (NDS.ARM9Timestamp < NDS.DMA9Timestamp) NDS.ARM9Timestamp = NDS.DMA9Timestamp; WriteBufferCheck<2>(); QueueFunction(&ARMv5::DWrite32S_3); } diff --git a/src/DMA.cpp b/src/DMA.cpp index 5269a974..4ea122f3 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -565,14 +565,15 @@ u32 DMA::UnitTimings7_32(bool burststart) void DMA::Run9() { - if (NDS.ARM9Timestamp >= NDS.ARM9Target) return; + NDS.DMA9Timestamp = std::max(NDS.DMA9Timestamp, NDS.ARM9Timestamp); + NDS.DMA9Timestamp = (NDS.DMA9Timestamp + ((1<= NDS.ARM9Target) return; Executing = true; // add NS penalty for first accesses in burst int burststart = Running-1; - - NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<= NDS.ARM9Target) break; + if (NDS.DMA9Timestamp-1 >= NDS.ARM9Target) break; } } else @@ -613,7 +614,7 @@ void DMA::Run9() } Running = 2; - NDS.ARM9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift); + NDS.DMA9Timestamp += (UnitTimings9_32(burststart) << NDS.ARM9ClockShift); burststart -= 1; NDS.ARM9Write32(CurDstAddr, NDS.ARM9Read32(CurSrcAddr)); @@ -623,10 +624,12 @@ void DMA::Run9() IterCount--; RemCount--; - if (NDS.ARM9Timestamp >= NDS.ARM9Target) break; + if (NDS.DMA9Timestamp-1 >= NDS.ARM9Target) break; } } + NDS.DMA9Timestamp -= 1; + if (burststart == 0) Running = 1; Executing = false; diff --git a/src/NDS.cpp b/src/NDS.cpp index 2f97a9db..5d6badef 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -470,7 +470,7 @@ void NDS::Reset() // unitialised on the first run ARM9.CP15Reset(); - ARM9Timestamp = 0; ARM9Target = 0; + ARM9Timestamp = 0; DMA9Timestamp = 0; ARM9Target = 0; ARM7Timestamp = 0; ARM7Target = 0; MainRAMTimestamp = 0; A9ContentionTS = 0; ConTSLock = false; @@ -1127,7 +1127,7 @@ void NDS::MainRAMHandleARM9() burststart -= 1; if (burststart <= 0) dma->Running = 1; else dma->Running = 2; - ARM9Timestamp = A9ContentionTS << ARM9ClockShift; + DMA9Timestamp = (A9ContentionTS << ARM9ClockShift) - 1; memset(&ARM9.MRTrack, 0, sizeof(ARM9.MRTrack)); ConTSLock = false; if (dma->RemCount) @@ -1229,7 +1229,7 @@ void NDS::MainRAMHandleARM9() burststart -= 1; if (burststart <= 0) Running = 1; else dma->Running = 2; - ARM9Timestamp = A9ContentionTS << ARM9ClockShift; + DMA9Timestamp = (A9ContentionTS << ARM9ClockShift) - 1; memset(&ARM9.MRTrack, 0, sizeof(ARM9.MRTrack)); ConTSLock = false; if (dma->RemCount) @@ -1416,6 +1416,8 @@ bool NDS::MainRAMHandle() if (ARM9.MRTrack.Type > MainRAMType::WriteBufferCmds) A9ContentionTS = (ARM9.WBTimestamp + ((1<> ARM9ClockShift; + else if (ARM9.MRTrack.Type == MainRAMType::DMA16 || ARM9.MRTrack.Type == MainRAMType::DMA32) + A9ContentionTS = (DMA9Timestamp + ((1<> ARM9ClockShift; else A9ContentionTS = (ARM9Timestamp + ((1<> ARM9ClockShift; } @@ -1523,7 +1525,7 @@ u32 NDS::RunFrame() ARM9Target = target << ARM9ClockShift; CurCPU = 0; - while (ARM9Timestamp < ARM9Target) + while (std::max(ARM9Timestamp, DMA9Timestamp) < ARM9Target) { if (ARM9.MRTrack.Type == MainRAMType::Null) { @@ -1532,11 +1534,10 @@ u32 NDS::RunFrame() // GXFIFO stall s32 cycles = GPU.GPU3D.CyclesToRunFor(); - ARM9Timestamp = std::min(ARM9Target, ARM9Timestamp+(cycles<(*this); dsi.RunNDMAs(0); } - ts = ARM9Timestamp - ts; - for (int i = 0; i < 7; i++) - { - ARM9.ICacheStreamTimes[i] += ts; - ARM9.DCacheStreamTimes[i] += ts; - } - ARM9.WBTimestamp += ts; } else { diff --git a/src/NDS.h b/src/NDS.h index b0b5a911..939a7a67 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -255,7 +255,7 @@ public: // TODO: Encapsulate the rest of these members bool LagFrameFlag; // no need to worry about those overflowing, they can keep going for atleast 4350 years - u64 ARM9Timestamp, ARM9Target; + u64 ARM9Timestamp, DMA9Timestamp, ARM9Target; u64 ARM7Timestamp, ARM7Target; u64 MainRAMTimestamp; u64 A9ContentionTS; bool ConTSLock;