From bb06a53e28ee3403e92e42aeba303ac69aecf3d6 Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sun, 7 Jun 2009 11:06:40 +0000 Subject: DSP LLE: Just some renaming and cleanup. Prepared for proper base address support in disassembly. Added a "DebugInterface" for the DSP which would allow us to hook up a CodeView .. although CoreView currently doesn't have any support for variable-length instructions. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3351 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/Debugger/DebugInterface.h | 1 - Source/Core/DSPCore/Src/DSPCodeUtil.cpp | 8 +- Source/Core/DSPCore/Src/DSPCore.cpp | 122 +++++++++++-------------- Source/Core/DSPCore/Src/DSPCore.h | 20 ++-- Source/Core/DSPCore/Src/disassemble.cpp | 6 +- Source/Core/DSPCore/Src/disassemble.h | 4 +- Source/Core/DSPCore/Src/gdsp_aram.cpp | 4 +- Source/Core/DSPCore/Src/gdsp_ext_op.cpp | 3 +- Source/Core/DSPCore/Src/gdsp_interpreter.cpp | 8 +- 9 files changed, 74 insertions(+), 102 deletions(-) (limited to 'Source/Core') diff --git a/Source/Core/Core/Src/Debugger/DebugInterface.h b/Source/Core/Core/Src/Debugger/DebugInterface.h index af2776ca24..7df1405e8e 100644 --- a/Source/Core/Core/Src/Debugger/DebugInterface.h +++ b/Source/Core/Core/Src/Debugger/DebugInterface.h @@ -13,7 +13,6 @@ public: virtual void disasm(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} virtual void getRawMemoryString(unsigned int /*address*/, char *dest, int /*max_size*/) {strcpy(dest, "NODEBUGGER");} virtual int getInstructionSize(int /*instruction*/) {return 1;} - virtual bool isAlive() {return true;} virtual bool isBreakpoint(unsigned int /*address*/) {return false;} virtual void setBreakpoint(unsigned int /*address*/){} diff --git a/Source/Core/DSPCore/Src/DSPCodeUtil.cpp b/Source/Core/DSPCore/Src/DSPCodeUtil.cpp index 2d247231e4..c78f0caae3 100644 --- a/Source/Core/DSPCore/Src/DSPCodeUtil.cpp +++ b/Source/Core/DSPCore/Src/DSPCodeUtil.cpp @@ -59,7 +59,7 @@ bool Disassemble(const std::vector &code, bool line_numbers, std::string &t settings.decode_registers = true; DSPDisassembler disasm(settings); - bool success = disasm.Disassemble(0, code, text); + bool success = disasm.Disassemble(0, code, 0x0000, text); return success; } @@ -80,9 +80,9 @@ bool Compare(const std::vector &code1, const std::vector &code2) { std::string line1, line2; u16 pc = i; - disassembler.DisOpcode(&code1[0], 2, &pc, line1); + disassembler.DisOpcode(&code1[0], 0x0000, 2, &pc, line1); pc = i; - disassembler.DisOpcode(&code2[0], 2, &pc, line2); + disassembler.DisOpcode(&code2[0], 0x0000, 2, &pc, line2); printf("!! %04x : %04x vs %04x - %s vs %s\n", i, code1[i], code2[i], line1.c_str(), line2.c_str()); } } @@ -94,7 +94,7 @@ bool Compare(const std::vector &code1, const std::vector &code2) { u16 pc = i; std::string line; - disassembler.DisOpcode(&longest[0], 2, &pc, line); + disassembler.DisOpcode(&longest[0], 0x0000, 2, &pc, line); printf("!! %s\n", line.c_str()); } } diff --git a/Source/Core/DSPCore/Src/DSPCore.cpp b/Source/Core/DSPCore/Src/DSPCore.cpp index ac684f5e9a..d9903871e2 100644 --- a/Source/Core/DSPCore/Src/DSPCore.cpp +++ b/Source/Core/DSPCore/Src/DSPCore.cpp @@ -32,16 +32,38 @@ #include "gdsp_registers.h" #include "gdsp_opcodes_helper.h" -//namespace DSPCore -//{ - SDSP g_dsp; +static bool LoadRom(const char *fname, int size_in_words, u16 *rom) +{ + FILE *pFile = fopen(fname, "rb"); + const size_t size_in_bytes = size_in_words * sizeof(u16); + if (pFile) + { + size_t read_bytes = fread(rom, 1, size_in_bytes, pFile); + if (read_bytes != size_in_bytes) + { + PanicAlert("ROM %s too short : %i/%i", fname, (int)read_bytes, (int)size_in_bytes); + fclose(pFile); + return false; + } + fclose(pFile); + + // Byteswap the rom. + for (int i = 0; i < DSP_IROM_SIZE; i++) + rom[i] = Common::swap16(rom[i]); -//------------------------------------------------------------------------------- + return true; + } + // Always keep ROMs write protected. + WriteProtectMemory(g_dsp.irom, size_in_bytes, false); + return false; +} -void gdsp_init() +bool DSPCore_Init(const char *irom_filename, const char *coef_filename) { + g_dsp.step_counter = 0; + g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE); g_dsp.iram = (u16*)AllocateMemoryPages(DSP_IRAM_BYTE_SIZE); g_dsp.dram = (u16*)AllocateMemoryPages(DSP_DRAM_BYTE_SIZE); @@ -51,6 +73,10 @@ void gdsp_init() memset(g_dsp.irom, 0, DSP_IROM_BYTE_SIZE); memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE); + // Try to load real ROM contents. Failing this, only homebrew will work correctly with the DSP. + LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom); + LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef); + for (int i = 0; i < 32; i++) { g_dsp.r[i] = 0; @@ -74,14 +100,15 @@ void gdsp_init() // Just zero out DRAM. for (int i = 0; i < DSP_DRAM_SIZE; i++) { - g_dsp.dram[i] = 0x2100; + g_dsp.dram[i] = 0; } - // copied from a real console after the custom UCode has been loaded - g_dsp.r[0x08] = 0xffff; - g_dsp.r[0x09] = 0xffff; - g_dsp.r[0x0a] = 0xffff; - g_dsp.r[0x0b] = 0xffff; + // Copied from a real console after the custom UCode has been loaded. + // These are the indexing wrapping registers. + g_dsp.r[DSP_REG_WR0] = 0xffff; + g_dsp.r[DSP_REG_WR1] = 0xffff; + g_dsp.r[DSP_REG_WR2] = 0xffff; + g_dsp.r[DSP_REG_WR3] = 0xffff; g_dsp.cr = 0x804; gdsp_ifx_init(); @@ -90,9 +117,11 @@ void gdsp_init() // in new ucodes. WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); DSPAnalyzer::Analyze(); + + return true; } -void gdsp_shutdown() +void DSPCore_Shutdown() { FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE); FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE); @@ -100,71 +129,24 @@ void gdsp_shutdown() FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE); } - -void gdsp_reset() +void DSPCore_Reset() { _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "reset while exception"); g_dsp.pc = DSP_RESET_VECTOR; g_dsp.exception_in_progress_hack = false; -} - -void gdsp_generate_exception(u8 level) -{ - g_dsp.exceptions |= 1 << level; + g_dsp.r[DSP_REG_WR0] = 0xffff; + g_dsp.r[DSP_REG_WR1] = 0xffff; + g_dsp.r[DSP_REG_WR2] = 0xffff; + g_dsp.r[DSP_REG_WR3] = 0xffff; } -bool gdsp_load_irom(const char *fname) +void DSPCore_SetException(u8 level) { - FILE *pFile = fopen(fname, "rb"); - if (pFile) - { - size_t size_in_bytes = DSP_IROM_SIZE * sizeof(u16); - size_t read_bytes = fread(g_dsp.irom, 1, size_in_bytes, pFile); - if (read_bytes != size_in_bytes) - { - PanicAlert("IROM too short : %i/%i", (int)read_bytes, (int)size_in_bytes); - fclose(pFile); - return false; - } - fclose(pFile); - - // Byteswap the rom. - for (int i = 0; i < DSP_IROM_SIZE; i++) - g_dsp.irom[i] = Common::swap16(g_dsp.irom[i]); - - return true; - } - // Always keep IROM write protected. - WriteProtectMemory(g_dsp.irom, DSP_IROM_BYTE_SIZE, false); - return false; -} - -bool gdsp_load_coef(const char *fname) -{ - FILE *pFile = fopen(fname, "rb"); - if (pFile) - { - size_t size_in_bytes = DSP_COEF_SIZE * sizeof(u16); - size_t read_bytes = fread(g_dsp.coef, 1, size_in_bytes, pFile); - if (read_bytes != size_in_bytes) - { - PanicAlert("COEF too short : %i/%i", (int)read_bytes, (int)size_in_bytes); - fclose(pFile); - return false; - } - fclose(pFile); - // Byteswap the rom. - for (int i = 0; i < DSP_IROM_SIZE; i++) - g_dsp.coef[i] = Common::swap16(g_dsp.coef[i]); - return true; - } - // Always keep COEF write protected. We unprotect only when DMA-ing - WriteProtectMemory(g_dsp.coef, DSP_COEF_BYTE_SIZE, false); - return false; + g_dsp.exceptions |= 1 << level; } -void gdsp_check_external_int() +void DSPCore_CheckExternalInterrupt() { // check if there is an external interrupt if (g_dsp.cr & CR_EXTERNAL_INT) @@ -172,13 +154,13 @@ void gdsp_check_external_int() if (dsp_SR_is_flag_set(FLAG_ENABLE_INTERUPT) && (g_dsp.exception_in_progress_hack == false)) { // level 7 is the interrupt exception - gdsp_generate_exception(7); + DSPCore_SetException(7); g_dsp.cr &= ~0x0002; } } } -void gdsp_check_exceptions() +void DSPCore_CheckExceptions() { // check exceptions if ((g_dsp.exceptions != 0) && (!g_dsp.exception_in_progress_hack)) @@ -201,5 +183,3 @@ void gdsp_check_exceptions() } } } - -//} // namespace diff --git a/Source/Core/DSPCore/Src/DSPCore.h b/Source/Core/DSPCore/Src/DSPCore.h index fa0232929b..4d0537adf4 100644 --- a/Source/Core/DSPCore/Src/DSPCore.h +++ b/Source/Core/DSPCore/Src/DSPCore.h @@ -26,9 +26,6 @@ #ifndef _DSPCORE_H #define _DSPCORE_H -//namespace DSPCore -//{ - #define DSP_IRAM_BYTE_SIZE 0x2000 #define DSP_IRAM_SIZE 0x1000 #define DSP_IRAM_MASK 0x0fff @@ -83,19 +80,14 @@ struct SDSP extern SDSP g_dsp; -void gdsp_init(); -void gdsp_reset(); -void gdsp_shutdown(); - -bool gdsp_load_irom(const char *filename); -bool gdsp_load_coef(const char *filename); +bool DSPCore_Init(const char *irom_filename, const char *coef_filename); +void DSPCore_Reset(); +void DSPCore_Shutdown(); // Frees all allocated memory. -void gdsp_check_external_int(); -void gdsp_check_exceptions(); +void DSPCore_CheckExternalInterrupt(); +void DSPCore_CheckExceptions(); // sets a flag in the pending exception register. -void gdsp_generate_exception(u8 level); - -//} // namespace +void DSPCore_SetException(u8 level); #endif // _DSPCORE_H diff --git a/Source/Core/DSPCore/Src/disassemble.cpp b/Source/Core/DSPCore/Src/disassemble.cpp index dc3841745c..b3ffd72ede 100644 --- a/Source/Core/DSPCore/Src/disassemble.cpp +++ b/Source/Core/DSPCore/Src/disassemble.cpp @@ -71,7 +71,7 @@ DSPDisassembler::~DSPDisassembler() fclose(uo); } -bool DSPDisassembler::Disassemble(int start_pc, const std::vector &code, std::string &text) +bool DSPDisassembler::Disassemble(int start_pc, const std::vector &code, int base_addr, std::string &text) { const char *tmp1 = "tmp1.bin"; const char *tmp2 = "tmp.txt"; @@ -186,7 +186,7 @@ static void MakeLowerCase(char *ptr) } } -void DSPDisassembler::DisOpcode(const u16 *binbuf, int pass, u16 *pc, std::string &dest) +void DSPDisassembler::DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 *pc, std::string &dest) { char buffer[256]; char *buf = buffer; @@ -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, pass, &pc, output); + DisOpcode(binbuf, 0x0000, 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 9f5242aa2c..96f1fb7b88 100644 --- a/Source/Core/DSPCore/Src/disassemble.h +++ b/Source/Core/DSPCore/Src/disassemble.h @@ -63,11 +63,11 @@ public: DSPDisassembler(const AssemblerSettings &settings); ~DSPDisassembler(); - bool Disassemble(int start_pc, const std::vector &code, std::string &text); + bool Disassemble(int start_pc, const std::vector &code, int base_addr, std::string &text); // 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 pass, u16 *pc, std::string &dest); + void DisOpcode(const u16 *binbuf, int base_addr, int pass, u16 *pc, std::string &dest); private: // Moves PC forward and writes the result to dest. diff --git a/Source/Core/DSPCore/Src/gdsp_aram.cpp b/Source/Core/DSPCore/Src/gdsp_aram.cpp index 1ca84a3c5d..d34de5515d 100644 --- a/Source/Core/DSPCore/Src/gdsp_aram.cpp +++ b/Source/Core/DSPCore/Src/gdsp_aram.cpp @@ -103,8 +103,8 @@ u16 dsp_read_aram() Address = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL]; // Do we really need both? - gdsp_generate_exception(3); - gdsp_generate_exception(5); + DSPCore_SetException(3); + DSPCore_SetException(5); // Somehow, YN1 and YN2 must be initialized with their "loop" values, so yeah, // it seems likely that we should raise an exception to let the DSP program do that, diff --git a/Source/Core/DSPCore/Src/gdsp_ext_op.cpp b/Source/Core/DSPCore/Src/gdsp_ext_op.cpp index 43c4345dac..67119eca2e 100644 --- a/Source/Core/DSPCore/Src/gdsp_ext_op.cpp +++ b/Source/Core/DSPCore/Src/gdsp_ext_op.cpp @@ -35,10 +35,11 @@ // "index" register (the second four, IXx). The addressing registers will wrap // in odd ways, dictated by the corresponding wrapping register, WP0-3. -// The following should be applied as a decrement: +// The following should be applied as a decrement (and is applied by dsp_decrement_addr_reg): // ar[i] = (ar[i] & wp[i]) == 0 ? ar[i] | wp[i] : ar[i] - 1; // I have not found the corresponding algorithms for increments yet. // It's gotta be fairly simple though. See R3123, R3125 in Google Code. +// (May have something to do with (ar[i] ^ wp[i]) == 0) namespace DSPInterpreter { diff --git a/Source/Core/DSPCore/Src/gdsp_interpreter.cpp b/Source/Core/DSPCore/Src/gdsp_interpreter.cpp index 757ddf9aac..733282e7f6 100644 --- a/Source/Core/DSPCore/Src/gdsp_interpreter.cpp +++ b/Source/Core/DSPCore/Src/gdsp_interpreter.cpp @@ -45,7 +45,7 @@ void WriteCR(u16 val) // reset if (val & 0x0001) { - gdsp_reset(); + DSPCore_Reset(); } val &= ~0x0001; @@ -99,7 +99,7 @@ void HandleLoop() void Step() { - gdsp_check_exceptions(); + DSPCore_CheckExceptions(); g_dsp.step_counter++; @@ -133,7 +133,7 @@ void Run() if (DSPHost_Running()) break; - gdsp_check_external_int(); + DSPCore_CheckExternalInterrupt(); // This number (500) is completely arbitrary. TODO: tweak. for (int i = 0; i < 500 && !(g_dsp.cr & CR_HALT); i++) Step(); @@ -147,7 +147,7 @@ void Run() // Used by non-thread mode. void RunCycles(int cycles) { - gdsp_check_external_int(); + DSPCore_CheckExternalInterrupt(); // 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++) -- cgit v1.2.3