summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/40105.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/40105.cpp')
-rw-r--r--src/devices/machine/40105.cpp86
1 files changed, 56 insertions, 30 deletions
diff --git a/src/devices/machine/40105.cpp b/src/devices/machine/40105.cpp
index 8dec8b78cec..981506b44b4 100644
--- a/src/devices/machine/40105.cpp
+++ b/src/devices/machine/40105.cpp
@@ -2,7 +2,16 @@
// copyright-holders:Curt Coder
/**********************************************************************
- CMOS 40105 FIFO Register emulation
+ CD40105/HC40105 4-bit x 16-word FIFO Register
+
+ Part of the 4000B series of CMOS TTL devices, the 40105 includes
+ an asynchronous master reset pin intended to be connected to the
+ system bus.
+
+ Word size can be expanded from 4 bits to 8 bits by connecting two
+ 40105s in parallel, with external AND gates to combine the DIR and
+ DOR outputs. They can also be connected in series to extend the
+ FIFO capacity, with DOR -> SI and /SO <- DIR.
**********************************************************************/
@@ -22,7 +31,7 @@
// DEVICE DEFINITIONS
//**************************************************************************
-const device_type CMOS_40105 = &device_creator<cmos_40105_device>;
+const device_type CD40105 = &device_creator<cmos_40105_device>;
@@ -34,10 +43,17 @@ const device_type CMOS_40105 = &device_creator<cmos_40105_device>;
// cmos_40105_device - constructor
//-------------------------------------------------
-cmos_40105_device::cmos_40105_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, CMOS_40105, "40105", tag, owner, clock, "40105", __FILE__),
+cmos_40105_device::cmos_40105_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, CD40105, "40105 FIFO", tag, owner, clock, "cd40105", __FILE__),
m_write_dir(*this),
- m_write_dor(*this), m_d(0), m_q(0), m_dir(0), m_dor(0), m_si(0), m_so(0)
+ m_write_dor(*this),
+ m_write_q(*this),
+ m_d(0),
+ m_q(0),
+ m_dir(false),
+ m_dor(false),
+ m_si(false),
+ m_so(false)
{
}
@@ -51,6 +67,7 @@ void cmos_40105_device::device_start()
// resolve callbacks
m_write_dir.resolve_safe();
m_write_dor.resolve_safe();
+ m_write_q.resolve_safe();
// state saving
save_item(NAME(m_d));
@@ -68,32 +85,32 @@ void cmos_40105_device::device_start()
void cmos_40105_device::device_reset()
{
- m_fifo = std::queue<uint8_t>();
-
- m_dir = 1;
- m_dor = 0;
- m_si = 0;
-
- m_write_dir(m_dir);
- m_write_dor(m_dor);
+ // invalidate data in queue
+ m_fifo = std::queue<u8>();
+
+ // reset control flip-flops
+ m_dir = true;
+ m_dor = false;
+ m_write_dir(1);
+ m_write_dor(0);
}
//-------------------------------------------------
-// read - read Q
+// read - read output buffer (Q0 to Q3)
//-------------------------------------------------
-uint8_t cmos_40105_device::read()
+u8 cmos_40105_device::read()
{
return m_q;
}
//-------------------------------------------------
-// write - write D
+// write - write input buffer (D0 to D3)
//-------------------------------------------------
-void cmos_40105_device::write(uint8_t data)
+void cmos_40105_device::write(u8 data)
{
m_d = data & 0x0f;
}
@@ -105,22 +122,24 @@ void cmos_40105_device::write(uint8_t data)
WRITE_LINE_MEMBER( cmos_40105_device::si_w )
{
+ // activate on rising edge when ready
if (m_dir && !m_si && state)
{
m_fifo.push(m_d);
+ // DIR remains low if FIFO is full, or else briefly pulses low
+ m_write_dir(0);
if (m_fifo.size() == 16)
- {
- m_dir = 0;
- m_write_dir(m_dir);
- }
+ m_dir = false;
+ else
+ m_write_dir(1);
+ // signal availability of propagated data
if (!m_dor)
{
- m_dor = 1;
- m_write_dor(m_dor);
+ m_dor = true;
+ m_write_dor(1);
}
-
}
m_si = state;
@@ -133,18 +152,25 @@ WRITE_LINE_MEMBER( cmos_40105_device::si_w )
WRITE_LINE_MEMBER( cmos_40105_device::so_w )
{
- if (m_dor && m_so && !m_so)
+ // activate on falling edge when ready
+ if (m_dor && m_so && !state)
{
- m_dor = 0;
- m_write_dor(m_dor);
-
m_q = m_fifo.front();
m_fifo.pop();
+ m_write_dor(0);
+ m_write_q(m_q);
+ // DOR remains low if FIFO is now empty, or else briefly pulses low
if (m_fifo.size() > 0)
+ m_write_dor(1);
+ else
+ m_dor = false;
+
+ // FIFO can no longer be full
+ if (!m_dir)
{
- m_dor = 1;
- m_write_dor(m_dor);
+ m_dir = true;
+ m_write_dir(1);
}
}