add MSR/MRS. also fix misc error with LDR ROR effect.

see shibboleet, I can do it too :>
This commit is contained in:
StapleButter 2016-12-03 02:09:04 +01:00
parent 23d584ca4c
commit 844ca45055
5 changed files with 113 additions and 16 deletions

View File

@ -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

View File

@ -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);

View File

@ -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) \
{ \

View File

@ -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,

View File

@ -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"