summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/lh5810.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-09-13 08:41:44 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2015-09-13 08:41:44 +0200
commitf88cefad27a1737c76e09d99c9fb43e173506081 (patch)
tree2d8167d03579c46e226471747eb4407bd00ed6fa /src/devices/machine/lh5810.c
parente92ac9e0fa8e99869894bea00589bbb526be30aa (diff)
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/devices/machine/lh5810.c')
-rw-r--r--src/devices/machine/lh5810.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/devices/machine/lh5810.c b/src/devices/machine/lh5810.c
new file mode 100644
index 00000000000..296a28a60ec
--- /dev/null
+++ b/src/devices/machine/lh5810.c
@@ -0,0 +1,171 @@
+// license:BSD-3-Clause
+// copyright-holders:Sandro Ronco
+/**********************************************************************
+
+ LH5810/LH5811 Input/Output Port Controller
+
+ TODO:
+ - serial data transfer
+ - data transfer to the cassette tape
+
+**********************************************************************/
+
+#include "emu.h"
+#include "lh5810.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type LH5810 = &device_creator<lh5810_device>;
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// lh5810_device - constructor
+//-------------------------------------------------
+
+lh5810_device::lh5810_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, LH5810, "LH5810", tag, owner, clock, "lh5810", __FILE__),
+ m_porta_r_cb(*this),
+ m_porta_w_cb(*this),
+ m_portb_r_cb(*this),
+ m_portb_w_cb(*this),
+ m_portc_w_cb(*this),
+ m_out_int_cb(*this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void lh5810_device::device_start()
+{
+ // resolve callbacks
+ m_porta_r_cb.resolve_safe(0);
+ m_porta_w_cb.resolve_safe();
+ m_portb_r_cb.resolve_safe(0);
+ m_portb_w_cb.resolve_safe();
+ m_portc_w_cb.resolve_safe();
+ m_out_int_cb.resolve_safe();
+
+ // register for state saving
+ save_item(NAME(m_irq));
+ save_item(NAME(m_reg));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void lh5810_device::device_reset()
+{
+ memset(m_reg, 0, sizeof(m_reg));
+ m_irq = 0;
+}
+
+
+//-------------------------------------------------
+// data_r - data read
+//-------------------------------------------------
+
+READ8_MEMBER( lh5810_device::data_r )
+{
+ switch (offset)
+ {
+ case LH5810_U:
+ case LH5810_L:
+ case LH5810_G:
+ case LH5810_DDA:
+ case LH5810_DDB:
+ case LH5810_OPC:
+ case LH5820_F:
+ return m_reg[offset];
+
+ case LH5810_IF:
+ if (BIT(m_portb_r_cb(0) & ~m_reg[LH5810_DDB], 7))
+ m_reg[offset] |= 2;
+ else
+ m_reg[offset] &= 0xfd;
+
+ return m_reg[offset];
+
+ case LH5810_MSK:
+ return (m_reg[offset]&0x0f) | (m_irq<<4) | (BIT(m_reg[LH5810_OPB],7)<<5);
+
+ case LH5810_OPA:
+ m_reg[offset] = (m_reg[offset] & m_reg[LH5810_DDA]) | (m_porta_r_cb(0) & ~m_reg[LH5810_DDA]);
+ return m_reg[offset];
+
+ case LH5810_OPB:
+ m_reg[offset] = (m_reg[offset] & m_reg[LH5810_DDB]) | (m_portb_r_cb(0) & ~m_reg[LH5810_DDB]);
+ m_out_int_cb((m_reg[offset] & 0x80 && m_reg[LH5810_MSK] & 0x02) ? ASSERT_LINE : CLEAR_LINE);
+ return m_reg[offset];
+
+ default:
+ return 0x00;
+ }
+}
+
+
+//-------------------------------------------------
+// data_w - data write
+//-------------------------------------------------
+
+WRITE8_MEMBER( lh5810_device::data_w )
+{
+ switch (offset)
+ {
+ case LH5810_RESET:
+ break;
+
+ case LH5810_G:
+ case LH5820_F:
+ case LH5810_DDA:
+ case LH5810_DDB:
+ m_reg[offset] = data;
+ break;
+
+ case LH5810_U:
+ //writing on U register clear the RD flag of IF register
+ m_reg[LH5810_IF] &= 0xfb;
+ m_reg[offset] = data;
+ break;
+
+ case LH5810_L:
+ //writing on L register clear the TD flag of IF register
+ m_reg[LH5810_IF] &= 0xf7;
+ m_reg[offset] = data;
+ break;
+
+ case LH5810_MSK:
+ m_reg[offset] = data & 0x0f;
+ break;
+
+ case LH5810_IF:
+ //only bit 0 and 1 are writable
+ m_reg[offset] = (m_reg[offset] & 0xfc) | (data & 0x03);
+ break;
+
+ case LH5810_OPA:
+ m_reg[offset] = (data & m_reg[LH5810_DDA]) | (m_reg[offset] & ~m_reg[LH5810_DDA]);
+ m_porta_w_cb((offs_t)0, m_reg[offset]);
+ break;
+
+ case LH5810_OPB:
+ m_reg[offset] = (data & m_reg[LH5810_DDB]) | (m_reg[offset] & ~m_reg[LH5810_DDB]);
+ m_portb_w_cb((offs_t)0, m_reg[offset]);
+ m_out_int_cb((m_reg[offset] & 0x80 && m_reg[LH5810_MSK] & 0x02) ? ASSERT_LINE : CLEAR_LINE);
+ break;
+
+ case LH5810_OPC:
+ m_reg[offset] = data;
+ m_portc_w_cb((offs_t)0, m_reg[offset]);
+ break;
+ }
+}