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.
// 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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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
{

View File

@ -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()