diff --git a/CHANGES b/CHANGES index 506e45dc4..fec76ac96 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Bugfixes: - LR35902: Fix pc overflowing current region off-by-one - GB MBC: Fix ROM bank overflows getting set to bank 0 - Qt: Fix timing issues on high refresh rate monitors + - GBA Savedata: Fix savedata unmasking (fixes mgba.io/i/441) Misc: - SDL: Remove scancode key input - GBA Video: Clean up unused timers @@ -59,7 +60,6 @@ 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: diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index a5b2a9a96..7b28a56da 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -173,12 +173,6 @@ 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); \ } \ diff --git a/include/mgba/internal/arm/arm.h b/include/mgba/internal/arm/arm.h index 238d50fdd..d7f7b77d0 100644 --- a/include/mgba/internal/arm/arm.h +++ b/include/mgba/internal/arm/arm.h @@ -68,15 +68,33 @@ enum LSMDirection { struct ARMCore; -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); +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; +}; struct ARMMemory { uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter); @@ -199,8 +217,8 @@ struct ARMCP15 { struct ARMCore { int32_t gprs[16]; - ARMPSR cpsr; - ARMPSR spsr; + union PSR cpsr; + union PSR spsr; int32_t cycles; int32_t nextEvent; diff --git a/include/mgba/internal/arm/isa-inlines.h b/include/mgba/internal/arm/isa-inlines.h index 1fa81c0f3..5850dab69 100644 --- a/include/mgba/internal/arm/isa-inlines.h +++ b/include/mgba/internal/arm/isa-inlines.h @@ -10,20 +10,20 @@ #include "arm.h" -#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_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_AL 1 #define ARM_SIGN(I) ((I) >> 31) @@ -31,8 +31,7 @@ #define ARM_SXT_16(I) (((int16_t) (I) << 16) >> 16) #define ARM_UXT_64(I) (uint64_t)(uint32_t) (I) -#define ARM_CARRY_FROM(M, N, D) (UINT_MAX - (uint32_t) (M) < (uint32_t) (N)) -#define ARM_CARRY_FROM_CARRY(M, N, D, C) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31)) +#define ARM_CARRY_FROM(M, N, D) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31)) #define ARM_BORROW_FROM(M, N, D) (((uint32_t) (M)) >= ((uint32_t) (N))) #define ARM_BORROW_FROM_CARRY(M, N, D, C) (ARM_UXT_64(M) >= (ARM_UXT_64(N)) + (uint64_t) (C)) #define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))) && (ARM_SIGN((N) ^ (D)))) @@ -84,23 +83,24 @@ static inline void _ARMSetMode(struct ARMCore* cpu, enum ExecutionMode execution cpu->executionMode = executionMode; switch (executionMode) { case MODE_ARM: - cpu->cpsr = ARMPSRClearT(cpu->cpsr); + cpu->cpsr.t = 0; break; case MODE_THUMB: - cpu->cpsr = ARMPSRFillT(cpu->cpsr); + cpu->cpsr.t = 1; } cpu->nextEvent = cpu->cycles; } static inline void _ARMReadCPSR(struct ARMCore* cpu) { - _ARMSetMode(cpu, ARMPSRGetT(cpu->cpsr)); - ARMSetPrivilegeMode(cpu, ARMPSRGetPriv(cpu->cpsr)); + _ARMSetMode(cpu, cpu->cpsr.t); + ARMSetPrivilegeMode(cpu, cpu->cpsr.priv); cpu->irqh.readCPSR(cpu); } static inline uint32_t _ARMPCAddress(struct ARMCore* cpu) { int instructionLength; - if (ARMPSRIsT(cpu->cpsr)) { + enum ExecutionMode mode = cpu->cpsr.t; + if (mode == MODE_ARM) { instructionLength = WORD_SIZE_ARM; } else { instructionLength = WORD_SIZE_THUMB; diff --git a/include/mgba/internal/gba/serialize.h b/include/mgba/internal/gba/serialize.h index 932f222ec..7f1e5e128 100644 --- a/include/mgba/internal/gba/serialize.h +++ b/include/mgba/internal/gba/serialize.h @@ -11,7 +11,6 @@ CXX_GUARD_START #include -#include #include #include @@ -238,8 +237,8 @@ struct GBASerializedState { struct { int32_t gprs[16]; - ARMPSR cpsr; - ARMPSR spsr; + union PSR cpsr; + union PSR spsr; int32_t cycles; int32_t nextEvent; diff --git a/src/arm/arm.c b/src/arm/arm.c index 5aed9a906..372da1411 100644 --- a/src/arm/arm.c +++ b/src/arm/arm.c @@ -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; - cpu->spsr = cpu->bankedSPSRs[newBank]; + cpu->bankedSPSRs[oldBank] = cpu->spsr.packed; + cpu->spsr.packed = cpu->bankedSPSRs[newBank]; } cpu->privilegeMode = mode; } @@ -132,8 +132,8 @@ void ARMReset(struct ARMCore* cpu) { } cpu->privilegeMode = MODE_SYSTEM; - cpu->cpsr = MODE_SYSTEM; - cpu->spsr = 0; + cpu->cpsr.packed = MODE_SYSTEM; + cpu->spsr.packed = 0; cpu->shifterOperand = 0; cpu->shifterCarryOut = 0; @@ -152,10 +152,10 @@ void ARMReset(struct ARMCore* cpu) { } void ARMRaiseIRQ(struct ARMCore* cpu) { - if (ARMPSRIsI(cpu->cpsr)) { + if (cpu->cpsr.i) { return; } - ARMPSR cpsr = cpu->cpsr; + union PSR cpsr = cpu->cpsr; int instructionWidth; if (cpu->executionMode == MODE_THUMB) { instructionWidth = WORD_SIZE_THUMB; @@ -163,7 +163,7 @@ void ARMRaiseIRQ(struct ARMCore* cpu) { instructionWidth = WORD_SIZE_ARM; } ARMSetPrivilegeMode(cpu, MODE_IRQ); - cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_IRQ); + cpu->cpsr.priv = MODE_IRQ; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM; cpu->gprs[ARM_PC] = BASE_IRQ; if (ARMControlRegIsVE(cpu->cp15.r1.c0)) { @@ -173,12 +173,12 @@ void ARMRaiseIRQ(struct ARMCore* cpu) { ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); cpu->spsr = cpsr; - cpu->cpsr = ARMPSRFillI(cpu->cpsr); + cpu->cpsr.i = 1; cpu->cycles += currentCycles; } void ARMRaiseSWI(struct ARMCore* cpu) { - ARMPSR cpsr = cpu->cpsr; + union PSR cpsr = cpu->cpsr; int instructionWidth; if (cpu->executionMode == MODE_THUMB) { instructionWidth = WORD_SIZE_THUMB; @@ -186,7 +186,7 @@ void ARMRaiseSWI(struct ARMCore* cpu) { instructionWidth = WORD_SIZE_ARM; } ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR); - cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_SUPERVISOR); + cpu->cpsr.priv = MODE_SUPERVISOR; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_SWI; if (ARMControlRegIsVE(cpu->cp15.r1.c0)) { @@ -196,12 +196,12 @@ void ARMRaiseSWI(struct ARMCore* cpu) { ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); cpu->spsr = cpsr; - cpu->cpsr = ARMPSRFillI(cpu->cpsr); + cpu->cpsr.i = 1; cpu->cycles += currentCycles; } void ARMRaiseUndefined(struct ARMCore* cpu) { - ARMPSR cpsr = cpu->cpsr; + union PSR cpsr = cpu->cpsr; int instructionWidth; if (cpu->executionMode == MODE_THUMB) { instructionWidth = WORD_SIZE_THUMB; @@ -209,7 +209,7 @@ void ARMRaiseUndefined(struct ARMCore* cpu) { instructionWidth = WORD_SIZE_ARM; } ARMSetPrivilegeMode(cpu, MODE_UNDEFINED); - cpu->cpsr = ARMPSRSetPriv(cpu->cpsr, MODE_UNDEFINED); + cpu->cpsr.priv = MODE_UNDEFINED; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_UNDEF; if (ARMControlRegIsVE(cpu->cp15.r1.c0)) { @@ -219,7 +219,7 @@ void ARMRaiseUndefined(struct ARMCore* cpu) { ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM); cpu->spsr = cpsr; - cpu->cpsr = ARMPSRFillI(cpu->cpsr); + cpu->cpsr.i = 1; cpu->cycles += currentCycles; } diff --git a/src/arm/debugger/cli-debugger.c b/src/arm/debugger/cli-debugger.c index 74d6bcc05..87a1655c5 100644 --- a/src/arm/debugger/cli-debugger.c +++ b/src/arm/debugger/cli-debugger.c @@ -37,15 +37,15 @@ static struct CLIDebuggerCommandSummary _armCommands[] = { { 0, 0, 0, 0 } }; -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 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 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 = ARMPSRIsT(cpu->cpsr); + enum ExecutionMode mode = cpu->cpsr.t; 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; + return cpu->cpsr.packed; } // TODO: test if mode has SPSR if (strcmp(name, "spsr") == 0) { - return cpu->spsr; + return cpu->spsr.packed; } if (name[0] == 'r' && name[1] >= '0' && name[1] <= '9') { int reg = atoi(&name[1]); diff --git a/src/arm/debugger/debugger.c b/src/arm/debugger/debugger.c index de4ccdaf1..76b474841 100644 --- a/src/arm/debugger/debugger.c +++ b/src/arm/debugger/debugger.c @@ -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 = ARMPSRIsT(debugger->cpu->cpsr); + enum ExecutionMode mode = debugger->cpu->cpsr.t; if (mode == MODE_ARM) { instructionLength = WORD_SIZE_ARM; } else { diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index 0433f81ab..7ed3b21c1 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -31,7 +31,7 @@ static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) { } if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (shift < 32) { cpu->shifterOperand = shiftVal << shift; cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1; @@ -46,7 +46,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 = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else { cpu->shifterOperand = cpu->gprs[rm] << immediate; cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1; @@ -70,7 +70,7 @@ static inline void _shiftLSR(struct ARMCore* cpu, uint32_t opcode) { } if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (shift < 32) { cpu->shifterOperand = shiftVal >> shift; cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1; @@ -109,7 +109,7 @@ static inline void _shiftASR(struct ARMCore* cpu, uint32_t opcode) { } if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (shift < 32) { cpu->shifterOperand = shiftVal >> shift; cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1; @@ -149,7 +149,7 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) { int rotate = shift & 0x1F; if (!shift) { cpu->shifterOperand = shiftVal; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else if (rotate) { cpu->shifterOperand = ROR(shiftVal, rotate); cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1; @@ -164,7 +164,7 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) { cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1; } else { // RRX - cpu->shifterOperand = (ARMPSRGetC(cpu->cpsr) << 31) | (((uint32_t) cpu->gprs[rm]) >> 1); + cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1); cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001; } } @@ -175,7 +175,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) { int immediate = opcode & 0x000000FF; if (!rotate) { cpu->shifterOperand = immediate; - cpu->shifterCarryOut = ARMPSRGetC(cpu->cpsr); + cpu->shifterCarryOut = cpu->cpsr.c; } else { cpu->shifterOperand = ROR(immediate, rotate); cpu->shifterCarryOut = ARM_SIGN(cpu->shifterOperand); @@ -186,76 +186,51 @@ 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(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - 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_ADDITION_CARRY_S(M, N, D, C) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ - cpu->cpsr = cpu->spsr; \ - _ARMReadCPSR(cpu); \ - } else { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM_CARRY(M, N, D, C)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ + 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); \ } #define ARM_SUBTRACTION_S(M, N, D) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - 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; \ + 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); \ } #define ARM_SUBTRACTION_CARRY_S(M, N, D, C) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - 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; \ + 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); \ } #define ARM_NEUTRAL_S(M, N, D) \ - if (rd == ARM_PC && _ARMModeHasSPSR(ARMPSRGetPriv(cpu->cpsr))) { \ + if (rd == ARM_PC && _ARMModeHasSPSR(cpu->cpsr.priv)) { \ cpu->cpsr = cpu->spsr; \ _ARMReadCPSR(cpu); \ } else { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, cpu->shifterCarryOut); \ - cpu->cpsr = (cpu->cpsr & (0x1FFFFFFF)) | cpsr; \ + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); \ + cpu->cpsr.c = cpu->shifterCarryOut; \ } #define ARM_NEUTRAL_HI_S(DLO, DHI) \ - { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(DHI)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !((DHI) | (DLO))); \ - cpu->cpsr = (cpu->cpsr & (0x3FFFFFFF)) | cpsr; \ - } + cpu->cpsr.n = ARM_SIGN(DHI); \ + cpu->cpsr.z = !((DHI) | (DLO)); #define ADDR_MODE_2_I_TEST (opcode & 0x00000F80) #define ADDR_MODE_2_I ((opcode & 0x00000F80) >> 7) @@ -273,7 +248,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) : (ARMPSRGetC(cpu->cpsr) << 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) : (cpu->cpsr.c << 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 @@ -479,9 +454,9 @@ DEFINE_ALU_INSTRUCTION_ARM(ADD, ARM_ADDITION_S(n, cpu->shifterOperand, cpu->gprs int32_t n = cpu->gprs[rn]; cpu->gprs[rd] = n + cpu->shifterOperand;) -DEFINE_ALU_INSTRUCTION_ARM(ADC, ARM_ADDITION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], ARMPSRGetC(cpu->cpsr)), +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 + ARMPSRGetC(cpu->cpsr);) + cpu->gprs[rd] = n + cpu->shifterOperand + cpu->cpsr.c;) DEFINE_ALU_INSTRUCTION_ARM(AND, ARM_NEUTRAL_S(cpu->gprs[rn], cpu->shifterOperand, cpu->gprs[rd]), cpu->gprs[rd] = cpu->gprs[rn] & cpu->shifterOperand;) @@ -511,13 +486,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], !ARMPSRIsC(cpu->cpsr)), +DEFINE_ALU_INSTRUCTION_ARM(RSC, ARM_SUBTRACTION_CARRY_S(cpu->shifterOperand, n, cpu->gprs[rd], !cpu->cpsr.c), int32_t n = cpu->gprs[rn]; - cpu->gprs[rd] = cpu->shifterOperand - n - !ARMPSRIsC(cpu->cpsr);) + cpu->gprs[rd] = cpu->shifterOperand - n - !cpu->cpsr.c;) -DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], !ARMPSRIsC(cpu->cpsr)), +DEFINE_ALU_INSTRUCTION_ARM(SBC, ARM_SUBTRACTION_CARRY_S(n, cpu->shifterOperand, cpu->gprs[rd], !cpu->cpsr.c), int32_t n = cpu->gprs[rn]; - cpu->gprs[rd] = n - cpu->shifterOperand - !ARMPSRIsC(cpu->cpsr);) + cpu->gprs[rd] = n - cpu->shifterOperand - !cpu->cpsr.c;) DEFINE_ALU_INSTRUCTION_ARM(SUB, ARM_SUBTRACTION_S(n, cpu->shifterOperand, cpu->gprs[rd]), int32_t n = cpu->gprs[rn]; @@ -740,14 +715,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 = (cpu->cpsr & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); } if (mask & PSR_STATE_MASK) { - cpu->cpsr = (cpu->cpsr & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~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 = (cpu->cpsr & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); } _ARMReadCPSR(cpu); if (cpu->executionMode == MODE_THUMB) { @@ -764,15 +739,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 = (cpu->spsr & ~mask) | (operand & mask) | 0x00000010;) + cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask) | 0x00000010;) DEFINE_INSTRUCTION_ARM(MRS, \ int rd = (opcode >> 12) & 0xF; \ - cpu->gprs[rd] = cpu->cpsr;) + cpu->gprs[rd] = cpu->cpsr.packed;) DEFINE_INSTRUCTION_ARM(MRSR, \ int rd = (opcode >> 12) & 0xF; \ - cpu->gprs[rd] = cpu->spsr;) + cpu->gprs[rd] = cpu->spsr.packed;) DEFINE_INSTRUCTION_ARM(MSRI, int c = opcode & 0x00010000; @@ -781,14 +756,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 = (cpu->cpsr & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_USER_MASK) | (operand & PSR_USER_MASK); } if (mask & PSR_STATE_MASK) { - cpu->cpsr = (cpu->cpsr & ~PSR_STATE_MASK) | (operand & PSR_STATE_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~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 = (cpu->cpsr & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); + cpu->cpsr.packed = (cpu->cpsr.packed & ~PSR_PRIV_MASK) | (operand & PSR_PRIV_MASK); } _ARMReadCPSR(cpu); if (cpu->executionMode == MODE_THUMB) { @@ -806,7 +781,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 = (cpu->spsr & ~mask) | (operand & mask) | 0x00000010;) + cpu->spsr.packed = (cpu->spsr.packed & ~mask) | (operand & mask) | 0x00000010;) DEFINE_INSTRUCTION_ARM(SWI, cpu->irqh.swi32(cpu, opcode & 0xFFFFFF)) diff --git a/src/arm/isa-thumb.c b/src/arm/isa-thumb.c index 88b3bf1ac..465c9c860 100644 --- a/src/arm/isa-thumb.c +++ b/src/arm/isa-thumb.c @@ -12,42 +12,20 @@ // Beware pre-processor insanity #define THUMB_ADDITION_S(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_ADDITION_CARRY_S(M, N, D, C) \ - { \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpsr = ARMPSROrUnsafeC(cpsr, ARM_CARRY_FROM_CARRY(M, N, D, C)); \ - cpsr = ARMPSROrUnsafeV(cpsr, ARM_V_ADDITION(M, N, D)); \ - cpu->cpsr = (cpu->cpsr & (0x0FFFFFFF)) | cpsr; \ - } + 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); #define THUMB_SUBTRACTION_S(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; \ - } + 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); #define THUMB_NEUTRAL_S(M, N, D) \ -{ \ - ARMPSR cpsr = 0; \ - cpsr = ARMPSROrUnsafeN(cpsr, ARM_SIGN(D)); \ - cpsr = ARMPSROrUnsafeZ(cpsr, !(D)); \ - cpu->cpsr = (cpu->cpsr & (0x3FFFFFFF)) | cpsr; \ - } + cpu->cpsr.n = ARM_SIGN(D); \ + cpu->cpsr.z = !(D); #define THUMB_ADDITION(D, M, N) \ int n = N; \ @@ -87,31 +65,31 @@ DEFINE_IMMEDIATE_5_INSTRUCTION_THUMB(LSL1, if (!immediate) { cpu->gprs[rd] = cpu->gprs[rm]; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (32 - immediate)) & 1); + cpu->cpsr.c = (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 = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rm])); + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]); cpu->gprs[rd] = 0; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (immediate - 1)) & 1); + cpu->cpsr.c = (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 = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rm])); - if (ARMPSRIsC(cpu->cpsr)) { + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rm]); + if (cpu->cpsr.c) { cpu->gprs[rd] = 0xFFFFFFFF; } else { cpu->gprs[rd] = 0; } } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rm] >> (immediate - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rm] >> (immediate - 1)) & 1; cpu->gprs[rd] = cpu->gprs[rm] >> immediate; } THUMB_NEUTRAL_S( , , cpu->gprs[rd]);) @@ -166,13 +144,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSL2, int rs = cpu->gprs[rn] & 0xFF; if (rs) { if (rs < 32) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (32 - rs)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (32 - rs)) & 1; cpu->gprs[rd] <<= rs; } else { if (rs > 32) { - cpu->cpsr = ARMPSRClearC(cpu->cpsr); + cpu->cpsr.c = 0; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, cpu->gprs[rd] & 0x00000001); + cpu->cpsr.c = cpu->gprs[rd] & 0x00000001; } cpu->gprs[rd] = 0; } @@ -183,13 +161,13 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSR2, int rs = cpu->gprs[rn] & 0xFF; if (rs) { if (rs < 32) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (rs - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1; cpu->gprs[rd] = (uint32_t) cpu->gprs[rd] >> rs; } else { if (rs > 32) { - cpu->cpsr = ARMPSRClearC(cpu->cpsr); + cpu->cpsr.c = 0; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd])); + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]); } cpu->gprs[rd] = 0; } @@ -200,11 +178,11 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2, int rs = cpu->gprs[rn] & 0xFF; if (rs) { if (rs < 32) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (rs - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (rs - 1)) & 1; cpu->gprs[rd] >>= rs; } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd])); - if (ARMPSRIsC(cpu->cpsr)) { + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]); + if (cpu->cpsr.c) { cpu->gprs[rd] = 0xFFFFFFFF; } else { cpu->gprs[rd] = 0; @@ -216,11 +194,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 + ARMPSRGetC(cpu->cpsr); - THUMB_ADDITION_CARRY_S(d, n, cpu->gprs[rd], ARMPSRGetC(cpu->cpsr));) + cpu->gprs[rd] = d + n + cpu->cpsr.c; + THUMB_ADDITION_S(d, n, cpu->gprs[rd]);) DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(SBC, - int n = cpu->gprs[rn] + !ARMPSRIsC(cpu->cpsr); + int n = cpu->gprs[rn] + !cpu->cpsr.c; int d = cpu->gprs[rd]; cpu->gprs[rd] = d - n; THUMB_SUBTRACTION_S(d, n, cpu->gprs[rd]);) @@ -229,10 +207,10 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ROR, if (rs) { int r4 = rs & 0x1F; if (r4 > 0) { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, (cpu->gprs[rd] >> (r4 - 1)) & 1); + cpu->cpsr.c = (cpu->gprs[rd] >> (r4 - 1)) & 1; cpu->gprs[rd] = ROR(cpu->gprs[rd], r4); } else { - cpu->cpsr = ARMPSRSetC(cpu->cpsr, ARM_SIGN(cpu->gprs[rd])); + cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]); } } THUMB_NEUTRAL_S( , , cpu->gprs[rd]);) diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 4dafaca1f..b497c24d7 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -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] - (ARMPSRIsT(cpu->cpsr) ? WORD_SIZE_THUMB : WORD_SIZE_ARM), &stub->outgoing[i]); + _int2hex32(cpu->gprs[ARM_PC] - (cpu->cpsr.t ? 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 = value; + cpu->cpsr.packed = 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; + value = cpu->cpsr.packed; } else { stub->outgoing[0] = '\0'; _sendMessage(stub); diff --git a/src/ds/ds.c b/src/ds/ds.c index ea9ed51e1..8faf018e6 100644 --- a/src/ds/ds.c +++ b/src/ds/ds.c @@ -261,7 +261,7 @@ static void DS9ProcessEvents(struct ARMCore* cpu) { static void DSProcessEvents(struct DSCommon* dscore) { struct ARMCore* cpu = dscore->cpu; struct DS* ds = dscore->p; - if (dscore->springIRQ && !ARMPSRGetI(cpu->cpsr)) { + if (dscore->springIRQ && !cpu->cpsr.i) { ARMRaiseIRQ(cpu); dscore->springIRQ = 0; } diff --git a/src/gba/bios.c b/src/gba/bios.c index b39a961cb..83e43b302 100644 --- a/src/gba/bios.c +++ b/src/gba/bios.c @@ -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 = 0; + cpu->spsr.packed = 0; cpu->gprs[ARM_LR] = 0; cpu->gprs[ARM_SP] = SP_BASE_IRQ; ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR); - cpu->spsr = 0; + cpu->spsr.packed = 0; cpu->gprs[ARM_LR] = 0; cpu->gprs[ARM_SP] = SP_BASE_SUPERVISOR; ARMSetPrivilegeMode(cpu, MODE_SYSTEM); diff --git a/src/gba/gba.c b/src/gba/gba.c index 0d10817f0..9627d85aa 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -227,7 +227,7 @@ static void GBAProcessEvents(struct ARMCore* cpu) { gba->bus |= cpu->prefetch[1] << 16; } - if (gba->springIRQ && !ARMPSRIsI(cpu->cpsr)) { + if (gba->springIRQ && !cpu->cpsr.i) { ARMRaiseIRQ(cpu); gba->springIRQ = 0; } diff --git a/src/gba/savedata.c b/src/gba/savedata.c index 5e8ef30c1..d82d80fd4 100644 --- a/src/gba/savedata.c +++ b/src/gba/savedata.c @@ -160,39 +160,35 @@ size_t GBASavedataSize(struct GBASavedata* savedata) { } bool GBASavedataLoad(struct GBASavedata* savedata, struct VFile* in) { - if (savedata->vf) { + if (savedata->data) { + if (!in && savedata->type != SAVEDATA_FORCE_NONE) { + return false; + } + ssize_t size = GBASavedataSize(savedata); + in->seek(in, 0, SEEK_SET); + return in->read(in, savedata->data, size) == size; + } else if (savedata->vf) { off_t read = 0; uint8_t buffer[2048]; - memset(buffer, 0xFF, sizeof(buffer)); - savedata->vf->seek(savedata->vf, 0, SEEK_SET); - while (savedata->vf->seek(savedata->vf, 0, SEEK_CUR) < savedata->vf->size(savedata->vf)) { - savedata->vf->write(savedata->vf, buffer, sizeof(buffer)); - } savedata->vf->seek(savedata->vf, 0, SEEK_SET); if (in) { + in->seek(in, 0, SEEK_SET); do { read = in->read(in, buffer, sizeof(buffer)); read = savedata->vf->write(savedata->vf, buffer, read); } while (read == sizeof(buffer)); } + memset(buffer, 0xFF, sizeof(buffer)); + ssize_t fsize = savedata->vf->size(savedata->vf); + ssize_t pos = savedata->vf->seek(savedata->vf, 0, SEEK_CUR); + while (fsize - pos >= (ssize_t) sizeof(buffer)) { + savedata->vf->write(savedata->vf, buffer, sizeof(buffer)); + pos = savedata->vf->seek(savedata->vf, 0, SEEK_CUR); + } + if (fsize - pos > 0) { + savedata->vf->write(savedata->vf, buffer, fsize - pos); + } return read >= 0; - } else if (savedata->data) { - if (!in && savedata->type != SAVEDATA_FORCE_NONE) { - return false; - } - switch (savedata->type) { - case SAVEDATA_SRAM: - return in->read(in, savedata->data, SIZE_CART_SRAM) == SIZE_CART_SRAM; - case SAVEDATA_FLASH512: - return in->read(in, savedata->data, SIZE_CART_FLASH512) == SIZE_CART_FLASH512; - case SAVEDATA_FLASH1M: - return in->read(in, savedata->data, SIZE_CART_FLASH1M) == SIZE_CART_FLASH1M; - case SAVEDATA_EEPROM: - return in->read(in, savedata->data, SIZE_CART_EEPROM) == SIZE_CART_EEPROM; - case SAVEDATA_AUTODETECT: - case SAVEDATA_FORCE_NONE: - return true; - } } return true; } @@ -560,8 +556,9 @@ void _flashSwitchBank(struct GBASavedata* savedata, int bank) { mLOG(GBA_SAVE, DEBUG, "Performing flash bank switch to bank %i", bank); savedata->currentBank = &savedata->data[bank << 16]; if (bank > 0 && savedata->type == SAVEDATA_FLASH512) { + mLOG(GBA_SAVE, INFO, "Updating flash chip from 512kb to 1Mb"); savedata->type = SAVEDATA_FLASH1M; - if (savedata->vf) { + if (savedata->vf && savedata->vf->size(savedata->vf) == SIZE_CART_FLASH512) { savedata->vf->truncate(savedata->vf, SIZE_CART_FLASH1M); memset(&savedata->data[SIZE_CART_FLASH512], 0xFF, SIZE_CART_FLASH512); } diff --git a/src/gba/serialize.c b/src/gba/serialize.c index e821af7e3..18692c0d3 100644 --- a/src/gba/serialize.c +++ b/src/gba/serialize.c @@ -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, 0, &state->cpu.cpsr); - STORE_32(gba->cpu->spsr, 0, &state->cpu.spsr); + 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->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, 0, &state->cpu.cpsr); - LOAD_32(gba->cpu->spsr, 0, &state->cpu.spsr); + 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->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 = ARMPSRGetPriv(gba->cpu->cpsr); + gba->cpu->privilegeMode = gba->cpu->cpsr.priv; 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 (ARMPSRIsT(gba->cpu->cpsr)) { + if (gba->cpu->cpsr.t) { gba->cpu->executionMode = MODE_THUMB; if (state->cpuPrefetch[0] && state->cpuPrefetch[1]) { LOAD_32(gba->cpu->prefetch[0], 0, state->cpuPrefetch); diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index bde726ede..b2804036b 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -236,7 +236,7 @@ if(Qt5LinguistTools_FOUND) qt5_add_translation(TRANSLATION_FILES ${TS_FILES}) endif() add_custom_command(OUTPUT ${TRANSLATION_QRC} - COMMAND ${CMAKE_COMMAND} -DTRANSLATION_QRC:FILEPATH="${TRANSLATION_QRC}" -DTRANSLATION_FILES="${TRANSLATION_FILES}" -P "${CMAKE_CURRENT_SOURCE_DIR}/ts.cmake" + COMMAND ${CMAKE_COMMAND} -DTRANSLATION_QRC:FILEPATH="${TRANSLATION_QRC}" -DQM_BASE="${CMAKE_CURRENT_BINARY_DIR}" -P "${CMAKE_CURRENT_SOURCE_DIR}/ts.cmake" DEPENDS ${TRANSLATION_FILES}) qt5_add_resources(TRANSLATION_RESOURCES ${TRANSLATION_QRC}) list(APPEND RESOURCES ${TRANSLATION_RESOURCES}) diff --git a/src/platform/qt/GameController.cpp b/src/platform/qt/GameController.cpp index 692de2d74..84f089cfd 100644 --- a/src/platform/qt/GameController.cpp +++ b/src/platform/qt/GameController.cpp @@ -525,11 +525,11 @@ void GameController::loadBIOS(int platform, const QString& path) { if (m_bios == path) { return; } - if (m_gameOpen && this->platform() == platform) { + if (!m_bios.isNull() && m_gameOpen && this->platform() == platform) { closeGame(); m_bios = path; openGame(); - } else if (!m_gameOpen) { + } else if (!m_gameOpen || m_bios.isNull()) { m_bios = path; } } diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index 3dfca440b..29df3ea8d 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -6,6 +6,11 @@ #include "GBAApp.h" #include "Window.h" +#include +#include + +#include + #ifdef QT_STATIC #include #ifdef _WIN32 @@ -18,5 +23,16 @@ Q_IMPORT_PLUGIN(QWindowsAudioPlugin); int main(int argc, char* argv[]) { QGBA::GBAApp application(argc, argv); + + QLocale locale = QLocale::system(); + + QTranslator qtTranslator; + qtTranslator.load(locale, "qt", "_", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); + application.installTranslator(&qtTranslator); + + QTranslator langTranslator; + langTranslator.load(locale, binaryName, "-", ":/translations/"); + application.installTranslator(&langTranslator); + return application.exec(); } diff --git a/src/platform/qt/ts.cmake b/src/platform/qt/ts.cmake index 0c1e3c9bb..3bb8c2e43 100644 --- a/src/platform/qt/ts.cmake +++ b/src/platform/qt/ts.cmake @@ -1,5 +1,8 @@ +file(GLOB TRANSLATION_FILES "${QM_BASE}/*.qm") file(WRITE ${TRANSLATION_QRC} "\n\t\n") +message(STATUS ${TRANSLATION_FILES}) foreach(TS ${TRANSLATION_FILES}) + message(STATUS ${TS}) get_filename_component(TS_BASE "${TS}" NAME) file(APPEND ${TRANSLATION_QRC} "\t\t${TS_BASE}\n") endforeach() diff --git a/src/platform/qt/ts/mgba-es.ts b/src/platform/qt/ts/mgba-es.ts index 38d0b48aa..0b242df8d 100644 --- a/src/platform/qt/ts/mgba-es.ts +++ b/src/platform/qt/ts/mgba-es.ts @@ -9,37 +9,48 @@ - + + <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://patreon.com/mgba">Donate</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> + + + + {projectName} - - © 2013 – 2016 Jeffrey Pfau — Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + + {projectName} would like to thank the following patrons from Patreon: - + + © 2013 – 2016 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 +Game Boy Advance is a registered trademark of Nintendo Co., Ltd. + + + + + {patrons} + + + + {projectVersion} - + {logo} - + {projectName} is an open-source Game Boy Advance emulator - - <a href="http://mgba.io/">Website</a> • <a href="https://forums.mgba.io/">Forums / Support</a> • <a href="https://github.com/mgba-emu/mgba/tree/{gitBranch}">Source</a> • <a href="https://github.com/mgba-emu/mgba/blob/{gitBranch}/LICENSE">License</a> - - - - + Branch: <tt>{gitBranch}</tt><br/>Revision: <tt>{gitCommit}</tt> @@ -51,6 +62,61 @@ Open in archive... + + + Loading... + + + + + AssetTile + + + AssetTile + + + + + Tile # + + + + + 0 + + + + + Address + + + + + 0x06000000 + + + + + Red + + + + + Green + + + + + Blue + + + + + + + 0x00 (00) + + CheatsView @@ -85,6 +151,24 @@ + + DebuggerConsole + + + Debugger + + + + + Enter command (try `help` for more info) + + + + + Break + + + GIFView @@ -216,6 +300,14 @@ + + LibraryView + + + Library + + + LoadSaveState @@ -379,16 +471,187 @@ - + Signed Integer: - + + String: + + + + + Load TBL + + + + + Copy Selection + + + + + Paste + + + + + Save Selection + + + + + Load + + + + Unsigned Integer: + + ObjView + + + Sprites + + + + + + × + + + + + Magnification + + + + + Attributes + + + + + Transform + + + + + Off + + + + + Palette + + + + + + + + 0 + + + + + Double Size + + + + + + + + Return, Ctrl+R + + + + + Flipped + + + + + H + + + + + V + + + + + Mode + + + + + Normal + + + + + Mosaic + + + + + Enabled + + + + + Priority + + + + + Tile + + + + + Geometry + + + + + Position + + + + + , + + + + + Dimensions + + + + + + 8 + + + + + Address + + + + + 0x07000000 + + + OverrideView @@ -631,15 +894,30 @@ + + QGBA::AssetTile + + + %0%1%2 + + + + + + + 0x%0 (%1) + + + QGBA::CheatsModel - + (untitled) - + Failed to open cheats file: %1 @@ -647,8 +925,8 @@ QGBA::CheatsView - - + + Select cheats file @@ -656,40 +934,83 @@ QGBA::GBAKeyEditor - + Clear Button - + Clear Analog - + Refresh - + Set all + + QGBA::GDBWindow + + + Server settings + + + + + Local port + + + + + Bind address + + + + + Break + + + + + Stop + + + + + Start + + + + + Crash + + + + + Could not start GDB server + + + QGBA::GIFView - + Failed to open output GIF file: %1 - + Select output file - + Graphics Interchange Format (*.gif) @@ -697,28 +1018,28 @@ QGBA::GameController - - + + Failed to open game file: %1 - + Failed to open save file: %1 - + Failed to open snapshot file for reading: %1 - + Failed to open snapshot file for writing: %1 - + Failed to start audio processor @@ -2094,8 +2415,8 @@ QGBA::KeyEditor - - + + --- @@ -2103,40 +2424,75 @@ QGBA::LibraryModel - + + Name + + + + Filename - + Size + + + Platform + + + + + GBA + + + + + GB + + + + + ? + + + + + Location + + + + + CRC32 + + QGBA::LoadSaveState - + Load State - + Save State - + Empty - + Corrupted - + Slot %1 @@ -2182,58 +2538,128 @@ QGBA::MemoryModel - + Copy selection - + Save selection - - + + Paste + + + + + Load + + + + + All - + + Load TBL + + + + Save selected memory - + Failed to open output file: %1 - - ASCII + + Load memory + + + + + Failed to open input file: %1 + + + + + TBL + + + + + ISO-8859-1 + + + + + QGBA::ObjView + + + + 0x%0 + + + + + Off + + + + + Normal + + + + + Trans + + + + + OBJWIN + + + + + Invalid + + + + + + N/A QGBA::PaletteView - + #%0 - + 0x%0 - + %0 + - 0x%0 (%1) @@ -2248,7 +2674,7 @@ - + Failed to open output palette file: %1 @@ -2256,22 +2682,22 @@ QGBA::ROMInfo - - - - - + + + + + (unknown) - - + + bytes - + (no database present) @@ -2279,32 +2705,32 @@ QGBA::SettingsView - + Qt Multimedia - + SDL - + Software (Qt) - + OpenGL - + OpenGL (force version 1.x) - + Select BIOS @@ -2312,37 +2738,37 @@ QGBA::ShaderSelector - + No shader active - + Load shader - + %1 Shader (%.shader) - + No shader loaded - + by %1 - + Preprocessing - + Pass %1 @@ -2365,29 +2791,20 @@ - - QGBA::TileView - - - - 0x%0 - - - QGBA::VideoView - + Failed to open output video file: %1 - + Native (%0x%1) - + Select output file @@ -2395,690 +2812,700 @@ QGBA::Window - + Game Boy Advance ROMs (%1) - + Game Boy ROMs (%1) - + All ROMs (%1) - + Archives (%1) - - - + + + Select ROM - + Game Boy Advance save files (%1) - - - + + + Select save - - Select BIOS - - - - + Select patch - + Patches (*.ips *.ups *.bps) - - + + GameShark saves (*.sps *.xps) - + Crash - + The game has crashed with the following error: %1 - + Couldn't Load - + Could not load game. Are you sure it's in the correct format? - + Unimplemented BIOS call - + This game uses a BIOS call that is not implemented. Please use the official BIOS for best experience. - + Really make portable? - + This will make the emulator load its configuration from the same directory as the executable. Do you want to continue? - + Restart needed - + Some changes will not take effect until the emulator is restarted. - + - Player %1 of %2 - + %1 - %2 - + %1 - %2 - %3 - + %1 - %2 (%3 fps) - %4 - + &File - + Load &ROM... - + Load ROM in archive... - - Load &BIOS... - - - - + Load temporary save... - + Load &patch... - + Boot BIOS - + Replace ROM... - + ROM &info... - + Recent - + Make portable - + &Load state - + F10 - + &Save state - + Shift+F10 - + Quick load - + Quick save - + Load recent - + Save recent - + Undo load state - + F11 - + Undo save state - + Shift+F11 - - + + State &%1 - + F%1 - + Shift+F%1 - + Import GameShark Save - + Export GameShark Save - + New multiplayer window - + About - + E&xit - + &Emulation - + &Reset - + Ctrl+R - + Sh&utdown - + Yank game pak - + &Pause - + Ctrl+P - + &Next frame - + Ctrl+N - + Fast forward (held) - + &Fast forward - + Shift+Tab - + Fast forward speed - + Unbounded - + %0x - + Rewind (held) - + Re&wind - + ~ - + Step backwards - + Ctrl+B - + Sync to &video - + Sync to &audio - + Solar sensor - + Increase solar level - + Decrease solar level - + Brightest solar level - + Darkest solar level - + Brightness %1 - + Audio/&Video - + Frame size - + %1x - + Toggle fullscreen - + Lock aspect ratio - + Resample video - + Frame&skip - + Shader options... - + Mute - + FPS target - + 15 - + 30 - + 45 - + Native (59.7) - + 60 - + 90 - + 120 - + 240 - + Take &screenshot - + F12 - + Record output... - + Record GIF... - + Video layers - + Background %0 - + OBJ (sprites) - + Audio channels - + Channel %0 - + Channel A - + Channel B - + &Tools - + View &logs... - + Game &overrides... - + Game &Pak sensors... - + &Cheats... - + + Open debugger console... + + + + Start &GDB server... - + Settings... - + + Select folder + + + + + Add folder to library... + + + + View &palette... - + + View &sprites... + + + + View &tiles... - + View memory... - + View &I/O registers... - + Exit fullscreen - + Autofire - + Autofire A - + Autofire B - + Autofire L - + Autofire R - + Autofire Start - + Autofire Select - + Autofire Up - + Autofire Right - + Autofire Down - + Autofire Left @@ -3224,310 +3651,342 @@ - + Audio/Video - + + Interface + + + + Emulation - - Savestates - - - - + Paths - + Audio driver: - + Audio buffer: - - + + 1536 - + 512 - + 768 - + 1024 - + 2048 - + 3072 - + 4096 - + samples - + Sample rate: - - + + 44100 - + 22050 - + 32000 - + 48000 - + Hz - + Volume: - + Mute - + Display driver: - + Frameskip: - + Skip every - - + + frames - + FPS target: - + frames per second - + Sync: - + Video - + Audio - + Lock aspect ratio - + Resample video - - BIOS file: + + Library: - - - - - + + Show when no game open + + + + + Clear cache + + + + + Fast forward speed: + + + + + + + + + + Browse - + Use BIOS file if found - + Skip BIOS intro - - Fast forward speed - - - - + × - + Unbounded - + Suspend screensaver - + + BIOS + + + + Pause when inactive - - Idle loops - - - - + Run all - + Remove known - + Detect and remove - + Allow opposing input directions - - Save extra data - - - - - + + Screenshot - - + + Save data - - + + Cheat codes - - Load extra data - - - - + Enable rewind - + Rewind history: - + + Idle loops: + + + + + Savestate extra data: + + + + + Load extra data: + + + + + GB BIOS file: + + + + + GBA BIOS file: + + + + + GBC BIOS file: + + + + Save games - - - - + + + + Same directory as the ROM - + Save states - + Screenshots - + Patches @@ -3606,32 +4065,12 @@ - - Tile # - - - - - 0 - - - - - Address - - - - - 0x06000000 - - - - + × - + Magnification