diff options
Diffstat (limited to 'src/devices/cpu/h8/h8_port.cpp')
-rw-r--r-- | src/devices/cpu/h8/h8_port.cpp | 130 |
1 files changed, 84 insertions, 46 deletions
diff --git a/src/devices/cpu/h8/h8_port.cpp b/src/devices/cpu/h8/h8_port.cpp index bc21c99d6df..782f5439646 100644 --- a/src/devices/cpu/h8/h8_port.cpp +++ b/src/devices/cpu/h8/h8_port.cpp @@ -1,102 +1,140 @@ // license:BSD-3-Clause // copyright-holders:Olivier Galibert +/*************************************************************************** + + h8_port.cpp + + H8 8 bits digital port + + TODO: + - Many I/O port pins have a double function, eg. for IRQs or timer input + strobe. Ideally this device should know the input pin state, instead + of having to implement it in the MAME drivers. + +***************************************************************************/ + #include "emu.h" #include "h8_port.h" DEFINE_DEVICE_TYPE(H8_PORT, h8_port_device, "h8_digital_port", "H8 digital port") -h8_port_device::h8_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +h8_port_device::h8_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, H8_PORT, tag, owner, clock), - cpu(*this, DEVICE_SELF_OWNER), io(nullptr), address(0), default_ddr(0), ddr(0), pcr(0), odr(0), mask(0), dr(0), last_output(0) + m_cpu(*this, DEVICE_SELF_OWNER), m_address(0), m_default_ddr(0), m_ddr(0), m_pcr(0), m_odr(0), m_mask(0), m_dr(0), m_last_output(0) { } -void h8_port_device::set_info(int _address, uint8_t _default_ddr, uint8_t _mask) +void h8_port_device::ddr_w(u8 data) { - address = _address; - default_ddr = _default_ddr; - mask = _mask; + //logerror("ddr_w %02x\n", data); + m_ddr = data; + update_output(); } -WRITE8_MEMBER(h8_port_device::ddr_w) +u8 h8_port_device::ddr_r() { - // logerror("ddr_w %02x\n", data); - ddr = data; - update_output(); + return m_ddr; } -WRITE8_MEMBER(h8_port_device::dr_w) +void h8_port_device::dr_w(u8 data) { - // logerror("dr_w %02x\n", data); - dr = data; + //logerror("dr_w %02x\n", data); + m_dr = data; update_output(); } -READ8_MEMBER(h8_port_device::dr_r) +u8 h8_port_device::dr_r() { - // logerror("dr_r %02x\n", (dr | mask) & 0xff); - return dr | mask; + //logerror("dr_r %02x\n", (dr | mask) & 0xff); + return m_dr | m_mask; } -READ8_MEMBER(h8_port_device::port_r) +u8 h8_port_device::port_r() { - uint8_t res = mask | (dr & ddr); - if((ddr & ~mask) != uint8_t(~mask)) - res |= io->read_word(address) & ~ddr; + u8 res = m_mask | (m_dr & m_ddr); + if((m_ddr & ~m_mask) != u8(~m_mask)) + res |= m_cpu->do_read_port(m_address) & ~m_ddr; - // logerror("port_r %02x (%02x %02x)\n", res, ddr & ~mask, uint8_t(~mask)); + //logerror("port_r %02x (%02x %02x)\n", res, ddr & ~mask, u8(~mask)); return res; } -WRITE8_MEMBER(h8_port_device::pcr_w) +void h8_port_device::pcr_w(u8 data) { logerror("pcr_w %02x\n", data); - pcr = data; + m_pcr = data; } -READ8_MEMBER(h8_port_device::pcr_r) +u8 h8_port_device::pcr_r() { - logerror("dr_r %02x\n", (pcr | mask) & 0xff); - return pcr | mask; + logerror("pcr_r %02x\n", (m_pcr | m_mask) & 0xff); + return m_pcr | m_mask; } -WRITE8_MEMBER(h8_port_device::odr_w) +void h8_port_device::odr_w(u8 data) { logerror("odr_w %02x\n", data); - odr = data; + m_odr = data; } -READ8_MEMBER(h8_port_device::odr_r) +u8 h8_port_device::odr_r() { - logerror("odr_r %02x\n", (odr | mask) & 0xff); - return odr | ~mask; + logerror("odr_r %02x\n", (m_odr | ~m_mask) & 0xff); + return m_odr | ~m_mask; } void h8_port_device::update_output() { - uint8_t res = dr & ddr & ~mask; - if(res != last_output) { - last_output = res; - io->write_word(address, res); + u8 data = (m_dr | ~m_ddr) & ~m_mask; + u8 ddr = m_ddr & ~m_mask; // 0-bits = hi-z + u16 res = ddr << 8 | data; + + if(res != m_last_output) { + m_last_output = res; + m_cpu->do_write_port(m_address, data, ddr); } } void h8_port_device::device_start() { - io = &cpu->space(AS_IO); - save_item(NAME(ddr)); - save_item(NAME(dr)); - save_item(NAME(pcr)); - save_item(NAME(odr)); - save_item(NAME(last_output)); - last_output = 0; + save_item(NAME(m_ddr)); + save_item(NAME(m_pcr)); + save_item(NAME(m_odr)); + save_item(NAME(m_dr)); + save_item(NAME(m_last_output)); + + m_last_output = -1; + m_dr = 0; + m_ddr = m_default_ddr; + m_pcr = 0; + m_odr = 0; } void h8_port_device::device_reset() { - dr = 0; - ddr = default_ddr; - pcr = 0; - odr = 0; update_output(); } + +bool h8_port_device::nvram_write(util::write_stream &file) +{ + u8 const buf[4]{ m_ddr, m_dr, m_pcr, m_odr }; + + auto const [err, actual] = write(file, buf, sizeof(buf)); + return !err; +} + +bool h8_port_device::nvram_read(util::read_stream &file) +{ + u8 buf[4]; + + auto const [err, actual] = read(file, buf, sizeof(buf)); + if(err || (sizeof(buf) != actual)) + return false; + + m_ddr = buf[0]; + m_dr = buf[1]; + m_pcr = buf[2]; + m_odr = buf[3]; + + return true; +} |