hd6305: add hd6305y0

This commit is contained in:
hap 2024-12-12 18:23:29 +01:00
parent cb1cb6f650
commit 0a18efc1fe
2 changed files with 85 additions and 2 deletions

View File

@ -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<int Port>
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<int Port>
@ -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")

View File

@ -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<u8, 9> m_port_data;
std::array<u8, 9> m_port_ddr;
std::array<u8, 9> 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