diff --git a/Source/Core/Core/Src/DSP/DSPCore.cpp b/Source/Core/Core/Src/DSP/DSPCore.cpp index 67c7cc6167..0d4ff5b962 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.cpp +++ b/Source/Core/Core/Src/DSP/DSPCore.cpp @@ -250,10 +250,6 @@ int DSPCore_RunCycles(int cycles) { if (dspjit) { - cyclesLeft = cycles; - DSPCompiledCode pExecAddr = (DSPCompiledCode)dspjit->enterDispatcher; - pExecAddr(); - if (g_dsp.external_interrupt_waiting) { DSPCore_CheckExternalInterrupt(); @@ -261,6 +257,10 @@ int DSPCore_RunCycles(int cycles) DSPCore_SetExternalInterrupt(false); } + cyclesLeft = cycles; + DSPCompiledCode pExecAddr = (DSPCompiledCode)dspjit->enterDispatcher; + pExecAddr(); + return cyclesLeft; } diff --git a/Source/Core/Core/Src/DSP/DSPEmitter.cpp b/Source/Core/Core/Src/DSP/DSPEmitter.cpp index ec14a0d30c..21b3307f4f 100644 --- a/Source/Core/Core/Src/DSP/DSPEmitter.cpp +++ b/Source/Core/Core/Src/DSP/DSPEmitter.cpp @@ -20,6 +20,7 @@ #include "DSPEmitter.h" #include "DSPMemoryMap.h" #include "DSPCore.h" +#include "DSPHost.h" #include "DSPInterpreter.h" #include "DSPAnalyzer.h" #include "Jit/DSPJitUtil.h" @@ -269,7 +270,7 @@ void DSPEmitter::Compile(u16 start_addr) DSPJitRegCache c(gpr); HandleLoop(); SaveDSPRegs(); - if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + if (!DSPHost_OnThread() && DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) { MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES)); } @@ -307,7 +308,7 @@ void DSPEmitter::Compile(u16 start_addr) DSPJitRegCache c(gpr); //don't update g_dsp.pc -- the branch insn already did SaveDSPRegs(); - if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + if (!DSPHost_OnThread() && DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) { MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES)); } @@ -373,7 +374,7 @@ void DSPEmitter::Compile(u16 start_addr) } SaveDSPRegs(); - if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + if (!DSPHost_OnThread() && DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) { MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES)); } @@ -401,6 +402,13 @@ void DSPEmitter::CompileDispatcher() const u8 *dispatcherLoop = GetCodePtr(); + FixupBranch exceptionExit; + if (DSPHost_OnThread()) + { + CMP(8, M(&g_dsp.external_interrupt_waiting), Imm8(0)); + exceptionExit = J_CC(CC_NE); + } + // Check for DSP halt #ifdef _M_IX86 TEST(8, M(&g_dsp.cr), Imm8(CR_HALT)); @@ -440,6 +448,10 @@ void DSPEmitter::CompileDispatcher() // DSP gave up the remaining cycles. SetJumpTarget(_halt); + if (DSPHost_OnThread()) + { + SetJumpTarget(exceptionExit); + } //MOV(32, M(&cyclesLeft), Imm32(0)); ABI_PopAllCalleeSavedRegsAndAdjustStack(); RET(); diff --git a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp index a2862affe3..5a78969de8 100644 --- a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp +++ b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp @@ -99,7 +99,12 @@ void gdsp_mbox_write_l(u8 mbx, u16 val) u16 gdsp_mbox_read_h(u8 mbx) { - return g_dsp.mbox[mbx][0]; // TODO: mask away the top bit? + if (DSPHost_OnThread()) + g_CriticalSection.Enter(); + u16 val = g_dsp.mbox[mbx][0]; // TODO: mask away the top bit? + if (DSPHost_OnThread()) + g_CriticalSection.Leave(); + return val; } diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp index 0183001be2..06a904dd62 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp @@ -86,12 +86,15 @@ void DSPLLE::dsp_thread(DSPLLE *lpParameter) { int cycles = (int)dsp_lle->m_cycle_count; if (cycles > 0) { - if (dspjit) + if (dspjit) + { DSPCore_RunCycles(cycles); + } else + { DSPInterpreter::RunCycles(cycles); - - Common::AtomicAdd(dsp_lle->m_cycle_count, -cycles); + } + Common::AtomicStore(dsp_lle->m_cycle_count, 0); } // yield? } @@ -261,8 +264,10 @@ void DSPLLE::DSP_WriteMailBoxLow(bool _CPUMailbox, u16 _uLowMail) void DSPLLE::DSP_Update(int cycles) { - unsigned int dsp_cycles = cycles / 6; //(jit?20:6); + int dsp_cycles = cycles / 6; + if (dsp_cycles <= 0) + return; // Sound stream update job has been handled by AudioDMA routine, which is more efficient /* // This gets called VERY OFTEN. The soundstream update might be expensive so only do it 200 times per second or something. @@ -289,10 +294,10 @@ void DSPLLE::DSP_Update(int cycles) } else { - // Wait for dsp thread to catch up reasonably. Note: this logic should be thought through. - while (m_cycle_count > dsp_cycles) + // Wait for dsp thread to complete its cycle. Note: this logic should be thought through. + while (m_cycle_count != 0) ; - Common::AtomicAdd(m_cycle_count, dsp_cycles); + Common::AtomicStore(m_cycle_count, dsp_cycles); } }