DSPLLE - idleskip-ing improved a little (it still fails totaly for zelda type games (exp7))

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5220 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Marko Pusljar 2010-03-22 13:46:00 +00:00
parent ef3a40c644
commit 11a215567b
5 changed files with 73 additions and 65 deletions

View File

@ -151,13 +151,9 @@ u16 dsp_read_accelerator()
// TODO: Take GAIN into account, whatever it is. // TODO: Take GAIN into account, whatever it is.
// adpcm = 0, pcm8 = 0x100, pcm16 = 0x800 // 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) 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]); //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 // so yeah, it seems likely that we should raise an exception to let
// the DSP program do that, at least if DSP_FORMAT == 0x0A. // 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_ACCAH] = Address >> 16;
g_dsp.ifx_regs[DSP_ACCAL] = Address & 0xffff; g_dsp.ifx_regs[DSP_ACCAL] = Address & 0xffff;
return(val); return val;
} }

View File

@ -30,7 +30,7 @@ u8 code_flags[ISPACE];
// as well give up its time slice immediately, after executing once. // as well give up its time slice immediately, after executing once.
// Max signature length is 6. A 0 in a signature is ignored. // 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 #define MAX_IDLE_SIG_SIZE 6
// 0xFFFF means ignore. // 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 0x03c0, 0x8000, // ANDCF $31, #0x8000
0x029c, 0xFFFF, // JLNZ 0x0280 0x029c, 0xFFFF, // JLNZ 0x0280
0, 0 }, // RET 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: // From Zelda:
{ 0x00de, 0xFFFE, // LR $AC0.M, @CMBH { 0x00de, 0xFFFE, // LR $AC0.M, @CMBH
0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000 0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000

View File

@ -165,7 +165,7 @@ void gdsp_ifx_write(u16 addr, u16 val)
dsp_write_aram_d3(val); dsp_write_aram_d3(val);
break; 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) { if (val) {
INFO_LOG(DSPLLE,"Gain Written: 0x%04x", val); INFO_LOG(DSPLLE,"Gain Written: 0x%04x", val);
} }

View File

@ -29,10 +29,8 @@
#include "DSPTables.h" #include "DSPTables.h"
// Extended opcode support. // Extended opcode support.
// Many opcode have the lower 0xFF free - there, an opcode extension // Many opcode have the lower 0xFF (some only 0x7f) free - there, an opcode extension
// can be stored. The ones that must be executed before the operation // can be stored.
// is handled as a prologue, the ones that must be executed afterwards
// is handled as an epilogue.
namespace DSPInterpreter namespace DSPInterpreter
{ {

View File

@ -73,7 +73,6 @@ u16 ReadCR()
void Step() void Step()
{ {
//DSPCore_CheckExternalInterrupt();
DSPCore_CheckExceptions(); DSPCore_CheckExceptions();
g_dsp.step_counter++; g_dsp.step_counter++;
@ -125,8 +124,7 @@ void Run()
// This one has basic idle skipping, and checks breakpoints. // This one has basic idle skipping, and checks breakpoints.
int RunCyclesDebug(int cycles) int RunCyclesDebug(int cycles)
{ {
// First, let's run a few cycles with no idle skipping so that things can // First, let's run a few cycles with no idle skipping so that things can progress a bit.
// progress a bit.
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
if (g_dsp.cr & CR_HALT) if (g_dsp.cr & CR_HALT)
@ -144,39 +142,44 @@ int RunCyclesDebug(int cycles)
DSPCore_CheckExternalInterrupt(); DSPCore_CheckExternalInterrupt();
// Now, let's run a few cycles with idle skipping. while (true)
for (int i = 0; i < 8; i++)
{ {
if (g_dsp.cr & CR_HALT) // Next, let's run a few cycles with idle skipping, so that we can skip
return 0; // idle loops.
if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc)) for (int i = 0; i < 8; i++)
{ {
DSPCore_SetState(DSPCORE_STEPPING); if (g_dsp.cr & CR_HALT)
return cycles; 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(); // Now, lets run some more without idle skipping.
cycles--; for (int i = 0; i < 200; i++)
if (cycles < 0)
return 0;
}
// Finally, run the rest of the block without.
while (cycles > 0)
{
if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc))
{ {
DSPCore_SetState(DSPCORE_STEPPING); if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc))
return cycles; {
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. // Used by non-thread mode. Meant to be efficient.
@ -195,32 +198,34 @@ int RunCycles(int cycles)
DSPCore_CheckExternalInterrupt(); DSPCore_CheckExternalInterrupt();
// Next, let's run a few cycles with idle skipping, so that we can skip while (true)
// idle loops.
for (int i = 0; i < 8; i++)
{ {
if (g_dsp.cr & CR_HALT) // Next, let's run a few cycles with idle skipping, so that we can skip
return 0; // idle loops.
if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) for (int i = 0; i < 8; i++)
return 0; {
Step(); if (g_dsp.cr & CR_HALT)
cycles--; return 0;
if (cycles < 0) // Idle skipping.
return 0; 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 // Now, lets run some more without idle skipping.
// a idle loop and if so we waste some time here. Might be beneficial to for (int i = 0; i < 200; i++)
// slice even further. {
while (cycles > 0) Step();
{ cycles--;
Step(); if (cycles < 0)
cycles--; return 0;
// We don't bother directly supporting pause - if the main emu pauses, // We don't bother directly supporting pause - if the main emu pauses,
// it just won't call this function anymore. // it just won't call this function anymore.
}
} }
return cycles;
} }
void Stop() void Stop()