From 3d6ebc1d2b6be2a69e678c7d969a1f5f60025d4a Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Sat, 7 Dec 2024 00:43:36 -0500 Subject: [PATCH] rework tracking of overlap --- src/ARM.cpp | 7 +- src/ARM.h | 1 - src/ARMInterpreter.cpp | 5 +- src/ARMInterpreter_ALU.cpp | 6 +- src/CP15.cpp | 179 ++++++++++++++++--------------------- src/DSi.cpp | 23 ++++- src/NDS.cpp | 3 +- 7 files changed, 108 insertions(+), 116 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index 31cc5028..3a0ffcf1 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -1399,12 +1399,9 @@ void ARMv5::AddCycles_MW(s32 numM) void ARMv5::AddCycles_MW_2() { - s32 numM = DataCycles; - TimestampActual = numM + NDS.ARM9Timestamp; + TimestampActual = NDS.ARM9Timestamp; - numM -= 3< 0) NDS.ARM9Timestamp += numM; + NDS.ARM9Timestamp -= DataCycles; } template diff --git a/src/ARM.h b/src/ARM.h index 41b99882..6add4d29 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -684,7 +684,6 @@ public: void JumpTo_3C(); void JumpTo_4(); void DAbortHandle(); - void DAbortHandleS(); void DCacheFin8(); void DRead8_2(); void DCacheFin16(); diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index 671b3d8b..cfe5ef92 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -37,7 +37,6 @@ namespace melonDS::ARMInterpreter void A_UNK(ARM* cpu) { cpu->AddCycles_C(); - cpu->abt=1; Log(LogLevel::Warn, "undefined ARM%d instruction %08X @ %08X\n", cpu->Num?7:9, cpu->CurInstr, cpu->R[15]-8); #ifdef GDBSTUB_ENABLED cpu->GdbStub.Enter(cpu->GdbStub.IsConnected(), Gdb::TgtStatus::FaultInsn, cpu->R[15]-8); @@ -232,7 +231,7 @@ void A_MRS(ARM* cpu) if (cpu->Num != 1) // arm9 { - cpu->AddCycles_C(); // 1 X + cpu->AddCycles_CI(2); // 1 X ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M } else cpu->AddCycles_C(); // arm7 @@ -314,7 +313,7 @@ void A_MRC(ARM* cpu) if (cpu->Num != 1) { - cpu->AddCycles_C(); // 1 Execute cycle + cpu->AddCycles_CI(2); // 1 Execute cycle ((ARMv5*)cpu)->AddCycles_MW(2); // 2 Memory cycles ((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 12) & 0xF; // only one rd interlocks ((ARMv5*)cpu)->ILCurrTime = ((ARMv5*)cpu)->TimestampActual; diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index 5edf5a39..073d3530 100644 --- a/src/ARMInterpreter_ALU.cpp +++ b/src/ARMInterpreter_ALU.cpp @@ -924,7 +924,7 @@ void A_MUL(ARM* cpu) if (cpu->CurInstr & (1<<20)) cpu->AddCycles_CI(3); // S else { - cpu->AddCycles_C(); // 1 X + cpu->AddCycles_CI(2); // 1 X ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M ((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 16) & 0xF; @@ -971,7 +971,7 @@ void A_MLA(ARM* cpu) if (cpu->CurInstr & (1<<20)) cpu->AddCycles_CI(3); else { - cpu->AddCycles_C(); // 1 X + cpu->AddCycles_CI(2); // 1 X ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M ((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 16) & 0xF; @@ -1331,7 +1331,7 @@ void A_SMLALxy(ARM* cpu) (1 << ((cpu->CurInstr >> 8) & 0xF)) | (1 << ((cpu->CurInstr >> 12) & 0xF))/* | (1 << ((cpu->CurInstr >> 16) & 0xF))*/, iltime); - cpu->AddCycles_C(); // 1 X + cpu->AddCycles_CI(2); // 1 X ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M ((ARMv5*)cpu)->ILCurrReg = (cpu->CurInstr >> 16) & 0xF; // only one rd interlocks diff --git a/src/CP15.cpp b/src/CP15.cpp index 2496fa68..27705262 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -636,7 +636,7 @@ bool ARMv5::DCacheLookup(const u32 addr) if (DCacheStreamPtr >= 7) { - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; } else { @@ -644,6 +644,8 @@ bool ARMv5::DCacheLookup(const u32 addr) //if (NDS.ARM9Timestamp < nextfill) // can this ever really fail? { DataCycles = nextfill - NDS.ARM9Timestamp; + if (DataCycles > (3<> 14][1] + (MemTimings[tag >> 14][2] * ((DCACHE_LINELENGTH / 4) - 2)); + NDS.ARM9Timestamp += MemTimings[tag >> 14][1] + (MemTimings[tag >> 14][2] * ((DCACHE_LINELENGTH / 4) - 1)); DataCycles = MemTimings[tag>>14][2]; DataRegion = NDS.ARM9Regions[addr>>14]; @@ -759,9 +761,9 @@ bool ARMv5::DCacheLookup(const u32 addr) u8 linepos = (addr & 0x1F) >> 2; // technically this is one too low, but we want that actually u64 cycles = ns + (seq * linepos); - DataCycles = cycles; - - cycles += NDS.ARM9Timestamp; + DataCycles = 3<> 2] = val; - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; DataRegion = Mem9_DCache; #if !DISABLE_CACHEWRITEBACK if (PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_BUFFERABLE) @@ -889,7 +891,7 @@ bool ARMv5::DCacheWrite16(const u32 addr, const u16 val) { u16 *cacheLine = (u16 *)&DCache[(id+set) << DCACHE_LINELENGTH_LOG2]; cacheLine[(addr & (DCACHE_LINELENGTH-1)) >> 1] = val; - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; DataRegion = Mem9_DCache; #if !DISABLE_CACHEWRITEBACK if (PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_BUFFERABLE) @@ -958,7 +960,7 @@ bool ARMv5::DCacheWrite8(const u32 addr, const u8 val) { u8 *cacheLine = &DCache[(id+set) << DCACHE_LINELENGTH_LOG2]; cacheLine[addr & (DCACHE_LINELENGTH-1)] = val; - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; DataRegion = Mem9_DCache; #if !DISABLE_CACHEWRITEBACK if (PU_Map[addr >> CP15_MAP_ENTRYSIZE_LOG2] & CP15_MAP_BUFFERABLE) @@ -2113,21 +2115,7 @@ void ARMv5::DAbortHandle() DCacheStreamPtr = 7; } - DataCycles = 1; -} - -void ARMv5::DAbortHandleS() -{ - NDS.ARM9Timestamp += DataCycles; - - if (DCacheStreamPtr < 7) - { - u64 fillend = DCacheStreamTimes[6] + 1; - if (NDS.ARM9Timestamp < fillend) NDS.ARM9Timestamp = fillend; // checkme: should this be data cycles? - DCacheStreamPtr = 7; - } - - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; } void ARMv5::DCacheFin8() @@ -2171,15 +2159,15 @@ void ARMv5::DRead8_2() if (addr < ITCMSize) { - DataCycles = 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + NDS.ARM9Timestamp += DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp; DataRegion = Mem9_ITCM; *val = *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)]; return; } if ((addr & DTCMMask) == DTCMBase) { - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; DataRegion = Mem9_DTCM; *val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)]; return; @@ -2216,8 +2204,6 @@ void ARMv5::DRead8_2() NDS.ARM9Timestamp = (NDS.ARM9Timestamp + ((1<> 14][0]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2226,12 +2212,14 @@ void ARMv5::DRead8_2() } else { + NDS.ARM9Timestamp += MemTimings[addr >> 14][0]; + DataCycles = 3<>14]; if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<> 14][0]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2334,12 +2320,14 @@ void ARMv5::DRead16_2() } else { + NDS.ARM9Timestamp += MemTimings[addr >> 14][0]; + DataCycles = 3<>14]; if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<> 14][1]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2443,12 +2429,14 @@ void ARMv5::DRead32_2() } else { + NDS.ARM9Timestamp += MemTimings[addr >> 14][1]; + DataCycles = 3<>14]; if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<>12] & CP15_MAP_READABLE)) [[unlikely]] { - QueueFunction(&ARMv5::DAbortHandleS); + QueueFunction(&ARMv5::DAbortHandle); return false; } @@ -2477,13 +2465,11 @@ void ARMv5::DRead32S_2() u32 addr = FetchAddr[reg]; u32 dummy; u32* val = (LDRFailedRegs & (1<>14][2]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2541,12 +2525,14 @@ void ARMv5::DRead32S_2() } else { + NDS.ARM9Timestamp += MemTimings[addr>>14][2]; + DataCycles = MemTimings[addr>>14][2]; DataRegion = NDS.ARM9Regions[addr>>14]; if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<>14][1]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2564,12 +2548,14 @@ void ARMv5::DRead32S_2() } else { + NDS.ARM9Timestamp += MemTimings[addr>>14][1]; + DataCycles = 3<>14]; if ((NDS.ARM9Timestamp <= WBReleaseTS) && (DataRegion == WBLastRegion)) // check write buffer NDS.ARM9Timestamp += 1<> 14][0]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2663,10 +2647,12 @@ void ARMv5::DWrite8_2() } else { + NDS.ARM9Timestamp += MemTimings[addr >> 14][0]; + DataCycles = 3<>14]; - if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<> 14][0]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2771,10 +2755,12 @@ void ARMv5::DWrite16_2() } else { + NDS.ARM9Timestamp += MemTimings[addr >> 14][0]; + DataCycles = NDS.ARM9ClockShift; DataRegion = NDS.ARM9Regions[addr>>14]; - if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<> 14][1]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2884,10 +2868,12 @@ void ARMv5::DWrite32_2() } else { + NDS.ARM9Timestamp += MemTimings[addr >> 14][1]; + DataCycles = 3<>14]; - if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<>12] & CP15_MAP_WRITEABLE)) [[unlikely]] { - QueueFunction(&ARMv5::DAbortHandleS); + QueueFunction(&ARMv5::DAbortHandle); return false; } @@ -2928,13 +2914,11 @@ void ARMv5::DWrite32S_2() u32 addr = FetchAddr[reg]; u32 val = STRVal[reg]; - NDS.ARM9Timestamp += DataCycles; - addr &= ~3; if (addr < ITCMSize) { - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; // we update the timestamp during the actual function, as a sequential itcm access can only occur during instructions with strange itcm wait cycles DataRegion = Mem9_ITCM; *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; @@ -2946,7 +2930,7 @@ void ARMv5::DWrite32S_2() } if ((addr & DTCMMask) == DTCMBase) { - DataCycles = 1; + NDS.ARM9Timestamp += DataCycles = 1; DataRegion = Mem9_DTCM; *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; STRRegs &= ~1<>14][2]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -2994,25 +2976,18 @@ void ARMv5::DWrite32S_2() } else { + NDS.ARM9Timestamp += DataCycles = MemTimings[addr>>14][2]; DataRegion = NDS.ARM9Regions[addr>>14]; - if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<>14][1]; - if ((addr >> 24) == 0x02) { MRTrack.Type = MainRAMType::Fetch; @@ -3021,10 +2996,12 @@ void ARMv5::DWrite32S_2() } else { + NDS.ARM9Timestamp += MemTimings[addr>>14][1]; + DataCycles = 3 << NDS.ARM9ClockShift; DataRegion = NDS.ARM9Regions[addr>>14]; - if (WBTimestamp < ((NDS.ARM9Timestamp + DataCycles + ((1<>= ARM9ClockShift; ARM9Target >>= ARM9ClockShift; + for (int i = 0; i < 7; i++) + { + ARM9.ICacheStreamTimes[i] >>= ARM9ClockShift; + ARM9.DCacheStreamTimes[i] >>= ARM9ClockShift; + } + ARM9.WBTimestamp >>= ARM9ClockShift; + ARM9.WBDelay >>= ARM9ClockShift; + ARM9.WBReleaseTS >>= ARM9ClockShift; + ARM9.WBInitialTS >>= ARM9ClockShift; Log(LogLevel::Debug, "CLOCK9=%04X\n", val); SCFG_Clock9 = val & 0x0187; @@ -1286,6 +1295,16 @@ void DSi::Set_SCFG_Clock9(u16 val) ARM9Timestamp <<= ARM9ClockShift; ARM9Target <<= ARM9ClockShift; + for (int i = 0; i < 7; i++) + { + ARM9.ICacheStreamTimes[i] <<= ARM9ClockShift; + ARM9.DCacheStreamTimes[i] <<= ARM9ClockShift; + } + ARM9.WBTimestamp <<= ARM9ClockShift; + ARM9.WBDelay <<= ARM9ClockShift; + ARM9.WBReleaseTS <<= ARM9ClockShift; + ARM9.WBInitialTS <<= ARM9ClockShift; + ARM9.UpdateRegionTimings(0x00000, 0x40000); } @@ -2562,7 +2581,7 @@ void DSi::ARM9IOWrite32(u32 addr, u32 val) if (oldvram != newvram) SetVRAMTimings(newvram); - /*switch ((SCFG_EXT[0] >> 14) & 0x3) + switch ((SCFG_EXT[0] >> 14) & 0x3) { case 0: case 1: @@ -2575,7 +2594,7 @@ void DSi::ARM9IOWrite32(u32 addr, u32 val) NDS::MainRAMMask = 0xFFFFFF; printf("RAM: 16MB\n"); break; - }*/ + } // HAX!! // a change to the RAM size setting is supposed to apply immediately (it does so on hardware) // however, doing so will cause DS-mode app startup to break, because the change happens while the ARM7 diff --git a/src/NDS.cpp b/src/NDS.cpp index 2436b926..034a2dcc 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -928,7 +928,8 @@ void NDS::MainRAMHandleARM9() if ((var & MRSequential) && A9WENTLAST) { - MainRAMTimestamp = A9ContentionTS += 2; + A9ContentionTS += 2; + MainRAMTimestamp += 2; ARM9.DataCycles = 2 << ARM9ClockShift; } else