summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mcs40
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mcs40')
-rw-r--r--src/devices/cpu/mcs40/mcs40.cpp95
-rw-r--r--src/devices/cpu/mcs40/mcs40.h27
-rw-r--r--src/devices/cpu/mcs40/mcs40dasm.cpp4
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;