Sync latest ASC from MESS (no whatsnew)

This commit is contained in:
R. Belmont 2010-10-22 02:58:17 +00:00
parent f661970a4a
commit a2df0152ab
2 changed files with 86 additions and 48 deletions

View File

@ -101,6 +101,14 @@ device_t *asc_device_config::alloc_device(running_machine &machine) const
// LIVE DEVICE
//**************************************************************************
// does nothing, this timer exists only to make MAME sync itself at our audio rate
static TIMER_CALLBACK( sync_timer_cb )
{
asc_device *pDevice = (asc_device *)ptr;
stream_update(pDevice->m_stream);
}
//-------------------------------------------------
// asc_device - constructor
//-------------------------------------------------
@ -125,6 +133,8 @@ void asc_device::device_start()
m_stream = stream_create(this, 0, 2, 22257, this, static_stream_generate);
memset(m_regs, 0, sizeof(m_regs));
m_sync_timer = timer_alloc(this->machine, sync_timer_cb, this);
}
@ -198,43 +208,55 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
m_fifo_cap_b--;
}
if ((m_fifo_cap_a) || (m_fifo_cap_b))
switch (m_chip_type)
{
switch (m_chip_type)
{
case ASC_TYPE_SONORA:
if (m_fifo_cap_a <= 0x200)
case ASC_TYPE_SONORA:
if (m_fifo_cap_a < 0x200)
{
m_regs[R_FIFOSTAT-0x800] |= 0x4; // fifo less than half full
m_regs[R_FIFOSTAT-0x800] |= 0x8; // just pass the damn test
if (m_irq_cb)
{
m_regs[R_FIFOSTAT-0x800] |= 0x4; // fifo less than half full
m_regs[R_FIFOSTAT-0x800] |= 0x8; // just pass the damn test
if (m_irq_cb)
{
m_irq_cb(this, 1);
}
m_irq_cb(this, 1);
}
break;
}
break;
default:
if (m_fifo_cap_a <= 0x200)
default:
if (m_fifo_cap_a == 0x1ff)
{
m_regs[R_FIFOSTAT-0x800] |= 1; // fifo A half-empty
if (m_irq_cb)
{
m_regs[R_FIFOSTAT-0x800] |= 1; // fifo A half-empty
if (m_irq_cb)
{
m_irq_cb(this, 1);
}
m_irq_cb(this, 1);
}
}
else if (m_fifo_cap_a == 0x1) // fifo A fully empty
{
m_regs[R_FIFOSTAT-0x800] |= 2; // fifo A empty
if (m_irq_cb)
{
m_irq_cb(this, 1);
}
}
// don't update for non-(E)ASC
if (m_fifo_cap_b <= 0x200)
if (m_fifo_cap_b == 0x1ff)
{
m_regs[R_FIFOSTAT-0x800] |= 4; // fifo B half-empty
if (m_irq_cb)
{
m_regs[R_FIFOSTAT-0x800] |= 4; // fifo B half-empty
if (m_irq_cb)
{
m_irq_cb(this, 1);
}
m_irq_cb(this, 1);
}
break;
}
}
else if (m_fifo_cap_b == 0x1) // fifo B fully empty
{
m_regs[R_FIFOSTAT-0x800] |= 8; // fifo B empty
if (m_irq_cb)
{
m_irq_cb(this, 1);
}
}
break;
}
outL[i] = smpll * 64;
@ -274,6 +296,8 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
}
break;
}
// printf("rdA %04x rdB %04x wrA %04x wrB %04x (capA %04x B %04x)\n", m_fifo_a_rdptr, m_fifo_b_rdptr, m_fifo_a_wrptr, m_fifo_b_wrptr, m_fifo_cap_a, m_fifo_cap_b);
}
//-------------------------------------------------
@ -284,7 +308,7 @@ UINT8 asc_device::read(UINT16 offset)
{
UINT8 rv;
// printf("ASC: read at %x\n", offset);
// printf("ASC: read at %x\n", offset);
// not sure what actually happens when the CPU reads the FIFO...
if (offset < 0x400)
@ -358,10 +382,12 @@ UINT8 asc_device::read(UINT16 offset)
rv = m_regs[R_FIFOSTAT-0x800];
}
// printf("Read FIFO stat = %02x\n", rv);
// reading this register clears all bits
m_regs[R_FIFOSTAT-0x800] = 0;
// reading this clears interrupts?
// reading this clears interrupts
if (m_irq_cb)
{
m_irq_cb(this, 0);
@ -416,7 +442,7 @@ UINT8 asc_device::read(UINT16 offset)
void asc_device::write(UINT16 offset, UINT8 data)
{
// printf("ASC: write %02x to %x\n", data, offset);
// printf("ASC: write %02x to %x\n", data, offset);
if (offset < 0x400)
{
@ -425,7 +451,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_fifo_a[m_fifo_a_wrptr++] = data;
m_fifo_cap_a++;
if (m_fifo_cap_a == 0x800)
if (m_fifo_cap_a == 0x3ff)
{
m_regs[R_FIFOSTAT-0x800] |= 2; // fifo A full
}
@ -444,7 +470,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_fifo_b[m_fifo_b_wrptr++] = data;
m_fifo_cap_b++;
if (m_fifo_cap_b == 0x800)
if (m_fifo_cap_b == 0x3ff)
{
m_regs[R_FIFOSTAT-0x800] |= 8; // fifo B full
}
@ -458,7 +484,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
}
else
{
// printf("ASC: %02x to %x (was %x)\n", data, offset, m_regs[offset-0x800]);
// printf("ASC: %02x to %x (was %x)\n", data, offset, m_regs[offset-0x800]);
stream_update(m_stream);
switch (offset)
@ -471,6 +497,15 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_fifo_a_rdptr = m_fifo_b_rdptr = 0;
m_fifo_a_wrptr = m_fifo_b_wrptr = 0;
m_fifo_cap_a = m_fifo_cap_b = 0;
if (data != 0)
{
timer_adjust_periodic(m_sync_timer, attotime_zero, 0, ATTOTIME_IN_HZ(22257/4));
}
else
{
timer_adjust_oneshot(m_sync_timer, attotime_never, 0);
}
}
break;
@ -484,7 +519,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
break;
case R_WTCONTROL:
// printf("One-shot wavetable %02x\n", data);
// printf("One-shot wavetable %02x\n", data);
break;
case 0x811:

View File

@ -99,6 +99,8 @@ public:
UINT8 read(UINT16 offset);
void write(UINT16 offset, UINT8 data);
sound_stream *m_stream;
protected:
enum
{
@ -133,7 +135,6 @@ protected:
UINT8 m_chip_type;
void (*m_irq_cb)(running_device *device, int state);
sound_stream *m_stream;
UINT8 m_fifo_a[0x400];
UINT8 m_fifo_b[0x400];
@ -145,6 +146,8 @@ protected:
int m_fifo_a_rdptr, m_fifo_b_rdptr;
int m_fifo_a_wrptr, m_fifo_b_wrptr;
int m_fifo_cap_a, m_fifo_cap_b;
emu_timer *m_sync_timer;
};