From aecaf271f1fe98cba1ebc8228ff9eff3e39e72c5 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sun, 21 Jun 2009 08:39:21 +0000 Subject: New DSP debugger: step one. (not ready yet, but try loading zelda WW and look at the dsp debugger..). Had to shuffle around quite a lot of code to be able to extract the CodeView into a library nicely so it can be used from both the main dolphin and the LLE plugin... also extracted the symboldb code. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3517 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/DSPCore/DSPCore.vcproj | 8 +++- Source/Core/DSPCore/Src/DSPCore.cpp | 2 + Source/Core/DSPCore/Src/DSPHost.h | 1 + Source/Core/DSPCore/Src/DSPTables.cpp | 60 ++++++++++++++++++++++++++-- Source/Core/DSPCore/Src/disassemble.cpp | 16 ++++---- Source/Core/DSPCore/Src/disassemble.h | 4 +- Source/Core/DSPCore/Src/gdsp_aram.cpp | 12 ++++++ Source/Core/DSPCore/Src/gdsp_aram.h | 1 + Source/Core/DSPCore/Src/gdsp_interface.cpp | 39 ++++++++++++++---- Source/Core/DSPCore/Src/gdsp_interpreter.cpp | 21 +++++++++- 10 files changed, 139 insertions(+), 25 deletions(-) (limited to 'Source/Core/DSPCore') diff --git a/Source/Core/DSPCore/DSPCore.vcproj b/Source/Core/DSPCore/DSPCore.vcproj index 268d721ab2..520c603292 100644 --- a/Source/Core/DSPCore/DSPCore.vcproj +++ b/Source/Core/DSPCore/DSPCore.vcproj @@ -299,7 +299,7 @@ Optimization="2" EnableIntrinsicFunctions="true" AdditionalIncludeDirectories="..\Common\Src" - PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" + PreprocessorDefinitions="LOGGING;WIN32;NDEBUG;_LIB;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -363,7 +363,7 @@ Optimization="2" EnableIntrinsicFunctions="true" AdditionalIncludeDirectories="..\Common\Src" - PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" + PreprocessorDefinitions="LOGGING;WIN32;NDEBUG;_LIB;_WINDOWS;NOPCH;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE" RuntimeLibrary="0" EnableFunctionLevelLinking="true" UsePrecompiledHeader="0" @@ -426,6 +426,10 @@ > + + diff --git a/Source/Core/DSPCore/Src/DSPCore.cpp b/Source/Core/DSPCore/Src/DSPCore.cpp index d9903871e2..692a202109 100644 --- a/Source/Core/DSPCore/Src/DSPCore.cpp +++ b/Source/Core/DSPCore/Src/DSPCore.cpp @@ -155,6 +155,8 @@ void DSPCore_CheckExternalInterrupt() { // level 7 is the interrupt exception DSPCore_SetException(7); + + // Uh, confusing. Can this really be right? g_dsp.cr &= ~0x0002; } } diff --git a/Source/Core/DSPCore/Src/DSPHost.h b/Source/Core/DSPCore/Src/DSPHost.h index 7a96fd1ff3..e154ddba19 100644 --- a/Source/Core/DSPCore/Src/DSPHost.h +++ b/Source/Core/DSPCore/Src/DSPHost.h @@ -24,6 +24,7 @@ // can be stubbed out. u8 DSPHost_ReadHostMemory(u32 addr); +void DSPHost_WriteHostMemory(u8 value, u32 addr); bool DSPHost_OnThread(); bool DSPHost_Running(); u32 DSPHost_CodeLoaded(const u8 *ptr, int size); diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index 8512c83296..371af34dac 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -364,15 +364,42 @@ const pdlabel_t pdlabels[] = {0xffad, "COEF_A2_6", "COEF_A2_6",}, {0xffae, "COEF_A1_7", "COEF_A1_7",}, {0xffaf, "COEF_A2_7", "COEF_A2_7",}, + {0xffb0, 0, 0,}, + {0xffb1, 0, 0,}, + {0xffb2, 0, 0,}, + {0xffb3, 0, 0,}, + {0xffb4, 0, 0,}, + {0xffb5, 0, 0,}, + {0xffb6, 0, 0,}, + {0xffb7, 0, 0,}, + {0xffb8, 0, 0,}, + {0xffb9, 0, 0,}, + {0xffba, 0, 0,}, + {0xffbb, 0, 0,}, + {0xffbc, 0, 0,}, + {0xffbd, 0, 0,}, + {0xffbe, 0, 0,}, + {0xffbf, 0, 0,}, + {0xffc0, 0, 0,}, + {0xffc1, 0, 0,}, + {0xffc2, 0, 0,}, + {0xffc3, 0, 0,}, + {0xffc4, 0, 0,}, + {0xffc5, 0, 0,}, + {0xffc6, 0, 0,}, + {0xffc7, 0, 0,}, + {0xffc8, 0, 0,}, {0xffc9, "DSCR", "DSP DMA Control Reg",}, + {0xffca, 0, 0,}, {0xffcb, "DSBL", "DSP DMA Block Length",}, + {0xffcc, 0, 0,}, {0xffcd, "DSPA", "DSP DMA DMEM Address",}, {0xffce, "DSMAH", "DSP DMA Mem Address H",}, {0xffcf, "DSMAL", "DSP DMA Mem Address L",}, + {0xffd0, 0,0,}, {0xffd1, "SampleFormat", "SampleFormat",}, - - {0xffd3, "Unk Zelda", "Unk Zelda writes to it",}, - + {0xffd2, 0,0,}, + {0xffd3, "UnkZelda", "Unk Zelda reads/writes from/to it",}, {0xffd4, "ACSAH", "Accelerator start address H",}, {0xffd5, "ACSAL", "Accelerator start address L",}, {0xffd6, "ACEAH", "Accelerator end address H",}, @@ -384,7 +411,34 @@ const pdlabel_t pdlabels[] = {0xffdc, "yn2", "yn2",}, {0xffdd, "ARAM", "Direct Read from ARAM (uses ADPCM)",}, {0xffde, "GAIN", "Gain",}, + {0xffdf, 0,0,}, + {0xffe0, 0,0,}, + {0xffe1, 0,0,}, + {0xffe2, 0,0,}, + {0xffe3, 0,0,}, + {0xffe4, 0,0,}, + {0xffe5, 0,0,}, + {0xffe6, 0,0,}, + {0xffe7, 0,0,}, + {0xffe8, 0,0,}, + {0xffe9, 0,0,}, + {0xffea, 0,0,}, + {0xffeb, 0,0,}, + {0xffec, 0,0,}, + {0xffed, 0,0,}, + {0xffee, 0,0,}, {0xffef, "AMDM", "ARAM DMA Request Mask",}, + {0xfff0, 0,0,}, + {0xfff1, 0,0,}, + {0xfff2, 0,0,}, + {0xfff3, 0,0,}, + {0xfff4, 0,0,}, + {0xfff5, 0,0,}, + {0xfff6, 0,0,}, + {0xfff7, 0,0,}, + {0xfff8, 0,0,}, + {0xfff9, 0,0,}, + {0xfffa, 0,0,}, {0xfffb, "DIRQ", "DSP IRQ Request",}, {0xfffc, "DMBH", "DSP Mailbox H",}, {0xfffd, "DMBL", "DSP Mailbox L",}, diff --git a/Source/Core/DSPCore/Src/disassemble.cpp b/Source/Core/DSPCore/Src/disassemble.cpp index b3ffd72ede..c58465e9fe 100644 --- a/Source/Core/DSPCore/Src/disassemble.cpp +++ b/Source/Core/DSPCore/Src/disassemble.cpp @@ -82,7 +82,7 @@ bool DSPDisassembler::Disassemble(int start_pc, const std::vector &code, in fclose(f); // Run the two passes. - return DisFile(tmp1, 1, text) && DisFile(tmp1, 2, text); + return DisFile(tmp1, base_addr, 1, text) && DisFile(tmp1, base_addr, 2, text); } char *DSPDisassembler::DisParams(const DSPOPCTemplate& opc, u16 op1, u16 op2, char *strbuf) @@ -186,7 +186,7 @@ static void MakeLowerCase(char *ptr) } } -void DSPDisassembler::DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 *pc, std::string &dest) +bool DSPDisassembler::DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 *pc, std::string &dest) { char buffer[256]; char *buf = buffer; @@ -200,11 +200,10 @@ void DSPDisassembler::DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 { *pc++; dest.append("; outside memory"); - return; + return false; } - *pc &= 0x0fff; - const u32 op1 = binbuf[*pc]; + const u32 op1 = binbuf[*pc & 0x0fff]; const DSPOPCTemplate *opc = NULL; const DSPOPCTemplate *opc_ext = NULL; @@ -259,7 +258,7 @@ void DSPDisassembler::DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 // Size 2 - the op has a large immediate. if ((opc->size & ~P_EXT) == 2) { - op2 = binbuf[*pc + 1]; + op2 = binbuf[(*pc + 1) & 0x0fff]; if (settings_.show_hex) buf += sprintf(buf, "%04x %04x ", op1, op2); } @@ -318,9 +317,10 @@ void DSPDisassembler::DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 if (pass == 2) dest.append(buffer); + return true; } -bool DSPDisassembler::DisFile(const char* name, int pass, std::string &output) +bool DSPDisassembler::DisFile(const char* name, int base_addr, int pass, std::string &output) { FILE* in = fopen(name, "rb"); if (in == NULL) @@ -339,7 +339,7 @@ bool DSPDisassembler::DisFile(const char* name, int pass, std::string &output) // Actually do the disassembly. for (u16 pc = 0; pc < (size / 2);) { - DisOpcode(binbuf, 0x0000, pass, &pc, output); + DisOpcode(binbuf, base_addr, pass, &pc, output); if (pass == 2) output.append("\n"); } diff --git a/Source/Core/DSPCore/Src/disassemble.h b/Source/Core/DSPCore/Src/disassemble.h index 96f1fb7b88..c1e2689659 100644 --- a/Source/Core/DSPCore/Src/disassemble.h +++ b/Source/Core/DSPCore/Src/disassemble.h @@ -67,11 +67,11 @@ public: // Warning - this one is trickier to use right. // Use pass == 2 if you're just using it by itself. - void DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 *pc, std::string &dest); + bool DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 *pc, std::string &dest); private: // Moves PC forward and writes the result to dest. - bool DisFile(const char* name, int pass, std::string &output); + bool DisFile(const char* name, int base_addr, int pass, std::string &output); char* DisParams(const DSPOPCTemplate& opc, u16 op1, u16 op2, char* strbuf); std::map unk_opcodes; diff --git a/Source/Core/DSPCore/Src/gdsp_aram.cpp b/Source/Core/DSPCore/Src/gdsp_aram.cpp index d34de5515d..22fd6f7813 100644 --- a/Source/Core/DSPCore/Src/gdsp_aram.cpp +++ b/Source/Core/DSPCore/Src/gdsp_aram.cpp @@ -64,6 +64,18 @@ s16 ADPCM_Step(u32& _rSamplePos) return val; } +void dsp_write_aram_d3(u16 value) +{ + // Not sure about this one but it sure looks like Zelda is writing to ARAM + // through 0xFFd3... + + const u32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL]; + u32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL]; + + DSPHost_WriteHostMemory(value >> 8, Address); + DSPHost_WriteHostMemory(value & 0xFF, Address + 1); +} + u16 dsp_read_aram() { const u32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL]; diff --git a/Source/Core/DSPCore/Src/gdsp_aram.h b/Source/Core/DSPCore/Src/gdsp_aram.h index 3c5685fc0a..e310b9858e 100644 --- a/Source/Core/DSPCore/Src/gdsp_aram.h +++ b/Source/Core/DSPCore/Src/gdsp_aram.h @@ -19,5 +19,6 @@ #define _GDSP_ARAM_H u16 dsp_read_aram(); +void dsp_write_aram_d3(u16 value); #endif diff --git a/Source/Core/DSPCore/Src/gdsp_interface.cpp b/Source/Core/DSPCore/Src/gdsp_interface.cpp index 4aae90a9ea..9a7fb823a0 100644 --- a/Source/Core/DSPCore/Src/gdsp_interface.cpp +++ b/Source/Core/DSPCore/Src/gdsp_interface.cpp @@ -30,6 +30,7 @@ #include "DSPCore.h" #include "DSPHost.h" +#include "DSPTables.h" #include "DSPAnalyzer.h" #include "gdsp_aram.h" #include "gdsp_interpreter.h" @@ -89,6 +90,8 @@ void gdsp_mbox_write_l(u8 mbx, u16 val) if (mbx == GDSP_MBOX_DSP) { DEBUG_LOG(DSPLLE, " - DSP writes mail to mbx %i: 0x%08x (pc=0x%04x)", mbx, gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.pc); + } else { + // Trigger exception? } } @@ -138,6 +141,11 @@ void gdsp_ifx_write(u16 addr, u16 val) gdsp_ifx_regs[DSP_DSCR] &= ~0x0004; break; + case 0xd3: // ZeldaUnk (accelerator WRITE) + ERROR_LOG(DSPLLE, "Write To ZeldaUnk pc=%04x (%04x)\n", g_dsp.pc, val); + dsp_write_aram_d3(val); + break; + case 0xde: //if (val) // PanicAlert("Gain written: %04x", val); // BMX XXX does, and sounds HORRIBLE. @@ -149,10 +157,17 @@ void gdsp_ifx_write(u16 addr, u16 val) break; default: -/* if ((addr & 0xff) >= 0xa0 && reg_names[addr - 0xa0]) - DEBUG_LOG(DSPLLE, "%04x MW %s (%04x)\n", g_dsp.pc, reg_names[addr - 0xa0], val); - else - DEBUG_LOG(DSPLLE, "%04x MW %04x (%04x)\n", g_dsp.pc, addr, val);*/ + if ((addr & 0xff) >= 0xa0) { + if (pdlabels[(addr & 0xFF) - 0xa0].name) { + INFO_LOG(DSPLLE, "%04x MW %s (%04x)\n", g_dsp.pc, pdlabels[(addr & 0xFF) - 0xa0].name, val); + } + else { + ERROR_LOG(DSPLLE, "%04x MW %04x (%04x)\n", g_dsp.pc, addr, val); + } + } + else { + ERROR_LOG(DSPLLE, "%04x MW %04x (%04x)\n", g_dsp.pc, addr, val); + } gdsp_ifx_regs[addr & 0xFF] = val; break; } @@ -176,14 +191,22 @@ u16 gdsp_ifx_read(u16 addr) return gdsp_ifx_regs[addr & 0xFF]; case 0xdd: + // ERROR_LOG(DSPLLE, "Accelerator"); return dsp_read_aram(); default: + if ((addr & 0xff) >= 0xa0) { + if (pdlabels[(addr & 0xFF) - 0xa0].name) { + INFO_LOG(DSPLLE, "%04x MR %s (%04x)\n", g_dsp.pc, pdlabels[(addr & 0xFF) - 0xa0].name, gdsp_ifx_regs[addr & 0xFF]); + } + else { + ERROR_LOG(DSPLLE, "%04x MR %04x (%04x)\n", g_dsp.pc, addr, gdsp_ifx_regs[addr & 0xFF]); + } + } + else { + ERROR_LOG(DSPLLE, "%04x MR %04x (%04x)\n", g_dsp.pc, addr, gdsp_ifx_regs[addr & 0xFF]); + } return gdsp_ifx_regs[addr & 0xFF]; -/* if ((addr & 0xff) >= 0xc0 && reg_names[addr & 0x3f]) - printf("%04x MR %s (%04x)\n", g_dsp.pc, reg_names[addr & 0x3f], val); - else - printf("%04x MR %04x (%04x)\n", g_dsp.pc, addr, val);*/ } } diff --git a/Source/Core/DSPCore/Src/gdsp_interpreter.cpp b/Source/Core/DSPCore/Src/gdsp_interpreter.cpp index 733282e7f6..4b1d137425 100644 --- a/Source/Core/DSPCore/Src/gdsp_interpreter.cpp +++ b/Source/Core/DSPCore/Src/gdsp_interpreter.cpp @@ -78,10 +78,12 @@ void HandleLoop() const u16 rCallAddress = g_dsp.r[DSP_REG_ST0]; const u16 rLoopAddress = g_dsp.r[DSP_REG_ST2]; + // This does not always work correctly! + // The loop end tends to point to the second part of + // two-byte instructions! if (g_dsp.pc == (rLoopAddress + 1)) { rLoopCounter--; - if (rLoopCounter > 0) { g_dsp.pc = rCallAddress; @@ -147,6 +149,21 @@ void Run() // Used by non-thread mode. void RunCycles(int cycles) { + if (cycles < 18) + { + for (int i = 0; i < cycles; i++) + { + if (g_dsp.cr & CR_HALT) + return; + if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) + return; + Step(); + cycles--; + } + return; + } + + DSPCore_CheckExternalInterrupt(); // First, let's run a few cycles with no idle skipping so that things can progress a bit. @@ -158,7 +175,7 @@ void RunCycles(int cycles) cycles--; } - // Next, let's run a few cycles with idle skipping, so that we can skip loops. + // 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) -- cgit v1.2.3