summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorShawn Hoffman <godisgovernment@gmail.com>2009-07-18 16:34:11 +0000
committerShawn Hoffman <godisgovernment@gmail.com>2009-07-18 16:34:11 +0000
commit89c55c32eceffda360922bc37df0f3a7eb20de0f (patch)
tree49f74c92ad6da74f0d5f0590435f6a68c646fc2e /Source
parent3ad0db68306e1aeb7c1f7750beab95e6b0039a44 (diff)
add a ucode to dspspy to dump rom areas from dsp to sd card
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3834 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/DSPCore/Src/DSPTables.cpp8
-rw-r--r--Source/DSPSpy/ConsoleHelper.h24
-rw-r--r--Source/DSPSpy/DSPSpy.vcproj112
-rw-r--r--Source/DSPSpy/Makefile3
-rw-r--r--Source/DSPSpy/dsp_interface.cpp2
-rw-r--r--Source/DSPSpy/main_spy.cpp206
-rw-r--r--Source/DSPSpy/real_dsp.cpp1
-rw-r--r--Source/DSPSpy/tests/dsp_base.inc44
-rw-r--r--Source/DSPSpy/util/dump_roms.ds186
-rw-r--r--Source/DSPTool/DSPTool.vcproj20
10 files changed, 487 insertions, 119 deletions
diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp
index 65bf4f3984..a371db3e68 100644
--- a/Source/Core/DSPCore/Src/DSPTables.cpp
+++ b/Source/Core/DSPCore/Src/DSPTables.cpp
@@ -107,8 +107,8 @@ const DSPOPCTemplate opcodes[] =
{"IFLE", 0x0273, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
{"IFNZ", 0x0274, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
{"IFZ", 0x0275, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFNC", 0x0276, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
- {"IFC", 0x0277, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFNC", 0x0276, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
+ {"IFC", 0x0277, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
{"IFLNZ", 0x027c, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
{"IFLZ", 0x027d, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL},
{"IF", 0x027f, 0xffff, DSPInterpreter::ifcc, nop, 1, 0, {}, NULL, NULL}, // This is just nop
@@ -132,8 +132,8 @@ const DSPOPCTemplate opcodes[] =
{"JRLE", 0x1703, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
{"JRNZ", 0x1704, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
{"JRZ", 0x1705, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRNC", 0x1706, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
- {"JRC", 0x1707, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRNC", 0x1706, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
+ {"JRC", 0x1707, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
{"JRLNZ", 0x170c, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
{"JRLZ", 0x170d, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
{"JMPR", 0x170f, 0xff1f, DSPInterpreter::jmprcc, nop, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}}, NULL, NULL},
diff --git a/Source/DSPSpy/ConsoleHelper.h b/Source/DSPSpy/ConsoleHelper.h
index faacff74fc..867998a6d6 100644
--- a/Source/DSPSpy/ConsoleHelper.h
+++ b/Source/DSPSpy/ConsoleHelper.h
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <iostream>
#define CON_BLACK 0
#define CON_RED 1
@@ -41,7 +42,7 @@
#define CON_BRIGHT_WHITE CON_WHITE | CON_BRIGHT
-void CON_Printf(int x, int y, const char* fmt, ...)
+inline void CON_Printf(const int x, const int y, const char* fmt, ...)
{
char tmpbuf[255];
@@ -53,7 +54,7 @@ void CON_Printf(int x, int y, const char* fmt, ...)
printf("\x1b[%d;%dH%s", y, x, tmpbuf);
}
-void CON_SetColor(u8 foreground, u8 background = CON_BLACK)
+inline void CON_SetColor(u8 foreground, u8 background = CON_BLACK)
{
u8 bright = foreground & CON_BRIGHT ? 1 : 0;
@@ -63,10 +64,27 @@ void CON_SetColor(u8 foreground, u8 background = CON_BLACK)
printf("\x1b[%d;%d;%dm", 30+foreground, bright, 40+background);
}
-void CON_Clear()
+inline void CON_Clear()
{
// Escape code to clear the whole screen.
printf("\x1b[2J");
}
+// libogc's clear escape codes are crappy
+inline void CON_BlankRow(const int y)
+{
+ int columns = 0, rows = 0;
+ CON_GetMetrics(&columns, &rows);
+ char* blank = new char[columns];
+ std::fill(blank, &blank[columns], ' ');
+ CON_Printf(0, y, "%s", blank);
+ delete blank;
+}
+
+#define CON_PrintRow(x, y, ...) \
+{ \
+ CON_BlankRow(y); \
+ CON_Printf(x, y, __VA_ARGS__); \
+}
+
#endif
diff --git a/Source/DSPSpy/DSPSpy.vcproj b/Source/DSPSpy/DSPSpy.vcproj
index 96ad0394a0..97f8e0c1bf 100644
--- a/Source/DSPSpy/DSPSpy.vcproj
+++ b/Source/DSPSpy/DSPSpy.vcproj
@@ -114,44 +114,124 @@
<References>
</References>
<Files>
- <File
- RelativePath=".\Config.h"
+ <Filter
+ Name="tests"
>
- </File>
- <File
- RelativePath=".\ConsoleHelper.h"
+ <File
+ RelativePath=".\tests\arith_test.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\dr_test.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\dsp_base.inc"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\dsp_test.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\ir_test.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\mul_test.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\neg_test.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\op_test.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\tests\unk_regs_test.ds"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="util"
>
- </File>
- <File
- RelativePath=".\tests\dsp_base.inc"
+ <File
+ RelativePath=".\util\createtest.pl"
+ >
+ </File>
+ <File
+ RelativePath=".\util\dump_roms.ds"
+ >
+ </File>
+ <File
+ RelativePath=".\util\printresult.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="templates"
>
- </File>
+ <File
+ RelativePath=".\templates\if_test.tpl"
+ >
+ </File>
+ <File
+ RelativePath=".\templates\tst_test.tpl"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="DSP Interface"
+ >
+ <File
+ RelativePath=".\dsp_interface.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\dsp_interface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\mem_dump.h"
+ >
+ </File>
+ <File
+ RelativePath=".\real_dsp.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\real_dsp.h"
+ >
+ </File>
+ </Filter>
<File
- RelativePath=".\dsp_interface.cpp"
+ RelativePath=".\build.sh"
>
</File>
<File
- RelativePath=".\dsp_interface.h"
+ RelativePath=".\Config.h"
>
</File>
<File
- RelativePath=".\main_spy.cpp"
+ RelativePath=".\ConsoleHelper.h"
>
</File>
<File
- RelativePath=".\Makefile"
+ RelativePath="..\..\docs\DSP\dsp_rom.txt"
>
</File>
<File
- RelativePath=".\mem_dump.h"
+ RelativePath=".\main_spy.cpp"
>
</File>
<File
- RelativePath=".\real_dsp.cpp"
+ RelativePath=".\Makefile"
>
</File>
<File
- RelativePath=".\real_dsp.h"
+ RelativePath=".\sbuild.sh"
>
</File>
<File
diff --git a/Source/DSPSpy/Makefile b/Source/DSPSpy/Makefile
index 690a0039ac..80f5f6f844 100644
--- a/Source/DSPSpy/Makefile
+++ b/Source/DSPSpy/Makefile
@@ -9,6 +9,7 @@ endif
#---------------------------------------------------------------------------------
# build for wii by default, make HW_TYPE=gamecube will do what it sounds like
+# NOTE: gamecube build may require use of dollz3 before running, if sending over BBA
#---------------------------------------------------------------------------------
HW_TYPE = wii
@@ -40,7 +41,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
ifeq ($(HW_TYPE), gamecube)
-LIBS := -lfat -lasnd -lmodplay -lz -logc -lm
+LIBS := -lfat -lasnd -lmodplay -lz -ldb -logc -lm
else
LIBS := -lfat -lasnd -lmodplay -lwiiuse -lbte -lz -logc -lm
endif
diff --git a/Source/DSPSpy/dsp_interface.cpp b/Source/DSPSpy/dsp_interface.cpp
index d6debd30bb..57dacf331f 100644
--- a/Source/DSPSpy/dsp_interface.cpp
+++ b/Source/DSPSpy/dsp_interface.cpp
@@ -40,4 +40,4 @@ void IDSP::SendTask(void *addr, u16 iram_addr, u16 len, u16 start)
while (CheckMailTo());
SendMailTo(start);
while (CheckMailTo());
-} \ No newline at end of file
+}
diff --git a/Source/DSPSpy/main_spy.cpp b/Source/DSPSpy/main_spy.cpp
index 8ea6c5303c..e62d0d7d76 100644
--- a/Source/DSPSpy/main_spy.cpp
+++ b/Source/DSPSpy/main_spy.cpp
@@ -32,10 +32,17 @@
#include <time.h>
#include <fat.h>
#include <fcntl.h>
+#include <debug.h>
+#include <unistd.h>
#include <ogc/color.h>
#include <ogc/consol.h>
+#ifdef _MSC_VER
+// Just for easy looking :)
+#define HW_RVL //HW_DOL
+#endif
+
#ifdef HW_RVL
#include <wiiuse/wpad.h>
#endif
@@ -55,7 +62,7 @@
// #include "virtual_dsp.h"
// Used for communications with the DSP, such as dumping registers etc.
-u16 dspbuffer[16 * 1024] __attribute__ ((aligned (0x4000)));
+u16 dspbuffer[16 * 1024] __attribute__ ((aligned (0x4000)));
static void *xfb = NULL;
void (*reboot)() = (void(*)())0x80001800;
@@ -112,9 +119,7 @@ s32 cursor_reg = 0;
// Currently selected digit.
s32 small_cursor_x;
// Value currently being edited.
-u16 *reg_value;
-
-char last_message[20] = "OK";
+u16 *reg_value;
RealDSP real_dsp;
@@ -123,8 +128,10 @@ int curUcode = 0, runningUcode = 1;
int dsp_steps = 0;
+
// When comparing regs, ignore the loop stack registers.
-bool regs_equal(int reg, u16 value1, u16 value2) {
+bool regs_equal(int reg, u16 value1, u16 value2)
+{
if (reg >= DSP_REG_ST0 && reg <= DSP_REG_ST3)
return true;
else
@@ -198,6 +205,38 @@ void print_regs(int _step, int _dsp_steps)
CON_Printf(4, 25, "%08x", count);
}
+void UpdateLastMessage(const char* msg)
+{
+ CON_PrintRow(4, 24, msg);
+}
+
+void DumpDSP_ROMs(const u16* rom, const u16* coef)
+{
+#ifdef HW_RVL
+ char filename[260] = {0};
+ sprintf(filename, "sd:/dsp_rom.bin");
+ FILE *fROM = fopen(filename, "wb");
+ sprintf(filename, "sd:/dsp_coef.bin");
+ FILE *fCOEF = fopen(filename, "wb");
+ if (fROM && fCOEF)
+ {
+ fwrite(rom, 0x2000, 1, fROM);
+ fclose(fROM);
+
+ fwrite(coef, 0x2000, 1, fCOEF);
+ fclose(fCOEF);
+ UpdateLastMessage("DSP ROMs dumped to SD");
+ }
+ else
+ {
+ UpdateLastMessage("SD Write Error");
+ }
+#else
+ // Allow to connect to gdb (dump ram... :s)
+ _break();
+#endif
+}
+
void ui_pad_sel(void)
{
#ifdef HW_RVL
@@ -288,8 +327,7 @@ void handle_dsp_mail(void)
DCFlushRange(dspbufC, 0x2000);
// Then send the code.
DCFlushRange((void *)dsp_code[curUcode], 0x2000);
- real_dsp.SendTask((void *)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]),
- 0, 4000, 0x10);
+ real_dsp.SendTask((void *)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]), 0, 4000, 0x10);
runningUcode = curUcode + 1;
}
@@ -297,15 +335,15 @@ void handle_dsp_mail(void)
{
u16* tmpBuf = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(mem_dump);
- while (DSP_CheckMailTo());
- DSP_SendMailTo((u32)tmpBuf);
- while (DSP_CheckMailTo());
- }
+ while (real_dsp.CheckMailTo());
+ real_dsp.SendMailTo((u32)tmpBuf);
+ while (real_dsp.CheckMailTo());
+ }
else if (mail == 0x8888beef)
{
- while (DSP_CheckMailTo());
- DSP_SendMailTo((u32)dspbufP);
- while (DSP_CheckMailTo());
+ while (real_dsp.CheckMailTo());
+ real_dsp.SendMailTo((u32)dspbufP);
+ while (real_dsp.CheckMailTo());
}
else if (mail == 0x8888feeb)
{
@@ -316,9 +354,26 @@ void handle_dsp_mail(void)
dsp_steps++;
- while (DSP_CheckMailTo());
- DSP_SendMailTo(0x8000DEAD);
- while (DSP_CheckMailTo());
+ while (real_dsp.CheckMailTo());
+ real_dsp.SendMailTo(0x8000dead);
+ while (real_dsp.CheckMailTo());
+ }
+ else if (mail == 0x8888c0de)
+ {
+ // DSP has copied irom to its dram...send address so it can dma it back
+ while (real_dsp.CheckMailTo());
+ real_dsp.SendMailTo((u32)dspbufP);
+ while (real_dsp.CheckMailTo());
+ }
+ else if (mail == 0x8888da7a)
+ {
+ // DSP has copied coef to its dram...send address so it can dma it back
+ while (real_dsp.CheckMailTo());
+ real_dsp.SendMailTo((u32)&dspbufP[0x1000]);
+ while (real_dsp.CheckMailTo());
+
+ // Now we can do something useful with the buffer :)
+ DumpDSP_ROMs(dspbufP, &dspbufP[0x1000]);
}
CON_Printf(2, 1, "UCode: %d/%d %s, Last mail: %08x", runningUcode, NUM_UCODES, UCODE_NAMES[runningUcode - 1], mail);
@@ -328,7 +383,7 @@ void handle_dsp_mail(void)
void dump_all_ucodes(void)
{
char filename[260] = {0};
- for(int i = 0; i < NUM_UCODES; i++)
+ for (int i = 0; i < NUM_UCODES; i++)
{
// First, change the microcode
dsp_steps = 0;
@@ -341,10 +396,11 @@ void dump_all_ucodes(void)
real_dsp.Reset();
VIDEO_WaitVSync();
- while(runningUcode != (curUcode + 1)) {
+ while (runningUcode != (curUcode + 1))
+ {
handle_dsp_mail();
- VIDEO_WaitVSync();
- }
+ VIDEO_WaitVSync();
+ }
// Then write microcode dump to file
sprintf(filename, "sd:/dsp_dump%d.bin", i + 1);
@@ -357,11 +413,11 @@ void dump_all_ucodes(void)
// Then write all the dumps.
fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f);
fclose(f);
- strcpy(last_message, "Dump Successful.");
+ UpdateLastMessage("Dump Successful.");
}
else
{
- strcpy(last_message, "SD Write Error");
+ UpdateLastMessage("SD Write Error");
break;
}
}
@@ -370,10 +426,10 @@ void dump_all_ucodes(void)
// Shove common, un-dsp-ish init things here
void InitGeneral()
{
- // Initialise the video system
+ // Initialize the video system
VIDEO_Init();
- // This function initialises the attached controllers
+ // This function initializes the attached controllers
PAD_Init();
#ifdef HW_RVL
WPAD_Init();
@@ -399,11 +455,26 @@ void InitGeneral()
if (rmode->viTVMode & VI_NON_INTERLACE)
VIDEO_WaitVSync();
- // Initialise the console, required for printf
+ // Initialize the console, required for printf
CON_Init(xfb, 20, 64, rmode->fbWidth, rmode->xfbHeight, rmode->fbWidth * VI_DISPLAY_PIX_SZ);
+#ifdef HW_RVL
// Initialize FAT so we can write to SD.
fatInit(8, false);
+#else
+ // Init debug over BBA...change IPs to suite your needs
+ tcp_localip="192.168.1.103";
+ tcp_netmask="255.255.255.0";
+ tcp_gateway="192.168.1.2";
+ DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT);
+#endif
+}
+
+void ExitToLoader()
+{
+ UpdateLastMessage("Exiting...");
+ real_dsp.Reset();
+ reboot();
}
int main()
@@ -412,9 +483,9 @@ int main()
ui_mode = UIM_SEL;
- dspbufP = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(dspbuffer);
- dspbufC = dspbuffer;
- dspbufU = (u32 *)(MEM_K0_TO_K1(dspbuffer));
+ dspbufP = (u16 *)MEM_VIRTUAL_TO_PHYSICAL(dspbuffer); // physical
+ dspbufC = dspbuffer; // cached
+ dspbufU = (u32 *)(MEM_K0_TO_K1(dspbuffer)); // uncached
DCInvalidateRange(dspbuffer, 0x2000);
for (int j = 0; j < 0x800; j++)
@@ -433,11 +504,11 @@ int main()
PAD_ScanPads();
if (PAD_ButtonsDown(0) & PAD_BUTTON_START)
- exit(0);
+ ExitToLoader();
#ifdef HW_RVL
WPAD_ScanPads();
if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME)
- exit(0);
+ ExitToLoader();
CON_Printf(2, 18, "Controls:");
CON_Printf(4, 19, "+/- to move");
@@ -455,8 +526,6 @@ int main()
print_regs(show_step, dsp_steps);
- CON_Printf(4, 24, last_message);
-
switch (ui_mode)
{
case UIM_SEL:
@@ -473,34 +542,6 @@ int main()
}
DCFlushRange(xfb, 0x200000);
-#ifdef HW_RVL
- if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_1) || (PAD_ButtonsDown(0) & PAD_TRIGGER_Z))
-#else
- if (PAD_ButtonsDown(0) & PAD_TRIGGER_Z)
-#endif
- {
- curUcode++;
- if(curUcode == NUM_UCODES)
- curUcode = 0;
-
- // Reset step counters since we're in a new ucode.
- show_step = 0;
- dsp_steps = 0;
-
- DCInvalidateRange(dspbufC, 0x2000);
- for (int n = 0 ; n < 0x2000 ; n++)
- {
- // dspbufU[n/2] = 0; dspbufC[n] = 0;
- }
- DCFlushRange(dspbufC, 0x2000);
-
- // Reset the DSP.
- real_dsp.Reset();
- strcpy(last_message, "OK");
-
- // Waiting for video to synchronize (enough time to set our new microcode)
- VIDEO_WaitVSync();
- }
// Use B to start over.
#ifdef HW_RVL
@@ -516,7 +557,7 @@ int main()
// Reset the DSP.
real_dsp.Reset();
- strcpy(last_message, "OK");
+ UpdateLastMessage("OK");
}
// Navigate between results using + and - buttons.
@@ -529,7 +570,7 @@ int main()
show_step++;
if (show_step >= dsp_steps)
show_step = 0;
- strcpy(last_message, "OK");
+ UpdateLastMessage("OK");
}
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_L))
@@ -540,7 +581,36 @@ int main()
show_step--;
if (show_step < 0)
show_step = dsp_steps - 1;
- strcpy(last_message, "OK");
+ UpdateLastMessage("OK");
+ }
+
+#ifdef HW_RVL
+ if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_1) || (PAD_ButtonsDown(0) & PAD_TRIGGER_Z))
+#else
+ if (PAD_ButtonsDown(0) & PAD_TRIGGER_Z)
+#endif
+ {
+ curUcode++;
+ if(curUcode == NUM_UCODES)
+ curUcode = 0;
+
+ // Reset step counters since we're in a new ucode.
+ show_step = 0;
+ dsp_steps = 0;
+
+ DCInvalidateRange(dspbufC, 0x2000);
+ for (int n = 0 ; n < 0x2000 ; n++)
+ {
+ // dspbufU[n/2] = 0; dspbufC[n] = 0;
+ }
+ DCFlushRange(dspbufC, 0x2000);
+
+ // Reset the DSP.
+ real_dsp.Reset();
+ UpdateLastMessage("OK");
+
+ // Waiting for video to synchronize (enough time to set our new microcode)
+ VIDEO_WaitVSync();
}
#ifdef HW_RVL
@@ -551,13 +621,9 @@ int main()
dump_all_ucodes();
}
#endif
- }
+ } // end main loop
- // Reset the DSP
- real_dsp.Reset();
-
- // Reboot back to Homebrew Channel or whatever started this binary.
- reboot();
+ ExitToLoader();
// Will never reach here, but just to be sure..
exit(0);
diff --git a/Source/DSPSpy/real_dsp.cpp b/Source/DSPSpy/real_dsp.cpp
index f4ec7505c0..8dbd4ed52a 100644
--- a/Source/DSPSpy/real_dsp.cpp
+++ b/Source/DSPSpy/real_dsp.cpp
@@ -39,7 +39,6 @@ void RealDSP::Init()
_dspReg[5] = (_dspReg[5] & ~(DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT)) | DSPCR_DSPRESET;
_dspReg[5] = (_dspReg[5] & ~(DSPCR_HALT|DSPCR_AIINT|DSPCR_ARINT|DSPCR_DSPINT));
- // This code looks odd - shouldn't we initialize level?
u32 level;
_CPU_ISR_Disable(level);
IRQ_Request(IRQ_DSP_DSP, dsp_irq_handler, NULL);
diff --git a/Source/DSPSpy/tests/dsp_base.inc b/Source/DSPSpy/tests/dsp_base.inc
index 664d0a0333..b05d06bc51 100644
--- a/Source/DSPSpy/tests/dsp_base.inc
+++ b/Source/DSPSpy/tests/dsp_base.inc
@@ -1,7 +1,7 @@
; This is the trojan program we send to the DSP from DSPSpy to figure it out.
-REGS_BASE: equ 0x0f80
-MEM_HI: equ 0x0f7E
-MEM_LO: equ 0x0f7F
+REGS_BASE: equ 0x0f80
+MEM_HI: equ 0x0f7E
+MEM_LO: equ 0x0f7F
;
; CODE STARTS HERE.
@@ -18,20 +18,19 @@ MEM_LO: equ 0x0f7F
jmp irq7
; Main code at 0x10
- sbset #0x02
- sbset #0x03
- sbclr #0x04
- sbset #0x05
- sbset #0x06
+ sbset #0x02
+ sbset #0x03
+ sbclr #0x04
+ sbset #0x05
+ sbset #0x06
s16
lri $CR, #0x00ff
; Why do we have a main label here?
main:
-
- clr $ACC1
- clr $ACC0
+ clr $ACC1
+ clr $ACC0
; get address of memory dump and copy it to DRAM
@@ -112,11 +111,10 @@ main:
lrri $ac1.m, @$ar0
lr $ar0, @REGS_BASE
- jmp start_of_test
+ jmp start_of_test
; This is where we jump when we're done testing, see above.
end_of_test:
-
nop
nop
nop
@@ -320,7 +318,7 @@ dma_copy:
lrri $ac1.m, @$ar0
lr $ar0, @REGS_BASE
- ret ; from send_back
+ ret ; from send_back
; If you are in set40 mode, use this instead of send_back if you want to stay
; in set40 mode.
@@ -339,20 +337,20 @@ dump_memory:
lri $ar1, #0x1000
bloop $ar1, _fill_loop2
- mrr $ar3, $ac0.m
+ mrr $ar3, $ac0.m
nx'ld : $AX0.H, $AX1.H, @$AR0
- mrr $ac1.m, $ar0
- mrr $ar0, $ar2
- srri @$ar0, $ax1.h
- mrr $ar2, $ar0
- mrr $ar0, $ac1.m
+ mrr $ac1.m, $ar0
+ mrr $ar0, $ar2
+ srri @$ar0, $ax1.h
+ mrr $ar2, $ar0
+ mrr $ar0, $ac1.m
- addis $acc0, #0x1
+ addis $acc0, #0x1
_fill_loop2:
nop
- ret ; from dump_memory
+ ret ; from dump_memory
-
+; Obviously this must be included directly before your test code
start_of_test:
diff --git a/Source/DSPSpy/util/dump_roms.ds b/Source/DSPSpy/util/dump_roms.ds
new file mode 100644
index 0000000000..326141d344
--- /dev/null
+++ b/Source/DSPSpy/util/dump_roms.ds
@@ -0,0 +1,186 @@
+; This ucode can copy the dsp instruction rom and coefficient table.
+; irom:
+; 0x8000 in instruction space
+; coef:
+; 0x1000 in data space
+;
+; Both irom and coef are 0x1000 words in length - remember, DSP
+; uses 16bit words
+;
+; The DSP has two address spaces, to load data from instruction
+; space you need to use 'i'-prefixed instructions.
+
+
+/********************************/
+/** HANDY THANGERS **/
+/********************************/
+; External
+MEM_BASE: equ 0x0000
+MEM_HI: equ MEM_BASE
+MEM_LO: equ MEM_BASE+1
+; DSP
+DRAM_BASE: equ 0x0000
+
+; Config reg controls dma behavior
+CR_TO_DSP: equ 0
+CR_TO_CPU: equ 1
+CR_IRAM: equ 2
+CR_DRAM: equ 0
+
+IROM_BASE: equ 0x8000
+COEF_BASE: equ 0x1000
+DUMP_SIZE: equ 0x2000 ; in bytes!
+
+
+/**************************************************************/
+/* CODE START */
+/**************************************************************/
+; iram 0x00 - Exception vectors
+; 8 vectors, 2 opcodes each
+ jmp exception0
+ jmp exception1
+ jmp exception2
+ jmp exception3
+ jmp exception4
+ jmp exception5
+ jmp exception6
+ jmp exception7
+
+; iram 0x10 - Our entry point
+ sbset #0x02
+ sbset #0x03
+ sbclr #0x04
+ sbset #0x05
+ sbset #0x06
+
+; ???
+ s16
+ lri $CR, #0x00ff
+
+/**************************************************************/
+/* MAIN */
+/**************************************************************/
+; This ucode is meant only to dump the ROMs, and as such is
+; self-contained and skimpy
+main:
+ clr $acc1
+ clr $acc0
+
+; This consumes ALL of dram! We must be careful until we dma it!
+ call copy_irom_to_dram
+; Send mail saying irom dump is done
+ call wait_for_dsp_mbox
+ si @DMBH, #0x8888
+ si @DMBL, #0xc0de
+ si @DIRQ, #0x0001
+; Get address to dma to, dma, and wait till done
+ call dma_dram_to_cmbl
+
+; Now we can start over for the coef
+ call copy_coef_to_dram
+; Send mail saying coef dump is done
+ call wait_for_dsp_mbox
+ si @DMBH, #0x8888
+ si @DMBL, #0xda7a
+ si @DIRQ, #0x0001
+; Get address to dma to, dma, and wait till done
+ call dma_dram_to_cmbl
+
+; Die
+do_halt:
+ halt
+
+/**************************************************************/
+/* HELPER FUNCTIONS */
+/**************************************************************/
+/********************************/
+/** DUMPING FUNCTIONS **/
+/********************************/
+; Dump irom from 0x8000 in instruction space
+copy_irom_to_dram:
+ lri $ar0, #IROM_BASE
+ lri $ar1, #DRAM_BASE
+ lri $ar2, #DUMP_SIZE
+ bloop $ar2, copy_irom_to_dram_end
+ ilrri $ac0.m, @$ar0
+ ; Now ac0.m is 16bits of irom!
+ srri @$ar1, $ac0.m
+copy_irom_to_dram_end:
+ nop
+ ret
+
+; Dump coef from 0x1000 in data space
+copy_coef_to_dram:
+ lri $ar0, #COEF_BASE
+ lri $ar1, #DRAM_BASE
+ lri $ar2, #DUMP_SIZE
+ bloop $ar2, copy_coef_to_dram_end
+ lrri $ac0.m, @$ar0
+ ; Now ac0.m is 16bits of coef!
+ srri @$ar1, $ac0.m
+copy_coef_to_dram_end:
+ nop
+ ret
+
+/********************************/
+/** DMA **/
+/********************************/
+; DMA implementation which does not write to dram
+; We take advantage of the fact that we know the mail is going to
+; contain the address which we should dma to
+dma_dram_to_cmbl:
+ call wait_for_cpu_mbox
+ lrs $ac0.m, @CMBL
+ andi $ac1.m, #0x7fff
+
+; Directly do dma; writing the length kicks it off
+ sr @DSMAH, $ac1.m
+ sr @DSMAL, $ac0.m
+ si @DSPA, #DRAM_BASE
+ si @DSCR, #(CR_TO_CPU|CR_DRAM)
+ si @DSBL, #DUMP_SIZE
+
+; Waits for previous DMA to complete by watching a bit in DSCR.
+wait_dma:
+ lrs $ac1.m, @DSCR
+ andcf $ac1.m, #0x0004
+ jlz wait_dma
+ ret
+
+/********************************/
+/** MAILBOX **/
+/********************************/
+; Waits for a mail to arrive in the DSP in-mailbox.
+wait_for_dsp_mbox:
+ lrs $ac1.m, @DMBH
+ andcf $ac1.m, #0x8000
+ jlz wait_for_dsp_mbox
+ ret
+
+; Waits for the CPU to grab a mail that we just sent from the DSP.
+wait_for_cpu_mbox:
+ lrs $ac1.m, @CMBH
+ andcf $ac1.m, #0x8000
+ jlnz wait_for_cpu_mbox
+ ret
+
+/********************************/
+/** EXCEPTION HANDLERS **/
+/********************************/
+; ...zey do nutzing!
+exception0:
+ rti
+exception1:
+ rti
+exception2:
+ rti
+exception3:
+ rti
+exception4:
+ rti
+exception5:
+ rti
+exception6:
+ rti
+exception7:
+ rti
diff --git a/Source/DSPTool/DSPTool.vcproj b/Source/DSPTool/DSPTool.vcproj
index 38664f65b6..1800cdbc5b 100644
--- a/Source/DSPTool/DSPTool.vcproj
+++ b/Source/DSPTool/DSPTool.vcproj
@@ -488,6 +488,26 @@
<References>
</References>
<Files>
+ <Filter
+ Name="TestData"
+ >
+ <File
+ RelativePath=".\Testdata\dsp_test.bin"
+ >
+ </File>
+ <File
+ RelativePath=".\Testdata\dsp_test.S"
+ >
+ </File>
+ <File
+ RelativePath=".\Testdata\hermes.bin"
+ >
+ </File>
+ <File
+ RelativePath=".\Testdata\hermes.s"
+ >
+ </File>
+ </Filter>
<File
RelativePath=".\Src\main.cpp"
>