arm7: add support for high vector option, fixed v5 BLX to save the return address in R14 [R. Belmont]

This commit is contained in:
arbee 2017-11-15 23:55:09 -05:00
parent b503e9c8c2
commit 78ceb48177
5 changed files with 27 additions and 8 deletions

View File

@ -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;
}

View File

@ -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<arm7_cpu_device &>(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

View File

@ -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();

View File

@ -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);
}

View File

@ -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! */