From 29a9165acb671f6c4c79ee889dcb52d51cbb9c24 Mon Sep 17 00:00:00 2001 From: AJR Date: Fri, 23 Dec 2016 09:46:18 -0500 Subject: [PATCH] Further attempts to improve accuracy of 40105 emulation (nw) --- src/devices/machine/40105.cpp | 87 ++++++++++++++++++------- src/devices/machine/40105.h | 8 ++- src/mame/machine/cedar_magnet_sound.cpp | 4 +- 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/src/devices/machine/40105.cpp b/src/devices/machine/40105.cpp index 981506b44b4..63db529d3bd 100644 --- a/src/devices/machine/40105.cpp +++ b/src/devices/machine/40105.cpp @@ -32,7 +32,7 @@ //************************************************************************** const device_type CD40105 = &device_creator; - +const device_type HC40105 = &device_creator; //************************************************************************** @@ -115,6 +115,54 @@ void cmos_40105_device::write(u8 data) m_d = data & 0x0f; } +WRITE8_MEMBER(cmos_40105_device::write) +{ + write(data); +} + + +//------------------------------------------------- +// load_input - load new data into FIFO +//------------------------------------------------- + +void cmos_40105_device::load_input() +{ + if (m_fifo.size() == 16) + { + logerror("Attempt to load data into full FIFO\n"); + return; + } + + 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 = false; + else + m_write_dir(1); +} + + +//------------------------------------------------- +// output_ready - place new data at output +//------------------------------------------------- + +void cmos_40105_device::output_ready() +{ + if (m_fifo.size() == 0) + { + logerror("Attempt to output data from empty FIFO\n"); + return; + } + + m_q = m_fifo.front(); + m_write_q(m_q); + + m_dor = true; + m_write_dor(1); +} + //------------------------------------------------- // si_w - shift in write @@ -122,24 +170,16 @@ void cmos_40105_device::write(u8 data) WRITE_LINE_MEMBER( cmos_40105_device::si_w ) { - // activate on rising edge when ready + // load input 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 = false; - else - m_write_dir(1); - - // signal availability of propagated data + load_input(); + } + else if (m_si && !state && m_fifo.size() > 0) + { + // data propagates through FIFO when SI goes low if (!m_dor) - { - m_dor = true; - m_write_dor(1); - } + output_ready(); } m_si = state; @@ -152,25 +192,26 @@ WRITE_LINE_MEMBER( cmos_40105_device::si_w ) WRITE_LINE_MEMBER( cmos_40105_device::so_w ) { - // activate on falling edge when ready + // shift out on falling edge when ready if (m_dor && m_so && !state) { - m_q = m_fifo.front(); m_fifo.pop(); + m_dor = false; 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; + output_ready(); - // FIFO can no longer be full if (!m_dir) { + // raise DIR since FIFO is no longer full m_dir = true; m_write_dir(1); + + // load new input immediately if SI is held high + if (m_si) + load_input(); } } diff --git a/src/devices/machine/40105.h b/src/devices/machine/40105.h index 7e4fe7dd370..47a8ce0b1ab 100644 --- a/src/devices/machine/40105.h +++ b/src/devices/machine/40105.h @@ -60,6 +60,7 @@ public: u8 read(); void write(u8 data); + DECLARE_WRITE8_MEMBER(write); DECLARE_WRITE_LINE_MEMBER( si_w ); DECLARE_WRITE_LINE_MEMBER( so_w ); @@ -73,6 +74,11 @@ protected: virtual void device_reset() override; private: + // private helpers + void load_input(); + void output_ready(); + + // callbacks devcb_write_line m_write_dir; devcb_write_line m_write_dor; devcb_write8 m_write_q; @@ -91,7 +97,7 @@ private: // device type definition extern const device_type CD40105; - +extern const device_type HC40105; #endif diff --git a/src/mame/machine/cedar_magnet_sound.cpp b/src/mame/machine/cedar_magnet_sound.cpp index a6db0b1cc90..d289c1ad200 100644 --- a/src/mame/machine/cedar_magnet_sound.cpp +++ b/src/mame/machine/cedar_magnet_sound.cpp @@ -79,9 +79,9 @@ WRITE8_MEMBER(cedar_magnet_sound_device::adpcm_fifo_w) // Z80 code first unpacks 8 bytes of ADPCM sample data into nibbles // and, upon receiving interrupt vector E6, fills FIFO at once using OTIR // 4-bit data is shifted out of the FIFO to the MSM5205 by another timer - m_fifo->si_w(0); m_fifo->write(data & 0x0f); // only low nibble is used here m_fifo->si_w(1); + m_fifo->si_w(0); } WRITE8_MEMBER(cedar_magnet_sound_device::ay0_porta_w) @@ -194,7 +194,7 @@ static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sound ) MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay1_porta_w)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) - MCFG_DEVICE_ADD("fifo", CD40105, 0) // HCF40105BE at IC13 + MCFG_DEVICE_ADD("fifo", HC40105, 0) // HCF40105BE at IC13 MCFG_40105_DATA_OUT_READY_CB(WRITELINE(cedar_magnet_sound_device, fifo_dor_w)) MCFG_40105_DATA_OUT_CB(DEVWRITELINE("adpcm", msm5205_device, data_w))