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 HC40105 = &device_creator<cmos_40105_device>;
//**************************************************************************
@ -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();
}
}

View File

@ -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

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
// 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))