summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2011-01-22 19:21:18 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2011-01-22 19:21:18 +0000
commitebcfde1e9caec5dbf205b63463227a0f2d62cc2e (patch)
treeafecea1d5f5c54fde1e4dc91fae03455f4a1d4a1
parent78ae041ff92034c5de8dc14bbef3b29735a46271 (diff)
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
-rw-r--r--src/emu/cpu/arm7/arm7.c33
-rw-r--r--src/emu/cpu/arm7/arm7core.c8
-rw-r--r--src/emu/cpu/arm7/arm7core.h1
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 \