more instructions. some handling of CPU mode switching.
This commit is contained in:
parent
6213245f3a
commit
30f85e3400
76
ARM.cpp
76
ARM.cpp
|
@ -74,6 +74,82 @@ void ARM::RestoreCPSR()
|
|||
printf("TODO: restore CPSR\n");
|
||||
}
|
||||
|
||||
void ARM::UpdateMode(u32 oldmode, u32 newmode)
|
||||
{
|
||||
u32 temp;
|
||||
#define SWAP(a, b) temp = a; a = b; b = temp;
|
||||
|
||||
if ((oldmode & 0x1F) == (newmode & 0x1F)) return;
|
||||
|
||||
switch (oldmode & 0x1F)
|
||||
{
|
||||
case 0x11:
|
||||
SWAP(R[8], R_FIQ[0]);
|
||||
SWAP(R[9], R_FIQ[1]);
|
||||
SWAP(R[10], R_FIQ[2]);
|
||||
SWAP(R[11], R_FIQ[3]);
|
||||
SWAP(R[12], R_FIQ[4]);
|
||||
SWAP(R[13], R_FIQ[5]);
|
||||
SWAP(R[14], R_FIQ[6]);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
SWAP(R[13], R_IRQ[0]);
|
||||
SWAP(R[14], R_IRQ[1]);
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
SWAP(R[13], R_SVC[0]);
|
||||
SWAP(R[14], R_SVC[1]);
|
||||
break;
|
||||
|
||||
case 0x17:
|
||||
SWAP(R[13], R_ABT[0]);
|
||||
SWAP(R[14], R_ABT[1]);
|
||||
break;
|
||||
|
||||
case 0x1B:
|
||||
SWAP(R[13], R_UND[0]);
|
||||
SWAP(R[14], R_UND[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (newmode & 0x1F)
|
||||
{
|
||||
case 0x11:
|
||||
SWAP(R[8], R_FIQ[0]);
|
||||
SWAP(R[9], R_FIQ[1]);
|
||||
SWAP(R[10], R_FIQ[2]);
|
||||
SWAP(R[11], R_FIQ[3]);
|
||||
SWAP(R[12], R_FIQ[4]);
|
||||
SWAP(R[13], R_FIQ[5]);
|
||||
SWAP(R[14], R_FIQ[6]);
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
SWAP(R[13], R_IRQ[0]);
|
||||
SWAP(R[14], R_IRQ[1]);
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
SWAP(R[13], R_SVC[0]);
|
||||
SWAP(R[14], R_SVC[1]);
|
||||
break;
|
||||
|
||||
case 0x17:
|
||||
SWAP(R[13], R_ABT[0]);
|
||||
SWAP(R[14], R_ABT[1]);
|
||||
break;
|
||||
|
||||
case 0x1B:
|
||||
SWAP(R[13], R_UND[0]);
|
||||
SWAP(R[14], R_UND[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
#undef SWAP
|
||||
}
|
||||
|
||||
s32 ARM::Execute(s32 cycles)
|
||||
{
|
||||
while (cycles > 0)
|
||||
|
|
2
ARM.h
2
ARM.h
|
@ -55,6 +55,8 @@ public:
|
|||
if (v) CPSR |= 0x10000000;
|
||||
}
|
||||
|
||||
void UpdateMode(u32 oldmode, u32 newmode);
|
||||
|
||||
|
||||
u8 Read8(u32 addr, u32 forceuser=0)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ s32 A_MSR_IMM(ARM* cpu)
|
|||
else
|
||||
psr = &cpu->CPSR;
|
||||
|
||||
u32 oldpsr = *psr;
|
||||
|
||||
u32 mask = 0;
|
||||
if (cpu->CurInstr & (1<<16)) mask |= 0x000000DF;
|
||||
if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00;
|
||||
|
@ -58,6 +60,9 @@ s32 A_MSR_IMM(ARM* cpu)
|
|||
*psr &= ~mask;
|
||||
*psr |= (val & mask);
|
||||
|
||||
if (!(cpu->CurInstr & (1<<22)))
|
||||
cpu->UpdateMode(oldpsr, cpu->CPSR);
|
||||
|
||||
return C_S(1);
|
||||
}
|
||||
|
||||
|
@ -79,6 +84,8 @@ s32 A_MSR_REG(ARM* cpu)
|
|||
else
|
||||
psr = &cpu->CPSR;
|
||||
|
||||
u32 oldpsr = *psr;
|
||||
|
||||
u32 mask = 0;
|
||||
if (cpu->CurInstr & (1<<16)) mask |= 0x000000DF;
|
||||
if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00;
|
||||
|
@ -92,6 +99,9 @@ s32 A_MSR_REG(ARM* cpu)
|
|||
*psr &= ~mask;
|
||||
*psr |= (val & mask);
|
||||
|
||||
if (!(cpu->CurInstr & (1<<22)))
|
||||
cpu->UpdateMode(oldpsr, cpu->CPSR);
|
||||
|
||||
return C_S(1);
|
||||
}
|
||||
|
||||
|
@ -119,6 +129,47 @@ s32 A_MRS(ARM* cpu)
|
|||
}
|
||||
|
||||
|
||||
s32 A_MCR(ARM* cpu)
|
||||
{
|
||||
u32 cp = (cpu->CurInstr >> 8) & 0xF;
|
||||
u32 op = (cpu->CurInstr >> 21) & 0x7;
|
||||
u32 cn = (cpu->CurInstr >> 16) & 0xF;
|
||||
u32 cm = cpu->CurInstr & 0xF;
|
||||
u32 cpinfo = (cpu->CurInstr >> 5) & 0x7;
|
||||
|
||||
if (cpu->Num==0 && cp==15)
|
||||
{
|
||||
printf("CP15: R%d -> %d,%d,%d\n", (cpu->CurInstr>>12)&0xF, cn, cm, cpinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("bad MCR opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9);
|
||||
}
|
||||
|
||||
return C_S(1) + 1; // TODO: checkme
|
||||
}
|
||||
|
||||
s32 A_MRC(ARM* cpu)
|
||||
{
|
||||
u32 cp = (cpu->CurInstr >> 8) & 0xF;
|
||||
u32 op = (cpu->CurInstr >> 21) & 0x7;
|
||||
u32 cn = (cpu->CurInstr >> 16) & 0xF;
|
||||
u32 cm = cpu->CurInstr & 0xF;
|
||||
u32 cpinfo = (cpu->CurInstr >> 5) & 0x7;
|
||||
|
||||
if (cpu->Num==0 && cp==15)
|
||||
{
|
||||
printf("CP15: R%d <- %d,%d,%d\n", (cpu->CurInstr>>12)&0xF, cn, cm, cpinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("bad MRC opcode p%d,%d,%d,%d on ARM%d\n", cp, cn, cm, cpinfo, cpu->Num?7:9);
|
||||
}
|
||||
|
||||
return C_S(1) + 1 + C_I(1); // TODO: checkme
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define INSTRFUNC_PROTO(x) s32 (*x)(ARM* cpu)
|
||||
#include "ARM_InstrTable.h"
|
||||
|
|
128
ARM_InstrTable.h
128
ARM_InstrTable.h
|
@ -1374,100 +1374,100 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
|||
|
||||
|
||||
// 1110 0000 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 0001 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
// 1110 0010 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 0011 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
// 1110 0100 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 0101 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
// 1110 0110 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 0111 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
// 1110 1000 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 1001 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
// 1110 1010 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 1011 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
// 1110 1100 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 1101 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
// 1110 1110 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
A_UNK, A_MCR, A_UNK, A_MCR,
|
||||
|
||||
// 1110 1111 0000
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
A_UNK, A_MRC, A_UNK, A_MRC,
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,23 +13,23 @@
|
|||
"NDS.h"
|
||||
"ARM.h"
|
||||
|
||||
1480729196 source:c:\documents\sources\melonds\arm.cpp
|
||||
1480736240 source:c:\documents\sources\melonds\arm.cpp
|
||||
<stdio.h>
|
||||
"NDS.h"
|
||||
"ARM.h"
|
||||
"ARMInterpreter.h"
|
||||
|
||||
1480722720 c:\documents\sources\melonds\arm.h
|
||||
1480735953 c:\documents\sources\melonds\arm.h
|
||||
"types.h"
|
||||
"NDS.h"
|
||||
|
||||
1480734093 c:\documents\sources\melonds\arm_instrtable.h
|
||||
1480735162 c:\documents\sources\melonds\arm_instrtable.h
|
||||
|
||||
1480725698 c:\documents\sources\melonds\arminterpreter.h
|
||||
"types.h"
|
||||
"ARM.h"
|
||||
|
||||
1480727235 source:c:\documents\sources\melonds\arminterpreter.cpp
|
||||
1480736379 source:c:\documents\sources\melonds\arminterpreter.cpp
|
||||
<stdio.h>
|
||||
"NDS.h"
|
||||
"ARMInterpreter.h"
|
||||
|
@ -51,6 +51,6 @@
|
|||
|
||||
1480734113 c:\documents\sources\melonds\arminterpreter_loadstore.h
|
||||
|
||||
1480731825 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp
|
||||
1480734224 source:c:\documents\sources\melonds\arminterpreter_loadstore.cpp
|
||||
"ARM.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue