diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index d6b324fc31a..6c745cec5f9 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -68,6 +68,7 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type , m_endian(endianness) , m_archRev(archRev) , m_archFlags(archFlags) + , m_vectorbase(0) , m_pc(0) { memset(m_r, 0x00, sizeof(m_r)); @@ -662,7 +663,7 @@ void arm7_cpu_device::device_reset() /* start up in SVC mode with interrupts disabled. */ m_r[eCPSR] = I_MASK | F_MASK | 0x10; SwitchMode(eARM7_MODE_SVC); - m_r[eR15] = 0; + m_r[eR15] = 0 | m_vectorbase; m_impstate.cache_dirty = true; } diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index 1a9681232bb..38b7d185b63 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -31,6 +31,9 @@ #define ARM7_MAX_FASTRAM 4 #define ARM7_MAX_HOTSPOTS 16 +#define MCFG_ARM_HIGH_VECTORS() \ + arm7_cpu_device::set_high_vectors(*device); + /*************************************************************************** COMPILER-SPECIFIC OPTIONS @@ -52,6 +55,12 @@ public: // construction/destruction arm7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static void set_high_vectors(device_t &device) + { + arm7_cpu_device &dev = downcast(device); + dev.m_vectorbase = 0xffff0000; + } + protected: enum { @@ -168,6 +177,8 @@ protected: uint8_t m_archRev; // ARM architecture revision (3, 4, and 5 are valid) uint8_t m_archFlags; // architecture flags + uint32_t m_vectorbase; + //#if ARM7_MMU_ENABLE_HACK // uint32_t mmu_enable_addr; // workaround for "MMU is enabled when PA != VA" problem //#endif diff --git a/src/devices/cpu/arm7/arm7core.hxx b/src/devices/cpu/arm7/arm7core.hxx index 0e418209e73..0fbe5f00868 100644 --- a/src/devices/cpu/arm7/arm7core.hxx +++ b/src/devices/cpu/arm7/arm7core.hxx @@ -136,6 +136,7 @@ void arm7_cpu_device::arm7_check_irq_state() set_cpsr(GET_CPSR | I_MASK | F_MASK); /* Mask both IRQ & FIQ */ set_cpsr(GET_CPSR & ~T_MASK); R15 = 0x1c; /* IRQ Vector address */ + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; return; } @@ -159,6 +160,7 @@ void arm7_cpu_device::arm7_check_irq_state() temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; set_cpsr(temp); /* Mask IRQ */ } + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; return; } @@ -172,7 +174,7 @@ void arm7_cpu_device::arm7_check_irq_state() SetRegister(SPSR, cpsr); /* Save current CPSR */ set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */ set_cpsr(GET_CPSR & ~T_MASK); - R15 = 0x0c; /* IRQ Vector address */ + R15 = 0x0c | m_vectorbase; /* IRQ Vector address */ if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingAbtP = false; update_irq_state(); @@ -196,7 +198,7 @@ void arm7_cpu_device::arm7_check_irq_state() SetRegister(SPSR, cpsr); /* Save current CPSR */ set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */ set_cpsr(GET_CPSR & ~T_MASK); - R15 = 0x04; /* IRQ Vector address */ + R15 = 0x04 | m_vectorbase; /* IRQ Vector address */ if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingUnd = false; update_irq_state(); @@ -230,6 +232,7 @@ void arm7_cpu_device::arm7_check_irq_state() temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; set_cpsr(temp); /* Mask IRQ */ } + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingSwi = false; update_irq_state(); diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp index dd65d8ae765..5b71b7e8d9f 100644 --- a/src/devices/cpu/arm7/arm7ops.cpp +++ b/src/devices/cpu/arm7/arm7ops.cpp @@ -380,8 +380,8 @@ void arm7_cpu_device::HandleBranch(uint32_t insn, bool h_bit) off |= (insn & 0x01000000) >> 23; } - /* Save PC into LR if this is a branch with link */ - if (insn & INSN_BL) + /* Save PC into LR if this is a branch with link or a BLX */ + if ((insn & INSN_BL) || ((m_archRev >= 5) && ((insn & 0xfe000000) == 0xfa000000))) { SetRegister(14, R15 + 4); } diff --git a/src/mame/drivers/nds.cpp b/src/mame/drivers/nds.cpp index 485d7c45a42..c9844a0702b 100644 --- a/src/mame/drivers/nds.cpp +++ b/src/mame/drivers/nds.cpp @@ -105,16 +105,17 @@ WRITE32_MEMBER(nds_state::arm9_io_w) } static ADDRESS_MAP_START( nds_arm7_map, AS_PROGRAM, 32, nds_state ) - AM_RANGE(0x00000000, 0x00003fff) AM_ROM - AM_RANGE(0x02000000, 0x023fffff) AM_RAM AM_SHARE("mainram") + AM_RANGE(0x00000000, 0x00003fff) AM_ROM AM_REGION("arm7", 0) + AM_RANGE(0x02000000, 0x023fffff) AM_RAM AM_MIRROR(0x00400000) AM_SHARE("mainram") AM_RANGE(0x03800000, 0x0380ffff) AM_RAM AM_RANGE(0x04000000, 0x0400ffff) AM_READWRITE(arm7_io_r, arm7_io_w) ADDRESS_MAP_END static ADDRESS_MAP_START( nds_arm9_map, AS_PROGRAM, 32, nds_state ) - AM_RANGE(0x00000000, 0x00000fff) AM_ROM + AM_RANGE(0x00000000, 0x00007fff) AM_RAM // Instruction TCM AM_RANGE(0x02000000, 0x023fffff) AM_RAM AM_SHARE("mainram") AM_RANGE(0x04000000, 0x0400ffff) AM_READWRITE(arm9_io_r, arm9_io_w) + AM_RANGE(0xffff0000, 0xffff0fff) AM_ROM AM_MIRROR(0x1000) AM_REGION("arm9", 0) ADDRESS_MAP_END static INPUT_PORTS_START( nds ) @@ -134,9 +135,12 @@ void nds_state::machine_start() static MACHINE_CONFIG_START( nds ) MCFG_CPU_ADD("arm7", ARM7, XTAL_33_333MHz) MCFG_CPU_PROGRAM_MAP(nds_arm7_map) + MCFG_DEVICE_DISABLE() MCFG_CPU_ADD("arm9", ARM946ES, XTAL_66_6667MHz) + MCFG_ARM_HIGH_VECTORS() MCFG_CPU_PROGRAM_MAP(nds_arm9_map) + MACHINE_CONFIG_END /* Help identifying the region and revisions of the set would be greatly appreciated! */