diff options
Diffstat (limited to 'src/devices/cpu/sh/sh7014_port.cpp')
-rw-r--r-- | src/devices/cpu/sh/sh7014_port.cpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/src/devices/cpu/sh/sh7014_port.cpp b/src/devices/cpu/sh/sh7014_port.cpp new file mode 100644 index 00000000000..96ed0701648 --- /dev/null +++ b/src/devices/cpu/sh/sh7014_port.cpp @@ -0,0 +1,243 @@ +// license:BSD-3-Clause +// copyright-holders:windyfairy +/*************************************************************************** + + SH7014 I/O Port + + TODO list (not comprehensive): + - Special functions specified by control registers are not implemented + +***************************************************************************/ + +#include "emu.h" +#include "sh7014_port.h" + +#define LOG_READ (1U << 1) +#define LOG_WRITE (1U << 2) + +// #define VERBOSE (LOG_GENERAL | LOG_READ | LOG_WRITE) + +#include "logmacro.h" + + +DEFINE_DEVICE_TYPE(SH7014_PORT, sh7014_port_device, "sh7014port", "SH7014 I/O Port") + + +sh7014_port_device::sh7014_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SH7014_PORT, tag, owner, clock) + , m_port_a_read_cb(*this, 0) + , m_port_a_write_cb(*this) + , m_port_b_read_cb(*this, 0) + , m_port_b_write_cb(*this) + , m_port_e_read_cb(*this, 0) + , m_port_e_write_cb(*this) + , m_port_f_read_cb(*this, 0) +{ +} + +void sh7014_port_device::device_start() +{ + save_item(NAME(m_padr)); + save_item(NAME(m_paior)); + save_item(NAME(m_pacr1)); + save_item(NAME(m_pacr2)); + + save_item(NAME(m_pbdr)); + save_item(NAME(m_pbior)); + save_item(NAME(m_pbcr1)); + save_item(NAME(m_pbcr2)); + + save_item(NAME(m_pedr)); + save_item(NAME(m_peior)); + save_item(NAME(m_pecr1)); + save_item(NAME(m_pecr2)); + + save_item(NAME(m_pfdr)); +} + +void sh7014_port_device::device_reset() +{ + m_padr = 0; + m_paior = 0; + m_pacr1 = m_pacr2 = 0; + + m_pbdr = 0; + m_pbior = 0; + m_pbcr1 = m_pbcr2 = 0; + + m_pedr = 0; + m_peior = 0; + m_pecr1 = m_pecr2 = 0; + + m_pfdr = 0; +} + +/// + +uint16_t sh7014_port_device::padrl_r() +{ + uint16_t pins = m_port_a_read_cb(); + uint16_t r = ((m_padr & m_paior) | (pins & ~m_paior)) & 0x83ff; + LOGMASKED(LOG_READ, "padrl_r %04x (pins: %04x %04x)\n", r, m_paior, pins); + return r; +} + +void sh7014_port_device::padrl_w(uint16_t data) +{ + m_padr = data & 0x83ff; + LOGMASKED(LOG_WRITE, "padrl_w %04x\n", m_padr); + + if (m_paior) + m_port_a_write_cb(m_padr & m_paior); +} + +uint16_t sh7014_port_device::paiorl_r() +{ + LOGMASKED(LOG_READ, "paiorl_r %04x\n", m_paior); + return m_paior; +} + +void sh7014_port_device::paiorl_w(uint16_t data) +{ + m_paior = data & 0x83ff; + LOGMASKED(LOG_WRITE, "paiorl_w %04x\n", m_paior); +} + +uint16_t sh7014_port_device::pacrl1_r() +{ + LOGMASKED(LOG_READ, "m_pacr1 %04x\n", m_pacr1); + return m_pacr1; +} + +void sh7014_port_device::pacrl1_w(uint16_t data) +{ + m_pacr1 = data & 0x400f; + LOGMASKED(LOG_WRITE, "pacrl1_w %04x\n", m_pacr1); +} + +uint16_t sh7014_port_device::pacrl2_r() +{ + LOGMASKED(LOG_READ, "pacrl2_r %04x\n", m_pacr2); + return m_pacr2; +} + +void sh7014_port_device::pacrl2_w(uint16_t data) +{ + m_pacr2 = data & 0xfd75; + LOGMASKED(LOG_WRITE, "pacrl2_w %04x\n", m_pacr2); +} + +uint16_t sh7014_port_device::pbdr_r() +{ + uint16_t pins = m_port_b_read_cb(); + uint16_t r = ((m_pbdr & m_pbior) | (pins & ~m_pbior)) & 0x3ff; + LOGMASKED(LOG_READ, "pbdr_r %04x (pins: %04x %04x)\n", r, m_pbior, pins); + return r; +} + +void sh7014_port_device::pbdr_w(uint16_t data) +{ + m_pbdr = data; + LOGMASKED(LOG_WRITE, "pbdr_w %04x\n", m_pbdr); + + if (m_pbior) + m_port_b_write_cb(m_pbdr & m_pbior); +} + +uint16_t sh7014_port_device::pbior_r() +{ + LOGMASKED(LOG_READ, "pbior_r %04x\n", m_pbior); + return m_pbior; +} + +void sh7014_port_device::pbior_w(uint16_t data) +{ + // For SH7014 specifically, bits 0 and 1 are read only + m_pbior = data & 0x3fc; + LOGMASKED(LOG_WRITE, "pbior_w %04x\n", m_pbior); +} + +uint16_t sh7014_port_device::pbcr1_r() +{ + LOGMASKED(LOG_READ, "pbcr1_r %04x\n", m_pbcr1); + return m_pbcr1; +} + +void sh7014_port_device::pbcr1_w(uint16_t data) +{ + m_pbcr1 = data & 0xf; + LOGMASKED(LOG_WRITE, "pbcr1_w %04x\n", m_pbcr1); +} + +uint16_t sh7014_port_device::pbcr2_r() +{ + LOGMASKED(LOG_READ, "pbcr2_r %04x\n", m_pbcr2); + return m_pbcr2; +} + +void sh7014_port_device::pbcr2_w(uint16_t data) +{ + m_pbcr2 = data & 0xfff5; + LOGMASKED(LOG_WRITE, "pbcr2_w %04x\n", m_pbcr2); +} + +uint16_t sh7014_port_device::pedr_r() +{ + uint16_t pins = m_port_e_read_cb(); + uint16_t r = ((m_pedr & m_peior) | (pins & ~m_peior)); + LOGMASKED(LOG_READ, "pedr_r %04x (pins: %04x %04x)\n", r, m_peior, pins); + return r; +} + +void sh7014_port_device::pedr_w(uint16_t data) +{ + m_pedr = data; + LOGMASKED(LOG_WRITE, "pedr_w %04x\n", m_pedr); + + if (m_peior) + m_port_e_write_cb(m_pedr & m_peior); +} + +uint16_t sh7014_port_device::peior_r() +{ + LOGMASKED(LOG_READ, "peior_r %04x\n", m_peior); + return m_peior; +} + +void sh7014_port_device::peior_w(uint16_t data) +{ + m_peior = data; + LOGMASKED(LOG_WRITE, "peior_w %04x\n", m_peior); +} + +uint16_t sh7014_port_device::pecr1_r() +{ + LOGMASKED(LOG_READ, "pecr1_r %04x\n", m_pecr1); + return m_pecr1; +} + +void sh7014_port_device::pecr1_w(uint16_t data) +{ + m_pecr1 = data & 0xf000; + LOGMASKED(LOG_WRITE, "pecr1_w %04x\n", m_pecr1); +} + +uint16_t sh7014_port_device::pecr2_r() +{ + LOGMASKED(LOG_READ, "pecr2_r %04x\n", m_pecr2); + return m_pecr2; +} + +void sh7014_port_device::pecr2_w(uint16_t data) +{ + m_pecr2 = data & 0x55ff; + LOGMASKED(LOG_WRITE, "pecr2_w %04x\n", m_pecr2); +} + + +uint8_t sh7014_port_device::pfdr_r() +{ + auto r = m_port_f_read_cb(); + LOGMASKED(LOG_READ, "pfdr_r %02x\n", r); + return r; +} |