summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2010-10-17 20:15:40 +0000
committer R. Belmont <rb6502@users.noreply.github.com>2010-10-17 20:15:40 +0000
commit0d8e40acb6ee20a04d82b80aa38f48f4874cc1e1 (patch)
treef17d6fedff5aac988f12b249d4bd6ef06c74e554 /src/emu
parent1d4ea432e9770483e85cad69f765364344cc370e (diff)
ASC: sync with MESS improvements (no whatsnew)
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/sound/asc.c183
-rw-r--r--src/emu/sound/asc.h4
2 files changed, 90 insertions, 97 deletions
diff --git a/src/emu/sound/asc.c b/src/emu/sound/asc.c
index e16d100e362..4be28c40bef 100644
--- a/src/emu/sound/asc.c
+++ b/src/emu/sound/asc.c
@@ -4,7 +4,7 @@
Apple Sound Chip (ASC) 344S0063
Enhanced Apple Sound Chip (EASC) 343S1063
-
+
Emulation by R. Belmont
Registers:
@@ -18,8 +18,8 @@
0x807: CLOCK RATE (0 = Mac 22257 Hz, 1 = undefined, 2 = 22050 Hz, 3 = 44100 Hz)
0x80a: PLAY REC A
0x80f: TEST (bits 6-7 = digital test, bits 4-5 = analog test)
- 0x810: WAVETABLE 0 PHASE (big-endian 8.16 fixed-point, only 24 bits valid)
- 0x814: WAVETABLE 0 INCREMENT (big-endian 8.16 fixed-point, only 24 bits valid)
+ 0x810: WAVETABLE 0 PHASE (big-endian 9.15 fixed-point, only 24 bits valid)
+ 0x814: WAVETABLE 0 INCREMENT (big-endian 9.15 fixed-point, only 24 bits valid)
0x818: WAVETABLE 1 PHASE
0x81C: WAVETABLE 1 INCREMENT
0x820: WAVETABLE 2 PHASE
@@ -141,11 +141,10 @@ void asc_device::device_reset()
memset(m_fifo_b, 0, sizeof(m_fifo_b));
memset(m_phase, 0, sizeof(m_phase));
memset(m_incr, 0, sizeof(m_incr));
- memset(m_fifo_a_wrhalf, 0, sizeof(m_fifo_a_wrhalf));
- memset(m_fifo_b_wrhalf, 0, sizeof(m_fifo_b_wrhalf));
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;
}
//-------------------------------------------------
@@ -161,7 +160,7 @@ STREAM_UPDATE( asc_device::static_stream_generate )
void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
stream_sample_t *outL, *outR;
- int i, ch, halt = 0;
+ int i, ch;
static UINT32 wtoffs[2] = { 0, 0x200 };
outL = outputs[0];
@@ -177,62 +176,70 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
break;
case 1: // FIFO mode
- if ((m_fifo_a_rdptr == 0) && (!m_fifo_a_wrhalf[0]))
- {
- halt = 1;
- }
- else if ((m_fifo_a_rdptr == 0x200) && (!m_fifo_a_wrhalf[1]))
- {
- halt = 1;
- }
-
for (i = 0; i < samples; i++)
{
INT8 smpll, smplr;
- if (m_fifo_a_rdptr < 0x200)
+ smpll = (INT8)m_fifo_a[m_fifo_a_rdptr]^0x80;
+ smplr = (INT8)m_fifo_b[m_fifo_b_rdptr]^0x80;
+
+ // don't advance the sample pointer if there are no more samples
+ if (m_fifo_cap_a)
{
- m_fifo_a_wrhalf[0] = 0;
- m_fifo_b_wrhalf[0] = 0;
+ m_fifo_a_rdptr++;
+ m_fifo_a_rdptr &= 0x3ff;
+ m_fifo_cap_a--;
}
- else
+
+ if (m_fifo_cap_b)
{
- m_fifo_a_wrhalf[1] = 0;
- m_fifo_b_wrhalf[1] = 0;
+ m_fifo_b_rdptr++;
+ m_fifo_b_rdptr &= 0x3ff;
+ m_fifo_cap_b--;
}
- smpll = (INT8)m_fifo_a[m_fifo_a_rdptr++]^0x80;
- smplr = (INT8)m_fifo_b[m_fifo_b_rdptr++]^0x80;
-
- if ((m_fifo_a_rdptr == 0x200) || (m_fifo_a_rdptr == 0x400))
+ if ((m_fifo_cap_a) || (m_fifo_cap_b))
{
- m_regs[R_FIFOSTAT-0x800] |= 1; // fifo A half-empty
- if (m_irq_cb)
+ switch (m_chip_type)
{
- m_irq_cb(this, 1);
+ 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_irq_cb(this, 1);
+ }
+ }
+ break;
+
+ default:
+ if (m_fifo_cap_a <= 0x200)
+ {
+ m_regs[R_FIFOSTAT-0x800] |= 1; // fifo A half-empty
+ if (m_irq_cb)
+ {
+ m_irq_cb(this, 1);
+ }
+ }
+
+ // don't update for non-(E)ASC
+ if (m_fifo_cap_b <= 0x200)
+ {
+ m_regs[R_FIFOSTAT-0x800] |= 4; // fifo B half-empty
+ if (m_irq_cb)
+ {
+ m_irq_cb(this, 1);
+ }
+ }
+ break;
}
}
- if ((m_fifo_b_rdptr == 0x200) || (m_fifo_b_rdptr == 0x400))
- {
- m_regs[R_FIFOSTAT-0x800] |= 4; // fifo B half-empty
- if (m_irq_cb)
- {
- m_irq_cb(this, 1);
- }
- }
-
- m_fifo_a_rdptr &= 0x3ff;
- m_fifo_b_rdptr &= 0x3ff;
-
outL[i] = smpll * 64;
outR[i] = smplr * 64;
}
-
- if (halt)
- {
-// m_regs[R_MODE-0x800] = 0;
- }
break;
case 2: // wavetable mode
@@ -242,7 +249,7 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
INT8 smpl;
mixL = mixR = 0;
-
+
// update channel pointers
for (ch = 0; ch < 4; ch++)
{
@@ -250,11 +257,11 @@ void asc_device::stream_generate(stream_sample_t **inputs, stream_sample_t **out
if (ch < 2)
{
- smpl = (INT8)m_fifo_a[((m_phase[ch]>>16)&0x1ff) + wtoffs[ch&1]];
+ smpl = (INT8)m_fifo_a[((m_phase[ch]>>15)&0x1ff) + wtoffs[ch&1]];
}
else
{
- smpl = (INT8)m_fifo_b[((m_phase[ch]>>16)&0x1ff) + wtoffs[ch&1]];
+ smpl = (INT8)m_fifo_b[((m_phase[ch]>>15)&0x1ff) + wtoffs[ch&1]];
}
smpl ^= 0x80;
@@ -277,7 +284,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)
@@ -409,30 +416,18 @@ 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)
{
if (m_regs[R_MODE-0x800] == 1)
{
- if (m_fifo_a_wrptr < 0x400)
- {
- m_fifo_a_wrhalf[0] = 1;
- }
- else
- {
- m_fifo_a_wrhalf[1] = 1;
- }
-
m_fifo_a[m_fifo_a_wrptr++] = data;
+ m_fifo_cap_a++;
- if ((m_fifo_a_wrptr == 0x200) || (m_fifo_a_wrptr == 0x400))
+ if (m_fifo_cap_a == 0x800)
{
- m_regs[R_FIFOSTAT-0x800] |= 2; // fifo A half-full
- if (m_irq_cb)
- {
- m_irq_cb(this, 1);
- }
+ m_regs[R_FIFOSTAT-0x800] |= 2; // fifo A full
}
m_fifo_a_wrptr &= 0x3ff;
@@ -446,28 +441,16 @@ void asc_device::write(UINT16 offset, UINT8 data)
{
if (m_regs[R_MODE-0x800] == 1)
{
- if (m_fifo_b_wrptr < 0x400)
- {
- m_fifo_b_wrhalf[0] = 1;
- }
- else
- {
- m_fifo_b_wrhalf[1] = 1;
- }
-
m_fifo_b[m_fifo_b_wrptr++] = data;
+ m_fifo_cap_b++;
- if ((m_fifo_a_wrptr == 0x200) || (m_fifo_a_wrptr == 0x400))
+ if (m_fifo_cap_b == 0x800)
{
- m_regs[R_FIFOSTAT-0x800] |= 8; // fifo B half-full
- if (m_irq_cb)
- {
- m_irq_cb(this, 1);
- }
+ m_regs[R_FIFOSTAT-0x800] |= 8; // fifo B full
}
m_fifo_b_wrptr &= 0x3ff;
- }
+ }
else
{
m_fifo_b[offset-0x400] = data;
@@ -475,7 +458,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)
@@ -483,18 +466,28 @@ void asc_device::write(UINT16 offset, UINT8 data)
case R_MODE:
data &= 3; // only bits 0 and 1 can be written
- memset(m_fifo_a_wrhalf, 0, sizeof(m_fifo_a_wrhalf));
- memset(m_fifo_b_wrhalf, 0, sizeof(m_fifo_b_wrhalf));
+ if (data != m_regs[R_MODE-0x800])
+ {
+ 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;
+ }
+ break;
- m_fifo_a_rdptr = m_fifo_b_rdptr = 0;
- m_fifo_a_wrptr = m_fifo_b_wrptr = 0;
+ case R_FIFOMODE:
+ if (data & 0x80)
+ {
+ 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;
+ }
break;
case R_WTCONTROL:
-// printf("One-shot wavetable %02x\n", data);
+// printf("One-shot wavetable %02x\n", data);
break;
- case 0x811:
+ case 0x811:
m_phase[0] &= 0x00ffff;
m_phase[0] |= data<<16;
break;
@@ -509,7 +502,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[0] |= data;
break;
- case 0x815:
+ case 0x815:
m_incr[0] &= 0x00ffff;
m_incr[0] |= data<<16;
break;
@@ -524,7 +517,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_incr[0] |= data;
break;
- case 0x819:
+ case 0x819:
m_phase[1] &= 0x00ffff;
m_phase[1] |= data<<16;
break;
@@ -539,7 +532,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[1] |= data;
break;
- case 0x81d:
+ case 0x81d:
m_incr[1] &= 0x00ffff;
m_incr[1] |= data<<16;
break;
@@ -554,7 +547,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_incr[1] |= data;
break;
- case 0x821:
+ case 0x821:
m_phase[2] &= 0x00ffff;
m_phase[2] |= data<<16;
break;
@@ -569,7 +562,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[2] |= data;
break;
- case 0x825:
+ case 0x825:
m_incr[2] &= 0x00ffff;
m_incr[2] |= data<<16;
break;
@@ -584,7 +577,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_incr[2] |= data;
break;
- case 0x829:
+ case 0x829:
m_phase[3] &= 0x00ffff;
m_phase[3] |= data<<16;
break;
@@ -599,7 +592,7 @@ void asc_device::write(UINT16 offset, UINT8 data)
m_phase[3] |= data;
break;
- case 0x82d:
+ case 0x82d:
m_incr[3] &= 0x00ffff;
m_incr[3] |= data<<16;
break;
diff --git a/src/emu/sound/asc.h b/src/emu/sound/asc.h
index 11097596c1e..50fc6db9cfc 100644
--- a/src/emu/sound/asc.h
+++ b/src/emu/sound/asc.h
@@ -138,13 +138,13 @@ protected:
UINT8 m_fifo_a[0x400];
UINT8 m_fifo_b[0x400];
- UINT8 m_regs[0x100];
+ UINT8 m_regs[0x800];
UINT32 m_phase[4], m_incr[4];
int m_fifo_a_rdptr, m_fifo_b_rdptr;
int m_fifo_a_wrptr, m_fifo_b_wrptr;
- int m_fifo_a_wrhalf[2], m_fifo_b_wrhalf[2];
+ int m_fifo_cap_a, m_fifo_cap_b;
};