parent
89e8549a55
commit
6ebabde392
33
src/ARM.cpp
33
src/ARM.cpp
|
@ -201,6 +201,13 @@ void ARMv5::Reset()
|
||||||
ARM::Reset();
|
ARM::Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMv4::Reset()
|
||||||
|
{
|
||||||
|
Thumb = false;
|
||||||
|
|
||||||
|
ARM::Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ARM::DoSavestate(Savestate* file)
|
void ARM::DoSavestate(Savestate* file)
|
||||||
{
|
{
|
||||||
|
@ -395,6 +402,7 @@ 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
|
||||||
{
|
{
|
||||||
|
@ -408,6 +416,7 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,7 +733,12 @@ void ARMv5::Execute()
|
||||||
ARMInterpreter::A_BLX_IMM(this);
|
ARMInterpreter::A_BLX_IMM(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
AddCycles_C();
|
{
|
||||||
|
if ((((CurInstr >> 4) & 0xF) | ((CurInstr >> 16) & 0xFF0)) == 0x127)
|
||||||
|
ARMInterpreter::A_BKPT(this); // always passes regardless of condition code
|
||||||
|
else
|
||||||
|
AddCycles_C();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO optimize this shit!!!
|
// TODO optimize this shit!!!
|
||||||
|
@ -826,8 +840,11 @@ void ARMv4::Execute()
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (CPSR & 0x20) // THUMB
|
if (Thumb) // THUMB
|
||||||
{
|
{
|
||||||
|
Thumb = (CPSR & 0x20);
|
||||||
|
bool fix = !Thumb;
|
||||||
|
|
||||||
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
|
if constexpr (mode == CPUExecuteMode::InterpreterGDB)
|
||||||
GdbCheckC();
|
GdbCheckC();
|
||||||
|
|
||||||
|
@ -841,12 +858,22 @@ void ARMv4::Execute()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// actually execute
|
// actually execute
|
||||||
u32 icode = (CurInstr >> 6);
|
u32 icode = (CurInstr >> 6) & 0x3FF;
|
||||||
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,6 +385,8 @@ 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;
|
||||||
|
@ -393,7 +395,7 @@ public:
|
||||||
template <CPUExecuteMode mode>
|
template <CPUExecuteMode mode>
|
||||||
void Execute();
|
void Execute();
|
||||||
|
|
||||||
u16 CodeRead16(u32 addr)
|
u32 CodeRead16(u32 addr)
|
||||||
{
|
{
|
||||||
return BusRead16(addr);
|
return BusRead16(addr);
|
||||||
}
|
}
|
||||||
|
@ -403,6 +405,8 @@ 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;
|
||||||
|
|
|
@ -69,6 +69,14 @@ void T_UNK(ARM* cpu)
|
||||||
cpu->JumpTo(cpu->ExceptionBase + 0x04);
|
cpu->JumpTo(cpu->ExceptionBase + 0x04);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void A_BKPT(ARM* cpu)
|
||||||
|
{
|
||||||
|
if (cpu->Num == 1) A_UNK(cpu); // checkme
|
||||||
|
|
||||||
|
Log(LogLevel::Warn, "BKPT: "); // combine with the prefetch abort warning message
|
||||||
|
((ARMv5*)cpu)->PrefetchAbort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void A_MSR_IMM(ARM* cpu)
|
void A_MSR_IMM(ARM* cpu)
|
||||||
|
@ -105,9 +113,6 @@ void A_MSR_IMM(ARM* cpu)
|
||||||
//if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000; // unused by arm 7 & 9
|
//if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000; // unused by arm 7 & 9
|
||||||
if (cpu->CurInstr & (1<<19)) mask |= ((cpu->Num==1) ? 0xF0000000 : 0xF8000000);
|
if (cpu->CurInstr & (1<<19)) mask |= ((cpu->Num==1) ? 0xF0000000 : 0xF8000000);
|
||||||
|
|
||||||
if (!(cpu->CurInstr & (1<<22)))
|
|
||||||
mask &= 0xFFFFFFDF;
|
|
||||||
|
|
||||||
if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;
|
if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;
|
||||||
|
|
||||||
u32 val = ROR((cpu->CurInstr & 0xFF), ((cpu->CurInstr >> 7) & 0x1E));
|
u32 val = ROR((cpu->CurInstr & 0xFF), ((cpu->CurInstr >> 7) & 0x1E));
|
||||||
|
@ -121,6 +126,9 @@ 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)) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this
|
||||||
|
|
||||||
cpu->AddCycles_C();
|
cpu->AddCycles_C();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,9 +166,6 @@ void A_MSR_REG(ARM* cpu)
|
||||||
//if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000; // unused by arm 7 & 9
|
//if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000; // unused by arm 7 & 9
|
||||||
if (cpu->CurInstr & (1<<19)) mask |= ((cpu->Num==1) ? 0xF0000000 : 0xF8000000);
|
if (cpu->CurInstr & (1<<19)) mask |= ((cpu->Num==1) ? 0xF0000000 : 0xF8000000);
|
||||||
|
|
||||||
if (!(cpu->CurInstr & (1<<22)))
|
|
||||||
mask &= 0xFFFFFFDF;
|
|
||||||
|
|
||||||
if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;
|
if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;
|
||||||
|
|
||||||
u32 val = cpu->R[cpu->CurInstr & 0xF];
|
u32 val = cpu->R[cpu->CurInstr & 0xF];
|
||||||
|
@ -173,6 +178,9 @@ 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)) cpu->NextInstr[1] &= 0xFFFF; // checkme: probably not the right way to handle this
|
||||||
|
|
||||||
cpu->AddCycles_C();
|
cpu->AddCycles_C();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ void A_MRS(ARM* cpu);
|
||||||
void A_MCR(ARM* cpu);
|
void A_MCR(ARM* cpu);
|
||||||
void A_MRC(ARM* cpu);
|
void A_MRC(ARM* cpu);
|
||||||
void A_SVC(ARM* cpu);
|
void A_SVC(ARM* cpu);
|
||||||
|
void A_BKPT(ARM* cpu);
|
||||||
|
|
||||||
void T_SVC(ARM* cpu);
|
void T_SVC(ARM* cpu);
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,7 @@ const u32 A_BX = A_BranchAlways | A_Read0 | ak(ak_BX);
|
||||||
const u32 A_BLX_REG = A_BranchAlways | A_Link | A_Read0 | ak(ak_BLX_REG);
|
const u32 A_BLX_REG = A_BranchAlways | A_Link | A_Read0 | ak(ak_BLX_REG);
|
||||||
|
|
||||||
const u32 A_UNK = A_BranchAlways | A_Link | ak(ak_UNK);
|
const u32 A_UNK = A_BranchAlways | A_Link | ak(ak_UNK);
|
||||||
|
const u32 A_BKPT = A_BranchAlways | A_Link | ak(ak_UNK);
|
||||||
const u32 A_MSR_IMM = ak(ak_MSR_IMM);
|
const u32 A_MSR_IMM = ak(ak_MSR_IMM);
|
||||||
const u32 A_MSR_REG = A_Read0 | ak(ak_MSR_REG);
|
const u32 A_MSR_REG = A_Read0 | ak(ak_MSR_REG);
|
||||||
const u32 A_MRS = A_Write12 | ak(ak_MRS);
|
const u32 A_MRS = A_Write12 | ak(ak_MRS);
|
||||||
|
|
|
@ -130,7 +130,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
||||||
|
|
||||||
// 0001 0010 0000
|
// 0001 0010 0000
|
||||||
A_MSR_REG, A_BX, A_UNK, A_BLX_REG,
|
A_MSR_REG, A_BX, A_UNK, A_BLX_REG,
|
||||||
A_UNK, A_QSUB, A_UNK, A_UNK,
|
A_UNK, A_QSUB, A_UNK, A_BKPT,
|
||||||
A_SMLAWy, A_UNK, A_SMULWy, A_STRH_REG,
|
A_SMLAWy, A_UNK, A_SMULWy, A_STRH_REG,
|
||||||
A_SMLAWy, A_LDRD_REG, A_SMULWy, A_STRD_REG,
|
A_SMLAWy, A_LDRD_REG, A_SMULWy, A_STRD_REG,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue