diff options
author | 2010-10-17 20:15:40 +0000 | |
---|---|---|
committer | 2010-10-17 20:15:40 +0000 | |
commit | 0d8e40acb6ee20a04d82b80aa38f48f4874cc1e1 (patch) | |
tree | f17d6fedff5aac988f12b249d4bd6ef06c74e554 /src/emu | |
parent | 1d4ea432e9770483e85cad69f765364344cc370e (diff) |
ASC: sync with MESS improvements (no whatsnew)
Diffstat (limited to 'src/emu')
-rw-r--r-- | src/emu/sound/asc.c | 183 | ||||
-rw-r--r-- | src/emu/sound/asc.h | 4 |
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; }; |