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 76d356fb..78ab8f95 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -683,6 +683,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/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index 00ae2d09..8c12dce3 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,17 @@ void A_MSR_IMM(ARM* cpu) cpu->CPSR &= ~0x20; // keep it from crashing the emulator at least } } - - cpu->AddCycles_C(); + + if (cpu->Num != 1) + { + if (cpu->CurInstr & (1<<22)) + { + cpu->AddCycles_CI(2); // spsr + } + else if (cpu->CurInstr & (0x7<<16)) cpu->AddCycles_CI(2); // cpsr_sxc + else cpu->AddCycles_C(); + } + else cpu->AddCycles_C(); } void A_MSR_REG(ARM* cpu) @@ -158,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; } } @@ -195,8 +206,17 @@ void A_MSR_REG(ARM* cpu) cpu->CPSR &= ~0x20; // keep it from crashing the emulator at least } } - - cpu->AddCycles_C(); + + if (cpu->Num != 1) + { + if (cpu->CurInstr & (1<<22)) + { + cpu->AddCycles_CI(2); // spsr + } + else if (cpu->CurInstr & (0x7<<16)) cpu->AddCycles_CI(2); // cpsr_sxc + else cpu->AddCycles_C(); + } + else cpu->AddCycles_C(); } void A_MRS(ARM* cpu) @@ -282,11 +302,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|(op<<12)); + if (rd != 15) cpu->R[rd] = ((ARMv5*)cpu)->CP15Read((cn<<8)|(cm<<4)|cpinfo|(op<<12)); + 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|(op<<12)) & 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); } diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index b2ba0d1f..e9439d2a 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(); @@ -1643,20 +1667,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(); } diff --git a/src/CP15.cpp b/src/CP15.cpp index b10b64bc..7cf8109f 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -912,43 +912,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; } @@ -985,43 +961,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; } @@ -1071,43 +1023,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; } @@ -1490,11 +1418,12 @@ void ARMv5::CP15Write(u32 id, u32 val) } // Test and clean (optional) // Is not present on the NDS/DSi - return; + return; + case 0x7A4: // Can be used in user and privileged mode // Drain Write Buffer: Stall until all write back completed - // TODO when write back was implemented instead of write through + WriteBufferDrain(); return; case 0x7D1: @@ -1870,9 +1799,6 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) } #endif - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); - if (addr < ITCMSize) { CodeCycles = 1; @@ -1893,6 +1819,8 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) CodeCycles = 1; } + WriteBufferDrain(); + NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 24) == 0x02) @@ -1938,9 +1866,6 @@ bool ARMv5::DataRead8(u32 addr, u32* val) } #endif - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); - if (addr < ITCMSize) { DataCycles = 1; @@ -1956,6 +1881,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) { @@ -2020,6 +1945,8 @@ bool ARMv5::DataRead16(u32 addr, u32* val) return true; } + WriteBufferDrain(); + NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][1]; @@ -2066,9 +1993,6 @@ bool ARMv5::DataRead32(u32 addr, u32* val) } #endif - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); - if (addr < ITCMSize) { DataCycles = 1; @@ -2085,6 +2009,8 @@ bool ARMv5::DataRead32(u32 addr, u32* val) return true; } + WriteBufferDrain(); + NDS.ARM9Timestamp = NDS.ARM9Timestamp + ((1<> 12][2]; @@ -2129,9 +2055,6 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) } #endif - if ((PU_Map[addr>>12] & 0x30)) - WriteBufferDrain(); - if (addr < ITCMSize) { DataCycles += 1; @@ -2148,6 +2071,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 @@ -2195,29 +2120,29 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) } #endif + 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) @@ -2233,10 +2158,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; } @@ -2270,29 +2196,29 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) } #endif + 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) @@ -2308,10 +2234,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; } @@ -2346,29 +2273,29 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) } #endif + 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) @@ -2384,10 +2311,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; } @@ -2420,27 +2348,27 @@ bool ARMv5::DataWrite32S(u32 addr, u32 val) } #endif + 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<> 12][3], addr); + WBDelay = NDS.ARM9Timestamp + DataCycles + 1; } return true; }