dspspy: fix a bug with ConsoleHelper
dspspy: remove some alignment for some vars. (should not have caused issues anyways) dspCodeUtil: pad ucodes converted to headers to 32byte multiples with nops (this is only mimicing what is seen in nintendo ucodes, probably because their's are originating on disc) Common.h: fix typo for gcc version of GC_ALIGNED32 (wtf? how did this work before?!) createtest.pl: add "jmp end_of_test" to the end of generated ucodes. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3994 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
2060cae79b
commit
6e61c32495
|
@ -96,7 +96,7 @@
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug definions
|
// Debug definitions
|
||||||
#if defined(_DEBUG)
|
#if defined(_DEBUG)
|
||||||
#include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
#undef CHECK_HEAP_INTEGRITY
|
#undef CHECK_HEAP_INTEGRITY
|
||||||
|
@ -120,7 +120,7 @@
|
||||||
#endif
|
#endif
|
||||||
// Alignment
|
// Alignment
|
||||||
#define GC_ALIGNED16(x) __attribute__((aligned(16))) x
|
#define GC_ALIGNED16(x) __attribute__((aligned(16))) x
|
||||||
#define GC_ALIGNED32(x) __attribute__((aligned(16))) x
|
#define GC_ALIGNED32(x) __attribute__((aligned(32))) x
|
||||||
#define GC_ALIGNED64(x) __attribute__((aligned(64))) x
|
#define GC_ALIGNED64(x) __attribute__((aligned(64))) x
|
||||||
#define GC_ALIGNED16_DECL(x) __attribute__((aligned(16))) x
|
#define GC_ALIGNED16_DECL(x) __attribute__((aligned(16))) x
|
||||||
#define GC_ALIGNED64_DECL(x) __attribute__((aligned(64))) x
|
#define GC_ALIGNED64_DECL(x) __attribute__((aligned(64))) x
|
||||||
|
|
|
@ -116,29 +116,26 @@ void GenRandomCode(int size, std::vector<u16> &code)
|
||||||
void CodeToHeader(const std::vector<u16> &code, std::string _filename,
|
void CodeToHeader(const std::vector<u16> &code, std::string _filename,
|
||||||
const char *name, std::string &header)
|
const char *name, std::string &header)
|
||||||
{
|
{
|
||||||
std::vector<u16> code_copy = code;
|
std::vector<u16> code_padded = code;
|
||||||
// Add some nops at the end to align the size a bit.
|
// Pad with nops to 32byte boundary
|
||||||
while (code_copy.size() & 7)
|
while (code_padded.size() & 0x7f)
|
||||||
code_copy.push_back(0);
|
code_padded.push_back(0);
|
||||||
|
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
header.clear();
|
header.clear();
|
||||||
header.reserve(code.size() * 4);
|
header.reserve(code_padded.size() * 4);
|
||||||
header.append("#define NUM_UCODES 1\n\n");
|
header.append("#define NUM_UCODES 1\n\n");
|
||||||
std::string filename;
|
std::string filename;
|
||||||
SplitPath(_filename, NULL, &filename, NULL);
|
SplitPath(_filename, NULL, &filename, NULL);
|
||||||
header.append(StringFromFormat("const char* UCODE_NAMES[NUM_UCODES] = {\"%s\"};\n\n", filename.c_str()));
|
header.append(StringFromFormat("const char* UCODE_NAMES[NUM_UCODES] = {\"%s\"};\n\n", filename.c_str()));
|
||||||
header.append("#ifndef _MSCVER\n");
|
|
||||||
header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
|
header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
|
||||||
header.append("#else\n");
|
|
||||||
header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] __attribute__ ((aligned (64))) = {\n");
|
|
||||||
header.append("#endif\n\n");
|
|
||||||
|
|
||||||
header.append("\t{\n\t\t");
|
header.append("\t{\n\t\t");
|
||||||
for (u32 j = 0; j < code.size(); j++)
|
for (u32 j = 0; j < code_padded.size(); j++)
|
||||||
{
|
{
|
||||||
if (j && ((j & 15) == 0))
|
if (j && ((j & 15) == 0))
|
||||||
header.append("\n\t\t");
|
header.append("\n\t\t");
|
||||||
sprintf(buffer, "0x%04x, ", code[j]);
|
sprintf(buffer, "0x%04x, ", code_padded[j]);
|
||||||
header.append(buffer);
|
header.append(buffer);
|
||||||
}
|
}
|
||||||
header.append("\n\t},\n");
|
header.append("\n\t},\n");
|
||||||
|
@ -149,10 +146,18 @@ void CodeToHeader(const std::vector<u16> &code, std::string _filename,
|
||||||
void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>* filenames,
|
void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>* filenames,
|
||||||
int numCodes, const char *name, std::string &header)
|
int numCodes, const char *name, std::string &header)
|
||||||
{
|
{
|
||||||
|
std::vector<std::vector<u16> > codes_padded;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
int reserveSize = 0;
|
int reserveSize = 0;
|
||||||
for(int i = 0; i < numCodes; i++)
|
for(int i = 0; i < numCodes; i++)
|
||||||
reserveSize += (int)codes[i].size();
|
{
|
||||||
|
codes_padded.push_back(codes[i]);
|
||||||
|
// Pad with nops to 32byte boundary
|
||||||
|
while (codes_padded.at(i).size() & 0x7f)
|
||||||
|
codes_padded.at(i).push_back(0);
|
||||||
|
|
||||||
|
reserveSize += (int)codes_padded.at(i).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
header.clear();
|
header.clear();
|
||||||
|
@ -169,27 +174,19 @@ void CodesToHeader(const std::vector<u16> *codes, const std::vector<std::string>
|
||||||
header.append(buffer);
|
header.append(buffer);
|
||||||
}
|
}
|
||||||
header.append("};\n\n");
|
header.append("};\n\n");
|
||||||
header.append("#ifndef _MSCVER\n");
|
|
||||||
header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
|
header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] = {\n");
|
||||||
header.append("#else\n");
|
|
||||||
header.append("const unsigned short dsp_code[NUM_UCODES][0x1000] __attribute__ ((aligned (64))) = {\n");
|
|
||||||
header.append("#endif\n\n");
|
|
||||||
|
|
||||||
for(int i = 0; i < numCodes; i++) {
|
for(int i = 0; i < numCodes; i++)
|
||||||
|
{
|
||||||
if(codes[i].size() == 0)
|
if(codes[i].size() == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::vector<u16> code_copy = codes[i];
|
|
||||||
// Add some nops at the end to align the size a bit.
|
|
||||||
while (code_copy.size() & 7)
|
|
||||||
code_copy.push_back(0);
|
|
||||||
|
|
||||||
header.append("\t{\n\t\t");
|
header.append("\t{\n\t\t");
|
||||||
for (u32 j = 0; j < codes[i].size(); j++)
|
for (u32 j = 0; j < codes_padded.at(i).size(); j++)
|
||||||
{
|
{
|
||||||
if (j && ((j & 15) == 0))
|
if (j && ((j & 15) == 0))
|
||||||
header.append("\n\t\t");
|
header.append("\n\t\t");
|
||||||
sprintf(buffer, "0x%04x, ", codes[i][j]);
|
sprintf(buffer, "0x%04x, ", codes_padded.at(i).at(j));
|
||||||
header.append(buffer);
|
header.append(buffer);
|
||||||
}
|
}
|
||||||
header.append("\n\t},\n");
|
header.append("\n\t},\n");
|
||||||
|
|
|
@ -52,7 +52,7 @@ u16 dsp_dmem_read(u16 addr)
|
||||||
return g_dsp.dram[addr & DSP_DRAM_MASK];
|
return g_dsp.dram[addr & DSP_DRAM_MASK];
|
||||||
|
|
||||||
case 0x1: // 1xxx COEF
|
case 0x1: // 1xxx COEF
|
||||||
// DEBUG_LOG(DSPLLE, "%04x : Coef Read @ %04x", g_dsp.pc, addr);
|
DEBUG_LOG(DSPLLE, "%04x : Coef Read @ %04x", g_dsp.pc, addr);
|
||||||
return g_dsp.coef[addr & DSP_COEF_MASK];
|
return g_dsp.coef[addr & DSP_COEF_MASK];
|
||||||
|
|
||||||
case 0xf: // Fxxx HW regs
|
case 0xf: // Fxxx HW regs
|
||||||
|
|
|
@ -76,7 +76,8 @@ inline void CON_BlankRow(const int y)
|
||||||
int columns = 0, rows = 0;
|
int columns = 0, rows = 0;
|
||||||
CON_GetMetrics(&columns, &rows);
|
CON_GetMetrics(&columns, &rows);
|
||||||
char* blank = new char[columns];
|
char* blank = new char[columns];
|
||||||
std::fill(blank, &blank[columns], ' ');
|
std::fill(blank, blank + columns, ' ');
|
||||||
|
blank[columns] = '\0';
|
||||||
CON_Printf(0, y, "%s", blank);
|
CON_Printf(0, y, "%s", blank);
|
||||||
delete blank;
|
delete blank;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
|
|
||||||
void IDSP::SendTask(void *addr, u16 iram_addr, u16 len, u16 start)
|
void IDSP::SendTask(void *addr, u16 iram_addr, u16 len, u16 start)
|
||||||
{
|
{
|
||||||
|
// addr main ram addr 4byte aligned (1 Gekko word)
|
||||||
|
// iram_addr dsp addr 4byte aligned (2 DSP words)
|
||||||
|
// len block length in bytes multiple of 4
|
||||||
|
// start dsp iram entry point
|
||||||
while (CheckMailTo());
|
while (CheckMailTo());
|
||||||
SendMailTo(0x80F3A001);
|
SendMailTo(0x80F3A001);
|
||||||
while (CheckMailTo());
|
while (CheckMailTo());
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
// #include "virtual_dsp.h"
|
// #include "virtual_dsp.h"
|
||||||
|
|
||||||
// Used for communications with the DSP, such as dumping registers etc.
|
// Used for communications with the DSP, such as dumping registers etc.
|
||||||
u16 dspbuffer[16 * 1024] __attribute__ ((aligned (0x4000)));
|
u16 dspbuffer[16 * 1024];
|
||||||
|
|
||||||
static void *xfb = NULL;
|
static void *xfb = NULL;
|
||||||
void (*reboot)() = (void(*)())0x80001800;
|
void (*reboot)() = (void(*)())0x80001800;
|
||||||
|
@ -327,8 +327,11 @@ void handle_dsp_mail(void)
|
||||||
DCFlushRange(dspbufC, 0x2000);
|
DCFlushRange(dspbufC, 0x2000);
|
||||||
// Then send the code.
|
// Then send the code.
|
||||||
DCFlushRange((void *)dsp_code[curUcode], 0x2000);
|
DCFlushRange((void *)dsp_code[curUcode], 0x2000);
|
||||||
// Fill whole iram with code, entry point is just after exception vectors...0x10
|
// DMA ucode to iram base, entry point is just after exception vectors...0x10
|
||||||
real_dsp.SendTask((void *)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]), 0, 4000, 0x10);
|
// (shuffle2) 5256 is the highest I could get the dma block length to on my wii - still needs to be looked into
|
||||||
|
// for the tstaxh test, 5256 only yields up to step 325. There are 532 send_backs in the ucode, and it takes up
|
||||||
|
// almost all of the iram.
|
||||||
|
real_dsp.SendTask((void *)MEM_VIRTUAL_TO_PHYSICAL(dsp_code[curUcode]), 0, 5256, 0x10);
|
||||||
|
|
||||||
runningUcode = curUcode + 1;
|
runningUcode = curUcode + 1;
|
||||||
|
|
||||||
|
@ -338,7 +341,7 @@ void handle_dsp_mail(void)
|
||||||
else if ((mail & 0xffff0000) == 0x8bad0000)
|
else if ((mail & 0xffff0000) == 0x8bad0000)
|
||||||
{
|
{
|
||||||
// dsp_base.inc is reporting an exception happened
|
// dsp_base.inc is reporting an exception happened
|
||||||
CON_PrintRow(4, 25, "%s caused exception %x", UCODE_NAMES[curUcode], mail & 0xff);
|
CON_PrintRow(4, 25, "%s caused exception %x at step %i", UCODE_NAMES[curUcode], mail & 0xff, dsp_steps);
|
||||||
}
|
}
|
||||||
else if (mail == 0x8888dead)
|
else if (mail == 0x8888dead)
|
||||||
{
|
{
|
||||||
|
@ -426,13 +429,11 @@ void dump_all_ucodes(void)
|
||||||
// Then write all the dumps.
|
// Then write all the dumps.
|
||||||
written += fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f);
|
written += fwrite(dspreg_out, 1, dsp_steps * 32 * 2, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
char temp[100];
|
CON_PrintRow(4, 24, "Dump %i Successful. Wrote %d bytes, steps: %d", UCodeToDump, written, dsp_steps);
|
||||||
sprintf(temp, "Dump Successful. Wrote %d bytes, steps: %d", written, dsp_steps);
|
|
||||||
UpdateLastMessage(temp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UpdateLastMessage("SD Write Error");
|
CON_PrintRow(4, 24, "Dump %i Failed", UCodeToDump);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ for(my $i = 0;$i < scalar(@cmdList);$i++) {
|
||||||
open(OUTPUT, ">$name$j.tst");
|
open(OUTPUT, ">$name$j.tst");
|
||||||
print OUTPUT generateSRFull($header, $body, $j*$ucodes,
|
print OUTPUT generateSRFull($header, $body, $j*$ucodes,
|
||||||
($j+1)*$ucodes-1);
|
($j+1)*$ucodes-1);
|
||||||
|
print OUTPUT "jmp end_of_test";
|
||||||
close(OUTPUT);
|
close(OUTPUT);
|
||||||
print NAMES "$name$j.tst";
|
print NAMES "$name$j.tst";
|
||||||
|
|
||||||
|
|
|
@ -1,186 +1,186 @@
|
||||||
; This ucode can copy the dsp instruction rom and coefficient table.
|
; This ucode can copy the dsp instruction rom and coefficient table.
|
||||||
; irom:
|
; irom:
|
||||||
; 0x8000 in instruction space
|
; 0x8000 in instruction space
|
||||||
; coef:
|
; coef:
|
||||||
; 0x1000 in data space
|
; 0x1000 in data space
|
||||||
;
|
;
|
||||||
; Both irom and coef are 0x1000 words in length - remember, DSP
|
; Both irom and coef are 0x1000 words in length - remember, DSP
|
||||||
; uses 16bit words
|
; uses 16bit words
|
||||||
;
|
;
|
||||||
; The DSP has two address spaces, to load data from instruction
|
; The DSP has two address spaces, to load data from instruction
|
||||||
; space you need to use 'i'-prefixed instructions.
|
; space you need to use 'i'-prefixed instructions.
|
||||||
|
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
/** HANDY THANGERS **/
|
/** HANDY THANGERS **/
|
||||||
/********************************/
|
/********************************/
|
||||||
; External
|
; External
|
||||||
MEM_BASE: equ 0x0000
|
MEM_BASE: equ 0x0000
|
||||||
MEM_HI: equ MEM_BASE
|
MEM_HI: equ MEM_BASE
|
||||||
MEM_LO: equ MEM_BASE+1
|
MEM_LO: equ MEM_BASE+1
|
||||||
; DSP
|
; DSP
|
||||||
DRAM_BASE: equ 0x0000
|
DRAM_BASE: equ 0x0000
|
||||||
|
|
||||||
; Config reg controls dma behavior
|
; Config reg controls dma behavior
|
||||||
CR_TO_DSP: equ 0
|
CR_TO_DSP: equ 0
|
||||||
CR_TO_CPU: equ 1
|
CR_TO_CPU: equ 1
|
||||||
CR_IRAM: equ 2
|
CR_IRAM: equ 2
|
||||||
CR_DRAM: equ 0
|
CR_DRAM: equ 0
|
||||||
|
|
||||||
IROM_BASE: equ 0x8000
|
IROM_BASE: equ 0x8000
|
||||||
COEF_BASE: equ 0x1000
|
COEF_BASE: equ 0x1000
|
||||||
DUMP_SIZE: equ 0x2000 ; in bytes!
|
DUMP_SIZE: equ 0x2000 ; in bytes!
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* CODE START */
|
/* CODE START */
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
; iram 0x00 - Exception vectors
|
; iram 0x00 - Exception vectors
|
||||||
; 8 vectors, 2 opcodes each
|
; 8 vectors, 2 opcodes each
|
||||||
jmp exception0
|
jmp exception0
|
||||||
jmp exception1
|
jmp exception1
|
||||||
jmp exception2
|
jmp exception2
|
||||||
jmp exception3
|
jmp exception3
|
||||||
jmp exception4
|
jmp exception4
|
||||||
jmp exception5
|
jmp exception5
|
||||||
jmp exception6
|
jmp exception6
|
||||||
jmp exception7
|
jmp exception7
|
||||||
|
|
||||||
; iram 0x10 - Our entry point
|
; iram 0x10 - Our entry point
|
||||||
sbset #0x02
|
sbset #0x02
|
||||||
sbset #0x03
|
sbset #0x03
|
||||||
sbclr #0x04
|
sbclr #0x04
|
||||||
sbset #0x05
|
sbset #0x05
|
||||||
sbset #0x06
|
sbset #0x06
|
||||||
|
|
||||||
; ???
|
; ???
|
||||||
s16
|
s16
|
||||||
lri $CR, #0x00ff
|
lri $CR, #0x00ff
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* MAIN */
|
/* MAIN */
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
; This ucode is meant only to dump the ROMs, and as such is
|
; This ucode is meant only to dump the ROMs, and as such is
|
||||||
; self-contained and skimpy
|
; self-contained and skimpy
|
||||||
main:
|
main:
|
||||||
clr $acc1
|
clr $acc1
|
||||||
clr $acc0
|
clr $acc0
|
||||||
|
|
||||||
; This consumes ALL of dram! We must be careful until we dma it!
|
; This consumes ALL of dram! We must be careful until we dma it!
|
||||||
call copy_irom_to_dram
|
call copy_irom_to_dram
|
||||||
; Send mail saying irom dump is done
|
; Send mail saying irom dump is done
|
||||||
call wait_for_dsp_mbox
|
call wait_for_dsp_mbox
|
||||||
si @DMBH, #0x8888
|
si @DMBH, #0x8888
|
||||||
si @DMBL, #0xc0de
|
si @DMBL, #0xc0de
|
||||||
si @DIRQ, #0x0001
|
si @DIRQ, #0x0001
|
||||||
; Get address to dma to, dma, and wait till done
|
; Get address to dma to, dma, and wait till done
|
||||||
call dma_dram_to_cmbl
|
call dma_dram_to_cmbl
|
||||||
|
|
||||||
; Now we can start over for the coef
|
; Now we can start over for the coef
|
||||||
call copy_coef_to_dram
|
call copy_coef_to_dram
|
||||||
; Send mail saying coef dump is done
|
; Send mail saying coef dump is done
|
||||||
call wait_for_dsp_mbox
|
call wait_for_dsp_mbox
|
||||||
si @DMBH, #0x8888
|
si @DMBH, #0x8888
|
||||||
si @DMBL, #0xda7a
|
si @DMBL, #0xda7a
|
||||||
si @DIRQ, #0x0001
|
si @DIRQ, #0x0001
|
||||||
; Get address to dma to, dma, and wait till done
|
; Get address to dma to, dma, and wait till done
|
||||||
call dma_dram_to_cmbl
|
call dma_dram_to_cmbl
|
||||||
|
|
||||||
; Die
|
; Die
|
||||||
do_halt:
|
do_halt:
|
||||||
halt
|
halt
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/* HELPER FUNCTIONS */
|
/* HELPER FUNCTIONS */
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
/********************************/
|
/********************************/
|
||||||
/** DUMPING FUNCTIONS **/
|
/** DUMPING FUNCTIONS **/
|
||||||
/********************************/
|
/********************************/
|
||||||
; Dump irom from 0x8000 in instruction space
|
; Dump irom from 0x8000 in instruction space
|
||||||
copy_irom_to_dram:
|
copy_irom_to_dram:
|
||||||
lri $ar0, #IROM_BASE
|
lri $ar0, #IROM_BASE
|
||||||
lri $ar1, #DRAM_BASE
|
lri $ar1, #DRAM_BASE
|
||||||
lri $ar2, #DUMP_SIZE/2 ; each iteration copies a word
|
lri $ar2, #DUMP_SIZE/2 ; each iteration copies a word
|
||||||
bloop $ar2, copy_irom_to_dram_end
|
bloop $ar2, copy_irom_to_dram_end
|
||||||
ilrri $ac0.m, @$ar0
|
ilrri $ac0.m, @$ar0
|
||||||
; Now ac0.m is 16bits of irom!
|
; Now ac0.m is 16bits of irom!
|
||||||
srri @$ar1, $ac0.m
|
srri @$ar1, $ac0.m
|
||||||
copy_irom_to_dram_end:
|
copy_irom_to_dram_end:
|
||||||
nop
|
nop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Dump coef from 0x1000 in data space
|
; Dump coef from 0x1000 in data space
|
||||||
copy_coef_to_dram:
|
copy_coef_to_dram:
|
||||||
lri $ar0, #COEF_BASE
|
lri $ar0, #COEF_BASE
|
||||||
lri $ar1, #DRAM_BASE
|
lri $ar1, #DRAM_BASE
|
||||||
lri $ar2, #DUMP_SIZE/2 ; each iteration copies a word
|
lri $ar2, #DUMP_SIZE/2 ; each iteration copies a word
|
||||||
bloop $ar2, copy_coef_to_dram_end
|
bloop $ar2, copy_coef_to_dram_end
|
||||||
lrri $ac0.m, @$ar0
|
lrri $ac0.m, @$ar0
|
||||||
; Now ac0.m is 16bits of coef!
|
; Now ac0.m is 16bits of coef!
|
||||||
srri @$ar1, $ac0.m
|
srri @$ar1, $ac0.m
|
||||||
copy_coef_to_dram_end:
|
copy_coef_to_dram_end:
|
||||||
nop
|
nop
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
/** DMA **/
|
/** DMA **/
|
||||||
/********************************/
|
/********************************/
|
||||||
; DMA implementation which does not write to dram
|
; DMA implementation which does not write to dram
|
||||||
; We take advantage of the fact that we know the mail is going to
|
; We take advantage of the fact that we know the mail is going to
|
||||||
; contain the address which we should dma to
|
; contain the address which we should dma to
|
||||||
dma_dram_to_cmbl:
|
dma_dram_to_cmbl:
|
||||||
call wait_for_cpu_mbox
|
call wait_for_cpu_mbox
|
||||||
lrs $ac0.m, @CMBL
|
lrs $ac0.m, @CMBL
|
||||||
andi $ac1.m, #0x7fff
|
andi $ac1.m, #0x7fff
|
||||||
|
|
||||||
; Directly do dma; writing the length kicks it off
|
; Directly do dma; writing the length kicks it off
|
||||||
sr @DSMAH, $ac1.m
|
sr @DSMAH, $ac1.m
|
||||||
sr @DSMAL, $ac0.m
|
sr @DSMAL, $ac0.m
|
||||||
si @DSPA, #DRAM_BASE
|
si @DSPA, #DRAM_BASE
|
||||||
si @DSCR, #(CR_TO_CPU|CR_DRAM)
|
si @DSCR, #(CR_TO_CPU|CR_DRAM)
|
||||||
si @DSBL, #DUMP_SIZE
|
si @DSBL, #DUMP_SIZE
|
||||||
|
|
||||||
; Waits for previous DMA to complete by watching a bit in DSCR.
|
; Waits for previous DMA to complete by watching a bit in DSCR.
|
||||||
wait_dma:
|
wait_dma:
|
||||||
lrs $ac1.m, @DSCR
|
lrs $ac1.m, @DSCR
|
||||||
andcf $ac1.m, #0x0004
|
andcf $ac1.m, #0x0004
|
||||||
jlz wait_dma
|
jlz wait_dma
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
/** MAILBOX **/
|
/** MAILBOX **/
|
||||||
/********************************/
|
/********************************/
|
||||||
; Waits for a mail to arrive in the DSP in-mailbox.
|
; Waits for a mail to arrive in the DSP in-mailbox.
|
||||||
wait_for_dsp_mbox:
|
wait_for_dsp_mbox:
|
||||||
lrs $ac1.m, @DMBH
|
lrs $ac1.m, @DMBH
|
||||||
andcf $ac1.m, #0x8000
|
andcf $ac1.m, #0x8000
|
||||||
jlz wait_for_dsp_mbox
|
jlz wait_for_dsp_mbox
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Waits for the CPU to grab a mail that we just sent from the DSP.
|
; Waits for the CPU to grab a mail that we just sent from the DSP.
|
||||||
wait_for_cpu_mbox:
|
wait_for_cpu_mbox:
|
||||||
lrs $ac1.m, @CMBH
|
lrs $ac1.m, @CMBH
|
||||||
andcf $ac1.m, #0x8000
|
andcf $ac1.m, #0x8000
|
||||||
jlnz wait_for_cpu_mbox
|
jlnz wait_for_cpu_mbox
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
/** EXCEPTION HANDLERS **/
|
/** EXCEPTION HANDLERS **/
|
||||||
/********************************/
|
/********************************/
|
||||||
; ...zey do nutzing!
|
; ...zey do nutzing!
|
||||||
exception0:
|
exception0:
|
||||||
rti
|
rti
|
||||||
exception1:
|
exception1:
|
||||||
rti
|
rti
|
||||||
exception2:
|
exception2:
|
||||||
rti
|
rti
|
||||||
exception3:
|
exception3:
|
||||||
rti
|
rti
|
||||||
exception4:
|
exception4:
|
||||||
rti
|
rti
|
||||||
exception5:
|
exception5:
|
||||||
rti
|
rti
|
||||||
exception6:
|
exception6:
|
||||||
rti
|
rti
|
||||||
exception7:
|
exception7:
|
||||||
rti
|
rti
|
||||||
|
|
|
@ -70,6 +70,7 @@ IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler)
|
||||||
return new CUCode_Zelda(_rMailHandler, _CRC);
|
return new CUCode_Zelda(_rMailHandler, _CRC);
|
||||||
|
|
||||||
// WII CRCs
|
// WII CRCs
|
||||||
|
case 0x2ea36ce6: // Wii THP demo
|
||||||
case 0xb7eb9a9c: // Wii Pikmin - PAL
|
case 0xb7eb9a9c: // Wii Pikmin - PAL
|
||||||
case 0xeaeb38cc: // Wii Pikmin 2 - PAL
|
case 0xeaeb38cc: // Wii Pikmin 2 - PAL
|
||||||
case 0x6c3f6f94: // zelda - PAL
|
case 0x6c3f6f94: // zelda - PAL
|
||||||
|
|
Loading…
Reference in New Issue