From e25dca003020cc39de90456c58340b69d0d108f1 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 10 Oct 2024 03:14:01 -0400 Subject: [PATCH 1/8] writing to the write buffer has a 1 cycle delay before it can be done again --- src/ARM.cpp | 1 + src/ARM.h | 1 + src/CP15.cpp | 11 +++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index 7072978d..8c74a248 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -210,6 +210,7 @@ void ARMv5::Reset() WBWritePointer = 16; WBFillPointer = 0; + WBDelay = 0; ARM::Reset(); } diff --git a/src/ARM.h b/src/ARM.h index 12675023..16f4b72a 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -377,6 +377,7 @@ public: u8 WBWritePointer; u8 WBFillPointer; + u64 WBDelay; u32 WBAddr; // current working address for the write buffer u32 storeaddr[16]; // debugging u64 WBCycles[16]; // timestamp each write will complete diff --git a/src/CP15.cpp b/src/CP15.cpp index c0da4711..1d082f04 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -1297,10 +1297,11 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) } else { - NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1< NDS.ARM9Timestamp) NDS.ARM9Timestamp = WBDelay; DataCycles = 1; WriteBufferWrite(addr, 3, 1); WriteBufferWrite(val, 0, MemTimings[addr >> 12][1], addr); + WBDelay = NDS.ARM9Timestamp + 2; } return true; } @@ -1357,10 +1358,11 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) } else { - NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1< NDS.ARM9Timestamp) NDS.ARM9Timestamp = WBDelay; DataCycles = 1; WriteBufferWrite(addr, 3, 1); WriteBufferWrite(val, 1, MemTimings[addr >> 12][1], addr); + WBDelay = NDS.ARM9Timestamp + 2; } return true; } @@ -1417,10 +1419,11 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) } else { - NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1< NDS.ARM9Timestamp) NDS.ARM9Timestamp = WBDelay; DataCycles = 1; WriteBufferWrite(addr, 3, 1); WriteBufferWrite(val, 2, MemTimings[addr >> 12][2], addr); + WBDelay = NDS.ARM9Timestamp + 2; } return true; } @@ -1476,9 +1479,9 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val) } else { - DataCycles += (((NDS.ARM9Timestamp + DataCycles) + ((1<> 12][3], addr); + WBDelay = NDS.ARM9Timestamp + DataCycles + 1; } return true; } From 53b38c363fb820f97c4f44b8601540970f9017cf Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 10 Oct 2024 03:32:53 -0400 Subject: [PATCH 2/8] ok no it didn't lie to me --- src/ARMInterpreter.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index 72d1e189..1f95c1f8 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -136,7 +136,8 @@ void A_MSR_IMM(ARM* cpu) } } - cpu->AddCycles_C(); + if ((cpu->Num != 1) && (cpu->CurInstr & (0x7<<16))) cpu->AddCycles_CI(2); + else cpu->AddCycles_C(); } void A_MSR_REG(ARM* cpu) @@ -196,7 +197,8 @@ void A_MSR_REG(ARM* cpu) } } - cpu->AddCycles_C(); + if ((cpu->Num != 1) && (cpu->CurInstr & (0x7<<16))) cpu->AddCycles_CI(2); + else cpu->AddCycles_C(); } void A_MRS(ARM* cpu) From 3870216fd06f634c2b0864feea5c4353ca94fd0b Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 10 Oct 2024 03:53:51 -0400 Subject: [PATCH 3/8] correction: --- src/ARMInterpreter.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index 1f95c1f8..2b14de73 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -98,7 +98,8 @@ void A_MSR_IMM(ARM* cpu) case 0x1A: case 0x1B: psr = &cpu->R_UND[2]; break; default: - cpu->AddCycles_C(); + if (cpu->Num != 1) cpu->AddCycles_C(); // arm 7 + else cpu->AddCycles_CI(2); // arm 9 return; } } @@ -135,8 +136,16 @@ void A_MSR_IMM(ARM* cpu) cpu->CPSR &= ~0x20; // keep it from crashing the emulator at least } } - - if ((cpu->Num != 1) && (cpu->CurInstr & (0x7<<16))) cpu->AddCycles_CI(2); + + if (cpu->Num != 1) + { + if (cpu->CurInstr & (1<<22)) + { + cpu->AddCycles_CI(2); // spsr_fsxc + } + else if (cpu->CurInstr & (0x7<<16)) cpu->AddCycles_CI(2); // cpsr_sxc + else cpu->AddCycles_C(); + } else cpu->AddCycles_C(); } @@ -159,7 +168,8 @@ void A_MSR_REG(ARM* cpu) case 0x1A: case 0x1B: psr = &cpu->R_UND[2]; break; default: - cpu->AddCycles_C(); + if (cpu->Num != 1) cpu->AddCycles_C(); // arm 7 + else cpu->AddCycles_CI(2); // arm 9 return; } } @@ -196,8 +206,16 @@ void A_MSR_REG(ARM* cpu) cpu->CPSR &= ~0x20; // keep it from crashing the emulator at least } } - - if ((cpu->Num != 1) && (cpu->CurInstr & (0x7<<16))) cpu->AddCycles_CI(2); + + if (cpu->Num != 1) + { + if (cpu->CurInstr & (1<<22)) + { + cpu->AddCycles_CI(2); // spsr_fsxc + } + else if (cpu->CurInstr & (0x7<<16)) cpu->AddCycles_CI(2); // cpsr_sxc + else cpu->AddCycles_C(); + } else cpu->AddCycles_C(); } From 93dce82b078a1df48fb2d74a6091300f5e807b37 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:48:17 -0400 Subject: [PATCH 4/8] implement cmp with "rd == 15" on arm9 cmp and friends with bits 12-15 set to 1 borrow characteristics from their legacy 26 bit p variants thumb version does nothing of note --- src/ARMInterpreter.cpp | 4 +- src/ARMInterpreter_ALU.cpp | 82 ++++++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index 2b14de73..a04b6140 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -141,7 +141,7 @@ void A_MSR_IMM(ARM* cpu) { if (cpu->CurInstr & (1<<22)) { - cpu->AddCycles_CI(2); // spsr_fsxc + cpu->AddCycles_CI(2); // spsr } else if (cpu->CurInstr & (0x7<<16)) cpu->AddCycles_CI(2); // cpsr_sxc else cpu->AddCycles_C(); @@ -211,7 +211,7 @@ void A_MSR_REG(ARM* cpu) { if (cpu->CurInstr & (1<<22)) { - cpu->AddCycles_CI(2); // spsr_fsxc + cpu->AddCycles_CI(2); // spsr } else if (cpu->CurInstr & (0x7<<16)) cpu->AddCycles_CI(2); // cpsr_sxc else cpu->AddCycles_C(); diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index 9305fc42..83fc1944 100644 --- a/src/ARMInterpreter_ALU.cpp +++ b/src/ARMInterpreter_ALU.cpp @@ -581,12 +581,12 @@ A_IMPLEMENT_ALU_OP(RSC,) #define A_TST(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a & b; \ - cpu->SetNZ(res & 0x80000000, \ - !res); \ - if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \ + if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* this seems to trigger alu rd==15 behavior for arm7 and legacy instruction behavior for arm9 */ \ { \ if (cpu->Num == 1) \ { \ + cpu->SetNZ(res & 0x80000000, \ + !res); \ u32 oldpsr = cpu->CPSR; \ cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ if (cpu->CPSR & 0x20) \ @@ -595,7 +595,12 @@ A_IMPLEMENT_ALU_OP(RSC,) cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \ } \ } \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TST w/ rd == 15 on ARM9\n"); \ + else cpu->JumpTo(res & ~1, true); /* TSTP dna, doesn't update flags */ \ + } \ + else \ + { \ + cpu->SetNZ(res & 0x80000000, \ + !res); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -605,12 +610,12 @@ A_IMPLEMENT_ALU_TEST(TST,_S) #define A_TEQ(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a ^ b; \ - cpu->SetNZ(res & 0x80000000, \ - !res); \ - if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \ + if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* this seems to trigger alu rd==15 behavior for arm7 and legacy instruction behavior for arm9 */ \ { \ if (cpu->Num == 1) \ { \ + cpu->SetNZ(res & 0x80000000, \ + !res); \ u32 oldpsr = cpu->CPSR; \ cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ if (cpu->CPSR & 0x20) \ @@ -619,7 +624,12 @@ A_IMPLEMENT_ALU_TEST(TST,_S) cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \ } \ } \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TEQ w/ rd == 15 on ARM9\n"); \ + else cpu->JumpTo(res & ~1, true); /* TEQP dna, doesn't update flags */ \ + } \ + else \ + { \ + cpu->SetNZ(res & 0x80000000, \ + !res); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -629,14 +639,14 @@ A_IMPLEMENT_ALU_TEST(TEQ,_S) #define A_CMP(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a - b; \ - cpu->SetNZCV(res & 0x80000000, \ - !res, \ - CarrySub(a, b), \ - OverflowSub(a, b)); \ - if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \ + if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* this seems to trigger alu rd==15 behavior for arm7 and legacy instruction behavior for arm9 */ \ { \ if (cpu->Num == 1) \ { \ + cpu->SetNZCV(res & 0x80000000, \ + !res, \ + CarrySub(a, b), \ + OverflowSub(a, b)); \ u32 oldpsr = cpu->CPSR; \ cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ if (cpu->CPSR & 0x20) \ @@ -645,7 +655,14 @@ A_IMPLEMENT_ALU_TEST(TEQ,_S) cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \ } \ } \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP w/ rd == 15 on ARM9\n"); \ + else cpu->JumpTo(res & ~1, true); /* CMPP dna, doesn't update flags */ \ + } \ + else \ + { \ + cpu->SetNZCV(res & 0x80000000, \ + !res, \ + CarrySub(a, b), \ + OverflowSub(a, b)); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -655,14 +672,14 @@ A_IMPLEMENT_ALU_TEST(CMP,) #define A_CMN(c) \ u32 a = cpu->R[(cpu->CurInstr>>16) & 0xF]; \ u32 res = a + b; \ - cpu->SetNZCV(res & 0x80000000, \ - !res, \ - CarryAdd(a, b), \ - OverflowAdd(a, b)); \ - if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* yes this instruction has a secret rd for some reason */ \ + if (((cpu->CurInstr>>12) & 0xF) == 15) [[unlikely]] /* this seems to trigger alu rd==15 behavior for arm7 and legacy instruction behavior for arm9 */ \ { \ if (cpu->Num == 1) \ { \ + cpu->SetNZCV(res & 0x80000000, \ + !res, \ + CarryAdd(a, b), \ + OverflowAdd(a, b)); \ u32 oldpsr = cpu->CPSR; \ cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ if (cpu->CPSR & 0x20) \ @@ -671,7 +688,14 @@ A_IMPLEMENT_ALU_TEST(CMP,) cpu->CPSR &= ~0x20; /* keep it from crashing the emulator at least */ \ } \ } \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMN w/ rd == 15 on ARM9\n"); \ + else cpu->JumpTo(res & ~1, true); /* CMNP dna, doesn't update flags */ \ + } \ + else \ + { \ + cpu->SetNZCV(res & 0x80000000, \ + !res, \ + CarryAdd(a, b), \ + OverflowAdd(a, b)); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -1625,20 +1649,18 @@ void T_CMP_HIREG(ARM* cpu) !res, CarrySub(a, b), OverflowSub(a, b)); - if (rd == 15) [[unlikely]] + + if ((cpu->Num == 1) && (rd == 15)) { - if (cpu->Num == 1) + u32 oldpsr = cpu->CPSR; + cpu->RestoreCPSR(); // ARM7TDMI restores cpsr and does ___not___ flush the pipeline. + if (!(cpu->CPSR & 0x20)) { - u32 oldpsr = cpu->CPSR; - cpu->RestoreCPSR(); // ARM7TDMI restores cpsr and does ___not___ flush the pipeline. - if (!(cpu->CPSR & 0x20)) - { - Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n"); - cpu->CPSR |= 0x20; // keep it from crashing the emulator at least - } + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n"); + cpu->CPSR |= 0x20; // keep it from crashing the emulator at least } - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP HIREG w/ rd == 15 on ARM9\n"); } + cpu->AddCycles_C(); } From 787d0c9afcd963380eb364b72ac71e7012d85689 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 10 Oct 2024 11:09:07 -0400 Subject: [PATCH 5/8] mrc r15 updates flags also my prior implementation made mrc w/ r15 raise an exception by accident oops! --- src/ARMInterpreter.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index a04b6140..82dc6876 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -297,11 +297,17 @@ void A_MRC(ARM* cpu) u32 cpinfo = (cpu->CurInstr >> 5) & 0x7; u32 rd = (cpu->CurInstr>>12) & 0xF; - if (cpu->Num==0 && cp==15 && rd!=15) + if (cpu->Num==0 && cp==15) { - cpu->R[rd] = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo); + if (rd != 15) cpu->R[rd] = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo); + else + { + // r15 updates the top 4 bits of the cpsr, done to "allow for conditional branching based on coprocessor status" + u32 flags = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo) & 0xF0000000; + cpu->CPSR = (cpu->CPSR & ~0xF0000000) | flags; + } } - else if (cpu->Num==1 && cp==14 && rd!=15) + else if (cpu->Num==1 && cp==14) { Log(LogLevel::Debug, "MRC p14,%d,%d,%d on ARM7\n", cn, cm, cpinfo); } From 34bba2589e3ddbe94642dd3325a49179cdf27f82 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:51:52 -0400 Subject: [PATCH 6/8] tcm (and cache?) reads dont trigger write buffer drains additionally drains are triggered even in no cache + no buffer regions despite documentation not specifying such --- src/CP15.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/CP15.cpp b/src/CP15.cpp index 1d082f04..3ea67f3f 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -1014,9 +1014,6 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) return 0; } - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); - if (addr < ITCMSize) { CodeCycles = 1; @@ -1039,6 +1036,8 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) //return *(u32*)&CurICacheLine[addr & 0x1C]; } + WriteBufferDrain(); + NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 24) == 0x02) @@ -1066,9 +1065,6 @@ bool ARMv5::DataRead8(u32 addr, u32* val) DataCycles = 1; return false; } - - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); if (addr < ITCMSize) { @@ -1085,6 +1081,8 @@ bool ARMv5::DataRead8(u32 addr, u32* val) *val = *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)]; return true; } + + WriteBufferDrain(); NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<>12] & 0x30)) - WriteBufferDrain(); if (addr < ITCMSize) { @@ -1133,6 +1129,8 @@ bool ARMv5::DataRead16(u32 addr, u32* val) return true; } + WriteBufferDrain(); + NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][1]; @@ -1162,9 +1160,6 @@ bool ARMv5::DataRead32(u32 addr, u32* val) addr &= ~3; - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); - if (addr < ITCMSize) { DataCycles = 1; @@ -1181,6 +1176,8 @@ bool ARMv5::DataRead32(u32 addr, u32* val) return true; } + WriteBufferDrain(); + NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][2]; @@ -1209,9 +1206,6 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) addr &= ~3; - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); - if (addr < ITCMSize) { DataCycles += 1; @@ -1228,6 +1222,8 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) return true; } + WriteBufferDrain(); + NDS.ARM9Timestamp += DataCycles; if (!(addr & 0x3FF)) return DataRead32(addr, val); // bursts cannot cross a 1kb boundary From 3d246ddf739af6b9c22e01349f9d139b3ab60c79 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 10 Oct 2024 22:54:33 -0400 Subject: [PATCH 7/8] tcms just aren't bufferable --- src/CP15.cpp | 245 ++++++++++++++++++--------------------------------- 1 file changed, 85 insertions(+), 160 deletions(-) diff --git a/src/CP15.cpp b/src/CP15.cpp index 3ea67f3f..ce56949b 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -450,43 +450,19 @@ void ARMv5::WriteBufferCheck() case 0: // byte { u8 val = WriteBufferFifo[WBWritePointer] & 0xFF; - if (WBAddr < ITCMSize) - { - *(u8*)&ITCM[WBAddr & (ITCMPhysicalSize - 1)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u8*)&DTCM[WBAddr & (DTCMPhysicalSize - 1)] = val; - else BusWrite8(storeaddr[WBWritePointer], val); + BusWrite8(storeaddr[WBWritePointer], val); break; } case 1: // halfword { u16 val = WriteBufferFifo[WBWritePointer] & 0xFFFF; - if (WBAddr < ITCMSize) - { - *(u16*)&ITCM[WBAddr & (ITCMPhysicalSize - 2)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u16*)&DTCM[WBAddr & (DTCMPhysicalSize - 2)] = val; - else BusWrite16(storeaddr[WBWritePointer], val); + BusWrite16(storeaddr[WBWritePointer], val); break; } case 2: // word { u32 val = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF; - if (WBAddr < ITCMSize) - { - *(u32*)&ITCM[WBAddr & (ITCMPhysicalSize - 4)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u32*)&DTCM[WBAddr & (DTCMPhysicalSize - 4)] = val; - else BusWrite32(storeaddr[WBWritePointer], val); + BusWrite32(storeaddr[WBWritePointer], val); WBAddr += 4; break; } @@ -523,43 +499,19 @@ void ARMv5::WriteBufferWrite(u32 val, u8 flag, u8 cycles, u32 addr) case 0: // byte { u8 val = WriteBufferFifo[WBWritePointer] & 0xFF; - if (WBAddr < ITCMSize) - { - *(u8*)&ITCM[WBAddr & (ITCMPhysicalSize - 1)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u8*)&DTCM[WBAddr & (DTCMPhysicalSize - 1)] = val; - else BusWrite8(storeaddr[WBWritePointer], val); + BusWrite8(storeaddr[WBWritePointer], val); break; } case 1: // halfword { u16 val = WriteBufferFifo[WBWritePointer] & 0xFFFF; - if (WBAddr < ITCMSize) - { - *(u16*)&ITCM[WBAddr & (ITCMPhysicalSize - 2)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u16*)&DTCM[WBAddr & (DTCMPhysicalSize - 2)] = val; - else BusWrite16(storeaddr[WBWritePointer], val); + BusWrite16(storeaddr[WBWritePointer], val); break; } case 2: // word { u32 val = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF; - if (WBAddr < ITCMSize) - { - *(u32*)&ITCM[WBAddr & (ITCMPhysicalSize - 4)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u32*)&DTCM[WBAddr & (DTCMPhysicalSize - 4)] = val; - else BusWrite32(storeaddr[WBWritePointer], val); + BusWrite32(storeaddr[WBWritePointer], val); WBAddr += 4; break; } @@ -609,43 +561,19 @@ void ARMv5::WriteBufferDrain() case 0: // byte { u8 val = WriteBufferFifo[WBWritePointer] & 0xFF; - if (WBAddr < ITCMSize) - { - *(u8*)&ITCM[WBAddr & (ITCMPhysicalSize - 1)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u8*)&DTCM[WBAddr & (DTCMPhysicalSize - 1)] = val; - else BusWrite8(storeaddr[WBWritePointer], val); + BusWrite8(storeaddr[WBWritePointer], val); break; } case 1: // halfword { u16 val = WriteBufferFifo[WBWritePointer] & 0xFFFF; - if (WBAddr < ITCMSize) - { - *(u16*)&ITCM[WBAddr & (ITCMPhysicalSize - 2)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u16*)&DTCM[WBAddr & (DTCMPhysicalSize - 2)] = val; - else BusWrite16(storeaddr[WBWritePointer], val); + BusWrite16(storeaddr[WBWritePointer], val); break; } case 2: // word { u32 val = WriteBufferFifo[WBWritePointer] & 0xFFFFFFFF; - if (WBAddr < ITCMSize) - { - *(u32*)&ITCM[WBAddr & (ITCMPhysicalSize - 4)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(WBAddr); -#endif - } - else if ((WBAddr & DTCMMask) == DTCMBase) *(u32*)&DTCM[WBAddr & (DTCMPhysicalSize - 4)] = val; - else BusWrite32(storeaddr[WBWritePointer], val); + BusWrite32(storeaddr[WBWritePointer], val); WBAddr += 4; break; } @@ -1255,29 +1183,29 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) return false; } + if (addr < ITCMSize) + { + DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + DataRegion = Mem9_ITCM; + *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; +#ifdef JIT_ENABLED + NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +#endif + return true; + } + if ((addr & DTCMMask) == DTCMBase) + { + DataCycles = 1; + DataRegion = Mem9_DTCM; + *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; + return true; + } + if (!(PU_Map[addr>>12] & (0x30))) { - if (addr < ITCMSize) - { - DataCycles = 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; - DataRegion = Mem9_ITCM; - *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); -#endif - return true; - } - if ((addr & DTCMMask) == DTCMBase) - { - DataCycles = 1; - DataRegion = Mem9_DTCM; - *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; - return true; - } - NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][1]; if ((addr >> 24) == 0x02) @@ -1315,30 +1243,29 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) addr &= ~1; + if (addr < ITCMSize) + { + DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + DataRegion = Mem9_ITCM; + *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; +#ifdef JIT_ENABLED + NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +#endif + return true; + } + if ((addr & DTCMMask) == DTCMBase) + { + DataCycles = 1; + DataRegion = Mem9_DTCM; + *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; + return true; + } if (!(PU_Map[addr>>12] & 0x30)) { - if (addr < ITCMSize) - { - DataCycles = 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; - DataRegion = Mem9_ITCM; - *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); -#endif - return true; - } - if ((addr & DTCMMask) == DTCMBase) - { - DataCycles = 1; - DataRegion = Mem9_DTCM; - *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; - return true; - } - NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][1]; if ((addr >> 24) == 0x02) @@ -1376,30 +1303,29 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) addr &= ~3; + if (addr < ITCMSize) + { + DataCycles = 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + DataRegion = Mem9_ITCM; + *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; +#ifdef JIT_ENABLED + NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +#endif + return true; + } + if ((addr & DTCMMask) == DTCMBase) + { + DataCycles = 1; + DataRegion = Mem9_DTCM; + *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; + return true; + } if (!(PU_Map[addr>>12] & 0x30)) { - if (addr < ITCMSize) - { - DataCycles = 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; - DataRegion = Mem9_ITCM; - *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); -#endif - return true; - } - if ((addr & DTCMMask) == DTCMBase) - { - DataCycles = 1; - DataRegion = Mem9_DTCM; - *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; - return true; - } - NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][2]; if ((addr >> 24) == 0x02) @@ -1436,28 +1362,27 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val) addr &= ~3; + if (addr < ITCMSize) + { + DataCycles += 1; + ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; + DataRegion = Mem9_ITCM; + *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; +#ifdef JIT_ENABLED + NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); +#endif + return true; + } + if ((addr & DTCMMask) == DTCMBase) + { + DataCycles += 1; + DataRegion = Mem9_DTCM; + *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; + return true; + } if (!(PU_Map[addr>>12] & 0x30)) { - if (addr < ITCMSize) - { - DataCycles += 1; - ITCMTimestamp = NDS.ARM9Timestamp + DataCycles; - DataRegion = Mem9_ITCM; - *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; -#ifdef JIT_ENABLED - NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); -#endif - return true; - } - if ((addr & DTCMMask) == DTCMBase) - { - DataCycles += 1; - DataRegion = Mem9_DTCM; - *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; - return true; - } - DataCycles += (((NDS.ARM9Timestamp + DataCycles) + ((1< Date: Thu, 10 Oct 2024 23:24:20 -0400 Subject: [PATCH 8/8] implement drain write buffer cache command --- src/CP15.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/CP15.cpp b/src/CP15.cpp index ce56949b..b1ed52a5 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -786,7 +786,9 @@ void ARMv5::CP15Write(u32 id, u32 val) case 0x7A2: //printf("flush data cache SI\n"); return; - + case 0x7A4: + WriteBufferDrain(); + return; case 0x910: DTCMSetting = val & 0xFFFFF03E;