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

@ -4,7 +4,7 @@
Apple Sound Chip (ASC) 344S0063 Apple Sound Chip (ASC) 344S0063
Enhanced Apple Sound Chip (EASC) 343S1063 Enhanced Apple Sound Chip (EASC) 343S1063
Emulation by R. Belmont Emulation by R. Belmont
Registers: Registers:
@ -101,6 +101,14 @@ device_t *asc_device_config::alloc_device(running_machine &machine) const
// LIVE DEVICE // 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 // asc_device - constructor
//------------------------------------------------- //-------------------------------------------------
@ -125,6 +133,8 @@ void asc_device::device_start()
m_stream = stream_create(this, 0, 2, 22257, this, static_stream_generate); m_stream = stream_create(this, 0, 2, 22257, this, static_stream_generate);
memset(m_regs, 0, sizeof(m_regs)); memset(m_regs, 0, sizeof(m_regs));
m_sync_timer = timer_alloc(this->machine, sync_timer_cb, this);
} }
@ -190,7 +200,7 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
m_fifo_a_rdptr &= 0x3ff; m_fifo_a_rdptr &= 0x3ff;
m_fifo_cap_a--; m_fifo_cap_a--;
} }
if (m_fifo_cap_b) if (m_fifo_cap_b)
{ {
m_fifo_b_rdptr++; m_fifo_b_rdptr++;
@ -198,43 +208,55 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
m_fifo_cap_b--; 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_irq_cb(this, 1);
m_regs[R_FIFOSTAT-0x800] |= 0x8; // just pass the damn test
if (m_irq_cb)
{
m_irq_cb(this, 1);
}
} }
break; }
break;
default: default:
if (m_fifo_cap_a <= 0x200) 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 m_irq_cb(this, 1);
if (m_irq_cb)
{
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 == 0x1ff)
if (m_fifo_cap_b <= 0x200) {
m_regs[R_FIFOSTAT-0x800] |= 4; // fifo B half-empty
if (m_irq_cb)
{ {
m_regs[R_FIFOSTAT-0x800] |= 4; // fifo B half-empty m_irq_cb(this, 1);
if (m_irq_cb)
{
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; outL[i] = smpll * 64;
@ -249,7 +271,7 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
INT8 smpl; INT8 smpl;
mixL = mixR = 0; mixL = mixR = 0;
// update channel pointers // update channel pointers
for (ch = 0; ch < 4; ch++) for (ch = 0; ch < 4; ch++)
{ {
@ -274,6 +296,8 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
} }
break; 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; 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... // not sure what actually happens when the CPU reads the FIFO...
if (offset < 0x400) if (offset < 0x400)
@ -358,10 +382,12 @@ UINT8 asc_device::read(UINT16 offset)
rv = m_regs[R_FIFOSTAT-0x800]; rv = m_regs[R_FIFOSTAT-0x800];
} }
// printf("Read FIFO stat = %02x\n", rv);
// reading this register clears all bits // reading this register clears all bits
m_regs[R_FIFOSTAT-0x800] = 0; m_regs[R_FIFOSTAT-0x800] = 0;
// reading this clears interrupts? // reading this clears interrupts
if (m_irq_cb) if (m_irq_cb)
{ {
m_irq_cb(this, 0); m_irq_cb(this, 0);
@ -416,7 +442,7 @@ UINT8 asc_device::read(UINT16 offset)
void asc_device::write(UINT16 offset, UINT8 data) 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) 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_a[m_fifo_a_wrptr++] = data;
m_fifo_cap_a++; 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 m_regs[R_FIFOSTAT-0x800] |= 2; // fifo A full
} }
@ -444,13 +470,13 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_fifo_b[m_fifo_b_wrptr++] = data; m_fifo_b[m_fifo_b_wrptr++] = data;
m_fifo_cap_b++; 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 m_regs[R_FIFOSTAT-0x800] |= 8; // fifo B full
} }
m_fifo_b_wrptr &= 0x3ff; m_fifo_b_wrptr &= 0x3ff;
} }
else else
{ {
m_fifo_b[offset-0x400] = data; m_fifo_b[offset-0x400] = data;
@ -458,7 +484,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
} }
else 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); stream_update(m_stream);
switch (offset) 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_rdptr = m_fifo_b_rdptr = 0;
m_fifo_a_wrptr = m_fifo_b_wrptr = 0; m_fifo_a_wrptr = m_fifo_b_wrptr = 0;
m_fifo_cap_a = m_fifo_cap_b = 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; break;
@ -484,10 +519,10 @@ void asc_device::write(UINT16 offset, UINT8 data)
break; break;
case R_WTCONTROL: case R_WTCONTROL:
// printf("One-shot wavetable %02x\n", data); // printf("One-shot wavetable %02x\n", data);
break; break;
case 0x811: case 0x811:
m_phase[0] &= 0x00ffff; m_phase[0] &= 0x00ffff;
m_phase[0] |= data<<16; m_phase[0] |= data<<16;
break; break;
@ -502,7 +537,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[0] |= data; m_phase[0] |= data;
break; break;
case 0x815: case 0x815:
m_incr[0] &= 0x00ffff; m_incr[0] &= 0x00ffff;
m_incr[0] |= data<<16; m_incr[0] |= data<<16;
break; break;
@ -517,7 +552,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_incr[0] |= data; m_incr[0] |= data;
break; break;
case 0x819: case 0x819:
m_phase[1] &= 0x00ffff; m_phase[1] &= 0x00ffff;
m_phase[1] |= data<<16; m_phase[1] |= data<<16;
break; break;
@ -532,7 +567,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[1] |= data; m_phase[1] |= data;
break; break;
case 0x81d: case 0x81d:
m_incr[1] &= 0x00ffff; m_incr[1] &= 0x00ffff;
m_incr[1] |= data<<16; m_incr[1] |= data<<16;
break; break;
@ -547,7 +582,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_incr[1] |= data; m_incr[1] |= data;
break; break;
case 0x821: case 0x821:
m_phase[2] &= 0x00ffff; m_phase[2] &= 0x00ffff;
m_phase[2] |= data<<16; m_phase[2] |= data<<16;
break; break;
@ -562,7 +597,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[2] |= data; m_phase[2] |= data;
break; break;
case 0x825: case 0x825:
m_incr[2] &= 0x00ffff; m_incr[2] &= 0x00ffff;
m_incr[2] |= data<<16; m_incr[2] |= data<<16;
break; break;
@ -577,7 +612,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_incr[2] |= data; m_incr[2] |= data;
break; break;
case 0x829: case 0x829:
m_phase[3] &= 0x00ffff; m_phase[3] &= 0x00ffff;
m_phase[3] |= data<<16; m_phase[3] |= data<<16;
break; break;
@ -592,7 +627,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[3] |= data; m_phase[3] |= data;
break; break;
case 0x82d: case 0x82d:
m_incr[3] &= 0x00ffff; m_incr[3] &= 0x00ffff;
m_incr[3] |= data<<16; m_incr[3] |= data<<16;
break; break;

View File

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