mirror of https://github.com/mgba-emu/mgba.git
ARM: Overhaul PSR access
This commit is contained in:
parent
849f80e7a1
commit
37f5feb713
1
CHANGES
1
CHANGES
|
@ -56,6 +56,7 @@ Misc:
|
|||
- SDL: Automatically map controllers when plugged in
|
||||
- Qt: Automatically load controller profile when plugged in
|
||||
- OpenGL: Add xBR-lv2 shader
|
||||
- ARM: Overhaul PSR bit access
|
||||
|
||||
0.5.2: (2016-12-31)
|
||||
Bugfixes:
|
||||
|
|
|
@ -173,6 +173,12 @@ typedef intptr_t ssize_t;
|
|||
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Fill ## FIELD (TYPE src) { \
|
||||
return FILL_BITS(src, (START), (START) + (SIZE)); \
|
||||
} \
|
||||
ATTRIBUTE_UNUSED static inline TYPE TYPE ## OrUnsafe ## FIELD (TYPE src, TYPE bits) { \
|
||||
return (src | ((bits) << (START))); \
|
||||
} \
|
||||
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Or ## FIELD (TYPE src, TYPE bits) { \
|
||||
return (src | (((bits) << (START)) & MAKE_MASK(START, (START) + (SIZE)))); \
|
||||
} \
|
||||
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Set ## FIELD (TYPE src, TYPE bits) { \
|
||||
return INS_BITS(src, (START), (START) + (SIZE), bits); \
|
||||
} \
|
||||
|
|
|
@ -68,33 +68,15 @@ enum LSMDirection {
|
|||
|
||||
struct ARMCore;
|
||||
|
||||
union PSR {
|
||||
struct {
|
||||
#if defined(__POWERPC__) || defined(__PPC__)
|
||||
unsigned n : 1;
|
||||
unsigned z : 1;
|
||||
unsigned c : 1;
|
||||
unsigned v : 1;
|
||||
unsigned unused : 20;
|
||||
unsigned i : 1;
|
||||
unsigned f : 1;
|
||||
unsigned t : 1;
|
||||
unsigned priv : 5;
|
||||
#else
|
||||
unsigned priv : 5;
|
||||
unsigned t : 1;
|
||||
unsigned f : 1;
|
||||
unsigned i : 1;
|
||||
unsigned unused : 20;
|
||||
unsigned v : 1;
|
||||
unsigned c : 1;
|
||||
unsigned z : 1;
|
||||
unsigned n : 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
int32_t packed;
|
||||
};
|
||||
DECL_BITFIELD(ARMPSR, uint32_t);
|
||||
DECL_BITS(ARMPSR, Priv, 0, 5);
|
||||
DECL_BIT(ARMPSR, T, 5);
|
||||
DECL_BIT(ARMPSR, F, 6);
|
||||
DECL_BIT(ARMPSR, I, 7);
|
||||
DECL_BIT(ARMPSR, V, 28);
|
||||
DECL_BIT(ARMPSR, C, 29);
|
||||
DECL_BIT(ARMPSR, Z, 30);
|
||||
DECL_BIT(ARMPSR, N, 31);
|
||||
|
||||
struct ARMMemory {
|
||||
uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);
|
||||
|
@ -135,8 +117,8 @@ struct ARMInterruptHandler {
|
|||
|
||||
struct ARMCore {
|
||||
int32_t gprs[16];
|
||||
union PSR cpsr;
|
||||
union PSR spsr;
|
||||
ARMPSR cpsr;
|
||||
ARMPSR spsr;
|
||||
|
||||
int32_t cycles;
|
||||
int32_t nextEvent;
|
||||
|
|
|
@ -10,20 +10,20 @@
|
|||
|
||||
#include "arm.h"
|
||||
|
||||
#define ARM_COND_EQ (cpu->cpsr.z)
|
||||
#define ARM_COND_NE (!cpu->cpsr.z)
|
||||
#define ARM_COND_CS (cpu->cpsr.c)
|
||||
#define ARM_COND_CC (!cpu->cpsr.c)
|
||||
#define ARM_COND_MI (cpu->cpsr.n)
|
||||
#define ARM_COND_PL (!cpu->cpsr.n)
|
||||
#define ARM_COND_VS (cpu->cpsr.v)
|
||||
#define ARM_COND_VC (!cpu->cpsr.v)
|
||||
#define ARM_COND_HI (cpu->cpsr.c && !cpu->cpsr.z)
|
||||
#define ARM_COND_LS (!cpu->cpsr.c || cpu->cpsr.z)
|
||||
#define ARM_COND_GE (!cpu->cpsr.n == !cpu->cpsr.v)
|
||||
#define ARM_COND_LT (!cpu->cpsr.n != !cpu->cpsr.v)
|
||||
#define ARM_COND_GT (!cpu->cpsr.z && !cpu->cpsr.n == !cpu->cpsr.v)
|
||||
#define ARM_COND_LE (cpu->cpsr.z || !cpu->cpsr.n != !cpu->cpsr.v)
|
||||
#define ARM_COND_EQ (ARMPSRIsZ(cpu->cpsr))
|
||||
#define ARM_COND_NE (!ARMPSRIsZ(cpu->cpsr))
|
||||
#define ARM_COND_CS (ARMPSRIsC(cpu->cpsr))
|
||||
#define ARM_COND_CC (!ARMPSRIsC(cpu->cpsr))
|
||||
#define ARM_COND_MI (ARMPSRIsN(cpu->cpsr))
|
||||
#define ARM_COND_PL (!ARMPSRIsN(cpu->cpsr))
|
||||
#define ARM_COND_VS (ARMPSRIsV(cpu->cpsr))
|
||||
#define ARM_COND_VC (!ARMPSRIsV(cpu->cpsr))
|
||||
#define ARM_COND_HI (ARMPSRIsC(cpu->cpsr) && !ARMPSRIsZ(cpu->cpsr))
|
||||
#define ARM_COND_LS (!ARMPSRIsC(cpu->cpsr) || ARMPSRIsZ(cpu->cpsr))
|
||||
#define ARM_COND_GE (!ARMPSRIsN(cpu->cpsr) == !ARMPSRIsV(cpu->cpsr))
|
||||
#define ARM_COND_LT (!ARMPSRIsN(cpu->cpsr) != !ARMPSRIsV(cpu->cpsr))
|
||||
#define ARM_COND_GT (!ARMPSRIsZ(cpu->cpsr) && !ARMPSRIsN(cpu->cpsr) == !ARMPSRIsV(cpu->cpsr))
|
||||
#define ARM_COND_LE (ARMPSRIsZ(cpu->cpsr) || !ARMPSRIsN(cpu->cpsr) != !ARMPSRIsV(cpu->cpsr))
|
||||
#define ARM_COND_AL 1
|
||||
|
||||
#define ARM_SIGN(I) ((I) >> 31)
|
||||
|
@ -83,24 +83,23 @@ static inline void _ARMSetMode(struct ARMCore* cpu, enum ExecutionMode execution
|
|||
cpu->executionMode = executionMode;
|
||||
switch (executionMode) {
|
||||
case MODE_ARM:
|
||||
cpu->cpsr.t = 0;
|
||||
cpu->cpsr = ARMPSRClearT(cpu->cpsr);
|
||||
break;
|
||||
case MODE_THUMB:
|
||||
cpu->cpsr.t = 1;
|
||||
cpu->cpsr = ARMPSRFillT(cpu->cpsr);
|
||||
}
|
||||
cpu->nextEvent = cpu->cycles;
|
||||
}
|
||||
|
||||
static inline void _ARMReadCPSR(struct ARMCore* cpu) {
|
||||
_ARMSetMode(cpu, cpu->cpsr.t);
|
||||
ARMSetPrivilegeMode(cpu, cpu->cpsr.priv);
|
||||
_ARMSetMode(cpu, ARMPSRGetT(cpu->cpsr));
|
||||
ARMSetPrivilegeMode(cpu, ARMPSRGetPriv(cpu->cpsr));
|
||||
cpu->irqh.readCPSR(cpu);
|
||||
}
|
||||
|
||||
static inline uint32_t _ARMPCAddress(struct ARMCore* cpu) {
|
||||
int instructionLength;
|
||||
enum ExecutionMode mode = cpu->cpsr.t;
|
||||
if (mode == MODE_ARM) {
|
||||
if (ARMPSRIsT(cpu->cpsr)) {
|
||||
instructionLength = WORD_SIZE_ARM;
|
||||
} else {
|
||||
instructionLength = WORD_SIZE_THUMB;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
CXX_GUARD_START
|
||||
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/internal/arm/arm.h>
|
||||
#include <mgba/internal/gba/gba.h>
|
||||
#include <mgba/internal/gb/serialize.h>
|
||||
|
||||
|
@ -237,8 +238,8 @@ struct GBASerializedState {
|
|||
|
||||
struct {
|
||||
int32_t gprs[16];
|
||||
union PSR cpsr;
|
||||
union PSR spsr;
|
||||
ARMPSR cpsr;
|
||||
ARMPSR spsr;
|
||||
|
||||
int32_t cycles;
|
||||
int32_t nextEvent;
|
||||
|
|
|
@ -40,8 +40,8 @@ void ARMSetPrivilegeMode(struct ARMCore* cpu, enum PrivilegeMode mode) {
|
|||
cpu->gprs[ARM_SP] = cpu->bankedRegisters[newBank][0];
|
||||
cpu->gprs[ARM_LR] = cpu->bankedRegisters[newBank][1];
|
||||
|
||||
cpu->bankedSPSRs[oldBank] = cpu->spsr.packed;
|
||||
cpu->spsr.packed = cpu->bankedSPSRs[newBank];
|
||||
cpu->bankedSPSRs[oldBank] = cpu->spsr;
|
||||
cpu->spsr = cpu->bankedSPSRs[newBank];
|
||||
}
|
||||
cpu->privilegeMode = mode;
|
||||
}
|
||||
|
@ -127,8 +127,8 @@ void ARMReset(struct ARMCore* cpu) {
|
|||
}
|
||||
|
||||
cpu->privilegeMode = MODE_SYSTEM;
|
||||
cpu->cpsr.packed = MODE_SYSTEM;
|
||||
cpu->spsr.packed = 0;
|
||||
cpu->cpsr = MODE_SYSTEM;
|
||||
cpu->spsr = 0;
|
||||
|
||||
cpu->shifterOperand = 0;
|
||||
cpu->shifterCarryOut = 0;
|
||||
|
@ -147,10 +147,10 @@ void ARMReset(struct ARMCore* cpu) {
|
|||
}
|
||||
|
||||
void ARMRaiseIRQ(struct ARMCore* cpu) {
|
||||
if (cpu->cpsr.i) {
|
||||
if (ARMPSRIsI(cpu->cpsr)) {
|
||||
return;
|
||||
}
|
||||
union PSR cpsr = cpu->cpsr;
|
||||
ARMPSR cpsr = cpu->cpsr;
|
||||
int instructionWidth;
|
||||
if (cpu->executionMode == MODE_THUMB) {
|
||||
instructionWidth = WORD_SIZE_THUMB;
|
||||
|
@ -158,19 +158,19 @@ void ARMRaiseIRQ(struct ARMCore* cpu) {
|
|||
instructionWidth = WORD_SIZE_ARM;
|
||||
}
|
||||
ARMSetPrivilegeMode(cpu, MODE_IRQ);
|
||||
cpu->cpsr.priv = MODE_IRQ;
|
||||
cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_IRQ);
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM;
|
||||
cpu->gprs[ARM_PC] = BASE_IRQ;
|
||||
int currentCycles = 0;
|
||||
ARM_WRITE_PC;
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
cpu->cpsr = ARMPSRFillI(cpu->cpsr);
|
||||
cpu->cycles += currentCycles;
|
||||
}
|
||||
|
||||
void ARMRaiseSWI(struct ARMCore* cpu) {
|
||||
union PSR cpsr = cpu->cpsr;
|
||||
ARMPSR cpsr = cpu->cpsr;
|
||||
int instructionWidth;
|
||||
if (cpu->executionMode == MODE_THUMB) {
|
||||
instructionWidth = WORD_SIZE_THUMB;
|
||||
|
@ -178,19 +178,19 @@ void ARMRaiseSWI(struct ARMCore* cpu) {
|
|||
instructionWidth = WORD_SIZE_ARM;
|
||||
}
|
||||
ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);
|
||||
cpu->cpsr.priv = MODE_SUPERVISOR;
|
||||
cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_SUPERVISOR);
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth;
|
||||
cpu->gprs[ARM_PC] = BASE_SWI;
|
||||
int currentCycles = 0;
|
||||
ARM_WRITE_PC;
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
cpu->cpsr = ARMPSRFillI(cpu->cpsr);
|
||||
cpu->cycles += currentCycles;
|
||||
}
|
||||
|
||||
void ARMRaiseUndefined(struct ARMCore* cpu) {
|
||||
union PSR cpsr = cpu->cpsr;
|
||||
ARMPSR cpsr = cpu->cpsr;
|
||||
int instructionWidth;
|
||||
if (cpu->executionMode == MODE_THUMB) {
|
||||
instructionWidth = WORD_SIZE_THUMB;
|
||||
|
@ -198,14 +198,14 @@ void ARMRaiseUndefined(struct ARMCore* cpu) {
|
|||
instructionWidth = WORD_SIZE_ARM;
|
||||
}
|
||||
ARMSetPrivilegeMode(cpu, MODE_UNDEFINED);
|
||||
cpu->cpsr.priv = MODE_UNDEFINED;
|
||||
cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_UNDEFINED);
|
||||
cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth;
|
||||
cpu->gprs[ARM_PC] = BASE_UNDEF;
|
||||
int currentCycles = 0;
|
||||
ARM_WRITE_PC;
|
||||
_ARMSetMode(cpu, MODE_ARM);
|
||||
cpu->spsr = cpsr;
|
||||
cpu->cpsr.i = 1;
|
||||
cpu->cpsr = ARMPSRFillI(cpu->cpsr);
|
||||
cpu->cycles += currentCycles;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,15 +37,15 @@ static struct CLIDebuggerCommandSummary _armCommands[] = {
|
|||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static inline void _printPSR(struct CLIDebuggerBackend* be, union PSR psr) {
|
||||
be->printf(be, "%08X [%c%c%c%c%c%c%c]\n", psr.packed,
|
||||
psr.n ? 'N' : '-',
|
||||
psr.z ? 'Z' : '-',
|
||||
psr.c ? 'C' : '-',
|
||||
psr.v ? 'V' : '-',
|
||||
psr.i ? 'I' : '-',
|
||||
psr.f ? 'F' : '-',
|
||||
psr.t ? 'T' : '-');
|
||||
static inline void _printPSR(struct CLIDebuggerBackend* be, ARMPSR psr) {
|
||||
be->printf(be, "%08X [%c%c%c%c%c%c%c]\n", psr,
|
||||
ARMPSRIsN(psr) ? 'N' : '-',
|
||||
ARMPSRIsZ(psr) ? 'Z' : '-',
|
||||
ARMPSRIsC(psr) ? 'C' : '-',
|
||||
ARMPSRIsV(psr) ? 'V' : '-',
|
||||
ARMPSRIsI(psr) ? 'I' : '-',
|
||||
ARMPSRIsF(psr) ? 'F' : '-',
|
||||
ARMPSRIsT(psr) ? 'T' : '-');
|
||||
}
|
||||
|
||||
static void _disassemble(struct CLIDebuggerSystem* debugger, struct CLIDebugVector* dv) {
|
||||
|
@ -136,7 +136,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
|
|||
}
|
||||
_printPSR(be, cpu->cpsr);
|
||||
int instructionLength;
|
||||
enum ExecutionMode mode = cpu->cpsr.t;
|
||||
enum ExecutionMode mode = ARMPSRIsT(cpu->cpsr);
|
||||
if (mode == MODE_ARM) {
|
||||
instructionLength = WORD_SIZE_ARM;
|
||||
} else {
|
||||
|
@ -196,11 +196,11 @@ static uint32_t _lookupPlatformIdentifier(struct CLIDebuggerSystem* debugger, co
|
|||
return cpu->gprs[ARM_PC];
|
||||
}
|
||||
if (strcmp(name, "cpsr") == 0) {
|
||||
return cpu->cpsr.packed;
|
||||
return cpu->cpsr;
|
||||
}
|
||||
// TODO: test if mode has SPSR
|
||||
if (strcmp(name, "spsr") == 0) {
|
||||
return cpu->spsr.packed;
|
||||
return cpu->spsr;
|
||||
}
|
||||
if (name[0] == 'r' && name[1] >= '0' && name[1] <= '9') {
|
||||
int reg = atoi(&name[1]);
|
||||
|
|
|
@ -26,7 +26,7 @@ static struct ARMDebugBreakpoint* _lookupBreakpoint(struct ARMDebugBreakpointLis
|
|||
static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
|
||||
struct ARMDebugger* debugger = (struct ARMDebugger*) d;
|
||||
int instructionLength;
|
||||
enum ExecutionMode mode = debugger->cpu->cpsr.t;
|
||||
enum ExecutionMode mode = ARMPSRIsT(debugger->cpu->cpsr);
|
||||
if (mode == MODE_ARM) {
|
||||
instructionLength = WORD_SIZE_ARM;
|
||||
} else {
|
||||
|
|
|
@ -30,7 +30,7 @@ static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) {
|
|||
}
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr);
|
||||
} else if (shift < 32) {
|
||||
cpu->shifterOperand = shiftVal << shift;
|
||||
cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1;
|
||||
|
@ -45,7 +45,7 @@ static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) {
|
|||
int immediate = (opcode & 0x00000F80) >> 7;
|
||||
if (!immediate) {
|
||||
cpu->shifterOperand = cpu->gprs[rm];
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr);
|
||||
} else {
|
||||
cpu->shifterOperand = cpu->gprs[rm] << immediate;
|
||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1;
|
||||
|
@ -69,7 +69,7 @@ static inline void _shiftLSR(struct ARMCore* cpu, uint32_t opcode) {
|
|||
}
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr);
|
||||
} else if (shift < 32) {
|
||||
cpu->shifterOperand = shiftVal >> shift;
|
||||
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
|
||||
|
@ -108,7 +108,7 @@ static inline void _shiftASR(struct ARMCore* cpu, uint32_t opcode) {
|
|||
}
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr);
|
||||
} else if (shift < 32) {
|
||||
cpu->shifterOperand = shiftVal >> shift;
|
||||
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
|
||||
|
@ -148,7 +148,7 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) {
|
|||
int rotate = shift & 0x1F;
|
||||
if (!shift) {
|
||||
cpu->shifterOperand = shiftVal;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr);
|
||||
} else if (rotate) {
|
||||
cpu->shifterOperand = ROR(shiftVal, rotate);
|
||||
cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;
|
||||
|
@ -163,7 +163,7 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) {
|
|||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
} else {
|
||||
// RRX
|
||||
cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
|
||||
cpu->shifterOperand = (ARMPSRGetC(cpu->cpsr) << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
|
||||
cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001;
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
int immediate = opcode & 0x000000FF;
|
||||
if (!rotate) {
|
||||
cpu->shifterOperand = immediate;
|
||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||
cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr);
|
||||
} else {
|
||||
cpu->shifterOperand = ROR(immediate, rotate);
|
||||
cpu->shifterCarryOut = ARM_SIGN(cpu->shifterOperand);
|
||||
|
@ -185,46 +185,54 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
// Beware pre-processor antics
|
||||
|
||||
#define ARM_ADDITION_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_ADDITION(M, N, D); \
|
||||
ARMPSR cpsr = 0; \
|
||||
cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \
|
||||
cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \
|
||||
cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM(M, N, D)); \
|
||||
cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \
|
||||
cpu->cpsr = cpu->cpsr & (0x0FFFFFFF) | cpsr; \
|
||||
}
|
||||
|
||||
#define ARM_SUBTRACTION_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); \
|
||||
ARMPSR cpsr = 0; \
|
||||
cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \
|
||||
cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \
|
||||
cpsr = ARMPSROrUnsafeC(cpsr, ARM_BORROW_FROM(M, N, D)); \
|
||||
cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_SUBTRACTION(M, N, D)); \
|
||||
cpu->cpsr = cpu->cpsr & (0x0FFFFFFF) | cpsr; \
|
||||
}
|
||||
|
||||
#define ARM_SUBTRACTION_CARRY_S(M, N, D, C) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_BORROW_FROM_CARRY(M, N, D, C); \
|
||||
cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D); \
|
||||
ARMPSR cpsr = 0; \
|
||||
cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \
|
||||
cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \
|
||||
cpsr = ARMPSROrUnsafeC(cpsr, ARM_BORROW_FROM_CARRY(M, N, D, C)); \
|
||||
cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_SUBTRACTION(M, N, D)); \
|
||||
cpu->cpsr = cpu->cpsr & (0x0FFFFFFF) | cpsr; \
|
||||
}
|
||||
|
||||
#define ARM_NEUTRAL_S(M, N, D) \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \
|
||||
if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \
|
||||
cpu->cpsr = cpu->spsr; \
|
||||
_ARMReadCPSR(cpu); \
|
||||
} else { \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = cpu->shifterCarryOut; \
|
||||
ARMPSR cpsr = 0; \
|
||||
cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \
|
||||
cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \
|
||||
cpsr = ARMPSROrUnsafeC(cpsr, cpu->shifterCarryOut); \
|
||||
cpu->cpsr = cpu->cpsr & (0x1FFFFFFF) | cpsr; \
|
||||
}
|
||||
|
||||
#define ARM_NEUTRAL_HI_S(DLO, DHI) \
|
||||
|
@ -247,7 +255,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
|||
#define ADDR_MODE_2_LSL (cpu->gprs[rm] << ADDR_MODE_2_I)
|
||||
#define ADDR_MODE_2_LSR (ADDR_MODE_2_I_TEST ? ((uint32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : 0)
|
||||
#define ADDR_MODE_2_ASR (ADDR_MODE_2_I_TEST ? ((int32_t) cpu->gprs[rm]) >> ADDR_MODE_2_I : ((int32_t) cpu->gprs[rm]) >> 31)
|
||||
#define ADDR_MODE_2_ROR (ADDR_MODE_2_I_TEST ? ROR(cpu->gprs[rm], ADDR_MODE_2_I) : (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1))
|
||||
#define ADDR_MODE_2_ROR (ADDR_MODE_2_I_TEST ? ROR(cpu->gprs[rm], ADDR_MODE_2_I) : (ARMPSRGetC(cpu->cpsr) << 31) | (((uint32_t) cpu->gprs[rm]) >> 1))
|
||||
|
||||
#define ADDR_MODE_3_ADDRESS ADDR_MODE_2_ADDRESS
|
||||
#define ADDR_MODE_3_RN ADDR_MODE_2_RN
|
||||
|
@ -450,7 +458,7 @@ DEFINE_ALU_INSTRUCTION_ARM(ADD, ARM_ADDITION_S(n, cpu->shifterOperand, cpu->gprs
|
|||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(ADC, ARM_ADDITION_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = n + cpu->shifterOperand + cpu->cpsr.c;)
|
||||
cpu->gprs[rd] = n + cpu->shifterOperand + ARMPSRGetC(cpu->cpsr);)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(AND, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]),
|
||||
cpu->gprs[rd] = cpu->gprs[rn] & cpu->shifterOperand;)
|
||||
|
@ -480,13 +488,13 @@ DEFINE_ALU_INSTRUCTION_ARM(RSB, ARM_SUBTRACTION_S(cpu->shifterOperand, n, cpu->g
|
|||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n;)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_CARRY_S(cpu->shifterOperand, n, cpu->gprs[rd], !cpu->cpsr.c),
|
||||
DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_CARRY_S(cpu->shifterOperand, n, cpu->gprs[rd], !ARMPSRIsC(cpu->cpsr)),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n - !cpu->cpsr.c;)
|
||||
cpu->gprs[rd] = cpu->shifterOperand - n - !ARMPSRIsC(cpu->cpsr);)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], !cpu->cpsr.c),
|
||||
DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], !ARMPSRIsC(cpu->cpsr)),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
cpu->gprs[rd] = n - cpu->shifterOperand - !cpu->cpsr.c;)
|
||||
cpu->gprs[rd] = n - cpu->shifterOperand - !ARMPSRIsC(cpu->cpsr);)
|
||||
|
||||
DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(n, cpu->shifterOperand, cpu->gprs[rd]),
|
||||
int32_t n = cpu->gprs[rn];
|
||||
|
@ -652,14 +660,14 @@ DEFINE_INSTRUCTION_ARM(MSR,
|
|||
int32_t operand = cpu->gprs[opcode & 0x0000000F];
|
||||
int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0);
|
||||
if (mask & PSR_USER_MASK) {
|
||||
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK);
|
||||
cpu->cpsr = (cpu->cpsr & ~PSR_USER_MASK) | (operand & PSR_USER_MASK);
|
||||
}
|
||||
if (mask & PSR_STATE_MASK) {
|
||||
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK);
|
||||
cpu->cpsr = (cpu->cpsr & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK);
|
||||
}
|
||||
if (cpu->privilegeMode != MODE_USER && (mask & PSR_PRIV_MASK)) {
|
||||
ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010));
|
||||
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK);
|
||||
cpu->cpsr = (cpu->cpsr & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK);
|
||||
}
|
||||
_ARMReadCPSR(cpu);
|
||||
if (cpu->executionMode == MODE_THUMB) {
|
||||
|
@ -676,15 +684,15 @@ DEFINE_INSTRUCTION_ARM(MSRR,
|
|||
int32_t operand = cpu->gprs[opcode & 0x0000000F];
|
||||
int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0);
|
||||
mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK;
|
||||
cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask) | 0x00000010;)
|
||||
cpu->spsr = (cpu->spsr & ~mask) | (operand & mask) | 0x00000010;)
|
||||
|
||||
DEFINE_INSTRUCTION_ARM(MRS, \
|
||||
int rd = (opcode >> 12) & 0xF; \
|
||||
cpu->gprs[rd] = cpu->cpsr.packed;)
|
||||
cpu->gprs[rd] = cpu->cpsr;)
|
||||
|
||||
DEFINE_INSTRUCTION_ARM(MRSR, \
|
||||
int rd = (opcode >> 12) & 0xF; \
|
||||
cpu->gprs[rd] = cpu->spsr.packed;)
|
||||
cpu->gprs[rd] = cpu->spsr;)
|
||||
|
||||
DEFINE_INSTRUCTION_ARM(MSRI,
|
||||
int c = opcode & 0x00010000;
|
||||
|
@ -693,14 +701,14 @@ DEFINE_INSTRUCTION_ARM(MSRI,
|
|||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0);
|
||||
if (mask & PSR_USER_MASK) {
|
||||
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK);
|
||||
cpu->cpsr = (cpu->cpsr & ~PSR_USER_MASK) | (operand & PSR_USER_MASK);
|
||||
}
|
||||
if (mask & PSR_STATE_MASK) {
|
||||
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK);
|
||||
cpu->cpsr = (cpu->cpsr & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK);
|
||||
}
|
||||
if (cpu->privilegeMode != MODE_USER && (mask & PSR_PRIV_MASK)) {
|
||||
ARMSetPrivilegeMode(cpu, (enum PrivilegeMode) ((operand & 0x0000000F) | 0x00000010));
|
||||
cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK);
|
||||
cpu->cpsr = (cpu->cpsr & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK);
|
||||
}
|
||||
_ARMReadCPSR(cpu);
|
||||
if (cpu->executionMode == MODE_THUMB) {
|
||||
|
@ -718,7 +726,7 @@ DEFINE_INSTRUCTION_ARM(MSRRI,
|
|||
int32_t operand = ROR(opcode & 0x000000FF, rotate);
|
||||
int32_t mask = (c ? 0x000000FF : 0) | (f ? 0xFF000000 : 0);
|
||||
mask &= PSR_USER_MASK | PSR_PRIV_MASK | PSR_STATE_MASK;
|
||||
cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask) | 0x00000010;)
|
||||
cpu->spsr = (cpu->spsr & ~mask) | (operand & mask) | 0x00000010;)
|
||||
|
||||
DEFINE_INSTRUCTION_ARM(SWI, cpu->irqh.swi32(cpu, opcode & 0xFFFFFF))
|
||||
|
||||
|
|
|
@ -12,20 +12,32 @@
|
|||
// Beware pre-processor insanity
|
||||
|
||||
#define THUMB_ADDITION_S(M, N, D) \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_CARRY_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_ADDITION(M, N, D);
|
||||
{ \
|
||||
ARMPSR cpsr = 0; \
|
||||
cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \
|
||||
cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \
|
||||
cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM(M, N, D)); \
|
||||
cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \
|
||||
cpu->cpsr = cpu->cpsr & (0x0FFFFFFF) | cpsr; \
|
||||
}
|
||||
|
||||
#define THUMB_SUBTRACTION_S(M, N, D) \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D); \
|
||||
cpu->cpsr.c = ARM_BORROW_FROM(M, N, D); \
|
||||
cpu->cpsr.v = ARM_V_SUBTRACTION(M, N, D);
|
||||
{ \
|
||||
ARMPSR cpsr = 0; \
|
||||
cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \
|
||||
cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \
|
||||
cpsr = ARMPSROrUnsafeC(cpsr, ARM_BORROW_FROM(M, N, D)); \
|
||||
cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_SUBTRACTION(M, N, D)); \
|
||||
cpu->cpsr = cpu->cpsr & (0x0FFFFFFF) | cpsr; \
|
||||
}
|
||||
|
||||
#define THUMB_NEUTRAL_S(M, N, D) \
|
||||
cpu->cpsr.n = ARM_SIGN(D); \
|
||||
cpu->cpsr.z = !(D);
|
||||
{ \
|
||||
ARMPSR cpsr = 0; \
|
||||
cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \
|
||||
cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \
|
||||
cpu->cpsr = cpu->cpsr & (0x3FFFFFFF) | cpsr; \
|
||||
}
|
||||
|
||||
#define THUMB_ADDITION(D, M, N) \
|
||||
int n = N; \
|
||||
|
@ -65,31 +77,31 @@ DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSL1,
|
|||
if (!immediate) {
|
||||
cpu->gprs[rd] = cpu->gprs[rm];
|
||||
} else {
|
||||
cpu->cpsr.c = (cpu->gprs[rm] >> (32 - immediate)) & 1;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (32 - immediate)) & 1);
|
||||
cpu->gprs[rd] = cpu->gprs[rm] << immediate;
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSR1,
|
||||
if (!immediate) {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]);
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rm]));
|
||||
cpu->gprs[rd] = 0;
|
||||
} else {
|
||||
cpu->cpsr.c = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (immediate - 1)) & 1);
|
||||
cpu->gprs[rd] = ((uint32_t) cpu->gprs[rm]) >> immediate;
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
||||
DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(ASR1,
|
||||
if (!immediate) {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]);
|
||||
if (cpu->cpsr.c) {
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rm]));
|
||||
if (ARMPSRIsC(cpu->cpsr)) {
|
||||
cpu->gprs[rd] = 0xFFFFFFFF;
|
||||
} else {
|
||||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
} else {
|
||||
cpu->cpsr.c = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (immediate - 1)) & 1);
|
||||
cpu->gprs[rd] = cpu->gprs[rm] >> immediate;
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
@ -144,13 +156,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSL2,
|
|||
int rs = cpu->gprs[rn] & 0xFF;
|
||||
if (rs) {
|
||||
if (rs < 32) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (32 - rs)) & 1;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (32 - rs)) & 1);
|
||||
cpu->gprs[rd] <<= rs;
|
||||
} else {
|
||||
if (rs > 32) {
|
||||
cpu->cpsr.c = 0;
|
||||
cpu->cpsr = ARMPSRClearC(cpu->cpsr);
|
||||
} else {
|
||||
cpu->cpsr.c = cpu->gprs[rd] & 0x00000001;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, cpu->gprs[rd] & 0x00000001);
|
||||
}
|
||||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
|
@ -161,13 +173,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSR2,
|
|||
int rs = cpu->gprs[rn] & 0xFF;
|
||||
if (rs) {
|
||||
if (rs < 32) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (rs - 1)) & 1);
|
||||
cpu->gprs[rd] = (uint32_t) cpu->gprs[rd] >> rs;
|
||||
} else {
|
||||
if (rs > 32) {
|
||||
cpu->cpsr.c = 0;
|
||||
cpu->cpsr = ARMPSRClearC(cpu->cpsr);
|
||||
} else {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd]));
|
||||
}
|
||||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
|
@ -178,11 +190,11 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2,
|
|||
int rs = cpu->gprs[rn] & 0xFF;
|
||||
if (rs) {
|
||||
if (rs < 32) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (rs - 1)) & 1);
|
||||
cpu->gprs[rd] >>= rs;
|
||||
} else {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
if (cpu->cpsr.c) {
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd]));
|
||||
if (ARMPSRIsC(cpu->cpsr)) {
|
||||
cpu->gprs[rd] = 0xFFFFFFFF;
|
||||
} else {
|
||||
cpu->gprs[rd] = 0;
|
||||
|
@ -194,11 +206,11 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2,
|
|||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ADC,
|
||||
int n = cpu->gprs[rn];
|
||||
int d = cpu->gprs[rd];
|
||||
cpu->gprs[rd] = d + n + cpu->cpsr.c;
|
||||
cpu->gprs[rd] = d + n + ARMPSRGetC(cpu->cpsr);
|
||||
THUMB_ADDITION_S(d, n, cpu->gprs[rd]);)
|
||||
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(SBC,
|
||||
int n = cpu->gprs[rn] + !cpu->cpsr.c;
|
||||
int n = cpu->gprs[rn] + !ARMPSRIsC(cpu->cpsr);
|
||||
int d = cpu->gprs[rd];
|
||||
cpu->gprs[rd] = d - n;
|
||||
THUMB_SUBTRACTION_S(d, n, cpu->gprs[rd]);)
|
||||
|
@ -207,10 +219,10 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ROR,
|
|||
if (rs) {
|
||||
int r4 = rs & 0x1F;
|
||||
if (r4 > 0) {
|
||||
cpu->cpsr.c = (cpu->gprs[rd] >> (r4 - 1)) & 1;
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (r4 - 1)) & 1);
|
||||
cpu->gprs[rd] = ROR(cpu->gprs[rd], r4);
|
||||
} else {
|
||||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd]));
|
||||
}
|
||||
}
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
|
|
|
@ -325,7 +325,7 @@ static void _readGPRs(struct GDBStub* stub, const char* message) {
|
|||
_int2hex32(cpu->gprs[r], &stub->outgoing[i]);
|
||||
i += 8;
|
||||
}
|
||||
_int2hex32(cpu->gprs[ARM_PC] - (cpu->cpsr.t ? WORD_SIZE_THUMB : WORD_SIZE_ARM), &stub->outgoing[i]);
|
||||
_int2hex32(cpu->gprs[ARM_PC] - (ARMPSRIsT(cpu->cpsr) ? WORD_SIZE_THUMB : WORD_SIZE_ARM), &stub->outgoing[i]);
|
||||
i += 8;
|
||||
|
||||
stub->outgoing[i] = 0;
|
||||
|
@ -359,7 +359,7 @@ static void _writeRegister(struct GDBStub* stub, const char* message) {
|
|||
}
|
||||
}
|
||||
} else if (reg == 0x19) {
|
||||
cpu->cpsr.packed = value;
|
||||
cpu->cpsr = value;
|
||||
} else {
|
||||
stub->outgoing[0] = '\0';
|
||||
_sendMessage(stub);
|
||||
|
@ -379,7 +379,7 @@ static void _readRegister(struct GDBStub* stub, const char* message) {
|
|||
if (reg < 0x10) {
|
||||
value = cpu->gprs[reg];
|
||||
} else if (reg == 0x19) {
|
||||
value = cpu->cpsr.packed;
|
||||
value = cpu->cpsr;
|
||||
} else {
|
||||
stub->outgoing[0] = '\0';
|
||||
_sendMessage(stub);
|
||||
|
|
|
@ -25,11 +25,11 @@ static void _unBitPack(struct GBA* gba);
|
|||
static void _SoftReset(struct GBA* gba) {
|
||||
struct ARMCore* cpu = gba->cpu;
|
||||
ARMSetPrivilegeMode(cpu, MODE_IRQ);
|
||||
cpu->spsr.packed = 0;
|
||||
cpu->spsr = 0;
|
||||
cpu->gprs[ARM_LR] = 0;
|
||||
cpu->gprs[ARM_SP] = SP_BASE_IRQ;
|
||||
ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);
|
||||
cpu->spsr.packed = 0;
|
||||
cpu->spsr = 0;
|
||||
cpu->gprs[ARM_LR] = 0;
|
||||
cpu->gprs[ARM_SP] = SP_BASE_SUPERVISOR;
|
||||
ARMSetPrivilegeMode(cpu, MODE_SYSTEM);
|
||||
|
|
|
@ -227,7 +227,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) {
|
|||
gba->bus |= cpu->prefetch[1] << 16;
|
||||
}
|
||||
|
||||
if (gba->springIRQ && !cpu->cpsr.i) {
|
||||
if (gba->springIRQ && !ARMPSRIsI(cpu->cpsr)) {
|
||||
ARMRaiseIRQ(cpu);
|
||||
gba->springIRQ = 0;
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
|
|||
for (i = 0; i < 16; ++i) {
|
||||
STORE_32(gba->cpu->gprs[i], i * sizeof(state->cpu.gprs[0]), state->cpu.gprs);
|
||||
}
|
||||
STORE_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed);
|
||||
STORE_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed);
|
||||
STORE_32(gba->cpu->cpsr, 0, &state->cpu.cpsr);
|
||||
STORE_32(gba->cpu->spsr, 0, &state->cpu.spsr);
|
||||
STORE_32(gba->cpu->cycles, 0, &state->cpu.cycles);
|
||||
STORE_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
||||
for (i = 0; i < 6; ++i) {
|
||||
|
@ -151,8 +151,8 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
for (i = 0; i < 16; ++i) {
|
||||
LOAD_32(gba->cpu->gprs[i], i * sizeof(gba->cpu->gprs[0]), state->cpu.gprs);
|
||||
}
|
||||
LOAD_32(gba->cpu->cpsr.packed, 0, &state->cpu.cpsr.packed);
|
||||
LOAD_32(gba->cpu->spsr.packed, 0, &state->cpu.spsr.packed);
|
||||
LOAD_32(gba->cpu->cpsr, 0, &state->cpu.cpsr);
|
||||
LOAD_32(gba->cpu->spsr, 0, &state->cpu.spsr);
|
||||
LOAD_32(gba->cpu->cycles, 0, &state->cpu.cycles);
|
||||
LOAD_32(gba->cpu->nextEvent, 0, &state->cpu.nextEvent);
|
||||
for (i = 0; i < 6; ++i) {
|
||||
|
@ -162,13 +162,13 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
}
|
||||
LOAD_32(gba->cpu->bankedSPSRs[i], i * sizeof(gba->cpu->bankedSPSRs[0]), state->cpu.bankedSPSRs);
|
||||
}
|
||||
gba->cpu->privilegeMode = gba->cpu->cpsr.priv;
|
||||
gba->cpu->privilegeMode = ARMPSRGetPriv(gba->cpu->cpsr);
|
||||
gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]);
|
||||
if (state->biosPrefetch) {
|
||||
LOAD_32(gba->memory.biosPrefetch, 0, &state->biosPrefetch);
|
||||
}
|
||||
LOAD_32(gba->memory.lastPrefetchedPc, 0, &state->lastPrefetchedPc);
|
||||
if (gba->cpu->cpsr.t) {
|
||||
if (ARMPSRIsT(gba->cpu->cpsr)) {
|
||||
gba->cpu->executionMode = MODE_THUMB;
|
||||
if (state->cpuPrefetch[0] && state->cpuPrefetch[1]) {
|
||||
LOAD_32(gba->cpu->prefetch[0], 0, state->cpuPrefetch);
|
||||
|
|
Loading…
Reference in New Issue