diff options
Diffstat (limited to 'src/devices/sound/aica.cpp')
-rw-r--r-- | src/devices/sound/aica.cpp | 77 |
1 files changed, 39 insertions, 38 deletions
diff --git a/src/devices/sound/aica.cpp b/src/devices/sound/aica.cpp index 597a52ad126..bb6cc9de495 100644 --- a/src/devices/sound/aica.cpp +++ b/src/devices/sound/aica.cpp @@ -14,9 +14,14 @@ - Some minor other tweeks (no EGHOLD, slighly more capable DSP) TODO: - - Convert I/O registers to space addresses; + - Convert I/O registers to space addresses; - Timebases are based on 44100KHz case? - - Derive from SCSP device; + - Derive from SCSP device; + - Sound clips a bit too much (cfr. deathcox, bdrdown, samba title screen, cfield). + According to skmp note: "The [ADX] sound decompression code on the sh4 uses FTRC + (float -> int) to convert the samples. Make sure you saturate the value when converting" + -> Verify this statement. + */ #include "emu.h" @@ -86,8 +91,8 @@ static constexpr s32 clip18(int x) { return std::clamp(x, -131072, 131071); } #define DISDL(slot) ((slot->udata.data[0x24 / 2] >> 0x8) & 0x000F) #define DIPAN(slot) (MONO() ? 0 : ((slot->udata.data[0x24 / 2] >> 0x0) & 0x001F)) -#define EFSDL(slot) ((m_EFSPAN[slot * 4] >> 8) & 0x000f) -#define EFPAN(slot) (MONO() ? 0 : ((m_EFSPAN[slot * 4] >> 0) & 0x001f)) +#define EFSDL(slot) ((m_EFSPAN[slot] >> 8) & 0x000f) +#define EFPAN(slot) (MONO() ? 0 : ((m_EFSPAN[slot] >> 0) & 0x001f)) //Unimplemented #define Q(slot) ((slot->udata.data[0x28 / 2] >> 0x0) & 0x001F) // (0.75 × register value - 3) @@ -439,9 +444,9 @@ void aica_device::Init() space().specific(m_DSP.space); space().cache(m_DSP.cache); - m_timerA = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(aica_device::timerA_cb), this)); - m_timerB = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(aica_device::timerB_cb), this)); - m_timerC = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(aica_device::timerC_cb), this)); + m_timerA = timer_alloc(FUNC(aica_device::timerA_cb), this); + m_timerB = timer_alloc(FUNC(aica_device::timerB_cb), this); + m_timerC = timer_alloc(FUNC(aica_device::timerC_cb), this); for (i = 0; i < 0x400; ++i) { @@ -657,7 +662,7 @@ void aica_device::UpdateReg(int reg) case 0x90: case 0x91: - if (!m_irq_cb.isnull()) + if (!m_irq_cb.isunset()) { u32 time; @@ -676,7 +681,7 @@ void aica_device::UpdateReg(int reg) break; case 0x94: case 0x95: - if (!m_irq_cb.isnull()) + if (!m_irq_cb.isunset()) { u32 time; @@ -695,7 +700,7 @@ void aica_device::UpdateReg(int reg) break; case 0x98: case 0x99: - if (!m_irq_cb.isnull()) + if (!m_irq_cb.isunset()) { u32 time; @@ -722,7 +727,7 @@ void aica_device::UpdateReg(int reg) case 0xa4: //SCIRE case 0xa5: - if (!m_irq_cb.isnull()) + if (!m_irq_cb.isunset()) { m_udata.data[0xa0 / 2] &= ~m_udata.data[0xa4 / 2]; ResetInterrupts(); @@ -749,7 +754,7 @@ void aica_device::UpdateReg(int reg) case 0xad: case 0xb0: case 0xb1: - if (!m_irq_cb.isnull()) + if (!m_irq_cb.isunset()) { m_IrqTimA = DecodeSCI(SCITMA); m_IrqTimBC = DecodeSCI(SCITMB); @@ -839,19 +844,10 @@ void aica_device::UpdateRegR(int reg) //m_stream->update(); int slotnum = MSLC(); AICA_SLOT *slot = m_Slots + slotnum; - u32 CA; - - if (PCMS(slot) == 0) // 16-bit samples - { - CA = (slot->cur_addr >> (SHIFT - 1)) & ~1; - } - else // 8-bit PCM and 4-bit ADPCM - { - CA = (slot->cur_addr >> SHIFT); - } - - //printf("%08x %08x\n",CA,slot->cur_addr & ~1); - + // NB: despite previous implementation this does not depend on PCMS setting. + // Was "CA = (slot->cur_addr >> (SHIFT - 1)) & ~1;" on 16-bit path, + // causing repeated samples/hangs in several ADX driven entries. + u32 CA = (slot->cur_addr >> SHIFT); m_udata.data[0x14 / 2] = CA; } break; @@ -878,7 +874,7 @@ void aica_device::w16(u32 addr,u16 val) if (addr <= 0x2044) { // printf("%x to EFSxx slot %d (addr %x)\n", val, (addr - 0x2000)/4, addr & 0x7f); - m_EFSPAN[addr & 0x7f] = val; + m_EFSPAN[(addr & 0x7f) >> 2] = val; } } else if (addr < 0x3000) @@ -918,7 +914,12 @@ void aica_device::w16(u32 addr,u16 val) else if (addr < 0x3300) *((u16 *)(m_DSP.MADRS+(addr - 0x3200) / 2)) = val; else if (addr < 0x3400) - popmessage("AICADSP write to undocumented reg %04x -> %04x", addr, val); + { + // 3300-fc zapped along with the full 0x3000-0x3bfc range, + // most likely done by the SDK for convenience in resetting DSP in one go. + if (val) + logerror("%s: AICADSP write to undocumented reg %04x -> %04x\n", machine().describe_context(), addr, val); + } else if (addr < 0x3c00) { *((u16 *)(m_DSP.MPRO+(addr - 0x3400) / 2)) = val; @@ -975,10 +976,12 @@ u16 aica_device::r16(u32 addr) { if (addr <= 0x2044) { - v = m_EFSPAN[addr & 0x7f]; + v = m_EFSPAN[(addr & 0x7f) >> 2]; } else if (addr < 0x2800) - popmessage("AICA read undocumented reg %04x", addr); + { + //logerror("%s: AICA read to undocumented reg %04x\n", machine().describe_context(), addr); + } else if (addr < 0x28be) { UpdateRegR(addr & 0xff); @@ -1001,11 +1004,15 @@ u16 aica_device::r16(u32 addr) else if (addr < 0x3300) v= *((u16 *)(m_DSP.MADRS+(addr - 0x3200) / 2)); else if (addr < 0x3400) - popmessage("AICADSP read undocumented reg %04x", addr); + { + //logerror("%s: AICADSP read to undocumented reg %04x\n", machine().describe_context(), addr); + } else if (addr < 0x3c00) v= *((u16 *)(m_DSP.MPRO+(addr - 0x3400) / 2)); else if (addr < 0x4000) - popmessage("AICADSP read undocumented reg %04x",addr); + { + //logerror("%s: AICADSP read to undocumented reg %04x\n", machine().describe_context(), addr); + } else if (addr < 0x4400) { if (addr & 4) @@ -1191,9 +1198,6 @@ s32 aica_device::UpdateSlot(AICA_SLOT *slot) } break; case 1: //normal loop - // TODO: loop mechanism causes hangs in Border Down/Metal Slug 6/Karous etc. - // - For mslug6 culprit RAM address is 0x13880 ARM side (a flag that should be zeroed somehow) - // - The lpend mechanism more or less works if the ARM CPU is downclocked at about 10%. if (*addr[addr_select] >= chanlea) { slot->lpend = 1; @@ -1296,6 +1300,7 @@ void aica_device::DoMasterSamples(std::vector<read_stream_view> const &inputs, w } bufl.put_int(s, smpl * m_LPANTABLE[MVOL() << 0xd], 32768 << SHIFT); + // TODO: diverges with SCSP, also wut? bufr.put_int(s, smpr * m_LPANTABLE[MVOL() << 0xd], 32768 << SHIFT); } } @@ -1399,10 +1404,6 @@ void aica_device::device_start() // init the emulation Init(); - // set up the IRQ callbacks - m_irq_cb.resolve_safe(); - m_main_irq_cb.resolve_safe(); - m_stream = stream_alloc(2, 2, (int)m_rate); // save state |