DSPLLE: sort of semi-working breakpoints and stepping, if you flip an #ifdef. more work to do, for some reason it gets very slow when you enable it atm

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3573 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-06-28 16:23:40 +00:00
parent b406203794
commit 04105baf4e
19 changed files with 841 additions and 774 deletions

View File

@ -24,7 +24,9 @@
====================================================================*/ ====================================================================*/
#include "Common.h" #include "Common.h"
#include "Thread.h"
#include "DSPCore.h" #include "DSPCore.h"
#include "DSPHost.h"
#include "DSPAnalyzer.h" #include "DSPAnalyzer.h"
#include "MemoryUtil.h" #include "MemoryUtil.h"
@ -33,6 +35,8 @@
SDSP g_dsp; SDSP g_dsp;
BreakPoints dsp_breakpoints; BreakPoints dsp_breakpoints;
DSPCoreState core_state = DSPCORE_RUNNING;
Common::Event step_event;
static bool LoadRom(const char *fname, int size_in_words, u16 *rom) static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
{ {
@ -118,11 +122,13 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename)
WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false);
DSPAnalyzer::Analyze(); DSPAnalyzer::Analyze();
step_event.Init();
return true; return true;
} }
void DSPCore_Shutdown() void DSPCore_Shutdown()
{ {
step_event.Shutdown();
FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE); FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE);
FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE); FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE);
FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE); FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE);
@ -184,3 +190,57 @@ void DSPCore_CheckExceptions()
} }
} }
} }
// Delegate to JIT (when it is written) or interpreter as appropriate.
// Handle state changes and stepping.
int DSPCore_RunCycles(int cycles)
{
while (cycles > 0) {
reswitch:
switch (core_state)
{
case DSPCORE_RUNNING:
#if 0 // Set to 1 to enable stepping
// Enable breakpoints
cycles = DSPInterpreter::RunCyclesDebug(cycles);
#else
//1: enter a fast runloop
cycles = DSPInterpreter::RunCycles(cycles);
#endif
break;
case DSPCORE_STEPPING:
step_event.Wait();
if (core_state != DSPCORE_STEPPING)
goto reswitch;
DSPInterpreter::Step();
cycles--;
DSPHost_UpdateDebugger();
break;
}
}
return cycles;
}
void DSPCore_SetState(DSPCoreState new_state)
{
core_state = new_state;
// kick the event, in case we are waiting
if (new_state == DSPCORE_RUNNING)
step_event.Set();
// Sleep(10);
DSPHost_UpdateDebugger();
}
DSPCoreState DSPCore_GetState()
{
return core_state;
}
void DSPCore_Step()
{
if (core_state == DSPCORE_STEPPING)
step_event.Set();
}

View File

@ -101,17 +101,35 @@
// Hardware registers address // Hardware registers address
#define DSP_REG_DSCR 0xffc9 // DSP DMA Control Reg #define DSP_COEF_A1_0 0xa0
#define DSP_REG_DSBL 0xffcb // DSP DMA Block Length
#define DSP_REG_DSPA 0xffcd // DSP DMA DMEM Address
#define DSP_REG_DSMAH 0xffce // DSP DMA Mem Address H
#define DSP_REG_DSMAL 0xffcf // DSP DMA Mem Address L
#define DSP_REG_DIRQ 0xfffb // DSP Irq Rest #define DSP_DSMAH 0xce
#define DSP_REG_DMBH 0xfffc // DSP Mailbox H #define DSP_DSMAL 0xcf
#define DSP_REG_DMBL 0xfffd // DSP Mailbox L #define DSP_DSCR 0xc9 // DSP DMA Control Reg
#define DSP_REG_CMBH 0xfffe // CPU Mailbox H #define DSP_DSPA 0xcd // DSP DMA Block Length
#define DSP_REG_CMBL 0xffff // CPU Mailbox L #define DSP_DSBL 0xcb // DSP DMA DMEM Address
#define DSP_DSMAH 0xce // DSP DMA Mem Address H
#define DSP_DSMAL 0xcf // DSP DMA Mem Address L
#define DSP_FORMAT 0xd1
#define DSP_ACDATA1 0xd3 // used only by Zelda ucodes
#define DSP_ACSAH 0xd4
#define DSP_ACSAL 0xd5
#define DSP_ACEAH 0xd6
#define DSP_ACEAL 0xd7
#define DSP_ACCAH 0xd8
#define DSP_ACCAL 0xd9
#define DSP_PRED_SCALE 0xda
#define DSP_YN1 0xdb
#define DSP_YN2 0xdc
#define DSP_ACCELERATOR 0xdd // ADPCM accelerator read. Used by AX.
#define DSP_GAIN 0xde
#define DSP_DIRQ 0xfb // DSP Irq Rest
#define DSP_DMBH 0xfc // DSP Mailbox H
#define DSP_DMBL 0xfd // DSP Mailbox L
#define DSP_CMBH 0xfe // CPU Mailbox H
#define DSP_CMBL 0xff // CPU Mailbox L
#define DMA_TO_DSP 0 #define DMA_TO_DSP 0
#define DMA_TO_CPU 1 #define DMA_TO_CPU 1
@ -125,6 +143,7 @@
#define CR_HALT 0x0004 #define CR_HALT 0x0004
#define CR_EXTERNAL_INT 0x0002 #define CR_EXTERNAL_INT 0x0002
// SR bits // SR bits
#define SR_CARRY 0x0001 #define SR_CARRY 0x0001
#define SR_2 0x0002 // overflow??? #define SR_2 0x0002 // overflow???
@ -194,4 +213,18 @@ void DSPCore_CheckExceptions();
// sets a flag in the pending exception register. // sets a flag in the pending exception register.
void DSPCore_SetException(u8 level); void DSPCore_SetException(u8 level);
enum DSPCoreState
{
DSPCORE_RUNNING = 0,
DSPCORE_STEPPING = 1,
};
int DSPCore_RunCycles(int cycles);
// These are meant to be called from the UI thread.
void DSPCore_SetState(DSPCoreState new_state);
DSPCoreState DSPCore_GetState();
void DSPCore_Step();
#endif // _DSPCORE_H #endif // _DSPCORE_H

View File

@ -36,7 +36,7 @@
#include "DSPInterpreter.h" #include "DSPInterpreter.h"
#include "DSPHWInterface.h" #include "DSPHWInterface.h"
void gdsp_dma(); void gdsp_do_dma();
Common::CriticalSection g_CriticalSection; Common::CriticalSection g_CriticalSection;
@ -137,7 +137,7 @@ void gdsp_ifx_write(u16 addr, u16 val)
case 0xcb: // DSBL case 0xcb: // DSBL
gdsp_ifx_regs[addr & 0xFF] = val; gdsp_ifx_regs[addr & 0xFF] = val;
gdsp_dma(); gdsp_do_dma();
gdsp_ifx_regs[DSP_DSCR] &= ~0x0004; gdsp_ifx_regs[DSP_DSCR] &= ~0x0004;
break; break;
@ -274,7 +274,7 @@ void gdsp_ddma_out(u16 dsp_addr, u32 addr, u32 size)
INFO_LOG(DSPLLE, "*** ddma_out DRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size); INFO_LOG(DSPLLE, "*** ddma_out DRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size);
} }
void gdsp_dma() void gdsp_do_dma()
{ {
u16 ctl; u16 ctl;
u32 addr; u32 addr;

View File

@ -30,26 +30,6 @@
#define GDSP_MBOX_CPU 0 #define GDSP_MBOX_CPU 0
#define GDSP_MBOX_DSP 1 #define GDSP_MBOX_DSP 1
#define DSP_DSMAH 0xce
#define DSP_DSMAL 0xcf
#define DSP_DSCR 0xc9
#define DSP_DSPA 0xcd
#define DSP_DSBL 0xcb
#define DSP_ACSAH 0xd4
#define DSP_ACSAL 0xd5
#define DSP_ACEAH 0xd6
#define DSP_ACEAL 0xd7
#define DSP_ACCAH 0xd8
#define DSP_ACCAL 0xd9
#define DSP_COEF_A1_0 0xa0
#define DSP_FORMAT 0xd1
#define DSP_PRED_SCALE 0xda
#define DSP_YN1 0xdb
#define DSP_YN2 0xdc
#define DSP_ARAM 0xdd
#define DSP_GAIN 0xde
extern u16 gdsp_ifx_regs[256]; extern u16 gdsp_ifx_regs[256];
u32 gdsp_mbox_peek(u8 mbx); u32 gdsp_mbox_peek(u8 mbx);

View File

@ -29,5 +29,6 @@ bool DSPHost_OnThread();
bool DSPHost_Running(); bool DSPHost_Running();
void DSPHost_InterruptRequest(); void DSPHost_InterruptRequest();
u32 DSPHost_CodeLoaded(const u8 *ptr, int size); u32 DSPHost_CodeLoaded(const u8 *ptr, int size);
void DSPHost_UpdateDebugger();
#endif #endif

View File

@ -32,12 +32,12 @@ void Update_SR_Register64(s64 _Value)
if (_Value < 0) if (_Value < 0)
{ {
g_dsp.r[DSP_REG_SR] |= 0x8; g_dsp.r[DSP_REG_SR] |= SR_SIGN;
} }
if (_Value == 0) if (_Value == 0)
{ {
g_dsp.r[DSP_REG_SR] |= 0x4; g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
} }
// weird // weird
@ -53,12 +53,12 @@ void Update_SR_Register16(s16 _Value)
if (_Value < 0) if (_Value < 0)
{ {
g_dsp.r[DSP_REG_SR] |= 0x8; g_dsp.r[DSP_REG_SR] |= SR_SIGN;
} }
if (_Value == 0) if (_Value == 0)
{ {
g_dsp.r[DSP_REG_SR] |= 0x4; g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
} }
// weird // weird
@ -90,92 +90,51 @@ int GetMultiplyModifier()
} }
inline bool isCarry() { inline bool isCarry() {
return (g_dsp.r[DSP_REG_SR] & 0x01) ? true : false; return (g_dsp.r[DSP_REG_SR] & SR_CARRY) ? true : false;
} }
inline bool isSign() { inline bool isSign() {
return ((g_dsp.r[DSP_REG_SR] & 0x02) != (g_dsp.r[DSP_REG_SR] & 0x08)); return ((g_dsp.r[DSP_REG_SR] & SR_2) != (g_dsp.r[DSP_REG_SR] & SR_SIGN));
} }
inline bool isZero() { inline bool isZero() {
return (g_dsp.r[DSP_REG_SR] & 0x04) ? true : false; return (g_dsp.r[DSP_REG_SR] & SR_ARITH_ZERO) ? true : false;
} }
//see gdsp_registers.h for flags //see gdsp_registers.h for flags
bool CheckCondition(u8 _Condition) bool CheckCondition(u8 _Condition)
{ {
bool taken = false;
switch (_Condition & 0xf) switch (_Condition & 0xf)
{ {
case 0x0: //NS - NOT SIGN case 0x0: //NS - NOT SIGN
if (! isSign()) return !isSign();
taken = true;
break;
case 0x1: // S - SIGN case 0x1: // S - SIGN
if (isSign()) return isSign();
taken = true;
break;
case 0x2: // G - GREATER case 0x2: // G - GREATER
if (! isSign() && !isZero()) return !isSign() && !isZero();
taken = true;
break;
case 0x3: // LE - LESS EQUAL case 0x3: // LE - LESS EQUAL
if (isSign() || isZero()) return isSign() || isZero();
taken = true;
break;
case 0x4: // NZ - NOT ZERO case 0x4: // NZ - NOT ZERO
return !isZero();
if (!isZero())
taken = true;
break;
case 0x5: // Z - ZERO case 0x5: // Z - ZERO
return isZero();
if (isZero())
taken = true;
break;
case 0x6: // L - LESS case 0x6: // L - LESS
// Should be that once we set 0x01 // Should be that once we set 0x01
if (!isCarry()) return !isCarry();
// if (isSign()) // if (isSign())
taken = true;
break;
case 0x7: // GE - GREATER EQUAL case 0x7: // GE - GREATER EQUAL
// Should be that once we set 0x01 // Should be that once we set 0x01
if (isCarry()) return isCarry();
// if (! isSign() || isZero()) // if (! isSign() || isZero())
taken = true;
break;
case 0xc: // LNZ - LOGIC NOT ZERO case 0xc: // LNZ - LOGIC NOT ZERO
return !(g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO);
if (!(g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO))
taken = true;
break;
case 0xd: // LZ - LOGIC ZERO case 0xd: // LZ - LOGIC ZERO
return (g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO) != 0;
if (g_dsp.r[DSP_REG_SR] & SR_LOGIC_ZERO) case 0xf: // Empty - always true.
taken = true; return true;
break;
case 0xf: // Empty
taken = true;
break;
default: default:
ERROR_LOG(DSPLLE, "Unknown condition check: 0x%04x\n", _Condition & 0xf); ERROR_LOG(DSPLLE, "Unknown condition check: 0x%04x\n", _Condition & 0xf);
break; return false;
} }
return taken;
} }
} // namespace } // namespace

View File

@ -32,7 +32,6 @@
#include "DSPCore.h" #include "DSPCore.h"
#include "DSPMemoryMap.h" #include "DSPMemoryMap.h"
#include "DSPStacks.h" #include "DSPStacks.h"
// #include "DSPIntExtOps.h"
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// --- SR // --- SR

View File

@ -71,8 +71,6 @@ u16 ReadCR()
return g_dsp.cr; return g_dsp.cr;
} }
void HandleLoop() void HandleLoop()
{ {
// Handle looping hardware. // Handle looping hardware.
@ -85,6 +83,7 @@ void HandleLoop()
// This does not always work correctly! // This does not always work correctly!
// The loop end tends to point to the second part of // The loop end tends to point to the second part of
// two-byte instructions! // two-byte instructions!
// 0179 1104 019f bloopi #0x04, 0x019f in zelda, for example
if (g_dsp.pc == (rLoopAddress + 1)) if (g_dsp.pc == (rLoopAddress + 1))
{ {
rLoopCounter--; rLoopCounter--;
@ -150,31 +149,62 @@ void Run()
gdsp_running = false; gdsp_running = false;
} }
// Used by non-thread mode. // This one has basic idle skipping, and checks breakpoints.
void RunCycles(int cycles) int RunCyclesDebug(int cycles)
{
// 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)
return 0;
Step();
cycles--;
}
while (cycles > 0)
{
if (g_dsp.cr & CR_HALT) {
return 0;
}
if (dsp_breakpoints.IsAddressBreakPoint(g_dsp.pc))
{
DSPCore_SetState(DSPCORE_STEPPING);
return cycles;
}
DSPCore_CheckExternalInterrupt();
Step();
cycles--;
// Idle skipping.
if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP)
return 0;
}
}
// Used by non-thread mode. Meant to be efficient.
int RunCycles(int cycles)
{ {
if (cycles < 18) if (cycles < 18)
{ {
for (int i = 0; i < cycles; i++) for (int i = 0; i < cycles; i++)
{ {
if (g_dsp.cr & CR_HALT) if (g_dsp.cr & CR_HALT)
return; return 0;
if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP)
return; return 0;
Step(); Step();
cycles--; cycles--;
} }
return; return cycles;
} }
DSPCore_CheckExternalInterrupt(); DSPCore_CheckExternalInterrupt();
// 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++) for (int i = 0; i < 8; i++)
{ {
if (g_dsp.cr & CR_HALT) if (g_dsp.cr & CR_HALT)
return; return 0;
Step(); Step();
cycles--; cycles--;
} }
@ -183,9 +213,9 @@ void RunCycles(int cycles)
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)
return; return 0;
if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP)
return; return 0;
Step(); Step();
cycles--; cycles--;
} }
@ -199,6 +229,8 @@ void RunCycles(int cycles)
// 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()

View File

@ -27,7 +27,13 @@ namespace DSPInterpreter {
void Step(); void Step();
void Run(); void Run();
void RunCycles(int cycles);
// If these simply return the same number of cycles as was passed into them,
// chances are that the DSP is halted.
// The difference between them is that the debug one obeys breakpoints.
int RunCycles(int cycles);
int RunCyclesDebug(int cycles);
void Stop(); void Stop();
void WriteCR(u16 val); void WriteCR(u16 val);

View File

@ -30,27 +30,27 @@
// Stacks. The stacks are outside the DSP RAM, in dedicated hardware. // Stacks. The stacks are outside the DSP RAM, in dedicated hardware.
void dsp_reg_stack_push(u8 stack_reg) void dsp_reg_stack_push(int stack_reg)
{ {
g_dsp.reg_stack_ptr[stack_reg]++; g_dsp.reg_stack_ptr[stack_reg]++;
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg]; g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
} }
void dsp_reg_stack_pop(u8 stack_reg) void dsp_reg_stack_pop(int stack_reg)
{ {
g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]]; g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]];
g_dsp.reg_stack_ptr[stack_reg]--; g_dsp.reg_stack_ptr[stack_reg]--;
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
} }
void dsp_reg_store_stack(u8 stack_reg, u16 val) void dsp_reg_store_stack(int stack_reg, u16 val)
{ {
dsp_reg_stack_push(stack_reg); dsp_reg_stack_push(stack_reg);
g_dsp.r[DSP_REG_ST0 + stack_reg] = val; g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
} }
u16 dsp_reg_load_stack(u8 stack_reg) u16 dsp_reg_load_stack(int stack_reg)
{ {
u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg]; u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg];
dsp_reg_stack_pop(stack_reg); dsp_reg_stack_pop(stack_reg);

View File

@ -28,7 +28,7 @@
#include "Common.h" #include "Common.h"
void dsp_reg_store_stack(u8 stack_reg, u16 val); void dsp_reg_store_stack(int stack_reg, u16 val);
u16 dsp_reg_load_stack(u8 stack_reg); u16 dsp_reg_load_stack(int stack_reg);
#endif #endif

View File

@ -252,8 +252,7 @@ const DSPOPCTemplate opcodes[] =
{"CLRL", 0xfc00, 0xffff, DSPInterpreter::clrl, nop, 1 | P_EXT, 1, {{P_ACCL, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acl0 {"CLRL", 0xfc00, 0xffff, DSPInterpreter::clrl, nop, 1 | P_EXT, 1, {{P_ACCL, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acl0
{"CLR", 0x8100, 0xf7ff, DSPInterpreter::clr, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acc0 {"CLR", 0x8100, 0xf7ff, DSPInterpreter::clr, nop, 1 | P_EXT, 1, {{P_ACC, 1, 0, 11, 0x0800}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, // clear acc0
{"CLRP", 0x8400, 0xffff, DSPInterpreter::clrp, nop, 1 | P_EXT, 0, {}, }, {"CLRP", 0x8400, 0xffff, DSPInterpreter::clrp, nop, 1 | P_EXT, 0, {}, },
{"MOV", 0x6c00, 0xfeff, DSPInterpreter::mov, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, {"MOV", 0x6c00, 0xfeff, DSPInterpreter::mov, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_ACC_D, 1, 0, 8, 0x0100}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
{"MOVAX", 0x6800, 0xfcff, DSPInterpreter::movax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, {"MOVAX", 0x6800, 0xfcff, DSPInterpreter::movax, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
{"MOVR", 0x6000, 0xf8ff, DSPInterpreter::movr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi}, {"MOVR", 0x6000, 0xf8ff, DSPInterpreter::movr, nop, 1 | P_EXT, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}}, dsp_op_ext_ops_pro, dsp_op_ext_ops_epi},
@ -368,6 +367,7 @@ const pdlabel_t pdlabels[] =
{0xffad, "COEF_A2_6", "COEF_A2_6",}, {0xffad, "COEF_A2_6", "COEF_A2_6",},
{0xffae, "COEF_A1_7", "COEF_A1_7",}, {0xffae, "COEF_A1_7", "COEF_A1_7",},
{0xffaf, "COEF_A2_7", "COEF_A2_7",}, {0xffaf, "COEF_A2_7", "COEF_A2_7",},
{0xffb0, 0, 0,}, {0xffb0, 0, 0,},
{0xffb1, 0, 0,}, {0xffb1, 0, 0,},
{0xffb2, 0, 0,}, {0xffb2, 0, 0,},
@ -384,6 +384,7 @@ const pdlabel_t pdlabels[] =
{0xffbd, 0, 0,}, {0xffbd, 0, 0,},
{0xffbe, 0, 0,}, {0xffbe, 0, 0,},
{0xffbf, 0, 0,}, {0xffbf, 0, 0,},
{0xffc0, 0, 0,}, {0xffc0, 0, 0,},
{0xffc1, 0, 0,}, {0xffc1, 0, 0,},
{0xffc2, 0, 0,}, {0xffc2, 0, 0,},
@ -400,6 +401,7 @@ const pdlabel_t pdlabels[] =
{0xffcd, "DSPA", "DSP DMA DMEM Address",}, {0xffcd, "DSPA", "DSP DMA DMEM Address",},
{0xffce, "DSMAH", "DSP DMA Mem Address H",}, {0xffce, "DSMAH", "DSP DMA Mem Address H",},
{0xffcf, "DSMAL", "DSP DMA Mem Address L",}, {0xffcf, "DSMAL", "DSP DMA Mem Address L",},
{0xffd0, 0,0,}, {0xffd0, 0,0,},
{0xffd1, "SampleFormat", "SampleFormat",}, {0xffd1, "SampleFormat", "SampleFormat",},
{0xffd2, 0,0,}, {0xffd2, 0,0,},
@ -416,6 +418,7 @@ const pdlabel_t pdlabels[] =
{0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",}, {0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",},
{0xffde, "GAIN", "Gain",}, {0xffde, "GAIN", "Gain",},
{0xffdf, 0,0,}, {0xffdf, 0,0,},
{0xffe0, 0,0,}, {0xffe0, 0,0,},
{0xffe1, 0,0,}, {0xffe1, 0,0,},
{0xffe2, 0,0,}, {0xffe2, 0,0,},
@ -432,6 +435,7 @@ const pdlabel_t pdlabels[] =
{0xffed, 0,0,}, {0xffed, 0,0,},
{0xffee, 0,0,}, {0xffee, 0,0,},
{0xffef, "AMDM", "ARAM DMA Request Mask",}, {0xffef, "AMDM", "ARAM DMA Request Mask",},
{0xfff0, 0,0,}, {0xfff0, 0,0,},
{0xfff1, 0,0,}, {0xfff1, 0,0,},
{0xfff2, 0,0,}, {0xfff2, 0,0,},

View File

@ -26,6 +26,7 @@ bool DSPHost_OnThread() { return false; }
bool DSPHost_Running() { return true; } bool DSPHost_Running() { return true; }
u32 DSPHost_CodeLoaded(const u8 *ptr, int size) {return 0x1337c0de;} u32 DSPHost_CodeLoaded(const u8 *ptr, int size) {return 0x1337c0de;}
void DSPHost_InterruptRequest() {} void DSPHost_InterruptRequest() {}
void DSPHost_UpdateDebugger() {}
// This test goes from text ASM to binary to text ASM and once again back to binary. // This test goes from text ASM to binary to text ASM and once again back to binary.
// Then the two binaries are compared. // Then the two binaries are compared.

View File

@ -69,7 +69,7 @@ u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
// this crc is comparable with the HLE plugin // this crc is comparable with the HLE plugin
u32 ector_crc = 0; u32 ector_crc = 0;
for (u32 i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
ector_crc ^= ptr[i]; ector_crc ^= ptr[i];
//let's rol //let's rol
@ -85,7 +85,8 @@ u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
DSPSymbols::Clear(); DSPSymbols::Clear();
bool success = false; bool success = false;
switch (ector_crc) { switch (ector_crc)
{
case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_Zelda.txt"); break; case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_Zelda.txt"); break;
case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_Luigi.txt"); break; case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_Luigi.txt"); break;
case 0x4e8a8b21: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_AX1.txt"); break; case 0x4e8a8b21: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_AX1.txt"); break;
@ -101,4 +102,9 @@ u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
m_DebuggerFrame->Refresh(); m_DebuggerFrame->Refresh();
return crc; return crc;
} }
void DSPHost_UpdateDebugger()
{
m_DebuggerFrame->Refresh();
}

View File

@ -39,8 +39,6 @@ DSPDebuggerLLE::DSPDebuggerLLE(wxWindow *parent, wxWindowID id, const wxString &
const wxPoint &position, const wxSize& size, long style) const wxPoint &position, const wxSize& size, long style)
: wxFrame(parent, id, title, position, size, style) : wxFrame(parent, id, title, position, size, style)
, m_CachedStepCounter(-1) , m_CachedStepCounter(-1)
, m_CachedCR(-1)
, m_State(RUN)
{ {
CreateGUIControls(); CreateGUIControls();
} }
@ -87,6 +85,8 @@ void DSPDebuggerLLE::CreateGUIControls()
this->SetSizer(sMain); this->SetSizer(sMain);
this->Layout(); this->Layout();
UpdateState();
} }
void DSPDebuggerLLE::OnClose(wxCloseEvent& event) void DSPDebuggerLLE::OnClose(wxCloseEvent& event)
@ -99,15 +99,17 @@ void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
switch (event.GetId()) switch (event.GetId())
{ {
case ID_RUNTOOL: case ID_RUNTOOL:
if ((m_State == RUN) || (m_State == RUN_START)) if (DSPCore_GetState() == DSPCORE_RUNNING)
m_State = PAUSE; DSPCore_SetState(DSPCORE_STEPPING);
else else
m_State = RUN_START; DSPCore_SetState(DSPCORE_RUNNING);
break; break;
case ID_STEPTOOL: case ID_STEPTOOL:
m_State = STEP; if (DSPCore_GetState() == DSPCORE_STEPPING)
DSPCore_Step();
break; break;
case ID_SHOWPCTOOL: case ID_SHOWPCTOOL:
FocusOnPC(); FocusOnPC();
break; break;
@ -137,10 +139,14 @@ void DSPDebuggerLLE::FocusOnPC()
void DSPDebuggerLLE::UpdateState() void DSPDebuggerLLE::UpdateState()
{ {
if ((m_State == RUN) || (m_State == RUN_START)) if (DSPCore_GetState() == DSPCORE_RUNNING) {
m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Pause")); m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Pause"));
else m_Toolbar->FindById(ID_STEPTOOL)->Enable(false);
}
else {
m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Run")); m_Toolbar->FindById(ID_RUNTOOL)->SetLabel(wxT("Run"));
m_Toolbar->FindById(ID_STEPTOOL)->Enable(true);
}
m_Toolbar->Realize(); m_Toolbar->Realize();
} }
@ -188,54 +194,7 @@ void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event)
void DSPDebuggerLLE::UpdateRegisterFlags() void DSPDebuggerLLE::UpdateRegisterFlags()
{ {
if (m_CachedCR == g_dsp.cr)
return;
// m_Toolbar->ToggleTool(ID_CHECK_ASSERTINT, g_dsp.cr & 0x02 ? true : false);
// m_Toolbar->ToggleTool(ID_CHECK_HALT, g_dsp.cr & 0x04 ? true : false);
// m_Toolbar->ToggleTool(ID_CHECK_INIT, g_dsp.cr & 0x800 ? true : false);
m_CachedCR = g_dsp.cr;
}
bool DSPDebuggerLLE::CanDoStep()
{
// update the symbols all the time because they're script cmds like bps
UpdateSymbolMap();
switch (m_State)
{
case RUN_START:
m_State = RUN;
return true;
case RUN:
/*
if (IsBreakPoint(g_dsp.pc))
{
Refresh();
m_State = PAUSE;
return false;
}*/
return true;
case PAUSE:
Refresh();
return false;
case STEP:
Refresh();
m_State = PAUSE;
return true;
}
return false;
}
void DSPDebuggerLLE::DebugBreak()
{
m_State = PAUSE;
} }
void DSPDebuggerLLE::OnAddrBoxChange(wxCommandEvent& event) void DSPDebuggerLLE::OnAddrBoxChange(wxCommandEvent& event)

View File

@ -54,8 +54,6 @@ public:
virtual ~DSPDebuggerLLE(); virtual ~DSPDebuggerLLE();
bool CanDoStep();
void DebugBreak();
void Refresh(); void Refresh();
private: private:
@ -95,18 +93,8 @@ private:
COLUMN_PARAM, COLUMN_PARAM,
}; };
enum EState
{
PAUSE,
STEP,
RUN,
RUN_START // ignores breakpoints and switches after one step to RUN
};
EState m_State;
DSPDebugInterface debug_interface; DSPDebugInterface debug_interface;
u64 m_CachedStepCounter; u64 m_CachedStepCounter;
u16 m_CachedCR;
// GUI updaters // GUI updaters
void UpdateDisAsmListView(); void UpdateDisAsmListView();

View File

@ -45,17 +45,12 @@ DSPDebuggerLLE* m_DebuggerFrame = NULL;
PLUGIN_GLOBALS* globals = NULL; PLUGIN_GLOBALS* globals = NULL;
DSPInitialize g_dspInitialize; DSPInitialize g_dspInitialize;
Common::Thread *g_hDSPThread = NULL; Common::Thread *g_hDSPThread = NULL;
SoundStream *soundStream = NULL; SoundStream *soundStream = NULL;
#define GDSP_MBOX_CPU 0
#define GDSP_MBOX_DSP 1
bool bCanWork = false;
bool bIsRunning = false; bool bIsRunning = false;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// UGLY wxw stuff, TODO fix up // UGLY WxW stuff, TODO fix up
// wxWidgets: Create the wxApp // wxWidgets: Create the wxApp
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
class wxDLLApp : public wxApp class wxDLLApp : public wxApp
@ -188,14 +183,14 @@ THREAD_RETURN dsp_thread(void* lpParameter)
void DSP_DebugBreak() void DSP_DebugBreak()
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if(m_DebuggerFrame) // if (m_DebuggerFrame)
m_DebuggerFrame->DebugBreak(); // m_DebuggerFrame->DebugBreak();
#endif #endif
} }
void Initialize(void *init) void Initialize(void *init)
{ {
bCanWork = true; bool bCanWork = true;
g_dspInitialize = *(DSPInitialize*)init; g_dspInitialize = *(DSPInitialize*)init;
g_Config.Load(); g_Config.Load();
@ -324,7 +319,7 @@ void DSP_Update(int cycles)
// If we're not on a thread, run cycles here. // If we're not on a thread, run cycles here.
if (!g_dspInitialize.bOnThread) if (!g_dspInitialize.bOnThread)
{ {
DSPInterpreter::RunCycles(cycles); DSPCore_RunCycles(cycles);
} }
} }
@ -347,8 +342,8 @@ void DSP_SendAIBuffer(unsigned int address, int sample_rate)
// so each sample now triggers the sound stream) // so each sample now triggers the sound stream)
// TODO: think about this. // TODO: think about this.
//static int counter = 0; // static int counter = 0;
//counter++; // counter++;
if (/*(counter & 31) == 0 &&*/ soundStream) if (/*(counter & 31) == 0 &&*/ soundStream)
soundStream->Update(); soundStream->Update();
} }

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,6 @@ BIG Questions:
- Why is a PB-Transfer from RAM to DMEM 0xC0 shorts long but DMEM to RAM just 0x80 - Why is a PB-Transfer from RAM to DMEM 0xC0 shorts long but DMEM to RAM just 0x80
DSP functionality to test: DSP functionality to test:
- CR
- Interrupts (7) - Interrupts (7)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */
@ -354,8 +353,8 @@ void 0067_CopyCommand(_destAddr($AR0), _loopCount($AC0.M))
// 0072 02df ret // 0072 02df ret
} }
/*
/*
0073 029f 0043 jmp 0x0043 0073 029f 0043 jmp 0x0043
0075 029f 0043 jmp 0x0043 0075 029f 0043 jmp 0x0043
0077 029f 0095 jmp 0x0095 0077 029f 0095 jmp 0x0095
@ -1752,7 +1751,7 @@ void 0561_SetupAcceleratorForMysteryAccess(ARAMAddress(ACC0), DestBuffer(AC1.M),
0569 2ed7 srs @ACEAL, $AC0.M 0569 2ed7 srs @ACEAL, $AC0.M
056a 1fda mrr $AC0.M, $AX0.H 056a 1fda mrr $AC0.M, $AX0.H
056b 1f98 mrr $AC0.L, $AX0.L 056b 1f98 mrr $AC0.L, $AX0.L
// Multiply "current" address by 2 since it's in nibbles? (love these negative shifts :/) // Divide "current" address by 2.
056c 147f lsr $ACC0, #-1 056c 147f lsr $ACC0, #-1
056d 2ed8 srs @ACCAH, $AC0.M // Current address 056d 2ed8 srs @ACCAH, $AC0.M // Current address
056e 2cd9 srs @ACCAL, $AC0.L 056e 2cd9 srs @ACCAL, $AC0.L
@ -1844,8 +1843,7 @@ void 05ad_SetupAccelerator(_acceleratorH(AC0.M), _accleratorL(AC0.L), _format(AC
// 05b7 02df ret // 05b7 02df ret
} }
void 05b8_NewMail() void 05b8_NewMail() {
{
# 05b8 1205 sbclr #0x05 # 05b8 1205 sbclr #0x05
# 05b9 8e00 set16 # 05b9 8e00 set16
@ -1861,7 +1859,7 @@ void 05b8_NewMail()
*/ */
*0x03fd = AC0.H *0x03fd = AC0.H
*0x03fF = AC0.L *0x03ff = AC0.L
ACC0 >>= 16 ACC0 >>= 16
*0x03fe = AC0.L *0x03fe = AC0.L
*0x03fa = AX0.H *0x03fa = AX0.H
@ -1871,7 +1869,7 @@ void 05b8_NewMail()
// 05c8 029c 06b9 jlnz 0x06b9 // 05c8 029c 06b9 jlnz 0x06b9
if (@CMBH & 0x8000 > 0) if (@CMBH & 0x8000 > 0)
{ {
!MISSING! !MISSING!
} }
// 05ca 00da ffff lr $AX0.H, @CMBL // 05ca 00da ffff lr $AX0.H, @CMBL
@ -2000,8 +1998,8 @@ void 0603_Unk(_returnAddr($AR0))
} }
0616 0021 halt 0616 0021 halt
0617 0021 halt 0617 0021 halt
void 0618_Unk() { void 0618_Unk() {
0618 009a 0002 lri $AX0.H, #0x0002 0618 009a 0002 lri $AX0.H, #0x0002
@ -3124,6 +3122,7 @@ void Decoder0x08() {
09a7 2605 lrs $AC0.M, @0x0005 09a7 2605 lrs $AC0.M, @0x0005
09a8 b100 tst $ACC0 09a8 b100 tst $ACC0
09a9 0295 09be jz 0x09be 09a9 0295 09be jz 0x09be
09ab 8100 clr $ACC0 09ab 8100 clr $ACC0
09ac 2e05 srs @0x0005, $AC0.M 09ac 2e05 srs @0x0005, $AC0.M
09ad 2281 lrs $AX0.H, @0xff81 09ad 2281 lrs $AX0.H, @0xff81
@ -3162,6 +3161,7 @@ void Decoder0x08() {
09d4 0a01 lris $AX0.H, #0x01 09d4 0a01 lris $AX0.H, #0x01
09d5 00fa 0405 sr @0x0405, $AX0.H 09d5 00fa 0405 sr @0x0405, $AX0.H
09d7 029f 09ab jmp 0x09ab 09d7 029f 09ab jmp 0x09ab
09d9 1f5f mrr $AX0.H, $AC1.M 09d9 1f5f mrr $AX0.H, $AC1.M
09da 02bf 0a0a call 0x0a0a 09da 02bf 0a0a call 0x0a0a
09dc 00fa 0362 sr @0x0362, $AX0.H 09dc 00fa 0362 sr @0x0362, $AX0.H
@ -3174,7 +3174,7 @@ void Decoder0x08() {
09e5 5c00 sub $ACC0, $AC1.L 09e5 5c00 sub $ACC0, $AC1.L
09e6 b100 tst $ACC0 09e6 b100 tst $ACC0
09e7 0275 ifz 09e7 0275 ifz
09e8 1a3a srr @$AR1, $AX0.H 09e8 1a3a srr @$AR1, $AX0.H
09e9 2e3a srs @0x003a, $AC0.M 09e9 2e3a srs @0x003a, $AC0.M
09ea 2c3b srs @0x003b, $AC0.L 09ea 2c3b srs @0x003b, $AC0.L
09eb 2638 lrs $AC0.M, @0x0038 09eb 2638 lrs $AC0.M, @0x0038
@ -3263,28 +3263,28 @@ void Decoder_0x10() {
0a2e 0295 0a43 jz 0x0a43 0a2e 0295 0a43 jz 0x0a43
if (*0x405) { if (*0x405) {
retry_0a30: retry_0a30:
0a30 8100 clr $ACC0 0a30 8100 clr $ACC0
0a31 2e05 srs @0x0005, $AC0.M 0a31 2e05 srs @0x0005, $AC0.M
0a32 2281 lrs $AX0.H, @0xff81 0a32 2281 lrs $AX0.H, @0xff81
0a33 8600 tstaxh $AX0.H 0a33 8600 tstaxh $AX0.H
0a34 0294 0a3d jnz 0x0a3d 0a34 0294 0a3d jnz 0x0a3d
if (!*401) { if (!*401) {
0a36 8100 clr $ACC0 0a36 8100 clr $ACC0
0a37 005f loop $AC1.M 0a37 005f loop $AC1.M
0a38 1b7e srri @$AR3, $AC0.M 0a38 1b7e srri @$AR3, $AC0.M
0a39 7400 incm $AC0.M 0a39 7400 incm $AC0.M
0a3a 2e01 srs @0x0001, $AC0.M 0a3a 2e01 srs @0x0001, $AC0.M
0a3b 029f 0a78 jmp 0x0a78 0a3b 029f 0a78 jmp 0x0a78
} else { } else {
// Copy [88,89] to [34,35] // Copy [88,89] to [34,35]
0a3d 2688 lrs $AC0.M, @0xff88 0a3d 2688 lrs $AC0.M, @0xff88
0a3e 2489 lrs $AC0.L, @0xff89 0a3e 2489 lrs $AC0.L, @0xff89
0a3f 2e34 srs @0x0034, $AC0.M 0a3f 2e34 srs @0x0034, $AC0.M
0a40 2c35 srs @0x0035, $AC0.L 0a40 2c35 srs @0x0035, $AC0.L
0a41 02bf 0a7f call 0x0a7f 0a41 02bf 0a7f call 0x0a7f
0a7f_UpdateSampleCounters10() 0a7f_UpdateSampleCounters10()
} }
} }
0a43: 0a43: