diff options
Diffstat (limited to 'src/devices/cpu/mcs40')
-rw-r--r-- | src/devices/cpu/mcs40/mcs40.cpp | 95 | ||||
-rw-r--r-- | src/devices/cpu/mcs40/mcs40.h | 27 | ||||
-rw-r--r-- | src/devices/cpu/mcs40/mcs40dasm.cpp | 4 |
3 files changed, 54 insertions, 72 deletions
diff --git a/src/devices/cpu/mcs40/mcs40.cpp b/src/devices/cpu/mcs40/mcs40.cpp index fa70e9d389e..bf9b6a310d6 100644 --- a/src/devices/cpu/mcs40/mcs40.cpp +++ b/src/devices/cpu/mcs40/mcs40.cpp @@ -10,7 +10,6 @@ #include "emu.h" #include "mcs40.h" #include "mcs40dasm.h" -#include "debugger.h" /* @@ -102,11 +101,10 @@ mcs40_cpu_device_base::mcs40_cpu_device_base( { "ramport", ENDIANNESS_LITTLE, 8, u8(5), 0 }, { "program", ENDIANNESS_LITTLE, 8, u8(rom_width - 3), 0 }, } , m_spaces{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } - , m_cache(nullptr) - , m_bus_cycle_cb() + , m_bus_cycle_cb(*this) , m_sync_cb(*this) - , m_cm_rom_cb{ { *this }, { *this } } - , m_cm_ram_cb{ { *this }, { *this }, { *this }, { *this }, } + , m_cm_rom_cb(*this) + , m_cm_ram_cb(*this) , m_cy_cb(*this), m_stp_ack_cb(*this) , m_4289_pm_cb(*this), m_4289_f_l_cb(*this) , m_extended_cm(extended_cm) @@ -142,20 +140,9 @@ void mcs40_cpu_device_base::device_start() m_spaces[AS_RAM_STATUS] = &space(AS_RAM_STATUS); m_spaces[AS_RAM_PORTS] = &space(AS_RAM_PORTS); m_spaces[AS_PROGRAM_MEMORY] = &space(AS_PROGRAM_MEMORY); - m_cache = m_spaces[AS_ROM]->cache<0, 0, ENDIANNESS_LITTLE>(); - - m_bus_cycle_cb.bind_relative_to(*owner()); - m_sync_cb.resolve_safe(); - m_cm_rom_cb[0].resolve_safe(); - m_cm_rom_cb[1].resolve_safe(); - m_cm_ram_cb[0].resolve_safe(); - m_cm_ram_cb[1].resolve_safe(); - m_cm_ram_cb[2].resolve_safe(); - m_cm_ram_cb[3].resolve_safe(); - m_cy_cb.resolve_safe(); - m_stp_ack_cb.resolve_safe(); - m_4289_pm_cb.resolve_safe(); - m_4289_f_l_cb.resolve_safe(); + m_spaces[AS_ROM]->cache(m_cache); + + m_bus_cycle_cb.resolve_safe(); m_stop_latch = m_decoded_halt = m_resume = false; @@ -523,39 +510,39 @@ inline void mcs40_cpu_device_base::set_rc(u8 val) inline u8 mcs40_cpu_device_base::read_memory() { - return m_spaces[AS_RAM_MEMORY]->read_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc) & 0x0fU; + return m_spaces[AS_RAM_MEMORY]->read_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc, 0x0fU) & 0x0fU; } inline void mcs40_cpu_device_base::write_memory(u8 val) { - m_spaces[AS_RAM_MEMORY]->write_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc, val & 0x0fU); + m_spaces[AS_RAM_MEMORY]->write_byte((u16(m_cr & 0x7U) << 8) | m_latched_rc, val & 0x0fU, 0x0fU); } inline u8 mcs40_cpu_device_base::read_status() { u16 const addr((((u16(m_cr) << 6) | (m_latched_rc >> 2)) & 0x01fcU) | (m_opa & 0x0003U)); - return m_spaces[AS_RAM_STATUS]->read_byte(addr) & 0x0fU; + return m_spaces[AS_RAM_STATUS]->read_byte(addr, 0x0fU) & 0x0fU; } inline void mcs40_cpu_device_base::write_status(u8 val) { u16 const addr((((u16(m_cr) << 6) | (m_latched_rc >> 2)) & 0x01fcU) | (m_opa & 0x0003U)); - m_spaces[AS_RAM_STATUS]->write_byte(addr, val & 0x0fU); + m_spaces[AS_RAM_STATUS]->write_byte(addr, val & 0x0fU, 0x0fU); } inline u8 mcs40_cpu_device_base::read_rom_port() { - return m_spaces[AS_ROM_PORTS]->read_byte((u16(m_cr) << 8) | m_latched_rc) & 0x0fU; + return m_spaces[AS_ROM_PORTS]->read_byte((u16(m_cr) << 8) | m_latched_rc, 0x0fU) & 0x0fU; } inline void mcs40_cpu_device_base::write_rom_port(u8 val) { - m_spaces[AS_ROM_PORTS]->write_byte((u16(m_cr) << 8) | m_latched_rc, val & 0x0fU); + m_spaces[AS_ROM_PORTS]->write_byte((u16(m_cr) << 8) | m_latched_rc, val & 0x0fU, 0x0fU); } inline void mcs40_cpu_device_base::write_memory_port(u8 val) { - m_spaces[AS_RAM_PORTS]->write_byte(((m_cr << 2) & 0x1cU) | (m_latched_rc >> 6), val & 0x0fU); + m_spaces[AS_RAM_PORTS]->write_byte(((m_cr << 2) & 0x1cU) | (m_latched_rc >> 6), val & 0x0fU, 0x0fU); } @@ -593,7 +580,7 @@ inline void mcs40_cpu_device_base::do_a1() if (cycle::OP == m_cycle) { m_pcbase = rom_bank() | m_rom_addr; - if (machine().debug_flags & DEBUG_FLAG_ENABLED) + if (debugger_enabled()) debugger_instruction_hook(pc()); if (m_stop_latch) { @@ -609,15 +596,13 @@ inline void mcs40_cpu_device_base::do_a1() m_sync_cb(1); update_4289_pm(1U); update_4289_f_l(1U); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::A1, 1U, m_rom_addr & 0x000fU); + m_bus_cycle_cb(phase::A1, 1U, m_rom_addr & 0x000fU); } inline void mcs40_cpu_device_base::do_a2() { m_4289_a = (m_4289_a & 0x0fU) | (m_rom_addr & 0xf0U); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::A2, 1U, (m_rom_addr >> 4) & 0x000fU); + m_bus_cycle_cb(phase::A2, 1U, (m_rom_addr >> 4) & 0x000fU); } inline void mcs40_cpu_device_base::do_a3() @@ -625,8 +610,7 @@ inline void mcs40_cpu_device_base::do_a3() m_4289_c = (m_rom_addr >> 8) & 0x0fU; update_cm_rom(BIT(m_cr, 3) ? 0x01U : 0x02U); update_cm_ram(f_cm_ram_table[m_cr & 0x07U]); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::A3, 1U, (m_rom_addr >> 8) & 0x000fU); + m_bus_cycle_cb(phase::A3, 1U, (m_rom_addr >> 8) & 0x000fU); } inline void mcs40_cpu_device_base::do_m1() @@ -637,7 +621,7 @@ inline void mcs40_cpu_device_base::do_m1() update_cm_rom(0x0fU); } // TODO: just read the high nybble here - MAME doesn't support this - u8 const read = m_cache->read_byte(rom_bank() | m_rom_addr); + u8 const read = m_cache.read_byte(rom_bank() | m_rom_addr); if (cycle::OP == m_cycle) { m_opr = (m_stop_ff) ? 0x0U : (read >> 4); @@ -648,14 +632,13 @@ inline void mcs40_cpu_device_base::do_m1() m_arg = read; } m_decoded_halt = false; - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::M1, 1U, (read >> 4) & 0x0fU); + m_bus_cycle_cb(phase::M1, 1U, (read >> 4) & 0x0fU); } inline void mcs40_cpu_device_base::do_m2() { // TODO: just read the low nybble here - MAME doesn't support this - u8 const read = m_cache->read_byte(rom_bank() | m_rom_addr); + u8 const read = m_cache.read_byte(rom_bank() | m_rom_addr); if (cycle::OP == m_cycle) m_opa = (m_stop_ff) ? 0x0U : (read & 0x0fU); else @@ -670,8 +653,7 @@ inline void mcs40_cpu_device_base::do_m2() if (!m_stop_ff && (cycle::IN != m_cycle)) pc() = (pc() + 1) & 0x0fff; m_rom_addr = pc(); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::M2, 1U, read & 0x0fU); + m_bus_cycle_cb(phase::M2, 1U, read & 0x0fU); } inline void mcs40_cpu_device_base::do_x1() @@ -708,8 +690,7 @@ inline void mcs40_cpu_device_base::do_x1() else assert(pmem::WRITE == m_program_op); } - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::X1, 1U, output); + m_bus_cycle_cb(phase::X1, 1U, output); } void mcs40_cpu_device_base::do_x2() @@ -738,8 +719,7 @@ void mcs40_cpu_device_base::do_x2() set_a(output = m_arg & 0x0fU); else if (pmem::WRITE == m_program_op) output = get_a(); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::X2, 1U, output); + m_bus_cycle_cb(phase::X2, 1U, output); } void mcs40_cpu_device_base::do_x3() @@ -769,8 +749,7 @@ void mcs40_cpu_device_base::do_x3() m_stp_ack_cb(1U); } m_resume = false; - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::X3, 0U, m_new_rc & 0x0fU); // FIXME: what appears on the bus if it isn't SRC? + m_bus_cycle_cb(phase::X3, 0U, m_new_rc & 0x0fU); // FIXME: what appears on the bus if it isn't SRC? } @@ -833,16 +812,15 @@ i4004_cpu_device::i4004_cpu_device(machine_config const &mconfig, char const *ta { } +i4004_cpu_device::~i4004_cpu_device() +{ +} + /*********************************************************************** device_execute_interface implementation ***********************************************************************/ -u32 i4004_cpu_device::execute_input_lines() const -{ - return 1U; -} - void i4004_cpu_device::execute_set_input(int inputnum, int state) { switch (inputnum) @@ -884,10 +862,9 @@ i4004_cpu_device::cycle i4004_cpu_device::do_cycle1(u8 opr, u8 opa, pmem &progra case 0x0: switch (opa) { + default: // in practice, the 4004 treats these as aliases for NOP case 0x0: // NOP return cycle::OP; - default: - break; } break; @@ -1143,16 +1120,15 @@ i4040_cpu_device::i4040_cpu_device(machine_config const &mconfig, char const *ta { } +i4040_cpu_device::~i4040_cpu_device() +{ +} + /*********************************************************************** device_execute_interface implementation ***********************************************************************/ -u32 i4040_cpu_device::execute_input_lines() const -{ - return 3U; -} - void i4040_cpu_device::execute_set_input(int inputnum, int state) { switch (inputnum) @@ -1187,6 +1163,8 @@ i4040_cpu_device::cycle i4040_cpu_device::do_cycle1(u8 opr, u8 opa, pmem &progra case 0x0: switch (opa) { + case 0x0: // NOP + return cycle::OP; case 0x1: // HLT halt_decoded(); return cycle::OP; @@ -1213,7 +1191,8 @@ i4040_cpu_device::cycle i4040_cpu_device::do_cycle1(u8 opr, u8 opa, pmem &progra program_op = pmem::READ; return cycle::OP; default: - break; + logerror("MCS-40: unhandled instruction OPR=%X OPA=%X\n", opr, opa); + return cycle::OP; } break; default: diff --git a/src/devices/cpu/mcs40/mcs40.h b/src/devices/cpu/mcs40/mcs40.h index d8ca4059631..80f0d1e44d8 100644 --- a/src/devices/cpu/mcs40/mcs40.h +++ b/src/devices/cpu/mcs40/mcs40.h @@ -51,7 +51,7 @@ public: template <typename... T> void set_ram_status_map(T &&... args) { set_addrmap(AS_RAM_STATUS, std::forward<T>(args)...); } template <typename... T> void set_ram_ports_map(T &&... args) { set_addrmap(AS_RAM_PORTS, std::forward<T>(args)...); } template <typename... T> void set_program_memory_map(T &&... args) { set_addrmap(AS_PROGRAM_MEMORY, std::forward<T>(args)...); } - template <typename... T> void set_bus_cycle_cb(T &&... args) { m_bus_cycle_cb = bus_cycle_delegate(std::forward<T>(args)...); } + template <typename... T> void set_bus_cycle_cb(T &&... args) { m_bus_cycle_cb.set(std::forward<T>(args)...); } auto i4289_pm_cb() { return m_4289_pm_cb.bind(); } auto i4289_f_l_cb() { return m_4289_f_l_cb.bind(); } @@ -62,8 +62,8 @@ public: // 4008/4009 or 4289 outputs u8 get_4289_a() const { return m_4289_a; } // 8-bit address u8 get_4289_c() const { return m_4289_c; } // 4-bit chip select - DECLARE_READ_LINE_MEMBER(get_4289_pm) const { return BIT(m_4289_pm, 0); } // 0 = active - DECLARE_READ_LINE_MEMBER(get_4289_f_l) const { return BIT(m_4289_f_l, 0); } // 1 = odd, 0 = even + int get_4289_pm() const { return BIT(m_4289_pm, 0); } // 0 = active + int get_4289_f_l() const { return BIT(m_4289_f_l, 0); } // 1 = odd, 0 = even protected: enum class cycle : u8 { OP, IM, IN }; @@ -82,8 +82,8 @@ protected: unsigned cr_mask); // device_t implementation - void device_start() override; - void device_reset() override; + void device_start() override ATTR_COLD; + void device_reset() override ATTR_COLD; // device_execute_interface implementation virtual void execute_run() override; @@ -182,18 +182,19 @@ private: // address spaces address_space_config const m_space_config[7]; address_space *m_spaces[7]; - memory_access_cache<0, 0, ENDIANNESS_LITTLE> *m_cache; + memory_access<12, 0, 0, ENDIANNESS_LITTLE>::cache m_cache; // bus snooping callback - bus_cycle_delegate m_bus_cycle_cb; + bus_cycle_delegate m_bus_cycle_cb; // output callbacks - devcb_write_line m_sync_cb; - devcb_write_line m_cm_rom_cb[2], m_cm_ram_cb[4]; - devcb_write_line m_cy_cb, m_stp_ack_cb; + devcb_write_line m_sync_cb; + devcb_write_line::array<2> m_cm_rom_cb; + devcb_write_line::array<4> m_cm_ram_cb; + devcb_write_line m_cy_cb, m_stp_ack_cb; // 4008/4009 or 4289 output callbacks - devcb_write_line m_4289_pm_cb, m_4289_f_l_cb; + devcb_write_line m_4289_pm_cb, m_4289_f_l_cb; // configuration bool const m_extended_cm; @@ -253,12 +254,12 @@ public: template <unsigned N> auto cm_ram_cb() { return mcs40_cpu_device_base::cm_ram_cb<N>(); } i4004_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + virtual ~i4004_cpu_device(); protected: using mcs40_cpu_device_base::mcs40_cpu_device_base; // device_execute_interface implementation - virtual u32 execute_input_lines() const override; virtual void execute_set_input(int inputnum, int state) override; // device_disasm_interface implementation @@ -282,13 +283,13 @@ public: using mcs40_cpu_device_base::stp_ack_cb; i4040_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + virtual ~i4040_cpu_device(); protected: // device_disasm_interface implementation virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; // device_execute_interface implementation - virtual u32 execute_input_lines() const override; virtual void execute_set_input(int inputnum, int state) override; // mcs40_cpu_device_base implementation diff --git a/src/devices/cpu/mcs40/mcs40dasm.cpp b/src/devices/cpu/mcs40/mcs40dasm.cpp index d0afd6e99a4..c7fdb44621d 100644 --- a/src/devices/cpu/mcs40/mcs40dasm.cpp +++ b/src/devices/cpu/mcs40/mcs40dasm.cpp @@ -119,10 +119,12 @@ offs_t mcs40_disassembler::disassemble(std::ostream &stream, offs_t pc, const da offs_t flags(0U); if (format::ILL != desc.m_format) { - if (0x50U == (opcode & 0xf0U)) // JMS + if (0x50 == (opcode & 0xf0)) // JMS flags = STEP_OVER; else if ((0xc0 == (opcode & 0xf0)) || (0x02 == opcode)) // BBL/BBS flags = STEP_OUT; + else if (0x10 == (opcode & 0xf0) || 0x70 == (opcode & 0xf0)) // JCN/ISZ + flags = STEP_COND; } return (npc - pc) | flags | SUPPORTED; |