Further attempts to improve accuracy of 40105 emulation (nw)

This commit is contained in:
AJR 2016-12-23 09:46:18 -05:00
parent 9537974530
commit 29a9165acb
3 changed files with 73 additions and 26 deletions

View File

@ -32,7 +32,7 @@
//************************************************************************** //**************************************************************************
const device_type CD40105 = &device_creator<cmos_40105_device>; const device_type CD40105 = &device_creator<cmos_40105_device>;
const device_type HC40105 = &device_creator<cmos_40105_device>;
//************************************************************************** //**************************************************************************
@ -115,6 +115,54 @@ void cmos_40105_device::write(u8 data)
m_d = data & 0x0f; 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 // si_w - shift in write
@ -122,24 +170,16 @@ void cmos_40105_device::write(u8 data)
WRITE_LINE_MEMBER( cmos_40105_device::si_w ) 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) if (m_dir && !m_si && state)
{ {
m_fifo.push(m_d); load_input();
}
// DIR remains low if FIFO is full, or else briefly pulses low else if (m_si && !state && m_fifo.size() > 0)
m_write_dir(0); {
if (m_fifo.size() == 16) // data propagates through FIFO when SI goes low
m_dir = false;
else
m_write_dir(1);
// signal availability of propagated data
if (!m_dor) if (!m_dor)
{ output_ready();
m_dor = true;
m_write_dor(1);
}
} }
m_si = state; m_si = state;
@ -152,25 +192,26 @@ WRITE_LINE_MEMBER( cmos_40105_device::si_w )
WRITE_LINE_MEMBER( cmos_40105_device::so_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) if (m_dor && m_so && !state)
{ {
m_q = m_fifo.front();
m_fifo.pop(); m_fifo.pop();
m_dor = false;
m_write_dor(0); m_write_dor(0);
m_write_q(m_q);
// DOR remains low if FIFO is now empty, or else briefly pulses low // DOR remains low if FIFO is now empty, or else briefly pulses low
if (m_fifo.size() > 0) if (m_fifo.size() > 0)
m_write_dor(1); output_ready();
else
m_dor = false;
// FIFO can no longer be full
if (!m_dir) if (!m_dir)
{ {
// raise DIR since FIFO is no longer full
m_dir = true; m_dir = true;
m_write_dir(1); m_write_dir(1);
// load new input immediately if SI is held high
if (m_si)
load_input();
} }
} }

View File

@ -60,6 +60,7 @@ public:
u8 read(); u8 read();
void write(u8 data); void write(u8 data);
DECLARE_WRITE8_MEMBER(write);
DECLARE_WRITE_LINE_MEMBER( si_w ); DECLARE_WRITE_LINE_MEMBER( si_w );
DECLARE_WRITE_LINE_MEMBER( so_w ); DECLARE_WRITE_LINE_MEMBER( so_w );
@ -73,6 +74,11 @@ protected:
virtual void device_reset() override; virtual void device_reset() override;
private: private:
// private helpers
void load_input();
void output_ready();
// callbacks
devcb_write_line m_write_dir; devcb_write_line m_write_dir;
devcb_write_line m_write_dor; devcb_write_line m_write_dor;
devcb_write8 m_write_q; devcb_write8 m_write_q;
@ -91,7 +97,7 @@ private:
// device type definition // device type definition
extern const device_type CD40105; extern const device_type CD40105;
extern const device_type HC40105;
#endif #endif

View File

@ -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 // Z80 code first unpacks 8 bytes of ADPCM sample data into nibbles
// and, upon receiving interrupt vector E6, fills FIFO at once using OTIR // 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 // 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->write(data & 0x0f); // only low nibble is used here
m_fifo->si_w(1); m_fifo->si_w(1);
m_fifo->si_w(0);
} }
WRITE8_MEMBER(cedar_magnet_sound_device::ay0_porta_w) 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_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay1_porta_w))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) 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_READY_CB(WRITELINE(cedar_magnet_sound_device, fifo_dor_w))
MCFG_40105_DATA_OUT_CB(DEVWRITELINE("adpcm", msm5205_device, data_w)) MCFG_40105_DATA_OUT_CB(DEVWRITELINE("adpcm", msm5205_device, data_w))