From ceb5a9febee5ab552d9e60dfce8b82c1f24dabf4 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Fri, 6 Sep 2024 03:59:59 -0400 Subject: [PATCH] draw (most of) the rest of the owl --- src/ARM.cpp | 13 ++++---- src/ARM.h | 13 ++++---- src/ARMInterpreter.cpp | 14 ++++++-- src/ARMInterpreter_ALU.cpp | 34 +++++++++++++++----- src/CP15.cpp | 65 +++++++++++++++++++++++++++++--------- src/NDS.h | 1 + 6 files changed, 102 insertions(+), 38 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index 105607f5..8bac58a2 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -1157,17 +1157,18 @@ u32 ARMv5::ReadMem(u32 addr, int size) #endif -void ARMv5::AddCycles_CI(s32 numI) +void ARMv5::AddCycles_CI(s32 numX) { - NDS.ARM9Timestamp += numI; + NDS.ARM9Timestamp += numX; } -void ARMv5::AddCycles_MW() +void ARMv5::AddCycles_MW(s32 numM) { - u64 TimestampActual = DataCycles + NDS.ARM9Timestamp; - s32 cycles = DataCycles - (3< 0) NDS.ARM9Timestamp += cycles; + numM -= 3< 0) NDS.ARM9Timestamp += numM; } u16 ARMv4::CodeRead16(u32 addr) diff --git a/src/ARM.h b/src/ARM.h index 31ff56cc..6fa74e22 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -284,22 +284,20 @@ public: } - void AddCycles_C() override - { - } + void AddCycles_C() override {} - void AddCycles_CI(s32 numI) override; + void AddCycles_CI(s32 numX) override; - void AddCycles_MW(); + void AddCycles_MW(s32 numM); void AddCycles_CDI() override { - AddCycles_MW(); + AddCycles_MW(DataCycles); } void AddCycles_CD() override { - AddCycles_MW(); + AddCycles_MW(DataCycles); } void GetCodeMemRegion(u32 addr, MemRegion* region); @@ -365,6 +363,7 @@ public: bool (*GetMemRegion)(u32 addr, bool write, MemRegion* region); + u64 ITCMTimestamp; u64 TimestampActual; u8 InterlockMem; u8 InterlockWBCur; diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index 15ec42db..108d343e 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -203,7 +203,12 @@ void A_MRS(ARM* cpu) cpu->R[(cpu->CurInstr>>12) & 0xF] = psr; - if (cpu->Num != 1) cpu->AddCycles_CI(1); // arm9 + if (cpu->Num != 1) // arm9 + { + cpu->AddCycles_C(); // 1 X + cpu->DataRegion = Mem9_Null; + ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M + } else cpu->AddCycles_C(); // arm7 } @@ -263,7 +268,12 @@ void A_MRC(ARM* cpu) return A_UNK(cpu); // TODO: check what kind of exception it really is } - if (cpu->Num != 1) cpu->AddCycles_CI(1); // checkme + if (cpu->Num != 1) + { + cpu->AddCycles_C(); // 1 Execute cycle + cpu->DataRegion = Mem9_Null; + ((ARMv5*)cpu)->AddCycles_MW(2); // 2 Memory cycles + } else cpu->AddCycles_CI(2 + 1); // TODO: checkme } diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index 37c79904..2e9c3078 100644 --- a/src/ARMInterpreter_ALU.cpp +++ b/src/ARMInterpreter_ALU.cpp @@ -774,18 +774,26 @@ void A_MUL(ARM* cpu) if (cpu->Num==1) cpu->SetC(0); } - u32 cycles; if (cpu->Num == 0) - cycles = (cpu->CurInstr & (1<<20)) ? 3 : 1; + { + if (cpu->CurInstr & (1<<20)) cpu->AddCycles_CI(3); + else + { + cpu->AddCycles_C(); // 1 X + cpu->DataRegion = Mem9_Null; + ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M + } + } else { + u32 cycles; if ((rs & 0xFFFFFF00) == 0x00000000 || (rs & 0xFFFFFF00) == 0xFFFFFF00) cycles = 1; else if ((rs & 0xFFFF0000) == 0x00000000 || (rs & 0xFFFF0000) == 0xFFFF0000) cycles = 2; else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 3; else cycles = 4; + cpu->AddCycles_CI(cycles); } - cpu->AddCycles_CI(cycles); } void A_MLA(ARM* cpu) @@ -804,18 +812,26 @@ void A_MLA(ARM* cpu) if (cpu->Num==1) cpu->SetC(0); } - u32 cycles; if (cpu->Num == 0) - cycles = (cpu->CurInstr & (1<<20)) ? 3 : 1; + { + if (cpu->CurInstr & (1<<20)) cpu->AddCycles_CI(3); + else + { + cpu->AddCycles_C(); // 1 X + cpu->DataRegion = Mem9_Null; + ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M + } + } else { + u32 cycles; if ((rs & 0xFFFFFF00) == 0x00000000 || (rs & 0xFFFFFF00) == 0xFFFFFF00) cycles = 2; else if ((rs & 0xFFFF0000) == 0x00000000 || (rs & 0xFFFF0000) == 0xFFFF0000) cycles = 3; else if ((rs & 0xFF000000) == 0x00000000 || (rs & 0xFF000000) == 0xFF000000) cycles = 4; else cycles = 5; + cpu->AddCycles_CI(cycles); } - cpu->AddCycles_CI(cycles); } void A_UMULL(ARM* cpu) @@ -1041,8 +1057,10 @@ void A_SMLALxy(ARM* cpu) cpu->R[(cpu->CurInstr >> 12) & 0xF] = (u32)res; cpu->R[(cpu->CurInstr >> 16) & 0xF] = (u32)(res >> 32ULL); - - cpu->AddCycles_CI(1); // TODO: interlock?? + + cpu->AddCycles_C(); // 1 X + cpu->DataRegion = Mem9_Null; + ((ARMv5*)cpu)->AddCycles_MW(2); // 2 M } diff --git a/src/CP15.cpp b/src/CP15.cpp index eb84d3ee..bcbfbb24 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -321,7 +321,7 @@ void ARMv5::UpdateRegionTimings(u32 addrstart, u32 addrend) { MemTimings[i][1] = ((bustimings[0] - 1) << NDS.ARM9ClockShift) + 1; MemTimings[i][2] = ((bustimings[2] - 1) << NDS.ARM9ClockShift) + 1; - MemTimings[i][3] = ((bustimings[3] - 1) << NDS.ARM9ClockShift) + 1; + MemTimings[i][3] = bustimings[3] << NDS.ARM9ClockShift; // inaccurate but ehgh } } } @@ -781,13 +781,21 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) if (!(PU_Map[addr>>12] & 0x04)) [[unlikely]] { CodeCycles = 1; + + NDS.ARM9Timestamp += CodeCycles; + if (NDS.ARM9Timestamp < TimestampActual) NDS.ARM9Timestamp = TimestampActual; + DataRegion = Mem9_Null; return 0; } if (addr < ITCMSize) { CodeCycles = 1; - if ((DataRegion == Mem9_ITCM) && (TimestampActual >= NDS.ARM9Timestamp)) NDS.ARM9Timestamp = TimestampActual + 1; + + if (NDS.ARM9Timestamp < ITCMTimestamp) NDS.ARM9Timestamp = ITCMTimestamp; + NDS.ARM9Timestamp += CodeCycles; + if (NDS.ARM9Timestamp < TimestampActual) NDS.ARM9Timestamp = TimestampActual; + DataRegion = Mem9_Null; return *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)]; } @@ -811,13 +819,13 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) if (DataRegion == Mem9_MainRAM) NDS.ARM9Timestamp += CodeCycles; } - if (CodeRegion == DataRegion && Store) NDS.ARM9Timestamp += (1<>14] == DataRegion && Store) NDS.ARM9Timestamp += (1<> 12][1]; if ((addr >> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_MainRAM; } else DataRegion = NDS.ARM9Regions[addr>>14]; *val = BusRead8(addr); - DataCycles = MemTimings[addr >> 12][1]; return true; } @@ -874,6 +885,7 @@ bool ARMv5::DataRead16(u32 addr, u32* val) if (addr < ITCMSize) { DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_ITCM; *val = *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)]; return true; @@ -887,16 +899,18 @@ bool ARMv5::DataRead16(u32 addr, u32* val) } NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][1]; if ((addr >> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_MainRAM; } else DataRegion = NDS.ARM9Regions[addr>>14]; *val = BusRead16(addr); - DataCycles = MemTimings[addr >> 12][1]; return true; } @@ -914,6 +928,7 @@ bool ARMv5::DataRead32(u32 addr, u32* val) if (addr < ITCMSize) { DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_ITCM; *val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)]; return true; @@ -927,16 +942,18 @@ bool ARMv5::DataRead32(u32 addr, u32* val) } NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][2]; if ((addr >> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_MainRAM; } else DataRegion = NDS.ARM9Regions[addr>>14]; *val = BusRead32(addr); - DataCycles = MemTimings[addr >> 12][2]; return true; } @@ -953,6 +970,7 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) if (addr < ITCMSize) { DataCycles += 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_ITCM; *val = *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)]; return true; @@ -964,19 +982,21 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) *val = *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)]; return true; } + + NDS.ARM9Timestamp += DataCycles; + DataCycles = MemTimings[addr >> 12][3]; NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_MainRAM; } else DataRegion = NDS.ARM9Regions[addr>>14]; *val = BusRead32(addr); - NDS.ARM9Timestamp += DataCycles; - DataCycles = MemTimings[addr >> 12][3]; return true; } @@ -992,6 +1012,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) if (addr < ITCMSize) { DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_ITCM; *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); @@ -1006,16 +1027,19 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) } NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][1]; if ((addr >> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; DataRegion = Mem9_MainRAM; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; + DataCycles -= (2<>14]; BusWrite8(addr, val); - DataCycles = MemTimings[addr >> 12][1]; return true; } @@ -1033,6 +1057,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) if (addr < ITCMSize) { DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_ITCM; *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); @@ -1047,16 +1072,19 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) } NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][1]; if ((addr >> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; DataRegion = Mem9_MainRAM; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; + DataCycles -= (2<>14]; BusWrite16(addr, val); - DataCycles = MemTimings[addr >> 12][1]; return true; } @@ -1074,6 +1102,7 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) if (addr < ITCMSize) { DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_ITCM; *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); @@ -1088,16 +1117,19 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) } NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][2]; if ((addr >> 24) == 0x02) { if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; DataRegion = Mem9_MainRAM; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; + DataCycles -= (2<>14]; BusWrite32(addr, val); - DataCycles = MemTimings[addr >> 12][2]; return true; } @@ -1114,6 +1146,7 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val, bool dataabort) if (addr < ITCMSize) { DataCycles += 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_ITCM; *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; #ifdef JIT_ENABLED @@ -1130,14 +1163,16 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val, bool dataabort) } NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 24) == 0x02) { - if (NDS.ARM9Timestamp < MainRAMTimestamp) NDS.ARM9Timestamp = MainRAMTimestamp; + if ((DataRegion != Mem9_MainRAM) && ((NDS.ARM9Timestamp + DataCycles) < MainRAMTimestamp)) NDS.ARM9Timestamp = MainRAMTimestamp - DataCycles; + MainRAMTimestamp = NDS.ARM9Timestamp + DataCycles; DataRegion = Mem9_MainRAM; } else DataRegion = NDS.ARM9Regions[addr>>14]; - + BusWrite32(addr, val); DataCycles += MemTimings[addr >> 12][3]; return true; diff --git a/src/NDS.h b/src/NDS.h index b2bfb385..6ee64ac8 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -192,6 +192,7 @@ enum Mem9_VRAM = 0x00000100, Mem9_GBAROM = 0x00020000, Mem9_GBARAM = 0x00040000, + Mem9_Null = 0x80000000, Mem7_BIOS = 0x00000001, Mem7_MainRAM = 0x00000002,