mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 06:10:03 -06:00
fix some gaps in CPU modes
* non-defined CPU modes are actually possible * bit4 of all PSRs is forced to one (modes 00-0F aren't possible) * modes 14/15/16 and 18/19/1A share a SPSR with modes 17 and 1B respectively (but they don't share the register banks) * modes 10 and 1C/1D/1E don't have a SPSR (MRS returns the CPSR always)
This commit is contained in:
24
src/ARM.cpp
24
src/ARM.cpp
@ -109,6 +109,22 @@ void ARM::Reset()
|
|||||||
|
|
||||||
CPSR = 0x000000D3;
|
CPSR = 0x000000D3;
|
||||||
|
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
R_FIQ[i] = 0;
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
R_SVC[i] = 0;
|
||||||
|
R_ABT[i] = 0;
|
||||||
|
R_IRQ[i] = 0;
|
||||||
|
R_UND[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
R_FIQ[7] = 0x00000010;
|
||||||
|
R_SVC[2] = 0x00000010;
|
||||||
|
R_ABT[2] = 0x00000010;
|
||||||
|
R_IRQ[2] = 0x00000010;
|
||||||
|
R_UND[2] = 0x00000010;
|
||||||
|
|
||||||
ExceptionBase = Num ? 0x00000000 : 0xFFFF0000;
|
ExceptionBase = Num ? 0x00000000 : 0xFFFF0000;
|
||||||
|
|
||||||
CodeMem.Mem = NULL;
|
CodeMem.Mem = NULL;
|
||||||
@ -375,10 +391,16 @@ void ARM::RestoreCPSR()
|
|||||||
CPSR = R_SVC[2];
|
CPSR = R_SVC[2];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x14:
|
||||||
|
case 0x15:
|
||||||
|
case 0x16:
|
||||||
case 0x17:
|
case 0x17:
|
||||||
CPSR = R_ABT[2];
|
CPSR = R_ABT[2];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x18:
|
||||||
|
case 0x19:
|
||||||
|
case 0x1A:
|
||||||
case 0x1B:
|
case 0x1B:
|
||||||
CPSR = R_UND[2];
|
CPSR = R_UND[2];
|
||||||
break;
|
break;
|
||||||
@ -388,6 +410,8 @@ void ARM::RestoreCPSR()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPSR |= 0x00000010;
|
||||||
|
|
||||||
UpdateMode(oldcpsr, CPSR);
|
UpdateMode(oldcpsr, CPSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +69,17 @@ void A_MSR_IMM(ARM* cpu)
|
|||||||
case 0x11: psr = &cpu->R_FIQ[7]; break;
|
case 0x11: psr = &cpu->R_FIQ[7]; break;
|
||||||
case 0x12: psr = &cpu->R_IRQ[2]; break;
|
case 0x12: psr = &cpu->R_IRQ[2]; break;
|
||||||
case 0x13: psr = &cpu->R_SVC[2]; break;
|
case 0x13: psr = &cpu->R_SVC[2]; break;
|
||||||
|
case 0x14:
|
||||||
|
case 0x15:
|
||||||
|
case 0x16:
|
||||||
case 0x17: psr = &cpu->R_ABT[2]; break;
|
case 0x17: psr = &cpu->R_ABT[2]; break;
|
||||||
|
case 0x18:
|
||||||
|
case 0x19:
|
||||||
|
case 0x1A:
|
||||||
case 0x1B: psr = &cpu->R_UND[2]; break;
|
case 0x1B: psr = &cpu->R_UND[2]; break;
|
||||||
default: printf("bad CPU mode %08X\n", cpu->CPSR); return;
|
default:
|
||||||
|
cpu->AddCycles_C();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -92,6 +100,9 @@ void A_MSR_IMM(ARM* cpu)
|
|||||||
|
|
||||||
u32 val = ROR((cpu->CurInstr & 0xFF), ((cpu->CurInstr >> 7) & 0x1E));
|
u32 val = ROR((cpu->CurInstr & 0xFF), ((cpu->CurInstr >> 7) & 0x1E));
|
||||||
|
|
||||||
|
// bit4 is forced to 1
|
||||||
|
val |= 0x00000010;
|
||||||
|
|
||||||
*psr &= ~mask;
|
*psr &= ~mask;
|
||||||
*psr |= (val & mask);
|
*psr |= (val & mask);
|
||||||
|
|
||||||
@ -111,9 +122,17 @@ void A_MSR_REG(ARM* cpu)
|
|||||||
case 0x11: psr = &cpu->R_FIQ[7]; break;
|
case 0x11: psr = &cpu->R_FIQ[7]; break;
|
||||||
case 0x12: psr = &cpu->R_IRQ[2]; break;
|
case 0x12: psr = &cpu->R_IRQ[2]; break;
|
||||||
case 0x13: psr = &cpu->R_SVC[2]; break;
|
case 0x13: psr = &cpu->R_SVC[2]; break;
|
||||||
|
case 0x14:
|
||||||
|
case 0x15:
|
||||||
|
case 0x16:
|
||||||
case 0x17: psr = &cpu->R_ABT[2]; break;
|
case 0x17: psr = &cpu->R_ABT[2]; break;
|
||||||
|
case 0x18:
|
||||||
|
case 0x19:
|
||||||
|
case 0x1A:
|
||||||
case 0x1B: psr = &cpu->R_UND[2]; break;
|
case 0x1B: psr = &cpu->R_UND[2]; break;
|
||||||
default: printf("bad CPU mode %08X\n", cpu->CPSR); return;
|
default:
|
||||||
|
cpu->AddCycles_C();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -134,6 +153,9 @@ void A_MSR_REG(ARM* cpu)
|
|||||||
|
|
||||||
u32 val = cpu->R[cpu->CurInstr & 0xF];
|
u32 val = cpu->R[cpu->CurInstr & 0xF];
|
||||||
|
|
||||||
|
// bit4 is forced to 1
|
||||||
|
val |= 0x00000010;
|
||||||
|
|
||||||
*psr &= ~mask;
|
*psr &= ~mask;
|
||||||
*psr |= (val & mask);
|
*psr |= (val & mask);
|
||||||
|
|
||||||
@ -153,9 +175,15 @@ void A_MRS(ARM* cpu)
|
|||||||
case 0x11: psr = cpu->R_FIQ[7]; break;
|
case 0x11: psr = cpu->R_FIQ[7]; break;
|
||||||
case 0x12: psr = cpu->R_IRQ[2]; break;
|
case 0x12: psr = cpu->R_IRQ[2]; break;
|
||||||
case 0x13: psr = cpu->R_SVC[2]; break;
|
case 0x13: psr = cpu->R_SVC[2]; break;
|
||||||
|
case 0x14:
|
||||||
|
case 0x15:
|
||||||
|
case 0x16:
|
||||||
case 0x17: psr = cpu->R_ABT[2]; break;
|
case 0x17: psr = cpu->R_ABT[2]; break;
|
||||||
|
case 0x18:
|
||||||
|
case 0x19:
|
||||||
|
case 0x1A:
|
||||||
case 0x1B: psr = cpu->R_UND[2]; break;
|
case 0x1B: psr = cpu->R_UND[2]; break;
|
||||||
default: printf("bad CPU mode %08X\n", cpu->CPSR); return;
|
default: psr = cpu->CPSR; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user