diff options
Diffstat (limited to 'src/devices/cpu/h8500/h8500.cpp')
-rw-r--r-- | src/devices/cpu/h8500/h8500.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/devices/cpu/h8500/h8500.cpp b/src/devices/cpu/h8500/h8500.cpp new file mode 100644 index 00000000000..9a0ebc225b0 --- /dev/null +++ b/src/devices/cpu/h8500/h8500.cpp @@ -0,0 +1,151 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Hitachi H8/500 Series + + Currently this device is just a stub with no actual execution core. + +***************************************************************************/ + +#include "emu.h" +#include "h8500.h" +#include "h8500dasm.h" + +h8500_device::h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, address_map_constructor map) + : cpu_device(mconfig, type, tag, owner, clock) + , m_program_config("program", ENDIANNESS_BIG, buswidth, addrbits, 0, map) + , m_ram_config("internal RAM", ENDIANNESS_BIG, 16, ramsize, 0, address_map_constructor(FUNC(h8500_device::ram_map), this)) + , m_program(nullptr) + , m_ram_cache(nullptr) + , m_pc(0) + , m_ppc(0) + , m_sr(0) + , m_cp(0) + , m_dp(0) + , m_ep(0) + , m_tp(0) + , m_br(0) + , m_r{0, 0, 0, 0, 0, 0, 0, 0} + , m_icount(0) +{ +} + +void h8500_device::device_config_complete() +{ + if (!h8_maximum_mode()) + m_program_config.m_addr_width = 16; +} + +std::unique_ptr<util::disasm_interface> h8500_device::create_disassembler() +{ + return std::make_unique<h8500_disassembler>(h8_maximum_mode()); +} + +device_memory_interface::space_config_vector h8500_device::memory_space_config() const +{ + return m_ram_config.addr_width() == 0 ? space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config) + } : space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_DATA, &m_ram_config) + }; +} + +void h8500_device::ram_map(address_map &map) +{ + map(0, (1 << m_ram_config.addr_width()) - 1).ram(); +} + +void h8500_device::debug_set_pc(offs_t pc) noexcept +{ + m_pc = m_ppc = pc & 0xffff; + if (h8_maximum_mode()) + m_cp = u8(pc >> 16); +} + +void h8500_device::device_start() +{ + m_program = &space(AS_PROGRAM); + if (has_space(AS_DATA)) + m_ram_cache = space(AS_DATA).cache<1, 0, ENDIANNESS_BIG>(); + + set_icountptr(m_icount); + + // Control registers + state_add(H8500_PC, "PC", m_pc); + if (h8_maximum_mode()) + { + state_add<u32>(STATE_GENPC, "GENPC", [this]() { return u32(m_cp) << 16 | m_pc; }, [this](u32 data) { debug_set_pc(data); }).noshow().mask(0xffffff); + state_add<u32>(STATE_GENPCBASE, "CURPC", [this]() { return u32(m_cp) << 16 | m_ppc; }, [this](u32 data) { debug_set_pc(data); }).noshow().mask(0xffffff); + } + else + { + state_add<u16>(STATE_GENPC, "GENPC", [this]() { return m_pc; }, [this](u16 data) { debug_set_pc(data); }).noshow(); + state_add<u16>(STATE_GENPCBASE, "CURPC", [this]() { return m_ppc; }, [this](u16 data) { debug_set_pc(data); }).noshow(); + } + state_add(H8500_SR, "SR", m_sr).mask(0x870f); + state_add<u8>(H8500_CCR, "CCR", [this]() { return m_sr & 0xff; }, [this](u8 data) { m_sr = (m_sr & 0xff00) | data; }).mask(0x0f).noshow(); + state_add<u8>(STATE_GENFLAGS, "FLAGS", [this]() { return m_sr & 0xff; }, [this](u8 data) { m_sr = (m_sr & 0xff00) | data; }).mask(0x0f).formatstr("%4s").noshow(); + if (h8_maximum_mode()) + { + state_add(H8500_CP, "CP", m_cp); + state_add(H8500_DP, "DP", m_dp); + state_add(H8500_EP, "EP", m_ep); + state_add(H8500_TP, "TP", m_tp); + } + state_add(H8500_BR, "BR", m_br); + + // General registers + for (int n = 0; n < 6; n++) + state_add(H8500_R0 + n, string_format("R%d", n).c_str(), m_r[n]); + state_add(H8500_FP, "FP", m_r[6]); + state_add(H8500_SP, "SP", m_r[7]); + + // Save state + save_item(NAME(m_pc)); + save_item(NAME(m_ppc)); + save_item(NAME(m_sr)); + if (h8_maximum_mode()) + save_item(NAME(m_cp)); + save_item(NAME(m_dp)); + save_item(NAME(m_ep)); + save_item(NAME(m_tp)); + save_item(NAME(m_br)); + save_item(NAME(m_r)); +} + +void h8500_device::device_reset() +{ + m_sr = 0x0700 | (m_sr & 0x000f); +} + +void h8500_device::execute_run() +{ + if (h8_maximum_mode()) + { + m_cp = m_program->read_word(0) & 0x00ff; + m_pc = m_program->read_word(2); + } + else + m_pc = m_program->read_word(0); + + m_ppc = m_pc; + debugger_instruction_hook(m_cp << 8 | m_pc); + + m_icount = 0; +} + +void h8500_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = string_format("%c%c%c%c", + BIT(m_sr, 3) ? 'N' : '.', + BIT(m_sr, 2) ? 'Z' : '.', + BIT(m_sr, 1) ? 'V' : '.', + BIT(m_sr, 0) ? 'C' : '.'); + break; + } +} |