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:
parent
ef3a40c644
commit
11a215567b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue