From 0a18efc1fee1a81c0f367f06ecc355a7a742fe67 Mon Sep 17 00:00:00 2001 From: hap Date: Thu, 12 Dec 2024 18:23:29 +0100 Subject: hd6305: add hd6305y0 --- src/devices/cpu/m6805/hd6305.cpp | 55 ++++++++++++++++++++++++++++++++++++++-- src/devices/cpu/m6805/hd6305.h | 32 +++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/src/devices/cpu/m6805/hd6305.cpp b/src/devices/cpu/m6805/hd6305.cpp index bffcb92779b..814746bf27c 100644 --- a/src/devices/cpu/m6805/hd6305.cpp +++ b/src/devices/cpu/m6805/hd6305.cpp @@ -27,6 +27,7 @@ hd6305_device::hd6305_device( m_read_port(*this, 0xff), m_write_port(*this) { + std::fill(m_port_ddr_override.begin(), m_port_ddr_override.end(), 0x00); } // common peripherals @@ -82,10 +83,11 @@ void hd6305_device::device_reset() template u8 hd6305_device::port_r() { - if(m_port_ddr[Port] == 0xff) + const u8 ddr = m_port_ddr[Port] & ~m_port_ddr_override[Port]; + if(ddr == 0xff) return m_port_data[Port]; - return (m_port_ddr[Port] & m_port_data[Port]) | (m_read_port[Port]() & ~m_port_ddr[Port]); + return (m_port_data[Port] & ddr) | (m_read_port[Port]() & ~ddr); } template @@ -398,6 +400,54 @@ void hd6305v0_device::internal_map(address_map &map) } +/**************************************************************************** + * HD6305Y0 section + ****************************************************************************/ + +hd6305y0_device::hd6305y0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + hd6305_device( + mconfig, + tag, + owner, + clock, + HD6305Y0, + { s_hmos_s_ops, s_cmos_cycles, 14, 0x00ff, 0x00c0, 0x1fff, 0x1ffc }, + address_map_constructor(FUNC(hd6305y0_device::internal_map), this)) +{ +} + +void hd6305y0_device::internal_map(address_map &map) +{ + map(0x0000, 0x0000).rw(FUNC(hd6305y0_device::port_r<0>), FUNC(hd6305y0_device::port_w<0>)); + map(0x0001, 0x0001).rw(FUNC(hd6305y0_device::port_r<1>), FUNC(hd6305y0_device::port_w<1>)); + map(0x0002, 0x0002).rw(FUNC(hd6305y0_device::port_r<2>), FUNC(hd6305y0_device::port_w<2>)); + map(0x0003, 0x0003).r(FUNC(hd6305y0_device::port_r<3>)); + map(0x0004, 0x0004).w(FUNC(hd6305y0_device::port_ddr_w<0>)); + map(0x0005, 0x0005).w(FUNC(hd6305y0_device::port_ddr_w<1>)); + map(0x0006, 0x0006).w(FUNC(hd6305y0_device::port_ddr_w<2>)); + map(0x0007, 0x0007).w(FUNC(hd6305y0_device::port_ddr_w<6>)); + map(0x0008, 0x0008).rw(FUNC(hd6305y0_device::timer_data_r), FUNC(hd6305y0_device::timer_data_w)); + map(0x0009, 0x0009).rw(FUNC(hd6305y0_device::timer_ctrl_r), FUNC(hd6305y0_device::timer_ctrl_w)); + map(0x000a, 0x000a).rw(FUNC(hd6305y0_device::misc_r), FUNC(hd6305y0_device::misc_w)); + map(0x000b, 0x000b).rw(FUNC(hd6305y0_device::port_r<4>), FUNC(hd6305y0_device::port_w<4>)); + map(0x000c, 0x000c).rw(FUNC(hd6305y0_device::port_r<5>), FUNC(hd6305y0_device::port_w<5>)); + map(0x000d, 0x000d).rw(FUNC(hd6305y0_device::port_r<6>), FUNC(hd6305y0_device::port_w<6>)); + map(0x0010, 0x0010).rw(FUNC(hd6305y0_device::sci_ctrl_r), FUNC(hd6305y0_device::sci_ctrl_w)); + map(0x0011, 0x0011).rw(FUNC(hd6305y0_device::sci_ssr_r), FUNC(hd6305y0_device::sci_ssr_w)); + map(0x0012, 0x0012).rw(FUNC(hd6305y0_device::sci_data_r), FUNC(hd6305y0_device::sci_data_w)); + map(0x0040, 0x013f).ram(); + map(0x0140, 0x1fff).rom().region(DEVICE_SELF, 0); +} + +void hd6305y0_device::device_reset() +{ + hd6305_device::device_reset(); + + // ports E and F are write-only + m_port_ddr[4] = m_port_ddr[5] = 0xff; +} + + /**************************************************************************** * HD6305Y2 section ****************************************************************************/ @@ -549,5 +599,6 @@ void hd63705z0_device::interrupt() DEFINE_DEVICE_TYPE(HD6305V0, hd6305v0_device, "hd6305v0", "Hitachi HD6305V0") +DEFINE_DEVICE_TYPE(HD6305Y0, hd6305y0_device, "hd6305y0", "Hitachi HD6305Y0") DEFINE_DEVICE_TYPE(HD6305Y2, hd6305y2_device, "hd6305y2", "Hitachi HD6305Y2") DEFINE_DEVICE_TYPE(HD63705Z0, hd63705z0_device, "hd63705z0", "Hitachi HD63705Z0") diff --git a/src/devices/cpu/m6805/hd6305.h b/src/devices/cpu/m6805/hd6305.h index 1ddef7b174b..8847d4b2cb7 100644 --- a/src/devices/cpu/m6805/hd6305.h +++ b/src/devices/cpu/m6805/hd6305.h @@ -15,6 +15,7 @@ // device type declarations DECLARE_DEVICE_TYPE(HD6305V0, hd6305v0_device) +DECLARE_DEVICE_TYPE(HD6305Y0, hd6305y0_device) DECLARE_DEVICE_TYPE(HD6305Y2, hd6305y2_device) DECLARE_DEVICE_TYPE(HD63705Z0, hd63705z0_device) @@ -81,6 +82,7 @@ protected: devcb_write8::array<9> m_write_port; std::array m_port_data; std::array m_port_ddr; + std::array m_port_ddr_override; emu_timer *m_timer_timer; emu_timer *m_timer_sci; @@ -121,6 +123,36 @@ private: void internal_map(address_map &map) ATTR_COLD; }; +// ======================> hd6305y0_device + +class hd6305y0_device : public hd6305_device +{ +public: + // construction/destruction + hd6305y0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + auto read_porta() { return m_read_port [0].bind(); } + auto write_porta() { return m_write_port[0].bind(); } + auto read_portb() { return m_read_port [1].bind(); } + auto write_portb() { return m_write_port[1].bind(); } + auto read_portc() { return m_read_port [2].bind(); } + auto write_portc() { return m_write_port[2].bind(); } + auto read_portd() { return m_read_port [3].bind(); } + auto write_porte() { return m_write_port[4].bind(); } + auto write_portf() { return m_write_port[5].bind(); } + auto read_portg() { return m_read_port [6].bind(); } + auto write_portg() { return m_write_port[6].bind(); } + + // port G voltage can override DDR, and read the input pins no matter the DDR value + void read_portg_override_mask(u8 mask) { m_port_ddr_override[6] = mask; } + +protected: + virtual void device_reset() override ATTR_COLD; + +private: + void internal_map(address_map &map) ATTR_COLD; +}; + // ======================> hd6305y2_device class hd6305y2_device : public hd6305_device -- cgit v1.2.3