DSPLLE: Wrapping behaviour for single increments/decrements of address registers implemented. It made little/no difference as far as I can tell :P
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3129 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
2352cf0fed
commit
474f1343f7
|
@ -166,6 +166,8 @@ void halt(const UDSPInstruction& opc)
|
|||
// from register $R reaches zero. Each execution decrement counter. Register
|
||||
// $R remains unchanged. If register $R is set to zero at the beginning of loop
|
||||
// then looped instruction will not get executed.
|
||||
// Actually, this instruction simply prepares the loop stacks for the above.
|
||||
// The looping hardware takes care of the rest.
|
||||
void loop(const UDSPInstruction& opc)
|
||||
{
|
||||
u16 reg = opc.hex & 0x1f;
|
||||
|
@ -186,6 +188,8 @@ void loop(const UDSPInstruction& opc)
|
|||
// immediate value I reaches zero. Each execution decrement counter. If
|
||||
// immediate value I is set to zero at the beginning of loop then looped
|
||||
// instruction will not get executed.
|
||||
// Actually, this instruction simply prepares the loop stacks for the above.
|
||||
// The looping hardware takes care of the rest.
|
||||
void loopi(const UDSPInstruction& opc)
|
||||
{
|
||||
u16 cnt = opc.hex & 0xff;
|
||||
|
@ -295,7 +299,7 @@ void lrrd(const UDSPInstruction& opc)
|
|||
|
||||
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
|
||||
dsp_op_write_reg(dreg, val);
|
||||
g_dsp.r[sreg]--;
|
||||
dsp_decrement_addr_reg(sreg);
|
||||
}
|
||||
|
||||
// LRRI $D, @$S
|
||||
|
@ -310,8 +314,7 @@ void lrri(const UDSPInstruction& opc)
|
|||
|
||||
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
|
||||
dsp_op_write_reg(dreg, val);
|
||||
g_dsp.r[sreg]++;
|
||||
|
||||
dsp_increment_addr_reg(sreg);
|
||||
}
|
||||
|
||||
// LRRN $D, @$S
|
||||
|
@ -326,7 +329,7 @@ void lrrn(const UDSPInstruction& opc)
|
|||
|
||||
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
|
||||
dsp_op_write_reg(dreg, val);
|
||||
g_dsp.r[sreg] += g_dsp.r[sreg + 4];
|
||||
g_dsp.r[sreg] += g_dsp.r[DSP_REG_IX0 + sreg];
|
||||
}
|
||||
|
||||
// SRR @$D, $S
|
||||
|
@ -355,7 +358,7 @@ void srrd(const UDSPInstruction& opc)
|
|||
|
||||
u16 val = dsp_op_read_reg(sreg);
|
||||
dsp_dmem_write(g_dsp.r[dreg], val);
|
||||
g_dsp.r[dreg]--;
|
||||
dsp_decrement_addr_reg(dreg);
|
||||
}
|
||||
|
||||
// SRRI @$D, $S
|
||||
|
@ -370,7 +373,7 @@ void srri(const UDSPInstruction& opc)
|
|||
|
||||
u16 val = dsp_op_read_reg(sreg);
|
||||
dsp_dmem_write(g_dsp.r[dreg], val);
|
||||
g_dsp.r[dreg]++;
|
||||
dsp_increment_addr_reg(dreg);
|
||||
}
|
||||
|
||||
// SRRN @$D, $S
|
||||
|
@ -411,7 +414,7 @@ void ilrrd(const UDSPInstruction& opc)
|
|||
|
||||
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
|
||||
|
||||
g_dsp.r[reg]--;
|
||||
dsp_decrement_addr_reg(reg);
|
||||
}
|
||||
|
||||
// ILRRI $acD.m, @$S
|
||||
|
@ -425,7 +428,7 @@ void ilrri(const UDSPInstruction& opc)
|
|||
|
||||
g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]);
|
||||
|
||||
g_dsp.r[reg]++;
|
||||
dsp_increment_addr_reg(reg);
|
||||
}
|
||||
|
||||
// ILRRN $acD.m, @$arS
|
||||
|
@ -1385,30 +1388,20 @@ void asr(const UDSPInstruction& opc)
|
|||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
||||
// hcs give me this code!!
|
||||
// DAR $arD
|
||||
// DAR $arD ?
|
||||
// 0000 0000 0000 01dd
|
||||
// Decrement address register $arD.
|
||||
// More docs needed - the operation is really odd!
|
||||
void dar(const UDSPInstruction& opc)
|
||||
{
|
||||
int reg = opc.hex & 0x3;
|
||||
|
||||
g_dsp.r[reg]--; // TODO: Wrap properly.
|
||||
dsp_decrement_addr_reg(opc.hex & 0x3);
|
||||
}
|
||||
|
||||
|
||||
// hcs give me this code!!
|
||||
// IAR $arD
|
||||
// IAR $arD ?
|
||||
// 0000 0000 0000 10dd
|
||||
// Increment address register $arD.
|
||||
// More docs needed - the operation is really odd!
|
||||
void iar(const UDSPInstruction& opc)
|
||||
{
|
||||
int reg = opc.hex & 0x3;
|
||||
|
||||
g_dsp.r[reg]++; // TODO: Wrap properly according to the corresponding WR register.
|
||||
dsp_increment_addr_reg(opc.hex & 0x3);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
|
|
@ -50,18 +50,14 @@ namespace Ext
|
|||
// xxxx xxxx 0000 01rr
|
||||
// Decrement addressing register $arR.
|
||||
void dr(const UDSPInstruction& opc) {
|
||||
u8 reg = opc.hex & 0x3;
|
||||
|
||||
g_dsp.r[reg]--;
|
||||
dsp_decrement_addr_reg(opc.hex & 0x3);
|
||||
}
|
||||
|
||||
// IR $arR
|
||||
// xxxx xxxx 0000 10rr
|
||||
// Increment addressing register $arR.
|
||||
void ir(const UDSPInstruction& opc) {
|
||||
u8 reg = opc.hex & 0x3;
|
||||
|
||||
g_dsp.r[reg]++;
|
||||
dsp_increment_addr_reg(opc.hex & 0x3);
|
||||
}
|
||||
|
||||
// NR $arR
|
||||
|
@ -95,7 +91,7 @@ void s(const UDSPInstruction& opc)
|
|||
|
||||
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
|
||||
|
||||
g_dsp.r[dreg]++;
|
||||
dsp_increment_addr_reg(dreg);
|
||||
}
|
||||
|
||||
// SN @$D, $acD.l
|
||||
|
@ -124,7 +120,7 @@ void l(const UDSPInstruction& opc)
|
|||
u16 val = dsp_dmem_read(g_dsp.r[sreg]);
|
||||
g_dsp.r[dreg] = val;
|
||||
|
||||
g_dsp.r[sreg]++;
|
||||
dsp_increment_addr_reg(sreg);
|
||||
}
|
||||
|
||||
// LN axD.l, @$S
|
||||
|
@ -153,8 +149,8 @@ void ld(const UDSPInstruction& opc)
|
|||
g_dsp.r[dreg] = dsp_dmem_read(g_dsp.r[sreg]);
|
||||
g_dsp.r[rreg] = dsp_dmem_read(g_dsp.r[DSP_REG_AR3]);
|
||||
|
||||
g_dsp.r[sreg]++;
|
||||
g_dsp.r[DSP_REG_AR3]++;
|
||||
dsp_increment_addr_reg(sreg);
|
||||
dsp_increment_addr_reg(DSP_REG_AR3);
|
||||
}
|
||||
|
||||
// Not in duddie's doc
|
||||
|
@ -169,7 +165,7 @@ void ldn(const UDSPInstruction& opc)
|
|||
g_dsp.r[rreg] = dsp_dmem_read(g_dsp.r[DSP_REG_AR3]);
|
||||
|
||||
g_dsp.r[sreg] += g_dsp.r[sreg + DSP_REG_IX0];
|
||||
g_dsp.r[DSP_REG_AR3]++;
|
||||
dsp_increment_addr_reg(DSP_REG_AR3);
|
||||
}
|
||||
|
||||
// Not in duddie's doc
|
||||
|
@ -183,7 +179,7 @@ void ldm(const UDSPInstruction& opc)
|
|||
g_dsp.r[dreg] = dsp_dmem_read(g_dsp.r[sreg]);
|
||||
g_dsp.r[rreg] = dsp_dmem_read(g_dsp.r[DSP_REG_AR3]);
|
||||
|
||||
g_dsp.r[sreg]++;
|
||||
dsp_increment_addr_reg(sreg);
|
||||
g_dsp.r[DSP_REG_AR3] += g_dsp.r[DSP_REG_IX3];
|
||||
}
|
||||
|
||||
|
@ -215,11 +211,11 @@ void dsp_op_ext_r_epi(const UDSPInstruction& opc)
|
|||
break;
|
||||
|
||||
case 0x01: // DR
|
||||
g_dsp.r[reg]--;
|
||||
dsp_decrement_addr_reg(reg);
|
||||
break;
|
||||
|
||||
case 0x02: // IR
|
||||
g_dsp.r[reg]++;
|
||||
dsp_increment_addr_reg(reg);
|
||||
break;
|
||||
|
||||
case 0x03: // NR
|
||||
|
@ -251,7 +247,7 @@ void dsp_op_ext_s(const UDSPInstruction& opc)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_dsp.r[dreg]++; // S
|
||||
dsp_increment_addr_reg(dreg); // S
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,7 +266,7 @@ void dsp_op_ext_l(const UDSPInstruction& opc)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_dsp.r[sreg]++; // LS
|
||||
dsp_increment_addr_reg(sreg); // LS
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +282,7 @@ void dsp_op_ext_ls_pro(const UDSPInstruction& opc)
|
|||
}
|
||||
else // LS
|
||||
{
|
||||
g_dsp.r[0x03]++;
|
||||
dsp_increment_addr_reg(0x03);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -303,7 +299,7 @@ void dsp_op_ext_ls_epi(const UDSPInstruction& opc)
|
|||
}
|
||||
else // LS
|
||||
{
|
||||
g_dsp.r[0x00]++;
|
||||
dsp_increment_addr_reg(0x00);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +315,7 @@ void dsp_op_ext_sl_pro(const UDSPInstruction& opc)
|
|||
}
|
||||
else // SL
|
||||
{
|
||||
g_dsp.r[0x00]++;
|
||||
dsp_increment_addr_reg(0x00);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,7 +332,7 @@ void dsp_op_ext_sl_epi(const UDSPInstruction& opc)
|
|||
}
|
||||
else // SL
|
||||
{
|
||||
g_dsp.r[0x03]++;
|
||||
dsp_increment_addr_reg(0x03);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,7 +351,7 @@ void dsp_op_ext_ld(const UDSPInstruction& opc)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_dsp.r[sreg]++;
|
||||
dsp_increment_addr_reg(sreg);
|
||||
}
|
||||
|
||||
if (opc.hex & 0x08) // M
|
||||
|
@ -364,9 +360,8 @@ void dsp_op_ext_ld(const UDSPInstruction& opc)
|
|||
}
|
||||
else
|
||||
{
|
||||
g_dsp.r[0x03]++;
|
||||
dsp_increment_addr_reg(0x03);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,10 +38,9 @@ namespace DSPInterpreter {
|
|||
|
||||
volatile u32 gdsp_running;
|
||||
|
||||
|
||||
// Hm, should instructions that change CR use this? Probably not (but they
|
||||
// should call UpdateCachedCR())
|
||||
void gdsp_write_cr(u16 val)
|
||||
void WriteCR(u16 val)
|
||||
{
|
||||
// reset
|
||||
if (val & 0x0001)
|
||||
|
@ -55,9 +54,8 @@ void gdsp_write_cr(u16 val)
|
|||
g_dsp.cr = val;
|
||||
}
|
||||
|
||||
|
||||
// Hm, should instructions that read CR use this? (Probably not).
|
||||
u16 gdsp_read_cr()
|
||||
u16 ReadCR()
|
||||
{
|
||||
if (g_dsp.pc & 0x8000)
|
||||
{
|
||||
|
@ -71,8 +69,7 @@ u16 gdsp_read_cr()
|
|||
return g_dsp.cr;
|
||||
}
|
||||
|
||||
|
||||
void gdsp_handle_loop()
|
||||
void HandleLoop()
|
||||
{
|
||||
// Handle looping hardware.
|
||||
u16& rLoopCounter = g_dsp.r[DSP_REG_ST3];
|
||||
|
@ -100,7 +97,7 @@ void gdsp_handle_loop()
|
|||
}
|
||||
}
|
||||
|
||||
void gdsp_step()
|
||||
void Step()
|
||||
{
|
||||
gdsp_check_exceptions();
|
||||
|
||||
|
@ -123,11 +120,11 @@ void gdsp_step()
|
|||
|
||||
u16 opc = dsp_fetch_code();
|
||||
ExecuteInstruction(UDSPInstruction(opc));
|
||||
gdsp_handle_loop();
|
||||
HandleLoop();
|
||||
}
|
||||
|
||||
// Used by thread mode.
|
||||
void gdsp_run()
|
||||
void Run()
|
||||
{
|
||||
gdsp_running = true;
|
||||
while (!(g_dsp.cr & CR_HALT))
|
||||
|
@ -139,7 +136,7 @@ void gdsp_run()
|
|||
gdsp_check_external_int();
|
||||
// This number (500) is completely arbitrary. TODO: tweak.
|
||||
for (int i = 0; i < 500 && !(g_dsp.cr & CR_HALT); i++)
|
||||
gdsp_step();
|
||||
Step();
|
||||
|
||||
if (!gdsp_running)
|
||||
break;
|
||||
|
@ -148,7 +145,7 @@ void gdsp_run()
|
|||
}
|
||||
|
||||
// Used by non-thread mode.
|
||||
void gdsp_run_cycles(int cycles)
|
||||
void RunCycles(int cycles)
|
||||
{
|
||||
gdsp_check_external_int();
|
||||
|
||||
|
@ -157,7 +154,7 @@ void gdsp_run_cycles(int cycles)
|
|||
{
|
||||
if (g_dsp.cr & CR_HALT)
|
||||
return;
|
||||
gdsp_step();
|
||||
Step();
|
||||
cycles--;
|
||||
}
|
||||
|
||||
|
@ -168,7 +165,7 @@ void gdsp_run_cycles(int cycles)
|
|||
return;
|
||||
if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP)
|
||||
return;
|
||||
gdsp_step();
|
||||
Step();
|
||||
cycles--;
|
||||
}
|
||||
|
||||
|
@ -176,14 +173,14 @@ void gdsp_run_cycles(int cycles)
|
|||
// idle loop and if so we waste some time here. Might be beneficial to slice even further.
|
||||
while (cycles > 0)
|
||||
{
|
||||
gdsp_step();
|
||||
Step();
|
||||
cycles--;
|
||||
// We don't bother directly supporting pause - if the main emu pauses,
|
||||
// it just won't call this function anymore.
|
||||
}
|
||||
}
|
||||
|
||||
void gdsp_stop()
|
||||
void Stop()
|
||||
{
|
||||
gdsp_running = false;
|
||||
}
|
||||
|
|
|
@ -48,14 +48,13 @@
|
|||
namespace DSPInterpreter {
|
||||
|
||||
// steps through DSP code, returns false if error occured
|
||||
void gdsp_step();
|
||||
void gdsp_loop_step();
|
||||
void gdsp_run();
|
||||
void gdsp_run_cycles(int cycles);
|
||||
void gdsp_stop();
|
||||
void Step();
|
||||
void Run();
|
||||
void RunCycles(int cycles);
|
||||
void Stop();
|
||||
|
||||
void gdsp_write_cr(u16 val);
|
||||
u16 gdsp_read_cr();
|
||||
void WriteCR(u16 val);
|
||||
u16 ReadCR();
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -50,6 +50,39 @@ inline bool dsp_SR_is_flag_set(int flag)
|
|||
return (g_dsp.r[DSP_REG_SR] & (1 << flag)) != 0;
|
||||
}
|
||||
|
||||
|
||||
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125
|
||||
inline void dsp_decrement_addr_reg(int reg)
|
||||
{
|
||||
// This one was easy. increment is worse...
|
||||
if ((g_dsp.r[reg] & g_dsp.r[DSP_REG_WR0 + reg]) == 0)
|
||||
g_dsp.r[reg] |= g_dsp.r[DSP_REG_WR0 + reg];
|
||||
else
|
||||
g_dsp.r[reg]--;
|
||||
}
|
||||
|
||||
|
||||
// HORRIBLE UGLINESS, someone please fix.
|
||||
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125
|
||||
|
||||
inline u16 ToMask(u16 a)
|
||||
{
|
||||
a = a | (a >> 8);
|
||||
a = a | (a >> 4);
|
||||
a = a | (a >> 2);
|
||||
return a | (a >> 1);
|
||||
}
|
||||
|
||||
inline void dsp_increment_addr_reg(int reg)
|
||||
{
|
||||
u16 tmb = ToMask(g_dsp.r[DSP_REG_WR0 + reg]);
|
||||
if ((g_dsp.r[reg] & tmb) == tmb)
|
||||
g_dsp.r[reg] ^= g_dsp.r[DSP_REG_WR0 + reg];
|
||||
else
|
||||
g_dsp.r[reg]++;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// --- reg
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
|
|
@ -179,7 +179,7 @@ THREAD_RETURN dsp_thread(void* lpParameter)
|
|||
{
|
||||
while (bIsRunning)
|
||||
{
|
||||
DSPInterpreter::gdsp_run();
|
||||
DSPInterpreter::Run();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ void Initialize(void *init)
|
|||
|
||||
void DSP_StopSoundStream()
|
||||
{
|
||||
DSPInterpreter::gdsp_stop();
|
||||
DSPInterpreter::Stop();
|
||||
bIsRunning = false;
|
||||
if (g_dspInitialize.bOnThread)
|
||||
{
|
||||
|
@ -266,13 +266,13 @@ void Shutdown()
|
|||
|
||||
u16 DSP_WriteControlRegister(u16 _uFlag)
|
||||
{
|
||||
DSPInterpreter::gdsp_write_cr(_uFlag);
|
||||
return DSPInterpreter::gdsp_read_cr();
|
||||
DSPInterpreter::WriteCR(_uFlag);
|
||||
return DSPInterpreter::ReadCR();
|
||||
}
|
||||
|
||||
u16 DSP_ReadControlRegister()
|
||||
{
|
||||
return DSPInterpreter::gdsp_read_cr();
|
||||
return DSPInterpreter::ReadCR();
|
||||
}
|
||||
|
||||
u16 DSP_ReadMailboxHigh(bool _CPUMailbox)
|
||||
|
@ -343,7 +343,7 @@ void DSP_Update(int cycles)
|
|||
// If we're not on a thread, run cycles here.
|
||||
if (!g_dspInitialize.bOnThread)
|
||||
{
|
||||
DSPInterpreter::gdsp_run_cycles(cycles);
|
||||
DSPInterpreter::RunCycles(cycles);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue