From ebcfde1e9caec5dbf205b63463227a0f2d62cc2e Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Sat, 22 Jan 2011 19:21:18 +0000 Subject: [PATCH] ARM7 updates [Tim Schuerewegen]: - Disable 26-bit back compatibility for ARM7 variants other than ARM7500 - Fix carry flag issue on add/subtract in ARM mode --- src/emu/cpu/arm7/arm7.c | 33 ++++++++++++++++++++------------- src/emu/cpu/arm7/arm7core.c | 8 ++++---- src/emu/cpu/arm7/arm7core.h | 1 + 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/emu/cpu/arm7/arm7.c b/src/emu/cpu/arm7/arm7.c index 14689dd3c69..6fee89a8004 100644 --- a/src/emu/cpu/arm7/arm7.c +++ b/src/emu/cpu/arm7/arm7.c @@ -77,27 +77,34 @@ INLINE arm_state *get_safe_token(device_t *device) void set_cpsr( arm_state *cpustate, UINT32 val) { - if ((val & 0x10) != (ARM7REG(eCPSR) & 0x10)) + if (cpustate->archFlags & eARM_ARCHFLAGS_MODE26) { - if (val & 0x10) + if ((val & 0x10) != (ARM7REG(eCPSR) & 0x10)) { - // 26 -> 32 - val = (val & 0x0FFFFF3F) | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; - R15 = R15 & 0x03FFFFFC; + if (val & 0x10) + { + // 26 -> 32 + val = (val & 0x0FFFFF3F) | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; + R15 = R15 & 0x03FFFFFC; + } + else + { + // 32 -> 26 + R15 = (R15 & 0x03FFFFFC) /* PC */ | (val & 0xF0000000) /* N Z C V */ | ((val & 0x000000C0) << (26 - 6)) /* I F */ | (val & 0x00000003) /* M1 M0 */; + } } else { - // 32 -> 26 - R15 = (R15 & 0x03FFFFFC) /* PC */ | (val & 0xF0000000) /* N Z C V */ | ((val & 0x000000C0) << (26 - 6)) /* I F */ | (val & 0x00000003) /* M1 M0 */; + if (!(val & 0x10)) + { + // mirror bits in pc + R15 = (R15 & 0x03FFFFFF) | (val & 0xF0000000) /* N Z C V */ | ((val & 0x000000C0) << (26 - 6)) /* I F */; + } } } else { - if (!(val & 0x10)) - { - // mirror bits in pc - R15 = (R15 & 0x03FFFFFF) | (val & 0xF0000000) /* N Z C V */ | ((val & 0x000000C0) << (26 - 6)) /* I F */; - } + val |= 0x10; // force valid mode } ARM7REG(eCPSR) = val; } @@ -360,7 +367,7 @@ static CPU_RESET( arm7500 ) arm7_core_reset(device); cpustate->archRev = 3; // ARMv3 - cpustate->archFlags = 0; + cpustate->archFlags = eARM_ARCHFLAGS_MODE26; } static CPU_RESET( arm9 ) diff --git a/src/emu/cpu/arm7/arm7core.c b/src/emu/cpu/arm7/arm7core.c index 0c5f9438eda..c07ae83e47c 100644 --- a/src/emu/cpu/arm7/arm7core.c +++ b/src/emu/cpu/arm7/arm7core.c @@ -243,12 +243,15 @@ INLINE UINT8 arm7_cpu_read8(arm_state *cpustate, offs_t addr) // - HandleALUAddFlags = HandleThumbALUAddFlags except for PC incr // - HandleALUSubFlags = HandleThumbALUSubFlags except for PC incr +#define IsNeg(i) ((i) >> 31) +#define IsPos(i) ((~(i)) >> 31) + /* Set NZCV flags for ADDS / SUBS */ #define HandleALUAddFlags(rd, rn, op2) \ if (insn & INSN_S) \ SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \ | (((!SIGN_BITS_DIFFER(rn, op2)) && SIGN_BITS_DIFFER(rn, rd)) << V_BIT) \ - | (((~(rn)) < (op2)) << C_BIT) \ + | (((IsNeg(rn) & IsNeg(op2)) | (IsNeg(rn) & IsPos(rd)) | (IsNeg(op2) & IsPos(rd))) ? C_MASK : 0) \ | HandleALUNZFlags(rd))); \ R15 += 4; @@ -259,9 +262,6 @@ INLINE UINT8 arm7_cpu_read8(arm_state *cpustate, offs_t addr) | HandleALUNZFlags(rd))); \ R15 += 2; -#define IsNeg(i) ((i) >> 31) -#define IsPos(i) ((~(i)) >> 31) - #define HandleALUSubFlags(rd, rn, op2) \ if (insn & INSN_S) \ SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK)) \ diff --git a/src/emu/cpu/arm7/arm7core.h b/src/emu/cpu/arm7/arm7core.h index de7097c59da..8209c3c89bb 100644 --- a/src/emu/cpu/arm7/arm7core.h +++ b/src/emu/cpu/arm7/arm7core.h @@ -162,6 +162,7 @@ enum eARM_ARCHFLAGS_MMU = 8, // has on-board MMU (traditional ARM style like the SA1110) eARM_ARCHFLAGS_SA = 16, // StrongARM extensions (enhanced TLB) eARM_ARCHFLAGS_XSCALE = 32, // XScale extensions (CP14, enhanced TLB) + eARM_ARCHFLAGS_MODE26 = 64, // supports 26-bit backwards compatibility mode }; #define ARM7CORE_REGS \