From e33d19cf14d2f0669d65de3f36b989ee54ef8c59 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Fri, 18 Oct 2024 21:08:56 -0400 Subject: [PATCH] fix a few misc things? --- src/ARM.cpp | 19 +++++-- src/ARMInterpreter_LoadStore.cpp | 86 +++++++++++++++++++++++++------- src/CP15.cpp | 58 +++++++++++---------- 3 files changed, 115 insertions(+), 48 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index 75d88aea..8bcdd452 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -1184,14 +1184,24 @@ void ARMv5::HandleInterlocksExecute(u16 ilmask) { if ((bitfield && (ilmask & (1<(u16 ilmask); void ARMv5::HandleInterlocksMemory(u8 reg) { if ((reg != ILPrevReg) || (NDS.ARM9Timestamp >= ILPrevTime)) return; - + + u64 diff = ILPrevTime - NDS.ARM9Timestamp; // should always be 1? NDS.ARM9Timestamp = ILPrevTime; + MainRAMTimestamp += diff; + ITCMTimestamp += diff; ILPrevTime = 16; } diff --git a/src/ARMInterpreter_LoadStore.cpp b/src/ARMInterpreter_LoadStore.cpp index b965c078..28256207 100644 --- a/src/ARMInterpreter_LoadStore.cpp +++ b/src/ARMInterpreter_LoadStore.cpp @@ -157,7 +157,11 @@ void StoreSingle(ARM* cpu, u8 rd, u8 rn, s32 offset, u16 ilmask) ((ARMv5*)cpu)->PU_Map = ((ARMv5*)cpu)->PU_UserMap; } - if (cpu->Num == 0) ((ARMv5*)cpu)->HandleInterlocksMemory(rd); + if (cpu->Num == 0) + { + ((ARMv5*)cpu)->HandleInterlocksMemory(rd); + ((ARMv5*)cpu)->Store = true; + } bool dabort; if constexpr (size == 8) dabort = !cpu->DataWrite8 (addr, storeval); @@ -614,14 +618,20 @@ void A_LDM(ARM* cpu) // switch back to previous regs if ((cpu->CurInstr & (1<<22)) && !(cpu->CurInstr & (1<<15))) cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true); - - cpu->AddCycles_CDI(); + if (__builtin_popcount(cpu->CurInstr & 0xFFFF) == 1) [[unlikely]] // single reg { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1; + cpu->AddCycles_CDI(); if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages else; // CHECKME: ARM7 timing behavior? } + else + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2; + cpu->AddCycles_CDI(); + } // handle data aborts if (dabort) [[unlikely]] @@ -739,13 +749,18 @@ void A_STM(ARM* cpu) if (cpu->CurInstr & (1<<22)) cpu->UpdateMode((cpu->CPSR&~0x1F)|0x10, cpu->CPSR, true); - cpu->AddCycles_CD(); - if (__builtin_popcount(cpu->CurInstr & 0xFFFF) == 1) [[unlikely]] // single reg { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1; + cpu->AddCycles_CD(); if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages else; // CHECKME: ARM7 timing behavior? } + else + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2; + cpu->AddCycles_CD(); + } // handle data aborts if (dabort) [[unlikely]] @@ -919,13 +934,18 @@ void T_PUSH(ARM* cpu) : cpu->DataWrite32S(base, cpu->R[14])); } - cpu->AddCycles_CD(); - if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1; + cpu->AddCycles_CD(); if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages else; // CHECKME: ARM7 timing behavior? } + else + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2; + cpu->AddCycles_CD(); + } if (dabort) [[unlikely]] { @@ -970,30 +990,47 @@ void T_POP(ARM* cpu) dabort |= !(first ? cpu->DataRead32 (base, &pc) : cpu->DataRead32S(base, &pc)); + if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1; + cpu->AddCycles_CDI(); + if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages + else; // CHECKME: ARM7 timing behavior? + } + else + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2; + cpu->AddCycles_CDI(); + } + if (!dabort) [[likely]] { - cpu->AddCycles_CDI(); - - if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg - { - if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages - else; // CHECKME: ARM7 timing behavior? - } - if (cpu->Num==1 || (((ARMv5*)cpu)->CP15Control & (1<<15))) pc |= 0x1; cpu->JumpTo(pc); base += 4; } + else [[unlikely]] + { + ((ARMv5*)cpu)->DataAbort(); + return; + } } else { - cpu->AddCycles_CDI(); + if (__builtin_popcount(cpu->CurInstr & 0x1FF) == 1) [[unlikely]] // single reg { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1; + cpu->AddCycles_CDI(); if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages else; // CHECKME: ARM7 timing behavior? } + else + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2; + cpu->AddCycles_CDI(); + } if (cpu->Num == 0) { @@ -1045,13 +1082,19 @@ void T_STMIA(ARM* cpu) } } - cpu->AddCycles_CD(); if (__builtin_popcount(cpu->CurInstr & 0xFF) == 1) [[unlikely]] // single reg { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1; + cpu->AddCycles_CD(); if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages else; // CHECKME: ARM7 timing behavior? } + else + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2; + cpu->AddCycles_CD(); + } if (dabort) [[unlikely]] { @@ -1090,13 +1133,18 @@ void T_LDMIA(ARM* cpu) } } - cpu->AddCycles_CDI(); - if (__builtin_popcount(cpu->CurInstr & 0xFF) == 1) [[unlikely]] // single reg { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1; + cpu->AddCycles_CDI(); if (cpu->Num == 0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampActual; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages else; // CHECKME: ARM7 timing behavior? } + else + { + if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 2; + cpu->AddCycles_CDI(); + } if (dabort) [[unlikely]] { diff --git a/src/CP15.cpp b/src/CP15.cpp index 6c9c7951..c9f184d6 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -926,7 +926,8 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp + ((1<>14] == DataRegion && Store) NDS.ARM9Timestamp += (1<>12] & 0x01)) [[unlikely]] @@ -984,7 +984,6 @@ bool ARMv5::DataRead8(u32 addr, u32* val) bool ARMv5::DataRead16(u32 addr, u32* val) { - Store = false; // Data Aborts // Exception is handled in the actual instruction implementation if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]] @@ -1032,7 +1031,6 @@ bool ARMv5::DataRead16(u32 addr, u32* val) bool ARMv5::DataRead32(u32 addr, u32* val) { - Store = false; // Data Aborts // Exception is handled in the actual instruction implementation if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]] @@ -1084,7 +1082,8 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) // Exception is handled in the actual instruction implementation if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]] { - DataCycles += 1; + NDS.ARM9Timestamp += DataCycles; + DataCycles = 1; return false; } @@ -1092,15 +1091,17 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) if (addr < ITCMSize) { - DataCycles += 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + NDS.ARM9Timestamp += DataCycles; + 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; *val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)]; return true; } if ((addr & DTCMMask) == DTCMBase) { - DataCycles += 1; + NDS.ARM9Timestamp += DataCycles; + DataCycles = 1; DataRegion = Mem9_DTCM; *val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)]; return true; @@ -1111,9 +1112,9 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) NDS.ARM9Timestamp += DataCycles; - if (!(addr & 0x3FF)) return DataRead32(addr, val); // bursts cannot cross a 1kb boundary - - DataCycles = MemTimings[addr >> 12][3]; + // bursts cannot cross a 1kb boundary + if (addr & 0x3FF) DataCycles = MemTimings[addr >> 12][3]; //s + else DataCycles = MemTimings[addr >> 12][2]; // ns NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<>12] & 0x02)) [[unlikely]] @@ -1143,7 +1143,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) if (addr < ITCMSize) { DataCycles = 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + // does not stall (for some reason?) DataRegion = Mem9_ITCM; *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; #ifdef JIT_ENABLED @@ -1170,7 +1170,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; DataRegion = Mem9_MainRAM; MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; - DataCycles -= (2<>14]; @@ -1196,7 +1196,6 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) bool ARMv5::DataWrite16(u32 addr, u16 val) { - Store = true; // Data Aborts // Exception is handled in the actual instruction implementation if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]] @@ -1210,7 +1209,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) if (addr < ITCMSize) { DataCycles = 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + // does not stall (for some reason?) DataRegion = Mem9_ITCM; *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; #ifdef JIT_ENABLED @@ -1237,7 +1236,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; DataRegion = Mem9_MainRAM; MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; - DataCycles -= (2<>14]; @@ -1263,7 +1262,6 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) bool ARMv5::DataWrite32(u32 addr, u32 val) { - Store = true; // Data Aborts // Exception is handled in the actual instruction implementation if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]] @@ -1277,7 +1275,7 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) if (addr < ITCMSize) { DataCycles = 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + // does not stall (for some reason?) DataRegion = Mem9_ITCM; *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; #ifdef JIT_ENABLED @@ -1304,7 +1302,7 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; DataRegion = Mem9_MainRAM; MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; - DataCycles -= (2<>14]; @@ -1343,7 +1341,7 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val) if (addr < ITCMSize) { DataCycles += 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + // 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; #ifdef JIT_ENABLED @@ -1362,13 +1360,16 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val) if (!(PU_Map[addr>>12] & 0x30)) { DataCycles += (((NDS.ARM9Timestamp + DataCycles) + ((1<> 12][3]; //s + else DataCycles += MemTimings[addr >> 12][2]; // ns if ((addr >> 24) == 0x02) { - if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) DataCycles += MainRAMTimestamp - NDS.ARM9Timestamp; - MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; + //if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) DataCycles += MainRAMTimestamp - NDS.ARM9Timestamp; // what the hell was i smoking here? + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles + (2 << NDS.ARM9ClockShift); DataRegion = Mem9_MainRAM; } else DataRegion = NDS.ARM9Regions[addr>>14]; @@ -1378,7 +1379,12 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val) } else { - u8 cycles = NDS.ARM9MemTimings[addr>>14][3]; + u8 cycles; + // bursts cannot cross a 1kb boundary + // CHECKME: does this actually apply to the write buffer too? it should + if (addr & 0x3FF) cycles = NDS.ARM9MemTimings[addr>>14][3]; //s + else cycles = NDS.ARM9MemTimings[addr>>14][2]; // ns + if ((addr >> 24) == 0x02) { cycles = (cycles - 2) | 0x80;