From 92064d1025c04765946d0038a021c9f22b215dc7 Mon Sep 17 00:00:00 2001 From: booto Date: Mon, 11 Aug 2014 02:02:18 +0800 Subject: [PATCH 1/3] DSP: Fixes behaviour for audio dmas of length 0 This behaviour was tested on a real (wii) console. --- Source/Core/Core/HW/DSP.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/HW/DSP.cpp b/Source/Core/Core/HW/DSP.cpp index 5cd14885e6..273e7ec76f 100644 --- a/Source/Core/Core/HW/DSP.cpp +++ b/Source/Core/Core/HW/DSP.cpp @@ -490,19 +490,19 @@ void UpdateAudioDMA() // Read audio at g_audioDMA.current_source_address in RAM and push onto an // external audio fifo in the emulator, to be mixed with the disc // streaming output. - g_audioDMA.remaining_blocks_count--; - g_audioDMA.current_source_address += 32; + + if (g_audioDMA.remaining_blocks_count != 0) + { + g_audioDMA.remaining_blocks_count--; + g_audioDMA.current_source_address += 32; + } if (g_audioDMA.remaining_blocks_count == 0) { g_audioDMA.current_source_address = g_audioDMA.SourceAddress; g_audioDMA.remaining_blocks_count = g_audioDMA.AudioDMAControl.NumBlocks; - if (g_audioDMA.AudioDMAControl.NumBlocks == 0) - { - g_audioDMA.AudioDMAControl.Enable = 0; - } - else + if (g_audioDMA.remaining_blocks_count != 0) { // We make the samples ready as soon as possible void *address = Memory::GetPointer(g_audioDMA.SourceAddress); From a4bc15e7ba42933c0727948a301b9d8ab98dc68d Mon Sep 17 00:00:00 2001 From: booto Date: Mon, 11 Aug 2014 02:04:08 +0800 Subject: [PATCH 2/3] DSP: Do updates to DSP interrupt bits asap This was being scheduled on the next possible event, which caused timing issues (in FFCC, AI interrupt would fire before DSP interrupt) --- Source/Core/Core/HW/DSP.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Core/Core/HW/DSP.cpp b/Source/Core/Core/HW/DSP.cpp index 273e7ec76f..01dce2e1b3 100644 --- a/Source/Core/Core/HW/DSP.cpp +++ b/Source/Core/Core/HW/DSP.cpp @@ -459,8 +459,7 @@ void GenerateDSPInterrupt(DSPInterruptType type, bool _bSet) // CALLED FROM DSP EMULATOR, POSSIBLY THREADED void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type, bool _bSet) { - CoreTiming::ScheduleEvent_Threadsafe( - 0, et_GenerateDSPInterrupt, type | (_bSet<<16)); + CoreTiming::ScheduleEvent_Threadsafe_Immediate(et_GenerateDSPInterrupt, type | (_bSet<<16)); CoreTiming::ForceExceptionCheck(100); } From adf2ae2ac912230f5f885d1eae8446c4bcca36c9 Mon Sep 17 00:00:00 2001 From: booto Date: Wed, 13 Aug 2014 00:20:13 +0800 Subject: [PATCH 3/3] DSP: Add minor delay to initial AIDMA interrupt When AIDMA begins, the first thing it does is load the source address and length into internal registers. It then triggers the AID interrupt. Some begin the AIDMA process without all the data necessary for the interrupt callback being set up already - they require a few more cycles to set it up (the delay between the DMA being set to begin and the interrupt firing). The value of this delay was approximated by tests on real hardware. --- Source/Core/Core/HW/DSP.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Core/Core/HW/DSP.cpp b/Source/Core/Core/HW/DSP.cpp index 01dce2e1b3..381b4203da 100644 --- a/Source/Core/Core/HW/DSP.cpp +++ b/Source/Core/Core/HW/DSP.cpp @@ -406,8 +406,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) // We make the samples ready as soon as possible void *address = Memory::GetPointer(g_audioDMA.SourceAddress); AudioCommon::SendAIBuffer((short*)address, g_audioDMA.AudioDMAControl.NumBlocks * 8); - - GenerateDSPInterrupt(DSP::INT_AID); + CoreTiming::ScheduleEvent_Threadsafe(80, et_GenerateDSPInterrupt, INT_AID | (1 << 16)); } }) );