diff --git a/Source/Core/DSPCore/Src/DSPAccelerator.cpp b/Source/Core/DSPCore/Src/DSPAccelerator.cpp index 11ef81974a..fa61651df5 100644 --- a/Source/Core/DSPCore/Src/DSPAccelerator.cpp +++ b/Source/Core/DSPCore/Src/DSPAccelerator.cpp @@ -151,13 +151,9 @@ u16 dsp_read_accelerator() // TODO: Take GAIN into account, whatever it is. // adpcm = 0, pcm8 = 0x100, pcm16 = 0x800 - // games using pcm8 : Phoenix Wright Ace Attorney (Wiiware) + // games using pcm8 : Phoenix Wright Ace Attorney (Wiiware), Megaman 9-10 (WiiWare) if (g_dsp.ifx_regs[DSP_GAIN] > 0) { - // this was trial&error -> it fixes "Super Monkey Ball - Step & Roll" - // sth it wrong with exceptions here... - //DSPCore_SetException(EXP_3); - //NOTICE_LOG(DSPLLE,"format: 0x%04x - val: 0x%04x - gain: 0x%04x", g_dsp.ifx_regs[DSP_FORMAT], val, g_dsp.ifx_regs[DSP_GAIN]); } @@ -177,8 +173,10 @@ u16 dsp_read_accelerator() // so yeah, it seems likely that we should raise an exception to let // the DSP program do that, at least if DSP_FORMAT == 0x0A. } + //else + // DSPCore_SetException(EXP_6); // test! (bunch of NOPs there - helps "SMB S&R (wii)") g_dsp.ifx_regs[DSP_ACCAH] = Address >> 16; g_dsp.ifx_regs[DSP_ACCAL] = Address & 0xffff; - return(val); + return val; } diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp index dedf35ce2b..2400f27274 100644 --- a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp +++ b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp @@ -30,7 +30,7 @@ u8 code_flags[ISPACE]; // as well give up its time slice immediately, after executing once. // Max signature length is 6. A 0 in a signature is ignored. -#define NUM_IDLE_SIGS 5 +#define NUM_IDLE_SIGS 7 #define MAX_IDLE_SIG_SIZE 6 // 0xFFFF means ignore. @@ -53,7 +53,14 @@ const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = 0x03c0, 0x8000, // ANDCF $31, #0x8000 0x029c, 0xFFFF, // JLNZ 0x0280 0, 0 }, // RET - + { 0x26fc, // lrs $AC0.M, @DMBH + 0x02a0, 0x8000, // andf $AC0.M, #0x8000 + 0x029c, 0xFFFF, // jlnz 0x???? + 0, 0 }, + { 0x27fc, // lrs $AC1.M, @DMBH + 0x03a0, 0x8000, // andf $AC1.M, #0x8000 + 0x029c, 0xFFFF, // jlnz 0x???? + 0, 0 }, // From Zelda: { 0x00de, 0xFFFE, // LR $AC0.M, @CMBH 0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000 diff --git a/Source/Core/DSPCore/Src/DSPHWInterface.cpp b/Source/Core/DSPCore/Src/DSPHWInterface.cpp index 1761026403..12c8c3000a 100644 --- a/Source/Core/DSPCore/Src/DSPHWInterface.cpp +++ b/Source/Core/DSPCore/Src/DSPHWInterface.cpp @@ -165,7 +165,7 @@ void gdsp_ifx_write(u16 addr, u16 val) dsp_write_aram_d3(val); break; - case DSP_GAIN: // BMX XXX does, and sounds HORRIBLE. / Spyro - A Hero's Tail / Sega GC games / Wiiware - World of Goo + case DSP_GAIN: if (val) { INFO_LOG(DSPLLE,"Gain Written: 0x%04x", val); } diff --git a/Source/Core/DSPCore/Src/DSPIntExtOps.h b/Source/Core/DSPCore/Src/DSPIntExtOps.h index 09d4610cdf..9f6b713f90 100644 --- a/Source/Core/DSPCore/Src/DSPIntExtOps.h +++ b/Source/Core/DSPCore/Src/DSPIntExtOps.h @@ -29,10 +29,8 @@ #include "DSPTables.h" // Extended opcode support. -// Many opcode have the lower 0xFF free - there, an opcode extension -// can be stored. The ones that must be executed before the operation -// is handled as a prologue, the ones that must be executed afterwards -// is handled as an epilogue. +// Many opcode have the lower 0xFF (some only 0x7f) free - there, an opcode extension +// can be stored. namespace DSPInterpreter { diff --git a/Source/Core/DSPCore/Src/DSPInterpreter.cpp b/Source/Core/DSPCore/Src/DSPInterpreter.cpp index 5a892fc954..4b1ba16045 100644 --- a/Source/Core/DSPCore/Src/DSPInterpreter.cpp +++ b/Source/Core/DSPCore/Src/DSPInterpreter.cpp @@ -73,7 +73,6 @@ u16 ReadCR() void Step() { - //DSPCore_CheckExternalInterrupt(); DSPCore_CheckExceptions(); g_dsp.step_counter++; @@ -125,8 +124,7 @@ void Run() // This one has basic idle skipping, and checks breakpoints. int RunCyclesDebug(int cycles) { - // First, let's run a few cycles with no idle skipping so that things can - // progress a bit. + // First, let's run a few cycles with no idle skipping so that things can progress a bit. for (int i = 0; i < 8; i++) { if (g_dsp.cr & CR_HALT) @@ -144,39 +142,44 @@ int RunCyclesDebug(int cycles) DSPCore_CheckExternalInterrupt(); - // Now, let's run a few cycles with idle skipping. - for (int i = 0; i < 8; i++) + while (true) { - if (g_dsp.cr & CR_HALT) - return 0; - if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc)) + // Next, let's run a few cycles with idle skipping, so that we can skip + // idle loops. + for (int i = 0; i < 8; i++) { - DSPCore_SetState(DSPCORE_STEPPING); - return cycles; + if (g_dsp.cr & CR_HALT) + return 0; + if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc)) + { + DSPCore_SetState(DSPCORE_STEPPING); + return cycles; + } + // Idle skipping. + if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) + return 0; + Step(); + cycles--; + if (cycles < 0) + return 0; } - // Idle skipping. - if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) - return 0; - Step(); - cycles--; - if (cycles < 0) - return 0; - } - - // Finally, run the rest of the block without. - while (cycles > 0) - { - if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc)) + // Now, lets run some more without idle skipping. + for (int i = 0; i < 200; i++) { - DSPCore_SetState(DSPCORE_STEPPING); - return cycles; + if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc)) + { + DSPCore_SetState(DSPCORE_STEPPING); + return cycles; + } + Step(); + 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. } - Step(); - cycles--; } - - return cycles; } // Used by non-thread mode. Meant to be efficient. @@ -195,32 +198,34 @@ int RunCycles(int cycles) DSPCore_CheckExternalInterrupt(); - // Next, let's run a few cycles with idle skipping, so that we can skip - // idle loops. - for (int i = 0; i < 8; i++) + while (true) { - if (g_dsp.cr & CR_HALT) - return 0; - if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) - return 0; - Step(); - cycles--; - if (cycles < 0) - return 0; - } + // Next, let's run a few cycles with idle skipping, so that we can skip + // idle loops. + for (int i = 0; i < 8; i++) + { + if (g_dsp.cr & CR_HALT) + return 0; + // Idle skipping. + if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) + return 0; + Step(); + cycles--; + if (cycles < 0) + return 0; + } - // Now, run the rest of the block without idle skipping. It might trip into - // a idle loop and if so we waste some time here. Might be beneficial to - // slice even further. - while (cycles > 0) - { - Step(); - cycles--; - // We don't bother directly supporting pause - if the main emu pauses, - // it just won't call this function anymore. + // Now, lets run some more without idle skipping. + for (int i = 0; i < 200; i++) + { + Step(); + 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. + } } - - return cycles; } void Stop()