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
This commit is contained in:
parent
6ebabde392
commit
45f87a1c8d
26
src/ARM.cpp
26
src/ARM.cpp
|
@ -201,13 +201,6 @@ void ARMv5::Reset()
|
||||||
ARM::Reset();
|
ARM::Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMv4::Reset()
|
|
||||||
{
|
|
||||||
Thumb = false;
|
|
||||||
|
|
||||||
ARM::Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ARM::DoSavestate(Savestate* file)
|
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];
|
Cycles += NDS.ARM7MemTimings[CodeCycles][0] + NDS.ARM7MemTimings[CodeCycles][1];
|
||||||
|
|
||||||
CPSR |= 0x20;
|
CPSR |= 0x20;
|
||||||
Thumb = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -416,7 +408,6 @@ void ARMv4::JumpTo(u32 addr, bool restorecpsr)
|
||||||
Cycles += NDS.ARM7MemTimings[CodeCycles][2] + NDS.ARM7MemTimings[CodeCycles][3];
|
Cycles += NDS.ARM7MemTimings[CodeCycles][2] + NDS.ARM7MemTimings[CodeCycles][3];
|
||||||
|
|
||||||
CPSR &= ~0x20;
|
CPSR &= ~0x20;
|
||||||
Thumb = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -840,11 +831,8 @@ void ARMv4::Execute()
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (Thumb) // THUMB
|
if (CPSR & 0x20) // THUMB
|
||||||
{
|
{
|
||||||
Thumb = (CPSR & 0x20);
|
|
||||||
bool fix = !Thumb;
|
|
||||||
|
|
||||||
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
|
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
|
||||||
GdbCheckC();
|
GdbCheckC();
|
||||||
|
|
||||||
|
@ -858,22 +846,12 @@ void ARMv4::Execute()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// actually execute
|
// actually execute
|
||||||
u32 icode = (CurInstr >> 6) & 0x3FF;
|
u32 icode = (CurInstr >> 6);
|
||||||
ARMInterpreter::THUMBInstrTable[icode](this);
|
ARMInterpreter::THUMBInstrTable[icode](this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fix) [[unlikely]]
|
|
||||||
{
|
|
||||||
// probably wrong?
|
|
||||||
// fixup
|
|
||||||
R[15] &= ~0x3;
|
|
||||||
NextInstr[1] = CodeRead32(R[15]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Thumb = (CPSR & 0x20);
|
|
||||||
|
|
||||||
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
|
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
|
||||||
GdbCheckC();
|
GdbCheckC();
|
||||||
|
|
||||||
|
|
|
@ -385,8 +385,6 @@ class ARMv4 : public ARM
|
||||||
public:
|
public:
|
||||||
ARMv4(melonDS::NDS& nds, std::optional<GDBArgs> gdb, bool jit);
|
ARMv4(melonDS::NDS& nds, std::optional<GDBArgs> gdb, bool jit);
|
||||||
|
|
||||||
void Reset() override;
|
|
||||||
|
|
||||||
void FillPipeline() override;
|
void FillPipeline() override;
|
||||||
|
|
||||||
void JumpTo(u32 addr, bool restorecpsr = false) override;
|
void JumpTo(u32 addr, bool restorecpsr = false) override;
|
||||||
|
@ -395,7 +393,7 @@ public:
|
||||||
template <CPUExecuteMode mode>
|
template <CPUExecuteMode mode>
|
||||||
void Execute();
|
void Execute();
|
||||||
|
|
||||||
u32 CodeRead16(u32 addr)
|
u16 CodeRead16(u32 addr)
|
||||||
{
|
{
|
||||||
return BusRead16(addr);
|
return BusRead16(addr);
|
||||||
}
|
}
|
||||||
|
@ -405,8 +403,6 @@ public:
|
||||||
return BusRead32(addr);
|
return BusRead32(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Thumb;
|
|
||||||
|
|
||||||
bool DataRead8(u32 addr, u32* val) override;
|
bool DataRead8(u32 addr, u32* val) override;
|
||||||
bool DataRead16(u32 addr, u32* val) override;
|
bool DataRead16(u32 addr, u32* val) override;
|
||||||
bool DataRead32(u32 addr, u32* val) override;
|
bool DataRead32(u32 addr, u32* val) override;
|
||||||
|
|
|
@ -126,8 +126,15 @@ void A_MSR_IMM(ARM* cpu)
|
||||||
if (!(cpu->CurInstr & (1<<22)))
|
if (!(cpu->CurInstr & (1<<22)))
|
||||||
cpu->UpdateMode(oldpsr, cpu->CPSR);
|
cpu->UpdateMode(oldpsr, cpu->CPSR);
|
||||||
|
|
||||||
if (cpu->Num == 0)
|
if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20))
|
||||||
if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this
|
{
|
||||||
|
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();
|
cpu->AddCycles_C();
|
||||||
}
|
}
|
||||||
|
@ -178,9 +185,16 @@ void A_MSR_REG(ARM* cpu)
|
||||||
|
|
||||||
if (!(cpu->CurInstr & (1<<22)))
|
if (!(cpu->CurInstr & (1<<22)))
|
||||||
cpu->UpdateMode(oldpsr, cpu->CPSR);
|
cpu->UpdateMode(oldpsr, cpu->CPSR);
|
||||||
|
|
||||||
if (cpu->Num == 0)
|
if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20))
|
||||||
if (!(oldpsr & 0x20) && (cpu->CPSR & 0x20)) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this
|
{
|
||||||
|
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();
|
cpu->AddCycles_C();
|
||||||
}
|
}
|
||||||
|
|
|
@ -585,8 +585,17 @@ A_IMPLEMENT_ALU_OP(RSC,)
|
||||||
!res); \
|
!res); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \
|
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. */ \
|
if (cpu->Num == 1) \
|
||||||
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING TST w/ rd == 15???"); \
|
{ \
|
||||||
|
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();
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
|
||||||
|
|
||||||
|
@ -600,8 +609,17 @@ A_IMPLEMENT_ALU_TEST(TST,_S)
|
||||||
!res); \
|
!res); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \
|
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. */ \
|
if (cpu->Num == 1) \
|
||||||
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING TEQ w/ rd == 15???"); \
|
{ \
|
||||||
|
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();
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
|
||||||
|
|
||||||
|
@ -617,8 +635,17 @@ A_IMPLEMENT_ALU_TEST(TEQ,_S)
|
||||||
OverflowSub(a, b)); \
|
OverflowSub(a, b)); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \
|
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. */ \
|
if (cpu->Num == 1) \
|
||||||
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING CMP w/ rd == 15???"); \
|
{ \
|
||||||
|
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();
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
|
||||||
|
|
||||||
|
@ -634,8 +661,17 @@ A_IMPLEMENT_ALU_TEST(CMP,)
|
||||||
OverflowAdd(a, b)); \
|
OverflowAdd(a, b)); \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) /* yes this instruction has a secret rd for some reason */ \
|
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. */ \
|
if (cpu->Num == 1) \
|
||||||
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: WHO IS USING CMN w/ rd == 15???"); \
|
{ \
|
||||||
|
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();
|
if (c) cpu->AddCycles_CI(c); else cpu->AddCycles_C();
|
||||||
|
|
||||||
|
@ -1589,11 +1625,20 @@ void T_CMP_HIREG(ARM* cpu)
|
||||||
!res,
|
!res,
|
||||||
CarrySub(a, b),
|
CarrySub(a, b),
|
||||||
OverflowSub(a, b));
|
OverflowSub(a, b));
|
||||||
if (rd == 15) \
|
if (rd == 15)
|
||||||
{ \
|
{
|
||||||
if (cpu->Num == 1) cpu->RestoreCPSR(); /* ARM7TDMI restores cpsr and does ___not___ flush the pipeline. */ \
|
if (cpu->Num == 1)
|
||||||
else Platform::Log(Platform::LogLevel::Warn, "UNIMPLEMENTED: CMP HIREG w/ rd == 15."); \
|
{
|
||||||
} \
|
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();
|
cpu->AddCycles_C();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue