diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp index 278505b8c1e..6c2f3de6622 100644 --- a/src/devices/cpu/m6805/m6805.cpp +++ b/src/devices/cpu/m6805/m6805.cpp @@ -415,7 +415,7 @@ m6805_base_device::m6805_base_device(const machine_config &mconfig, const char * { } -m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source) +m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source) : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source), m_program_config("program", ENDIANNESS_BIG, 8, addr_width, 0, internal_map) { @@ -965,63 +965,146 @@ void m68705_device::execute_set_input(int inputnum, int state) /* ddr - direction registers */ -WRITE8_MEMBER(m68705_new_device::mc68705_ddrA_w) +WRITE8_MEMBER(m68705_new_device::internal_ddrA_w) { + const u8 ddr_old = m_ddrA; m_ddrA = data; + + // update outputs if lines switched to output + if ((m_ddrA & ~ddr_old) != 0) + update_portA_state(); } -WRITE8_MEMBER(m68705_new_device::mc68705_ddrB_w) +WRITE8_MEMBER(m68705_new_device::internal_ddrB_w) { + const u8 ddr_old = m_ddrB; m_ddrB = data; + + // update outputs if lines switched to output + if ((m_ddrB & ~ddr_old) != 0) + update_portB_state(); } -WRITE8_MEMBER(m68705_new_device::mc68705_ddrC_w) +WRITE8_MEMBER(m68705_new_device::internal_ddrC_w) { + const u8 ddr_old = m_ddrC; m_ddrC = data; + + // update outputs if lines switched to output + if ((m_ddrC & ~ddr_old) != 0) + update_portC_state(); } /* read ports */ -READ8_MEMBER(m68705_new_device::mc68705_portA_r) +READ8_MEMBER(m68705_new_device::internal_portA_r) { - m_portA_in = m_portA_cb_r(0, ~m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pulled - uint8_t res = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA); - return res; - -} - -READ8_MEMBER(m68705_new_device::mc68705_portB_r) -{ - m_portB_in = m_portB_cb_r(0, ~m_ddrB); - uint8_t res = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB); + if (!m_portA_cb_r.isnull()) + m_portA_in = m_portA_cb_r(space, 0, ~m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pulled + u8 res = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA); return res; } -READ8_MEMBER(m68705_new_device::mc68705_portC_r) +READ8_MEMBER(m68705_new_device::internal_portB_r) { - m_portC_in = m_portC_cb_r(0, ~m_ddrC); - uint8_t res = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC); + if (!m_portB_cb_r.isnull()) + m_portB_in = m_portB_cb_r(space, 0, ~m_ddrB); + u8 res = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB); + return res; +} + +READ8_MEMBER(m68705_new_device::internal_portC_r) +{ + if (!m_portC_cb_r.isnull()) + m_portC_in = m_portC_cb_r(space, 0, ~m_ddrC); + u8 res = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC); return res; } /* write ports */ -WRITE8_MEMBER(m68705_new_device::mc68705_portA_w) +WRITE8_MEMBER(m68705_new_device::internal_portA_w) { - m_portA_cb_w(0, data, m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pushed + // load the output latch m_portA_out = data; + + // update the output lines + update_portA_state(); } -WRITE8_MEMBER(m68705_new_device::mc68705_portB_w) +void m68705_new_device::update_portA_state() { - m_portB_cb_w(0, data, m_ddrB); + // pass bits through DDR output mask + m_portA_in = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA); + + // pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed + m_portA_cb_w(space(AS_PROGRAM), 0, m_portA_in, m_ddrA); +} + +WRITE8_MEMBER(m68705_new_device::internal_portB_w) +{ + // load the output latch m_portB_out = data; + + // update the output lines + update_portB_state(); } -WRITE8_MEMBER(m68705_new_device::mc68705_portC_w) +void m68705_new_device::update_portB_state() { - m_portC_cb_w(0, data, m_ddrC); + // pass bits through DDR output mask + m_portB_in = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB); + + // pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed + m_portB_cb_w(space(AS_PROGRAM), 0, m_portB_in, m_ddrB); +} + +WRITE8_MEMBER(m68705_new_device::internal_portC_w) +{ + // load the output latch m_portC_out = data; + + // update the output lines + update_portC_state(); +} + +void m68705_new_device::update_portC_state() +{ + // pass bits through DDR output mask + m_portC_in = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC); + + // pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed + m_portC_cb_w(space(AS_PROGRAM), 0, m_portC_in, m_ddrC); +} + +READ8_MEMBER(m68705_new_device::pa_r) +{ + return m_portA_in; +} + +READ8_MEMBER(m68705_new_device::pb_r) +{ + return m_portB_in; +} + +READ8_MEMBER(m68705_new_device::pc_r) +{ + return m_portC_in; +} + +WRITE8_MEMBER(m68705_new_device::pa_w) +{ + COMBINE_DATA(&m_portA_in); +} + +WRITE8_MEMBER(m68705_new_device::pb_w) +{ + COMBINE_DATA(&m_portB_in); +} + +WRITE8_MEMBER(m68705_new_device::pc_w) +{ + COMBINE_DATA(&m_portC_in); } /* @@ -1079,13 +1162,13 @@ selftest rom at similar area; selftest roms differ between the U2 and U3 version */ -ADDRESS_MAP_START( m68705_internal_map, AS_PROGRAM, 8, m68705_new_device ) - AM_RANGE(0x000, 0x000) AM_READWRITE(mc68705_portA_r, mc68705_portA_w) - AM_RANGE(0x001, 0x001) AM_READWRITE(mc68705_portB_r, mc68705_portB_w) - AM_RANGE(0x002, 0x002) AM_READWRITE(mc68705_portC_r, mc68705_portC_w) - AM_RANGE(0x004, 0x004) AM_WRITE(mc68705_ddrA_w) - AM_RANGE(0x005, 0x005) AM_WRITE(mc68705_ddrB_w) - AM_RANGE(0x006, 0x006) AM_WRITE(mc68705_ddrC_w) +DEVICE_ADDRESS_MAP_START( internal_map, 8, m68705_new_device ) + AM_RANGE(0x000, 0x000) AM_READWRITE(internal_portA_r, internal_portA_w) + AM_RANGE(0x001, 0x001) AM_READWRITE(internal_portB_r, internal_portB_w) + AM_RANGE(0x002, 0x002) AM_READWRITE(internal_portC_r, internal_portC_w) + AM_RANGE(0x004, 0x004) AM_WRITE(internal_ddrA_w) + AM_RANGE(0x005, 0x005) AM_WRITE(internal_ddrB_w) + AM_RANGE(0x006, 0x006) AM_WRITE(internal_ddrC_w) AM_RANGE(0x010, 0x07f) AM_RAM AM_RANGE(0x080, 0x7ff) AM_ROM @@ -1111,10 +1194,23 @@ void m68705_new_device::device_start() m_portB_cb_w.resolve_safe(); m_portC_cb_w.resolve_safe(); - m_portA_cb_r.resolve_safe(0xff); - m_portB_cb_r.resolve_safe(0xff); - m_portC_cb_r.resolve_safe(0xff); + m_portA_cb_r.resolve(); + m_portB_cb_r.resolve(); + m_portC_cb_r.resolve(); + m_portA_in = 0xff; + m_portB_in = 0xff; + m_portC_in = 0xff; +} + +void m68705_new_device::device_reset() +{ + m68705_device::device_reset(); + + // all bits of ports A, B and C revert to inputs on reset + m_ddrA = 0; + m_ddrB = 0; + m_ddrC = 0; } /**************************************************************************** diff --git a/src/devices/cpu/m6805/m6805.h b/src/devices/cpu/m6805/m6805.h index 24b75f57158..f0d6e5200a7 100644 --- a/src/devices/cpu/m6805/m6805.h +++ b/src/devices/cpu/m6805/m6805.h @@ -28,7 +28,7 @@ class m6805_base_device : public cpu_device public: // construction/destruction m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, const char *shortname, const char *source); - m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source); + m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source); protected: // device-level overrides @@ -330,7 +330,7 @@ public: m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6805_base_device(mconfig, tag, owner, clock, M68705, "M68705", 12, "m68705", __FILE__) { } - m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source) + m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source) : m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source) { } @@ -345,26 +345,24 @@ protected: // ======================> m68705_new_device -ADDRESS_MAP_EXTERN(m68705_internal_map, 8); - #define MCFG_M68705_PORTA_W_CB(_devcb) \ - m68705_new_device::set_portA_cb_w(*device, DEVCB_##_devcb); + devcb = &m68705_new_device::set_portA_cb_w(*device, DEVCB_##_devcb); #define MCFG_M68705_PORTB_W_CB(_devcb) \ - m68705_new_device::set_portB_cb_w(*device, DEVCB_##_devcb); + devcb = &m68705_new_device::set_portB_cb_w(*device, DEVCB_##_devcb); #define MCFG_M68705_PORTC_W_CB(_devcb) \ - m68705_new_device::set_portC_cb_w(*device, DEVCB_##_devcb); + devcb = &m68705_new_device::set_portC_cb_w(*device, DEVCB_##_devcb); #define MCFG_M68705_PORTA_R_CB(_devcb) \ - m68705_new_device::set_portA_cb_r(*device, DEVCB_##_devcb); + devcb = &m68705_new_device::set_portA_cb_r(*device, DEVCB_##_devcb); #define MCFG_M68705_PORTB_R_CB(_devcb) \ - m68705_new_device::set_portB_cb_r(*device, DEVCB_##_devcb); + devcb = &m68705_new_device::set_portB_cb_r(*device, DEVCB_##_devcb); #define MCFG_M68705_PORTC_R_CB(_devcb) \ - m68705_new_device::set_portC_cb_r(*device, DEVCB_##_devcb); + devcb = &m68705_new_device::set_portC_cb_r(*device, DEVCB_##_devcb); class m68705_new_device : public m68705_device @@ -372,7 +370,7 @@ class m68705_new_device : public m68705_device public: // construction/destruction m68705_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : m68705_device(mconfig, tag, owner, clock, M68705_NEW, "M68705 (NEW)", 11, ADDRESS_MAP_NAME( m68705_internal_map ), "m68705_new", __FILE__), + : m68705_device(mconfig, tag, owner, clock, M68705_NEW, "M68705 (NEW)", 11, address_map_delegate(FUNC(m68705_new_device::internal_map), this), "m68705_new", __FILE__), m_portA_in(0), m_portB_in(0), m_portC_in(0), @@ -399,31 +397,44 @@ public: template static devcb_base &set_portB_cb_r(device_t &device, _Object object) { return downcast(device).m_portB_cb_r.set_callback(object); } template static devcb_base &set_portC_cb_r(device_t &device, _Object object) { return downcast(device).m_portC_cb_r.set_callback(object); } - DECLARE_READ8_MEMBER(mc68705_portA_r); - DECLARE_READ8_MEMBER(mc68705_portB_r); - DECLARE_READ8_MEMBER(mc68705_portC_r); + DECLARE_READ8_MEMBER(pa_r); + DECLARE_READ8_MEMBER(pb_r); + DECLARE_READ8_MEMBER(pc_r); - DECLARE_WRITE8_MEMBER(mc68705_portA_w); - DECLARE_WRITE8_MEMBER(mc68705_portB_w); - DECLARE_WRITE8_MEMBER(mc68705_portC_w); - - DECLARE_WRITE8_MEMBER(mc68705_ddrA_w); - DECLARE_WRITE8_MEMBER(mc68705_ddrB_w); - DECLARE_WRITE8_MEMBER(mc68705_ddrC_w); + DECLARE_WRITE8_MEMBER(pa_w); + DECLARE_WRITE8_MEMBER(pb_w); + DECLARE_WRITE8_MEMBER(pc_w); protected: + DECLARE_ADDRESS_MAP(internal_map, 8); - uint8_t m_portA_in; - uint8_t m_portB_in; - uint8_t m_portC_in; + DECLARE_READ8_MEMBER(internal_portA_r); + DECLARE_READ8_MEMBER(internal_portB_r); + DECLARE_READ8_MEMBER(internal_portC_r); - uint8_t m_portA_out; - uint8_t m_portB_out; - uint8_t m_portC_out; + DECLARE_WRITE8_MEMBER(internal_portA_w); + DECLARE_WRITE8_MEMBER(internal_portB_w); + DECLARE_WRITE8_MEMBER(internal_portC_w); - uint8_t m_ddrA; - uint8_t m_ddrB; - uint8_t m_ddrC; + DECLARE_WRITE8_MEMBER(internal_ddrA_w); + DECLARE_WRITE8_MEMBER(internal_ddrB_w); + DECLARE_WRITE8_MEMBER(internal_ddrC_w); + + void update_portA_state(); + void update_portB_state(); + void update_portC_state(); + + u8 m_portA_in; + u8 m_portB_in; + u8 m_portC_in; + + u8 m_portA_out; + u8 m_portB_out; + u8 m_portC_out; + + u8 m_ddrA; + u8 m_ddrB; + u8 m_ddrC; /* Callbacks */ devcb_write8 m_portA_cb_w; @@ -437,6 +448,7 @@ protected: // device-level overrides virtual void device_start() override; + virtual void device_reset() override; // virtual void execute_set_input(int inputnum, int state) override;