// 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 //************************************************************************** // 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 //------------------------------------------------- void alpha_8921_device::clk_w(int state) { 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 //------------------------------------------------- void alpha_8921_device::load_w(int state) { m_load = state; } //------------------------------------------------- // even_w - Change EVEN pin status //------------------------------------------------- void alpha_8921_device::even_w(int state) { m_even = state; } //------------------------------------------------- // h_w - Change H pin status //------------------------------------------------- void alpha_8921_device::h_w(int state) { 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)) { if (m_h) { m_gbd = bitswap<4>(m_sr, 30, 22, 14, 6); m_gad = bitswap<4>(m_sr, 31, 23, 15, 7); } else { m_gbd = bitswap<4>(m_sr, 25, 17, 9, 1); m_gad = bitswap<4>(m_sr, 24, 16, 8, 0); } if (m_even) std::swap(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) //------------------------------------------------- int alpha_8921_device::dota_r() { update_output(); return m_dota; } //------------------------------------------------- // dotb_r - Read DOTB pin data (GBD isn't 0) //------------------------------------------------- int alpha_8921_device::dotb_r() { update_output(); return m_dotb; }