diff --git a/Source/Core/Core/Src/DSP/DSPCore.cpp b/Source/Core/Core/Src/DSP/DSPCore.cpp index 5085fb5f37..a0e2925082 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.cpp +++ b/Source/Core/Core/Src/DSP/DSPCore.cpp @@ -40,6 +40,7 @@ SDSP g_dsp; DSPBreakpoints dsp_breakpoints; DSPCoreState core_state = DSPCORE_STOP; u16 cyclesLeft = 0; +bool init_hax = false; DSPEmitter *dspjit = NULL; Common::Event step_event; diff --git a/Source/Core/Core/Src/DSP/DSPCore.h b/Source/Core/Core/Src/DSP/DSPCore.h index 44519c1f86..36991027b3 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.h +++ b/Source/Core/Core/Src/DSP/DSPCore.h @@ -266,6 +266,7 @@ extern SDSP g_dsp; extern DSPBreakpoints dsp_breakpoints; extern DSPEmitter *dspjit; extern u16 cyclesLeft; +extern bool init_hax; bool DSPCore_Init(const char *irom_filename, const char *coef_filename, bool bUsingJIT); diff --git a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp index 382d152d6c..14269090db 100644 --- a/Source/Core/Core/Src/DSP/DSPHWInterface.cpp +++ b/Source/Core/Core/Src/DSP/DSPHWInterface.cpp @@ -81,6 +81,11 @@ void gdsp_mbox_write_l(u8 mbx, u16 val) u16 gdsp_mbox_read_h(u8 mbx) { + if (init_hax && mbx) + { + return 0x8054; + } + return (u16)(Common::AtomicLoad(g_dsp.mbox[mbx]) >> 16); // TODO: mask away the top bit? } @@ -89,6 +94,13 @@ u16 gdsp_mbox_read_l(u8 mbx) const u32 value = Common::AtomicLoadAcquire(g_dsp.mbox[mbx]); Common::AtomicStoreRelease(g_dsp.mbox[mbx], value & ~0x80000000); + if (init_hax && mbx) + { + init_hax = false; + DSPCore_Reset(); + return 0x4348; + } + #if defined(_DEBUG) || defined(DEBUGFAST) if (mbx == GDSP_MBOX_DSP) { diff --git a/Source/Core/Core/Src/DSP/DSPInterpreter.cpp b/Source/Core/Core/Src/DSP/DSPInterpreter.cpp index 86e4c69dcf..8c3a59dbd9 100644 --- a/Source/Core/Core/Src/DSP/DSPInterpreter.cpp +++ b/Source/Core/Core/Src/DSP/DSPInterpreter.cpp @@ -42,17 +42,17 @@ void WriteCR(u16 val) // reset if (val & 1) { + INFO_LOG(DSPLLE,"DSP_CONTROL RESET"); DSPCore_Reset(); val &= ~1; } - // init - can reset and init be done at the same time? + // init else if (val == 4) { - // this looks like a hack! OSInitAudioSystem ucode - // should send this mail - not dsp core itself - // this doesnt work anymore - //gdsp_mbox_write_h(GDSP_MBOX_DSP, 0x8054); - //gdsp_mbox_write_l(GDSP_MBOX_DSP, 0x4348); + // HAX! + // OSInitAudioSystem ucode should send this mail - not dsp core itself + INFO_LOG(DSPLLE,"DSP_CONTROL INIT"); + init_hax = true; val |= 0x800; } @@ -103,32 +103,25 @@ void Step() } // Used by thread mode. -//void Run() -//{ -// int checkInterrupt = 0; -// gdsp_running = true; -// while (!(g_dsp.cr & CR_HALT) && gdsp_running) -// { -// if (jit) -// jit->RunForCycles(1); -// else { -// // Automatically let the other threads work if we're idle skipping -// if(DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) -// Common::YieldCPU(); -// -// Step(); -// -// // Turns out the less you check for external interrupts, the more -// // sound you hear, and it becomes slower -// checkInterrupt++; -// if(checkInterrupt == 500) { // <-- Arbitrary number. TODO: tweak -// DSPCore_CheckExternalInterrupt(); -// checkInterrupt = 0; -// } -// } -// } -// gdsp_running = false; -//} +int RunCyclesThread(int cycles) +{ + while (true) + { + if (g_dsp.cr & CR_HALT) + return 0; + + if (g_dsp.external_interrupt_waiting) + { + DSPCore_CheckExternalInterrupt(); + DSPCore_SetExternalInterrupt(false); + } + + Step(); + cycles--; + if (cycles < 0) + return 0; + } +} // This one has basic idle skipping, and checks breakpoints. int RunCyclesDebug(int cycles) @@ -149,14 +142,6 @@ int RunCyclesDebug(int cycles) return 0; } - // In thread mode, process external interrupts - if (g_dsp.external_interrupt_waiting) - { - DSPCore_CheckExternalInterrupt(); - DSPCore_CheckExceptions(); - DSPCore_SetExternalInterrupt(false); - } - while (true) { // Next, let's run a few cycles with idle skipping, so that we can skip @@ -191,7 +176,6 @@ int RunCyclesDebug(int cycles) cycles--; if (cycles < 0) return 0; - // We don't bother directly supporting pause - if the main emu pauses, // it just won't call this function anymore. } @@ -213,14 +197,6 @@ int RunCycles(int cycles) return 0; } - // In thread mode, process external interrupts - if (g_dsp.external_interrupt_waiting) - { - DSPCore_CheckExternalInterrupt(); - DSPCore_CheckExceptions(); - DSPCore_SetExternalInterrupt(false); - } - while (true) { // Next, let's run a few cycles with idle skipping, so that we can skip diff --git a/Source/Core/Core/Src/DSP/DSPInterpreter.h b/Source/Core/Core/Src/DSP/DSPInterpreter.h index af469cc3bb..916d43d8b4 100644 --- a/Source/Core/Core/Src/DSP/DSPInterpreter.h +++ b/Source/Core/Core/Src/DSP/DSPInterpreter.h @@ -25,7 +25,6 @@ namespace DSPInterpreter { void Step(); -void Run(); // See: DspIntBranch.cpp void HandleLoop(); @@ -33,6 +32,7 @@ void HandleLoop(); // If these simply return the same number of cycles as was passed into them, // chances are that the DSP is halted. // The difference between them is that the debug one obeys breakpoints. +int RunCyclesThread(int cycles); int RunCycles(int cycles); int RunCyclesDebug(int cycles); diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp index 3d82641143..8dd5b5040f 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp @@ -91,7 +91,7 @@ void DSPLLE::dsp_thread(DSPLLE *dsp_lle) } else { - DSPInterpreter::RunCycles(cycles); + DSPInterpreter::RunCyclesThread(cycles); } Common::AtomicStore(dsp_lle->m_cycle_count, 0); }