diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 106e2bd623..226ac660b4 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -213,6 +213,11 @@ static u16 g_AR_REFRESH; Common::PluginDSP *dsp_plugin; +static int dsp_slice = 0; +static bool dsp_is_lle = false; + +//time given to lle dsp on every read of the high bits in a mailbox +static const int DSP_MAIL_SLICE=12; void DoState(PointerWrap &p) { @@ -243,6 +248,10 @@ void GenerateDSPInterrupt_Wrapper(u64 userdata, int cyclesLate) void Init() { dsp_plugin = CPluginManager::GetInstance().GetDSP(); + PLUGIN_INFO DSPType; + dsp_plugin->GetInfo(DSPType); + std::string DSPName(DSPType.Name); + dsp_is_lle = (DSPName.find("LLE") != std::string::npos) || (DSPName.find("lle") != std::string::npos); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) { @@ -288,6 +297,10 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) { // DSP case DSP_MAIL_TO_DSP_HI: + if (dsp_slice > DSP_MAIL_SLICE && dsp_is_lle) { + CPluginManager::GetInstance().GetDSP()->DSP_Update(DSP_MAIL_SLICE); + dsp_slice -= DSP_MAIL_SLICE; + } _uReturnValue = dsp_plugin->DSP_ReadMailboxHigh(true); break; @@ -296,6 +309,10 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) break; case DSP_MAIL_FROM_DSP_HI: + if (dsp_slice > DSP_MAIL_SLICE && dsp_is_lle) { + CPluginManager::GetInstance().GetDSP()->DSP_Update(DSP_MAIL_SLICE); + dsp_slice -= DSP_MAIL_SLICE; + } _uReturnValue = dsp_plugin->DSP_ReadMailboxHigh(false); break; @@ -610,6 +627,19 @@ void GenerateDSPInterruptFromPlugin(DSPInterruptType type, bool _bSet) 0, et_GenerateDSPInterrupt, type | (_bSet<<16)); } +// called whenever SystemTimers thinks the dsp deserves a few more cycles +void UpdateDSPSlice(int cycles) { + if (dsp_is_lle) { + //use up the rest of the slice(if any) + CPluginManager::GetInstance().GetDSP()->DSP_Update(dsp_slice); + dsp_slice %= 6; + //note the new budget + dsp_slice += cycles; + } else { + CPluginManager::GetInstance().GetDSP()->DSP_Update(cycles); + } +} + // This happens at 4 khz, since 32 bytes at 4khz = 4 bytes at 32 khz (16bit stereo pcm) void UpdateAudioDMA() { diff --git a/Source/Core/Core/Src/HW/DSP.h b/Source/Core/Core/Src/HW/DSP.h index af5fb95e2e..0e501d6445 100644 --- a/Source/Core/Core/Src/HW/DSP.h +++ b/Source/Core/Core/Src/HW/DSP.h @@ -61,6 +61,7 @@ void WriteARAM(u8 value, u32 _uAddress); u8* GetARAMPtr(); void UpdateAudioDMA(); +void UpdateDSPSlice(int cycles); }// end of namespace DSP diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 82ad7ff6cb..41f4d0f275 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -158,7 +158,9 @@ void AICallback(u64 userdata, int cyclesLate) // DSP/CPU timeslicing. void DSPCallback(u64 userdata, int cyclesLate) { - CPluginManager::GetInstance().GetDSP()->DSP_Update(DSP_PERIOD + cyclesLate); + //splits up the cycle budget in case lle is used + //for hle, just gives all of the slice to hle + DSP::UpdateDSPSlice(DSP_PERIOD - cyclesLate); CoreTiming::ScheduleEvent(DSP_PERIOD - cyclesLate, et_DSP); }