mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 06:10:03 -06:00
add MSR/MRS. also fix misc error with LDR ROR effect.
see shibboleet, I can do it too :>
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user