add MSR/MRS. also fix misc error with LDR ROR effect.
see shibboleet, I can do it too :>
This commit is contained in:
parent
23d584ca4c
commit
844ca45055
|
@ -27,6 +27,99 @@ s32 T_UNK(ARM* cpu)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s32 A_MSR_IMM(ARM* cpu)
|
||||||
|
{
|
||||||
|
u32* psr;
|
||||||
|
if (cpu->CurInstr & (1<<22))
|
||||||
|
{
|
||||||
|
switch (cpu->CPSR & 0x1F)
|
||||||
|
{
|
||||||
|
case 0x11: psr = &cpu->R_FIQ[7]; break;
|
||||||
|
case 0x12: psr = &cpu->R_IRQ[2]; break;
|
||||||
|
case 0x13: psr = &cpu->R_SVC[2]; break;
|
||||||
|
case 0x17: psr = &cpu->R_ABT[2]; break;
|
||||||
|
case 0x1B: psr = &cpu->R_UND[2]; break;
|
||||||
|
default: printf("bad CPU mode %08X\n", cpu->CPSR); return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
psr = &cpu->CPSR;
|
||||||
|
|
||||||
|
u32 mask = 0;
|
||||||
|
if (cpu->CurInstr & (1<<16)) mask |= 0x000000DF;
|
||||||
|
if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00;
|
||||||
|
if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000;
|
||||||
|
if (cpu->CurInstr & (1<<19)) mask |= 0xFF000000;
|
||||||
|
|
||||||
|
if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;
|
||||||
|
|
||||||
|
u32 val = ROR((cpu->CurInstr & 0xFF), ((cpu->CurInstr >> 7) & 0x1E));
|
||||||
|
|
||||||
|
*psr &= ~mask;
|
||||||
|
*psr |= (val & mask);
|
||||||
|
|
||||||
|
return C_S(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 A_MSR_REG(ARM* cpu)
|
||||||
|
{
|
||||||
|
u32* psr;
|
||||||
|
if (cpu->CurInstr & (1<<22))
|
||||||
|
{
|
||||||
|
switch (cpu->CPSR & 0x1F)
|
||||||
|
{
|
||||||
|
case 0x11: psr = &cpu->R_FIQ[7]; break;
|
||||||
|
case 0x12: psr = &cpu->R_IRQ[2]; break;
|
||||||
|
case 0x13: psr = &cpu->R_SVC[2]; break;
|
||||||
|
case 0x17: psr = &cpu->R_ABT[2]; break;
|
||||||
|
case 0x1B: psr = &cpu->R_UND[2]; break;
|
||||||
|
default: printf("bad CPU mode %08X\n", cpu->CPSR); return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
psr = &cpu->CPSR;
|
||||||
|
|
||||||
|
u32 mask = 0;
|
||||||
|
if (cpu->CurInstr & (1<<16)) mask |= 0x000000DF;
|
||||||
|
if (cpu->CurInstr & (1<<17)) mask |= 0x0000FF00;
|
||||||
|
if (cpu->CurInstr & (1<<18)) mask |= 0x00FF0000;
|
||||||
|
if (cpu->CurInstr & (1<<19)) mask |= 0xFF000000;
|
||||||
|
|
||||||
|
if ((cpu->CPSR & 0x1F) == 0x10) mask &= 0xFFFFFF00;
|
||||||
|
|
||||||
|
u32 val = cpu->R[cpu->CurInstr & 0xF];
|
||||||
|
|
||||||
|
*psr &= ~mask;
|
||||||
|
*psr |= (val & mask);
|
||||||
|
|
||||||
|
return C_S(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 A_MRS(ARM* cpu)
|
||||||
|
{
|
||||||
|
u32 psr;
|
||||||
|
if (cpu->CurInstr & (1<<22))
|
||||||
|
{
|
||||||
|
switch (cpu->CPSR & 0x1F)
|
||||||
|
{
|
||||||
|
case 0x11: psr = cpu->R_FIQ[7]; break;
|
||||||
|
case 0x12: psr = cpu->R_IRQ[2]; break;
|
||||||
|
case 0x13: psr = cpu->R_SVC[2]; break;
|
||||||
|
case 0x17: psr = cpu->R_ABT[2]; break;
|
||||||
|
case 0x1B: psr = cpu->R_UND[2]; break;
|
||||||
|
default: printf("bad CPU mode %08X\n", cpu->CPSR); return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
psr = cpu->CPSR;
|
||||||
|
|
||||||
|
cpu->R[(cpu->CurInstr>>12) & 0xF] = psr;
|
||||||
|
|
||||||
|
return C_S(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define INSTRFUNC_PROTO(x) s32 (*x)(ARM* cpu)
|
#define INSTRFUNC_PROTO(x) s32 (*x)(ARM* cpu)
|
||||||
#include "ARM_InstrTable.h"
|
#include "ARM_InstrTable.h"
|
||||||
#undef INSTRFUNC_PROTO
|
#undef INSTRFUNC_PROTO
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
namespace ARMInterpreter
|
namespace ARMInterpreter
|
||||||
{
|
{
|
||||||
|
|
||||||
|
s32 A_MSR_IMM(ARM* cpu);
|
||||||
|
s32 A_MSR_REG(ARM* cpu);
|
||||||
|
s32 A_MRS(ARM* cpu);
|
||||||
|
|
||||||
extern s32 (*ARMInstrTable[4096])(ARM* cpu);
|
extern s32 (*ARMInstrTable[4096])(ARM* cpu);
|
||||||
extern s32 (*THUMBInstrTable[1024])(ARM* cpu);
|
extern s32 (*THUMBInstrTable[1024])(ARM* cpu);
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace ARMInterpreter
|
||||||
|
|
||||||
#define A_LDR \
|
#define A_LDR \
|
||||||
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
offset += cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val = ROR(cpu->Read32(offset), offset&0x3); \
|
u32 val = ROR(cpu->Read32(offset), ((offset&0x3)<<3)); \
|
||||||
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
if (cpu->CurInstr & (1<<21)) cpu->R[(cpu->CurInstr>>16) & 0xF] = offset; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -83,7 +83,7 @@ namespace ARMInterpreter
|
||||||
|
|
||||||
#define A_LDR_POST \
|
#define A_LDR_POST \
|
||||||
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
u32 addr = cpu->R[(cpu->CurInstr>>16) & 0xF]; \
|
||||||
u32 val = ROR(cpu->Read32(addr, cpu->CurInstr & (1<<21)), addr&0x3); \
|
u32 val = ROR(cpu->Read32(addr, cpu->CurInstr & (1<<21)), ((addr&0x3)<<3)); \
|
||||||
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
cpu->R[(cpu->CurInstr>>16) & 0xF] += offset; \
|
||||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -100,7 +100,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
||||||
|
|
||||||
|
|
||||||
// 0001 0000 0000
|
// 0001 0000 0000
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MRS, 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_UNK, A_UNK,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||||
|
@ -112,7 +112,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||||
|
|
||||||
// 0001 0010 0000
|
// 0001 0010 0000
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_REG, 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_UNK, A_UNK,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||||
|
@ -124,7 +124,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||||
|
|
||||||
// 0001 0100 0000
|
// 0001 0100 0000
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MRS, 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_UNK, A_UNK,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||||
|
@ -136,7 +136,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||||
|
|
||||||
// 0001 0110 0000
|
// 0001 0110 0000
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_REG, 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_UNK, A_UNK,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||||
|
@ -308,10 +308,10 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
||||||
A_TST_IMM, A_TST_IMM, A_TST_IMM, A_TST_IMM,
|
A_TST_IMM, A_TST_IMM, A_TST_IMM, A_TST_IMM,
|
||||||
|
|
||||||
// 0011 0010 0000
|
// 0011 0010 0000
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
|
|
||||||
// 0011 0011 0000
|
// 0011 0011 0000
|
||||||
A_TEQ_IMM, A_TEQ_IMM, A_TEQ_IMM, A_TEQ_IMM,
|
A_TEQ_IMM, A_TEQ_IMM, A_TEQ_IMM, A_TEQ_IMM,
|
||||||
|
@ -332,10 +332,10 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
||||||
A_CMP_IMM, A_CMP_IMM, A_CMP_IMM, A_CMP_IMM,
|
A_CMP_IMM, A_CMP_IMM, A_CMP_IMM, A_CMP_IMM,
|
||||||
|
|
||||||
// 0011 0110 0000
|
// 0011 0110 0000
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
A_UNK, A_UNK, A_UNK, A_UNK,
|
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||||
|
|
||||||
// 0011 0111 0000
|
// 0011 0111 0000
|
||||||
A_CMN_IMM, A_CMN_IMM, A_CMN_IMM, A_CMN_IMM,
|
A_CMN_IMM, A_CMN_IMM, A_CMN_IMM, A_CMN_IMM,
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"ARM.h"
|
"ARM.h"
|
||||||
|
|
||||||
1480027981 source:c:\documents\sources\melonds\arm.cpp
|
1480726419 source:c:\documents\sources\melonds\arm.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"ARM.h"
|
"ARM.h"
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
1480724917 c:\documents\sources\melonds\arm_instrtable.h
|
1480724917 c:\documents\sources\melonds\arm_instrtable.h
|
||||||
|
|
||||||
1480018830 c:\documents\sources\melonds\arminterpreter.h
|
1480725698 c:\documents\sources\melonds\arminterpreter.h
|
||||||
"types.h"
|
"types.h"
|
||||||
"ARM.h"
|
"ARM.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue