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