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)
|
||||
#include "ARM_InstrTable.h"
|
||||
#undef INSTRFUNC_PROTO
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
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 (*THUMBInstrTable[1024])(ARM* cpu);
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace ARMInterpreter
|
|||
|
||||
#define A_LDR \
|
||||
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>>12) & 0xF) == 15) \
|
||||
{ \
|
||||
|
@ -83,7 +83,7 @@ namespace ARMInterpreter
|
|||
|
||||
#define A_LDR_POST \
|
||||
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; \
|
||||
if (((cpu->CurInstr>>12) & 0xF) == 15) \
|
||||
{ \
|
||||
|
|
|
@ -100,7 +100,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
|||
|
||||
|
||||
// 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,
|
||||
|
@ -112,7 +112,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
|||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
|
||||
// 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,
|
||||
|
@ -124,7 +124,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
|||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
|
||||
// 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,
|
||||
|
@ -136,7 +136,7 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
|||
A_UNK, A_UNK, A_UNK, A_UNK,
|
||||
|
||||
// 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,
|
||||
|
@ -308,10 +308,10 @@ INSTRFUNC_PROTO(ARMInstrTable[4096]) =
|
|||
A_TST_IMM, A_TST_IMM, A_TST_IMM, A_TST_IMM,
|
||||
|
||||
// 0011 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_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
|
||||
// 0011 0011 0000
|
||||
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,
|
||||
|
||||
// 0011 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_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
A_MSR_IMM, A_MSR_IMM, A_MSR_IMM, A_MSR_IMM,
|
||||
|
||||
// 0011 0111 0000
|
||||
A_CMN_IMM, A_CMN_IMM, A_CMN_IMM, A_CMN_IMM,
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"NDS.h"
|
||||
"ARM.h"
|
||||
|
||||
1480027981 source:c:\documents\sources\melonds\arm.cpp
|
||||
1480726419 source:c:\documents\sources\melonds\arm.cpp
|
||||
<stdio.h>
|
||||
"NDS.h"
|
||||
"ARM.h"
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
1480724917 c:\documents\sources\melonds\arm_instrtable.h
|
||||
|
||||
1480018830 c:\documents\sources\melonds\arminterpreter.h
|
||||
1480725698 c:\documents\sources\melonds\arminterpreter.h
|
||||
"types.h"
|
||||
"ARM.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue