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.
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue