summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/h8/h8_port.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/h8/h8_port.cpp')
-rw-r--r--src/devices/cpu/h8/h8_port.cpp130
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;
+}