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
This commit is contained in:
Shawn Hoffman 2009-07-18 16:34:11 +00:00
parent 3ad0db6830
commit 89c55c32ec
10 changed files with 500 additions and 132 deletions

View File

@ -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},

View File

@ -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

View File

@ -114,6 +114,102 @@
<References>
</References>
<Files>
<Filter
Name="tests"
>
<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
RelativePath=".\util\createtest.pl"
>
</File>
<File
RelativePath=".\util\dump_roms.ds"
>
</File>
<File
RelativePath=".\util\printresult.cpp"
>
</File>
</Filter>
<Filter
Name="templates"
>
<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=".\build.sh"
>
</File>
<File
RelativePath=".\Config.h"
>
@ -123,15 +219,7 @@
>
</File>
<File
RelativePath=".\tests\dsp_base.inc"
>
</File>
<File
RelativePath=".\dsp_interface.cpp"
>
</File>
<File
RelativePath=".\dsp_interface.h"
RelativePath="..\..\docs\DSP\dsp_rom.txt"
>
</File>
<File
@ -143,15 +231,7 @@
>
</File>
<File
RelativePath=".\mem_dump.h"
>
</File>
<File
RelativePath=".\real_dsp.cpp"
>
</File>
<File
RelativePath=".\real_dsp.h"
RelativePath=".\sbuild.sh"
>
</File>
<File

View File

@ -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

View File

@ -40,4 +40,4 @@ void IDSP::SendTask(void *addr, u16 iram_addr, u16 len, u16 start)
while (CheckMailTo());
SendMailTo(start);
while (CheckMailTo());
}
}

View File

@ -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,6 +542,48 @@ int main()
}
DCFlushRange(xfb, 0x200000);
// Use B to start over.
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_B) || (PAD_ButtonsDown(0) & PAD_BUTTON_B))
#else
if (PAD_ButtonsDown(0) & PAD_BUTTON_B)
#endif
{
dsp_steps = 0; // Let's not add the new steps after the original ones. That was just annoying.
DCInvalidateRange(dspbufC, 0x2000);
DCFlushRange(dspbufC, 0x2000);
// Reset the DSP.
real_dsp.Reset();
UpdateLastMessage("OK");
}
// Navigate between results using + and - buttons.
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_R))
#else
if (PAD_ButtonsDown(0) & PAD_TRIGGER_R)
#endif
{
show_step++;
if (show_step >= dsp_steps)
show_step = 0;
UpdateLastMessage("OK");
}
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_L))
#else
if (PAD_ButtonsDown(0) & PAD_TRIGGER_L)
#endif
{
show_step--;
if (show_step < 0)
show_step = dsp_steps - 1;
UpdateLastMessage("OK");
}
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_1) || (PAD_ButtonsDown(0) & PAD_TRIGGER_Z))
#else
@ -496,53 +607,12 @@ int main()
// Reset the DSP.
real_dsp.Reset();
strcpy(last_message, "OK");
UpdateLastMessage("OK");
// Waiting for video to synchronize (enough time to set our new microcode)
VIDEO_WaitVSync();
}
// Use B to start over.
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_B) || (PAD_ButtonsDown(0) & PAD_BUTTON_B))
#else
if (PAD_ButtonsDown(0) & PAD_BUTTON_B)
#endif
{
dsp_steps = 0; // Let's not add the new steps after the original ones. That was just annoying.
DCInvalidateRange(dspbufC, 0x2000);
DCFlushRange(dspbufC, 0x2000);
// Reset the DSP.
real_dsp.Reset();
strcpy(last_message, "OK");
}
// Navigate between results using + and - buttons.
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_R))
#else
if (PAD_ButtonsDown(0) & PAD_TRIGGER_R)
#endif
{
show_step++;
if (show_step >= dsp_steps)
show_step = 0;
strcpy(last_message, "OK");
}
#ifdef HW_RVL
if ((WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) || (PAD_ButtonsDown(0) & PAD_TRIGGER_L))
#else
if (PAD_ButtonsDown(0) & PAD_TRIGGER_L)
#endif
{
show_step--;
if (show_step < 0)
show_step = dsp_steps - 1;
strcpy(last_message, "OK");
}
#ifdef HW_RVL
// Probably could offer to save to sd gecko or something on gc...
// The future is web-based reporting ;)
@ -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);

View File

@ -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);

View File

@ -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:

View File

@ -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

View File

@ -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"
>