From 45f87a1c8d529289f031619e3b13d4e6d67c3d57 Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Thu, 19 Sep 2024 20:57:55 -0400 Subject: [PATCH] prevent t bit changes without pipeline flush on arm7 idk what's happening fully and its gonna be slow to emulate most likely we'll figure this out later --- src/ARM.cpp | 26 ++------------ src/ARM.h | 6 +--- src/ARMInterpreter.cpp | 24 ++++++++++--- src/ARMInterpreter_ALU.cpp | 71 +++++++++++++++++++++++++++++++------- 4 files changed, 80 insertions(+), 47 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index c7fea92d..6518b751 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -201,13 +201,6 @@ void ARMv5::Reset() ARM::Reset(); } -void ARMv4::Reset() -{ - Thumb = false; - - ARM::Reset(); -} - void ARM::DoSavestate(Savestate* file) { @@ -402,7 +395,6 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr) Cycles += NDS.ARM7MemTimings[CodeCycles][0] + NDS.ARM7MemTimings[CodeCycles][1]; CPSR |= 0x20; - Thumb = true; } else { @@ -416,7 +408,6 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr) Cycles += NDS.ARM7MemTimings[CodeCycles][2] + NDS.ARM7MemTimings[CodeCycles][3]; CPSR &= ~0x20; - Thumb = false; } } @@ -840,11 +831,8 @@ void ARMv4::Execute() else #endif { - if (Thumb) // THUMB + if (CPSR & 0x20) // THUMB { - Thumb = (CPSR & 0x20); - bool fix = !Thumb; - if constexpr (mode == CPUExecuteMode::InterpreterGDB) GdbCheckC(); @@ -858,22 +846,12 @@ void ARMv4::Execute() else { // actually execute - u32 icode = (CurInstr >> 6) & 0x3FF; + u32 icode = (CurInstr >> 6); ARMInterpreter::THUMBInstrTable[icode](this); } - - if (fix) [[unlikely]] - { - // probably wrong? - // fixup - R[15] &= ~0x3; - NextInstr[1] = CodeRead32(R[15]); - } } else { - Thumb = (CPSR & 0x20); - if constexpr (mode == CPUExecuteMode::InterpreterGDB) GdbCheckC(); diff --git a/src/ARM.h b/src/ARM.h index 8d640a30..26080b51 100644 --- a/src/ARM.h +++ b/src/ARM.h @@ -385,8 +385,6 @@ class ARMv4 : public ARM public: ARMv4(melonDS::NDS& nds, std::optional gdb, bool jit); - void Reset() override; - void FillPipeline() override; void JumpTo(u32 addr, bool restorecpsr = false) override; @@ -395,7 +393,7 @@ public: template void Execute(); - u32 CodeRead16(u32 addr) + u16 CodeRead16(u32 addr) { return BusRead16(addr); } @@ -405,8 +403,6 @@ public: return BusRead32(addr); } - bool Thumb; - bool DataRead8(u32 addr, u32* val) override; bool DataRead16(u32 addr, u32* val) override; bool DataRead32(u32 addr, u32* val) override; diff --git a/src/ARMInterpreter.cpp b/src/ARMInterpreter.cpp index 979e3bb8..b11913ef 100644 --- a/src/ARMInterpreter.cpp +++ b/src/ARMInterpreter.cpp @@ -126,8 +126,15 @@ void A_MSR_IMM(ARM* cpu) if (!(cpu->CurInstr & (1<<22))) cpu->UpdateMode(oldpsr, cpu->CPSR); - if (cpu->Num == 0) - if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this + if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) + { + if (cpu->Num == 0) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this + else + { + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR IMM T bit change on ARM7\n"); + cpu->CPSR = (cpu->CPSR & ~0x20) | (oldpsr & 0x20); // keep it from crashing the emulator at least + } + } cpu->AddCycles_C(); } @@ -178,9 +185,16 @@ void A_MSR_REG(ARM* cpu) if (!(cpu->CurInstr & (1<<22))) cpu->UpdateMode(oldpsr, cpu->CPSR); - - if (cpu->Num == 0) - if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this + + if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) + { + if (cpu->Num == 0) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this + else + { + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n"); + cpu->CPSR = (cpu->CPSR & ~0x20) | (oldpsr & 0x20); // keep it from crashing the emulator at least + } + } cpu->AddCycles_C(); } diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index f04ab9b5..fd60b5f0 100644 --- a/src/ARMInterpreter_ALU.cpp +++ b/src/ARMInterpreter_ALU.cpp @@ -585,8 +585,17 @@ A_IMPLEMENT_ALU_OP(RSC,) !res); \ if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \ { \ - if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING TST w/ rd == 15???"); \ + if (cpu->Num == 1) \ + { \ + u32 oldcpsr = cpu->CPSR; \ + cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ + if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) \ + { \ + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TST T bit change on ARM7\n"); \ + cpu->CPSR = (cpu->CPSR & ~0x20) | (oldpsr & 0x20); /* keep it from crashing the emulator at least */ \ + } \ + } \ + else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TST w/ rd == 15 on ARM9\n"); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -600,8 +609,17 @@ A_IMPLEMENT_ALU_TEST(TST,_S) !res); \ if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \ { \ - if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING TEQ w/ rd == 15???"); \ + if (cpu->Num == 1) \ + { \ + u32 oldcpsr = cpu->CPSR; \ + cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ + if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) \ + { \ + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TEQ T bit change on ARM7\n"); \ + cpu->CPSR = (cpu->CPSR & ~0x20) | (oldpsr & 0x20); /* keep it from crashing the emulator at least */ \ + } \ + } \ + else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: TEQ w/ rd == 15 on ARM9\n"); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -617,8 +635,17 @@ A_IMPLEMENT_ALU_TEST(TEQ,_S) OverflowSub(a, b)); \ if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \ { \ - if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING CMP w/ rd == 15???"); \ + if (cpu->Num == 1) \ + { \ + u32 oldcpsr = cpu->CPSR; \ + cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ + if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) \ + { \ + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP T bit change on ARM7\n"); \ + cpu->CPSR = (cpu->CPSR & ~0x20) | (oldpsr & 0x20); /* keep it from crashing the emulator at least */ \ + } \ + } \ + else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP w/ rd == 15 on ARM9\n"); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -634,8 +661,17 @@ A_IMPLEMENT_ALU_TEST(CMP,) OverflowAdd(a, b)); \ if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \ { \ - if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING CMN w/ rd == 15???"); \ + if (cpu->Num == 1) \ + { \ + u32 oldcpsr = cpu->CPSR; \ + cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ + if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) \ + { \ + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMN T bit change on ARM7\n"); \ + cpu->CPSR = (cpu->CPSR & ~0x20) | (oldpsr & 0x20); /* keep it from crashing the emulator at least */ \ + } \ + } \ + else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMN w/ rd == 15 on ARM9\n"); \ } \ if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C(); @@ -1589,11 +1625,20 @@ void T_CMP_HIREG(ARM* cpu) !res, CarrySub(a, b), OverflowSub(a, b)); - if (rd == 15) \ - { \ - if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \ - else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP HIREG w/ rd == 15."); \ - } \ + if (rd == 15) + { + if (cpu->Num == 1) + { + u32 oldcpsr = cpu->CPSR; + cpu->RestoreCPSR(); // ARM7TDMI restores cpsr and does ___not___ flush the pipeline. + if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) + { + Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: MSR REG T bit change on ARM7\n"); + cpu->CPSR = (cpu->CPSR & ~0x20) | (oldpsr & 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(); }