summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/alpha_8921.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/alpha_8921.cpp')
-rw-r--r--src/devices/machine/alpha_8921.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/devices/machine/alpha_8921.cpp b/src/devices/machine/alpha_8921.cpp
new file mode 100644
index 00000000000..1157b061f28
--- /dev/null
+++ b/src/devices/machine/alpha_8921.cpp
@@ -0,0 +1,213 @@
+// license:BSD-3-Clause
+// copyright-holders:cam900
+/***************************************************************************
+
+ Alpha denshi ALPHA-8921 emulation
+
+ Also known as
+ SNK PRO-CT0
+ SNK-9201
+
+ This chip is sprite ROM data serializer, or optional security device.
+ used in some later 80s Alpha Denshi hardware(ex: Gang Wars),
+ Some early Neogeo MVS motherboards, AES cartridges.
+ also integrated in NEO-ZMC2, NEO-CMC.
+
+ reference: https://wiki.neogeodev.org/index.php?title=PRO-CT0
+
+***************************************************************************/
+
+#include "emu.h"
+#include "alpha_8921.h"
+#include <algorithm>
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// device type definition
+DEFINE_DEVICE_TYPE(ALPHA_8921, alpha_8921_device, "alpha_8921", "Alpha denshi ALPHA-8921")
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// alpha_8921_device - constructor
+//-------------------------------------------------
+
+alpha_8921_device::alpha_8921_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, ALPHA_8921, tag, owner, clock)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void alpha_8921_device::device_start()
+{
+ // save states
+ save_item(NAME(m_clk));
+ save_item(NAME(m_load));
+ save_item(NAME(m_even));
+ save_item(NAME(m_h));
+ save_item(NAME(m_c));
+ save_item(NAME(m_gad));
+ save_item(NAME(m_gbd));
+ save_item(NAME(m_dota));
+ save_item(NAME(m_dotb));
+ save_item(NAME(m_sr));
+ save_item(NAME(m_old_sr));
+ save_item(NAME(m_old_even));
+ save_item(NAME(m_old_h));
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void alpha_8921_device::device_reset()
+{
+ // force update outputs
+ m_old_sr = ~m_sr;
+ m_old_even = !m_even;
+ m_old_h = !m_h;
+ update_output();
+}
+
+
+//**************************************************************************
+// READ/WRITE HANDLERS
+//**************************************************************************
+
+//-------------------------------------------------
+// clk_w - Change clock pin status
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER(alpha_8921_device::clk_w)
+{
+ if (m_clk != state)
+ {
+ m_clk = state;
+ if (!m_clk) // falling edge
+ {
+ if (m_load)
+ m_sr = m_c;
+ else if (m_h)
+ m_sr = (BIT(m_sr, 24, 6) << 26) | (BIT(m_sr, 16, 6) << 18) | (BIT(m_sr, 8, 6) << 10) | (BIT(m_sr, 0, 6) << 2);
+ else
+ m_sr = ((BIT(m_sr, 26, 6)) << 24) | ((BIT(m_sr, 18, 6)) << 16) | ((BIT(m_sr, 10, 6)) << 8) | (BIT(m_sr, 2, 6));
+ }
+ }
+}
+
+//-------------------------------------------------
+// load_w - Change LOAD pin status
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER(alpha_8921_device::load_w)
+{
+ m_load = state;
+}
+
+//-------------------------------------------------
+// even_w - Change EVEN pin status
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER(alpha_8921_device::even_w)
+{
+ m_even = state;
+}
+
+//-------------------------------------------------
+// h_w - Change H pin status
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER(alpha_8921_device::h_w)
+{
+ m_h = state;
+}
+
+//-------------------------------------------------
+// c_w - Change C data
+//-------------------------------------------------
+
+void alpha_8921_device::c_w(u32 data)
+{
+ m_c = data;
+}
+
+//-------------------------------------------------
+// update_output - Update output results
+//-------------------------------------------------
+
+void alpha_8921_device::update_output()
+{
+ if ((m_old_sr != m_sr) || (m_old_even != m_even) || (m_old_h != m_h))
+ {
+ switch (m_h)
+ {
+ case 1:
+ m_gbd = bitswap<4>(m_sr, 30, 22, 14, 6);
+ m_gad = bitswap<4>(m_sr, 31, 23, 15, 7);
+ break;
+ case 0:
+ m_gbd = bitswap<4>(m_sr, 25, 17, 9, 1);
+ m_gad = bitswap<4>(m_sr, 24, 16, 8, 0);
+ break;
+ }
+ if (m_even)
+ std::swap<u8>(m_gad, m_gbd);
+
+ m_dota = m_gad ? true : false;
+ m_dotb = m_gbd ? true : false;
+ m_old_sr = m_sr;
+ m_old_even = m_even;
+ m_old_h = m_h;
+ }
+}
+
+//-------------------------------------------------
+// gad_r - Read GAD data
+//-------------------------------------------------
+
+u8 alpha_8921_device::gad_r()
+{
+ update_output();
+ return m_gad & 0xf;
+}
+
+//-------------------------------------------------
+// gbd_r - Read GBD data
+//-------------------------------------------------
+
+u8 alpha_8921_device::gbd_r()
+{
+ update_output();
+ return m_gbd & 0xf;
+}
+
+//-------------------------------------------------
+// dota_r - Read DOTA pin data (GAD isn't 0)
+//-------------------------------------------------
+
+READ_LINE_MEMBER(alpha_8921_device::dota_r)
+{
+ update_output();
+ return m_dota;
+}
+
+//-------------------------------------------------
+// dotb_r - Read DOTB pin data (GBD isn't 0)
+//-------------------------------------------------
+
+READ_LINE_MEMBER(alpha_8921_device::dotb_r)
+{
+ update_output();
+ return m_dotb;
+}