mac: preliminary working but imperfect sound for maclc3 [R. Belmont]

This commit is contained in:
arbee 2018-01-27 14:19:40 -05:00
parent 20eedd9cf4
commit 87be177ec3

View File

@ -11,7 +11,7 @@
Registers:
0x800: VERSION
0x801: MODE (1=FIFO mode, 2=wavetable mode)
0x801: MODE (0=inactive, 1=FIFO mode, 2=wavetable mode)
0x802: CONTROL (bit 0=analog or PWM output, 1=stereo/mono, 7=processing time exceeded)
0x803: FIFO MODE (bit 7=clear FIFO, bit 1="non-ROM companding", bit 0="ROM companding")
0x804: FIFO IRQ STATUS (bit 0=ch A 1/2 full, 1=ch A full, 2=ch B 1/2 full, 3=ch B full)
@ -152,7 +152,14 @@ void asc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inp
int8_t smpll, smplr;
smpll = (int8_t)m_fifo_a[m_fifo_a_rdptr]^0x80;
smplr = (int8_t)m_fifo_b[m_fifo_b_rdptr]^0x80;
if ((m_chip_type <= asc_type::EASC) || (m_chip_type == asc_type::SONORA))
{
smplr = (int8_t)m_fifo_b[m_fifo_b_rdptr]^0x80;
}
else
{
smplr = smpll;
}
// don't advance the sample pointer if there are no more samples
if (m_fifo_cap_a)
@ -162,25 +169,18 @@ void asc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inp
m_fifo_cap_a--;
}
if (m_fifo_cap_b)
if ((m_fifo_cap_b) && ((m_chip_type <= asc_type::EASC) || (m_chip_type == asc_type::SONORA)))
{
m_fifo_b_rdptr++;
m_fifo_b_rdptr &= 0x3ff;
m_fifo_cap_b--;
}
//printf("chip updating: cap A %x cap B %x\n", m_fifo_cap_a, m_fifo_cap_b);
switch (m_chip_type)
{
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
write_irq(ASSERT_LINE);
}
break;
default:
case asc_type::ASC:
case asc_type::EASC:
if (m_fifo_cap_a == 0x1ff)
{
m_regs[R_FIFOSTAT-0x800] |= 1; // fifo A half-empty
@ -203,6 +203,33 @@ void asc_device::sound_stream_update(sound_stream &stream, stream_sample_t **inp
write_irq(ASSERT_LINE);
}
break;
default: // V8/Sonora/Eagle/etc
if (m_fifo_cap_a < 0x1ff)
{
m_regs[R_FIFOSTAT-0x800] |= 1; // fifo A less than half full
if (m_fifo_cap_a == 0) // fifo A fully empty
{
m_regs[R_FIFOSTAT-0x800] |= 2; // fifo A empty
}
write_irq(ASSERT_LINE);
}
if (m_chip_type == asc_type::SONORA)
{
if (m_fifo_cap_b < 0x1ff)
{
m_regs[R_FIFOSTAT-0x800] |= 4; // fifo B less than half full
if (m_fifo_cap_b == 0) // fifo B fully empty
{
m_regs[R_FIFOSTAT-0x800] |= 8; // fifo B empty
}
write_irq(ASSERT_LINE);
}
}
break;
}
outL[i] = smpll * 64;
@ -276,8 +303,10 @@ READ8_MEMBER( asc_device::read )
case asc_type::ASC:
return 0;
case asc_type::V8:
case asc_type::EAGLE:
return 0xe0;
case asc_type::V8:
case asc_type::SPICE:
case asc_type::VASP:
return 0xe8;
@ -297,6 +326,7 @@ READ8_MEMBER( asc_device::read )
case asc_type::EAGLE:
case asc_type::SPICE:
case asc_type::VASP:
case asc_type::SONORA:
return 1;
default:
@ -311,6 +341,7 @@ READ8_MEMBER( asc_device::read )
case asc_type::EAGLE:
case asc_type::SPICE:
case asc_type::VASP:
case asc_type::SONORA:
return 1;
default:
@ -319,18 +350,23 @@ READ8_MEMBER( asc_device::read )
break;
case R_FIFOSTAT:
if (m_chip_type == asc_type::V8)
switch (m_chip_type)
{
rv = 3;
}
else
{
rv = m_regs[R_FIFOSTAT-0x800];
case asc_type::V8:
case asc_type::EAGLE:
case asc_type::SPICE:
case asc_type::VASP:
rv = m_regs[R_FIFOSTAT-0x800] & 3;
break;
default:
rv = m_regs[R_FIFOSTAT-0x800];
break;
}
// printf("Read FIFO stat = %02x\n", rv);
//if (rv != 0) printf("Read FIFO stat = %02x\n", rv);
// reading this register clears all bits
// reading this register clears all bits (true also on V8/EAGLE?)
m_regs[R_FIFOSTAT-0x800] = 0;
// reading this clears interrupts
@ -389,7 +425,7 @@ READ8_MEMBER( asc_device::read )
WRITE8_MEMBER( asc_device::write )
{
// printf("ASC: write %02x to %x\n", data, offset);
//printf("ASC: write %02x to %x\n", data, offset);
if (offset < 0x400)
{
@ -439,6 +475,8 @@ WRITE8_MEMBER( asc_device::write )
case R_MODE:
data &= 3; // only bits 0 and 1 can be written
//printf("%d to MODE\n", data);
if (data != m_regs[R_MODE-0x800])
{
m_fifo_a_rdptr = m_fifo_b_rdptr = 0;
@ -462,6 +500,7 @@ WRITE8_MEMBER( asc_device::write )
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;
m_regs[R_FIFOSTAT-0x800] |= 0xa; // fifos A&B empty
}
break;