diff options
Diffstat (limited to 'src/devices/cpu/arm7/arm7.cpp')
-rw-r--r-- | src/devices/cpu/arm7/arm7.cpp | 90 |
1 files changed, 65 insertions, 25 deletions
diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 7f479a668d4..46ffa46e41a 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -2,10 +2,10 @@ // copyright-holders:Steve Ellenoff,R. Belmont,Ryan Holtz /***************************************************************************** * - * arm7.c + * arm7.cpp * Portable CPU Emulator for 32-bit ARM v3/4/5/6 * - * Copyright Steve Ellenoff, all rights reserved. + * Copyright Steve Ellenoff * Thumb, DSP, and MMU support and many bugfixes by R. Belmont and Ryan Holtz. * * This work is based on: @@ -31,12 +31,16 @@ TODO: *****************************************************************************/ #include "emu.h" -#include "debug/debugcon.h" -#include "debugger.h" #include "arm7.h" + #include "arm7core.h" //include arm7 core #include "arm7help.h" +#include "debug/debugcon.h" +#include "debugger.h" + +#include <cassert> + #define LOG_MMU (1U << 1) #define LOG_DSP (1U << 2) #define LOG_COPRO_READS (1U << 3) @@ -75,6 +79,7 @@ DEFINE_DEVICE_TYPE(ARM1176JZF_S, arm1176jzf_s_cpu_device, "arm1176jzf_s", "ARM11 DEFINE_DEVICE_TYPE(PXA250, pxa250_cpu_device, "pxa250", "Intel XScale PXA250") DEFINE_DEVICE_TYPE(PXA255, pxa255_cpu_device, "pxa255", "Intel XScale PXA255") DEFINE_DEVICE_TYPE(PXA270, pxa270_cpu_device, "pxa270", "Intel XScale PXA270") +DEFINE_DEVICE_TYPE(SA1100, sa1100_cpu_device, "sa1100", "Intel StrongARM SA-1100") DEFINE_DEVICE_TYPE(SA1110, sa1110_cpu_device, "sa1110", "Intel StrongARM SA-1110") DEFINE_DEVICE_TYPE(IGS036, igs036_cpu_device, "igs036", "IGS036") @@ -83,9 +88,17 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, const char *tag, { } -arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness) +arm7_cpu_device::arm7_cpu_device( + const machine_config &mconfig, + device_type type, + const char *tag, device_t *owner, + uint32_t clock, + uint8_t archRev, + uint32_t archFlags, + endianness_t endianness, + address_map_constructor internal_map) : cpu_device(mconfig, type, tag, owner, clock) - , m_program_config("program", endianness, 32, 32, 0) + , m_program_config("program", endianness, 32, 32, 0, internal_map) , m_prefetch_word0_shift(endianness == ENDIANNESS_LITTLE ? 0 : 16) , m_prefetch_word1_shift(endianness == ENDIANNESS_LITTLE ? 16 : 0) , m_endian(endianness) @@ -113,6 +126,10 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type m_actual_log = 0; } +arm7_cpu_device::~arm7_cpu_device() +{ +} + arm7_be_cpu_device::arm7_be_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : arm7_cpu_device(mconfig, ARM7_BE, tag, owner, clock, 4, ARCHFLAG_T, ENDIANNESS_BIG) @@ -274,6 +291,16 @@ pxa270_cpu_device::pxa270_cpu_device(const machine_config &mconfig, const char * | ARM9_COPRO_ID_STEP_PXA255_A0; } +sa1100_cpu_device::sa1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : arm7_cpu_device(mconfig, SA1100, tag, owner, clock, 4, ARCHFLAG_SA, ENDIANNESS_LITTLE) + // has StrongARM, no Thumb, no Enhanced DSP +{ + m_copro_id = ARM9_COPRO_ID_MFR_DEC + | ARM9_COPRO_ID_ARCH_V4 + | ARM9_COPRO_ID_PART_SA1100 + | ARM9_COPRO_ID_STEP_SA1100_A; +} + sa1110_cpu_device::sa1110_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : arm7_cpu_device(mconfig, SA1110, tag, owner, clock, 4, ARCHFLAG_SA, ENDIANNESS_LITTLE) // has StrongARM, no Thumb, no Enhanced DSP @@ -1041,7 +1068,7 @@ void arm7_cpu_device::device_start() state_add(STATE_GENFLAGS, "GENFLAGS", m_r[eCPSR]).formatstr("%13s").noshow(); - if (machine().debug_flags & DEBUG_FLAG_ENABLED) + if (debugger_enabled()) { using namespace std::placeholders; machine().debugger().console().register_command("translate_insn", CMDFLAG_NONE, 1, 1, std::bind(&arm7_cpu_device::translate_insn_command, this, _1)); @@ -1154,10 +1181,6 @@ void arm1176jzf_s_cpu_device::device_reset() m_control = 0x00050078; } -#define UNEXECUTED() \ - m_r[eR15] += 4; \ - m_icount +=2; /* Any unexecuted instruction only takes 1 cycle (page 193) */ - void arm7_cpu_device::update_insn_prefetch(uint32_t curr_pc) { curr_pc &= ~3; @@ -1237,6 +1260,8 @@ void arm7_cpu_device::add_ce_kernel_addr(offs_t addr, std::string value) void arm7_cpu_device::execute_run() { + auto const UNEXECUTED = [this] { m_r[eR15] += 4; m_icount += 2; }; // Any unexecuted instruction only takes 1 cycle (page 193) + m_tlb_log = m_actual_log; uint32_t insn; @@ -1446,12 +1471,10 @@ void arm7_cpu_device::execute_run() /* handle Thumb instructions if active */ if (T_IS_SET(m_r[eCPSR])) { - offs_t raddr; - pc = m_r[eR15]; // "In Thumb state, bit [0] is undefined and must be ignored. Bits [31:1] contain the PC." - raddr = pc & (~1); + offs_t const raddr = pc & ~uint32_t(1); if (!insn_fetch_thumb(raddr, insn)) { @@ -1463,12 +1486,10 @@ void arm7_cpu_device::execute_run() } else { - offs_t raddr; - /* load 32 bit instruction */ // "In ARM state, bits [1:0] of r15 are undefined and must be ignored. Bits [31:2] contain the PC." - raddr = pc & (~3); + offs_t const raddr = pc & ~uint32_t(3); if (!insn_fetch_arm(raddr, insn)) { @@ -1573,24 +1594,25 @@ skip_exec: void arm7_cpu_device::execute_set_input(int irqline, int state) { - switch (irqline) { - case ARM7_IRQ_LINE: /* IRQ */ - m_pendingIrq = state ? true : false; + switch (irqline) + { + case ARM7_IRQ_LINE: // IRQ + m_pendingIrq = state != 0; break; - case ARM7_FIRQ_LINE: /* FIRQ */ - m_pendingFiq = state ? true : false; + case ARM7_FIRQ_LINE: // FIQ + m_pendingFiq = state != 0; break; case ARM7_ABORT_EXCEPTION: - m_pendingAbtD = state ? true : false; + m_pendingAbtD = state != 0; break; case ARM7_ABORT_PREFETCH_EXCEPTION: - m_pendingAbtP = state ? true : false; + m_pendingAbtP = state != 0; break; case ARM7_UNDEFINE_EXCEPTION: - m_pendingUnd = state ? true : false; + m_pendingUnd = state != 0; break; } @@ -1599,6 +1621,24 @@ void arm7_cpu_device::execute_set_input(int irqline, int state) } +void arm7_cpu_device::set_irq(int state) +{ + assert((machine().scheduler().currently_executing() == static_cast<device_execute_interface *>(this)) || !machine().scheduler().currently_executing()); + m_pendingIrq = state != 0; + update_irq_state(); + arm7_check_irq_state(); +} + + +void arm7_cpu_device::set_fiq(int state) +{ + assert((machine().scheduler().currently_executing() == static_cast<device_execute_interface *>(this)) || !machine().scheduler().currently_executing()); + m_pendingFiq = state != 0; + update_irq_state(); + arm7_check_irq_state(); +} + + std::unique_ptr<util::disasm_interface> arm7_cpu_device::create_disassembler() { return std::make_unique<arm7_disassembler>(this); |