SPU: Check voice addresses on IRQ re-enable

NASCAR 2001 music depends on the IRQ firing multiple times, when the
voice address is still set to the IRQ address.
This commit is contained in:
Connor McLaughlin 2021-01-05 00:20:24 +10:00
parent e3262fc0a4
commit 73f6521452
2 changed files with 23 additions and 0 deletions

View file

@ -437,6 +437,10 @@ void SPU::WriteRegister(u32 offset, u16 value)
Log_DebugPrintf("SPU IRQ address register <- 0x%04X", ZeroExtend32(value));
m_tick_event->InvokeEarly();
m_irq_address = value;
if (m_SPUCNT.irq9_enable)
CheckForLateRAMIRQs();
return;
}
@ -445,6 +449,7 @@ void SPU::WriteRegister(u32 offset, u16 value)
Log_DebugPrintf("SPU transfer address register <- 0x%04X", ZeroExtend32(value));
m_transfer_address_reg = value;
m_transfer_address = ZeroExtend32(value) * 8;
CheckRAMIRQ(m_transfer_address);
return;
}
@ -489,6 +494,8 @@ void SPU::WriteRegister(u32 offset, u16 value)
if (!m_SPUCNT.irq9_enable)
m_SPUSTAT.irq9_flag = false;
else if (!m_SPUSTAT.irq9_flag)
CheckForLateRAMIRQs();
UpdateEventInterval();
UpdateDMARequest();
@ -691,6 +698,21 @@ void SPU::CheckRAMIRQ(u32 address)
}
}
void SPU::CheckForLateRAMIRQs()
{
for (u32 i = 0; i < NUM_VOICES && !m_SPUSTAT.irq9_flag; i++)
{
// we skip voices which haven't started this block yet - because they'll check
// the next time they're sampled, and the delay might be important.
const Voice& v = m_voices[i];
if (!v.has_samples)
continue;
CheckRAMIRQ(v.current_address * 8);
CheckRAMIRQ(v.current_address * 8 + 8);
}
}
void SPU::WriteToCaptureBuffer(u32 index, s16 value)
{
const u32 ram_address = (index * CAPTURE_BUFFER_SIZE_PER_CHANNEL) | ZeroExtend16(m_capture_buffer_position);

View file

@ -335,6 +335,7 @@ private:
void WriteVoiceRegister(u32 offset, u16 value);
void CheckRAMIRQ(u32 address);
void CheckForLateRAMIRQs();
void WriteToCaptureBuffer(u32 index, s16 value);
void IncrementCaptureBufferPosition();