From 9267fa627de4ee1728bd7b02a5a59755c658b0f6 Mon Sep 17 00:00:00 2001 From: dbalatoni13 Date: Tue, 12 Nov 2024 02:09:45 +0100 Subject: [PATCH] Imported dolphin/dsp --- config/GMPE01_00/symbols.txt | 32 +-- configure.py | 12 +- include/dolphin/dsp.h | 1 + src/dolphin/dsp/dsp.c | 99 +++++++++ src/dolphin/dsp/dsp_debug.c | 5 + src/dolphin/dsp/dsp_task.c | 389 +++++++++++++++++++++++++++++++++++ 6 files changed, 520 insertions(+), 18 deletions(-) create mode 100644 src/dolphin/dsp/dsp.c create mode 100644 src/dolphin/dsp/dsp_debug.c create mode 100644 src/dolphin/dsp/dsp_task.c diff --git a/config/GMPE01_00/symbols.txt b/config/GMPE01_00/symbols.txt index 5acdcfae..c1bb0fa7 100644 --- a/config/GMPE01_00/symbols.txt +++ b/config/GMPE01_00/symbols.txt @@ -4366,16 +4366,24 @@ lbl_8013C958 = .data:0x8013C958; // type:object size:0x29 scope:local data:strin lbl_8013C984 = .data:0x8013C984; // type:object size:0x29 scope:local data:string lbl_8013C9B0 = .data:0x8013C9B0; // type:object size:0x29 scope:local data:string DEMOFontBitmap = .data:0x8013C9E0; // type:object size:0xC00 align:32 -lbl_8013D5E0 = .data:0x8013D5E0; // type:object size:0xC data:string -lbl_8013D5EC = .data:0x8013D5EC; // type:object size:0x28 +lbl_8013D5E0 = .data:0x8013D5E0; // type:object size:0xC scope:local data:string +lbl_8013D5EC = .data:0x8013D5EC; // type:object size:0x28 scope:local data:string jumptable_8013D614 = .data:0x8013D614; // type:object size:0x28 scope:local jumptable_8013D698 = .data:0x8013D698; // type:object size:0x28 scope:local jumptable_8013D6C0 = .data:0x8013D6C0; // type:object size:0x28 scope:local jumptable_8013D6E8 = .data:0x8013D6E8; // type:object size:0x28 scope:local jumptable_8013D710 = .data:0x8013D710; // type:object size:0x28 scope:local ResetFunctionInfo = .data:0x8013D738; // type:object size:0x10 -lbl_8013D748 = .data:0x8013D748; // type:object size:0x38 -lbl_8013D780 = .data:0x8013D780; // type:object size:0x140 +lbl_8013D748 = .data:0x8013D748; // type:object size:0x20 scope:local data:string +lbl_8013D768 = .data:0x8013D768; // type:object size:0xC scope:local data:string +lbl_8013D774 = .data:0x8013D774; // type:object size:0xC scope:local data:string +lbl_8013D780 = .data:0x8013D780; // type:object size:0x20 scope:local data:string +lbl_8013D7A0 = .data:0x8013D7A0; // type:object size:0x30 scope:local data:string +lbl_8013D7D0 = .data:0x8013D7D0; // type:object size:0x30 scope:local data:string +lbl_8013D800 = .data:0x8013D800; // type:object size:0x30 scope:local data:string +lbl_8013D830 = .data:0x8013D830; // type:object size:0x30 scope:local data:string +lbl_8013D860 = .data:0x8013D860; // type:object size:0x30 scope:local data:string +lbl_8013D890 = .data:0x8013D890; // type:object size:0x30 scope:local data:string jumptable_8013D8C0 = .data:0x8013D8C0; // type:object size:0x68 scope:local jumptable_8013D928 = .data:0x8013D928; // type:object size:0x44 scope:local jumptable_8013D96C = .data:0x8013D96C; // type:object size:0x1C scope:local @@ -4982,7 +4990,7 @@ autoInvalidation = .sdata:0x801D38F0; // type:object size:0x4 scope:local data:4 @35 = .sdata:0x801D38F8; // type:object size:0x2 scope:local data:string @40 = .sdata:0x801D38FC; // type:object size:0x4 scope:local data:string @41 = .sdata:0x801D3900; // type:object size:0x3 scope:local data:string -lbl_801D3908 = .sdata:0x801D3908; // type:object size:0x8 data:string +lbl_801D3908 = .sdata:0x801D3908; // type:object size:0x8 scope:local data:string ClampRegion = .sdata:0x801D3910; // type:object size:0x8 scope:local data:byte ResettingChan = .sdata:0x801D3918; // type:object size:0x4 scope:local data:4byte XPatchBits = .sdata:0x801D391C; // type:object size:0x4 scope:local data:4byte @@ -7307,13 +7315,13 @@ lbl_801D63A8 = .sdata2:0x801D63A8; // type:object size:0x4 data:float lbl_801D63AC = .sdata2:0x801D63AC; // type:object size:0x4 data:float lbl_801D63B0 = .sdata2:0x801D63B0; // type:object size:0x4 data:float lbl_801D63B4 = .sdata2:0x801D63B4; // type:object size:0x4 data:float -lbl_801D63B8 = .sdata2:0x801D63B8; // type:object size:0x4 data:float -lbl_801D63BC = .sdata2:0x801D63BC; // type:object size:0x4 data:float -lbl_801D63C0 = .sdata2:0x801D63C0; // type:object size:0x8 data:double -lbl_801D63C8 = .sdata2:0x801D63C8; // type:object size:0x8 data:double -lbl_801D63D0 = .sdata2:0x801D63D0; // type:object size:0x8 data:float -lbl_801D63D8 = .sdata2:0x801D63D8; // type:object size:0x4 data:float -lbl_801D63E0 = .sdata2:0x801D63E0; // type:object size:0x8 data:double +lbl_801D63B8 = .sdata2:0x801D63B8; // type:object size:0x4 scope:local data:float +lbl_801D63BC = .sdata2:0x801D63BC; // type:object size:0x4 scope:local data:float +lbl_801D63C0 = .sdata2:0x801D63C0; // type:object size:0x8 scope:local data:double +lbl_801D63C8 = .sdata2:0x801D63C8; // type:object size:0x8 scope:local data:double +lbl_801D63D0 = .sdata2:0x801D63D0; // type:object size:0x8 scope:local data:float +lbl_801D63D8 = .sdata2:0x801D63D8; // type:object size:0x4 scope:local data:float +lbl_801D63E0 = .sdata2:0x801D63E0; // type:object size:0x8 scope:local data:double lbl_801D63E8 = .sdata2:0x801D63E8; // type:object size:0x4 data:4byte lbl_801D63EC = .sdata2:0x801D63EC; // type:object size:0x4 data:4byte lbl_801D63F0 = .sdata2:0x801D63F0; // type:object size:0x4 data:4byte diff --git a/configure.py b/configure.py index cc9c8936..27a4ba3a 100644 --- a/configure.py +++ b/configure.py @@ -517,10 +517,10 @@ config.libs = [ DolphinLib( "demo", [ - Object(NonMatching, "dolphin/demo/DEMOInit.c"), - Object(NonMatching, "dolphin/demo/DEMOFont.c"), + Object(Matching, "dolphin/demo/DEMOInit.c"), + Object(Matching, "dolphin/demo/DEMOFont.c"), Object(NonMatching, "dolphin/demo/DEMOPuts.c"), - Object(NonMatching, "dolphin/demo/DEMOStats.c"), + Object(Matching, "dolphin/demo/DEMOStats.c"), ], ), DolphinLib( @@ -546,9 +546,9 @@ config.libs = [ DolphinLib( "dsp", [ - Object(NonMatching, "dolphin/dsp/dsp.c"), - Object(NonMatching, "dolphin/dsp/dsp_debug.c"), - Object(NonMatching, "dolphin/dsp/dsp_task.c"), + Object(Matching, "dolphin/dsp/dsp.c"), + Object(Matching, "dolphin/dsp/dsp_debug.c"), + Object(Matching, "dolphin/dsp/dsp_task.c"), ], ), DolphinLib( diff --git a/include/dolphin/dsp.h b/include/dolphin/dsp.h index 368138c9..18df2eb6 100644 --- a/include/dolphin/dsp.h +++ b/include/dolphin/dsp.h @@ -59,6 +59,7 @@ DSPTaskInfo* DSPAddTask(DSPTaskInfo* task); void __DSP_exec_task(DSPTaskInfo* curr, DSPTaskInfo* next); void __DSP_boot_task(DSPTaskInfo* task); +void __DSP_insert_task(DSPTaskInfo* task); void __DSP_remove_task(DSPTaskInfo* task); void __DSP_add_task(DSPTaskInfo* task); void __DSP_debug_printf(const char* fmt, ...); diff --git a/src/dolphin/dsp/dsp.c b/src/dolphin/dsp/dsp.c new file mode 100644 index 00000000..f003f6fb --- /dev/null +++ b/src/dolphin/dsp/dsp.c @@ -0,0 +1,99 @@ +#include "dolphin/dsp.h" +#include "dolphin/os.h" + +#include "dolphin/hw_regs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static s32 __DSP_init_flag = 0; +extern DSPTaskInfo* __DSP_tmp_task; +extern DSPTaskInfo* __DSP_last_task; +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_curr_task; + +extern void __DSPHandler(__OSInterrupt, OSContext*); +extern void __DSP_debug_printf(const char* fmt, ...); +extern void __DSP_boot_task(DSPTaskInfo* task); + +u32 DSPCheckMailToDSP(void) { return (__DSPRegs[0] >> 0xF) & 1; } + +u32 DSPCheckMailFromDSP(void) { return (__DSPRegs[2] >> 0xF) & 1; } + +u32 DSPReadMailFromDSP() { + u16 reg1; + u16 reg2; + reg1 = __DSPRegs[2]; + reg2 = __DSPRegs[3]; + return reg1 << 16 | reg2; +} + +void DSPSendMailToDSP(u32 mail) { + __DSPRegs[0] = mail >> 16; + __DSPRegs[1] = mail; +} + +void DSPInit(void) { + u32 oldInt; + u16 reg; + __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", "Dec 17 2001", "18:25:00"); + + if (__DSP_init_flag == 1) { + return; + } + oldInt = OSDisableInterrupts(); + __OSSetInterruptHandler(7, __DSPHandler); + __OSUnmaskInterrupts(0x1000000); + reg = __DSPRegs[5]; + reg = (reg & ~0xA8) | 0x800; + __DSPRegs[5] = reg; + reg = __DSPRegs[5]; + reg = reg & ~0xAC; + __DSPRegs[5] = reg; + __DSP_tmp_task = 0; + __DSP_curr_task = 0; + __DSP_last_task = 0; + __DSP_first_task = 0; + __DSP_init_flag = 1; + OSRestoreInterrupts(oldInt); +} + +void DSPReset(void) { + u16 reg; + u32 oldInt; + oldInt = OSDisableInterrupts(); + reg = __DSPRegs[5]; + __DSPRegs[5] = (reg & ~0xA8) | 0x801; + __DSP_init_flag = 0; + OSRestoreInterrupts(oldInt); +} + +void DSPHalt(void) { + u16 reg; + u32 oldInt; + oldInt = OSDisableInterrupts(); + reg = __DSPRegs[5]; + __DSPRegs[5] = (reg & ~0xA8) | 4; + OSRestoreInterrupts(oldInt); +} + +u32 DSPGetDMAStatus(void) { return __DSPRegs[5] & 0x200; } + +DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) { + u32 oldInt; + oldInt = OSDisableInterrupts(); + __DSP_insert_task(task); + task->state = 0; + task->flags = 1; + OSRestoreInterrupts(oldInt); + if (task == __DSP_first_task) { + __DSP_boot_task(task); + } + + return task; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/dolphin/dsp/dsp_debug.c b/src/dolphin/dsp/dsp_debug.c new file mode 100644 index 00000000..22455a34 --- /dev/null +++ b/src/dolphin/dsp/dsp_debug.c @@ -0,0 +1,5 @@ +#include "types.h" + +void __DSP_debug_printf(const char* fmt, ...) { + // UNUSED(fmt); +} diff --git a/src/dolphin/dsp/dsp_task.c b/src/dolphin/dsp/dsp_task.c new file mode 100644 index 00000000..9ba343cf --- /dev/null +++ b/src/dolphin/dsp/dsp_task.c @@ -0,0 +1,389 @@ +#include "dolphin/dsp.h" +#include "dolphin/hw_regs.h" + +DSPTaskInfo *__DSP_curr_task; +DSPTaskInfo *__DSP_first_task; +DSPTaskInfo *__DSP_last_task; +DSPTaskInfo *__DSP_tmp_task; +DSPTaskInfo *__DSP_rude_task; + +BOOL __DSP_rude_task_pending; + +void __DSPHandler(__OSInterrupt, OSContext *context) +{ + DSPTaskInfo *tmp_task; + OSContext exceptionContext; + u16 tmp; + u32 mail; + + tmp = __DSPRegs[5]; + tmp = (u16)(tmp & ~0x28) | 0x80; + __DSPRegs[5] = tmp; + + OSClearContext(&exceptionContext); + OSSetCurrentContext(&exceptionContext); + + while (!DSPCheckMailFromDSP()) + ; + mail = DSPReadMailFromDSP(); + + if ((__DSP_curr_task->flags & DSP_TASK_FLAG_CANCEL) && (mail == 0xDCD10002)) { + mail = 0xDCD10003; + } + + switch (mail) { + case 0xDCD10000: + __DSP_curr_task->state = DSP_TASK_STATE_RUN; + + if (__DSP_curr_task->init_cb) { + (*(__DSP_curr_task->init_cb))((void *)(__DSP_curr_task)); + } + break; + case 0xDCD10001: + __DSP_curr_task->state = DSP_TASK_STATE_RUN; + if (__DSP_curr_task->res_cb) { + (*(__DSP_curr_task->res_cb))((void *)(__DSP_curr_task)); + } + break; + case 0xDCD10002: + if (__DSP_rude_task_pending) { + + if (__DSP_curr_task == __DSP_rude_task) { + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP()) { } + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + if (__DSP_curr_task->res_cb) { + (*(__DSP_curr_task->res_cb))((void *)(__DSP_curr_task)); + } + + break; + } + else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + __DSP_exec_task(__DSP_curr_task, __DSP_rude_task); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_rude_task; + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + break; + } + } + + if (__DSP_curr_task->next == NULL) { + + if (__DSP_curr_task == __DSP_first_task) { + + DSPSendMailToDSP(0xCDD10003); + while (DSPCheckMailToDSP()) + ; + + if (__DSP_curr_task->res_cb) { + (*(__DSP_curr_task->res_cb))((void *)(__DSP_curr_task)); + } + } + else { + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) { } + + __DSP_exec_task(__DSP_curr_task, __DSP_first_task); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_first_task; + } + } + else { + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) { } + + __DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next); + + __DSP_curr_task->state = DSP_TASK_STATE_YIELD; + __DSP_curr_task = __DSP_curr_task->next; + } + break; + case 0xDCD10003: + if (__DSP_rude_task_pending) { + + if (__DSP_curr_task->done_cb) { + (*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_exec_task(NULL, __DSP_rude_task); + + __DSP_remove_task(__DSP_curr_task); + __DSP_curr_task = __DSP_rude_task; + + __DSP_rude_task = NULL; + __DSP_rude_task_pending = FALSE; + + break; + } + + if (__DSP_curr_task->next == NULL) { + + if (__DSP_curr_task == __DSP_first_task) { + + if (__DSP_curr_task->done_cb) { + (*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10002); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + + __DSP_remove_task(__DSP_curr_task); + } + else { + + if (__DSP_curr_task->done_cb) { + (*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task)); + } + + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + __DSP_exec_task(NULL, __DSP_first_task); + + __DSP_curr_task = __DSP_first_task; + __DSP_remove_task(__DSP_last_task); + } + } + else { + if (__DSP_curr_task->done_cb) { + (*(__DSP_curr_task->done_cb))((void *)(__DSP_curr_task)); + } + DSPSendMailToDSP(0xCDD10001); + while (DSPCheckMailToDSP()) + ; + + __DSP_curr_task->state = DSP_TASK_STATE_DONE; + __DSP_exec_task(NULL, __DSP_curr_task->next); + + __DSP_curr_task = __DSP_curr_task->next; + __DSP_remove_task(__DSP_curr_task->prev); + } + break; + + case 0xDCD10004: + + if (__DSP_curr_task->req_cb) { + (*(__DSP_curr_task->req_cb))((void *)(__DSP_curr_task)); + } + break; + default: + break; + } + OSClearContext(&exceptionContext); + OSSetCurrentContext(context); +} + +void __DSP_exec_task(DSPTaskInfo *curr, DSPTaskInfo *next) +{ + if (curr) { + DSPSendMailToDSP((u32)(curr->dram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(curr->dram_length)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(curr->dram_addr)); + while (DSPCheckMailToDSP()) + ; + } + else { + + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + } + + DSPSendMailToDSP((u32)(next->iram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->iram_length)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->iram_addr)); + while (DSPCheckMailToDSP()) + ; + + if (DSP_TASK_STATE_INIT == next->state) { + DSPSendMailToDSP((u32)(next->dsp_init_vector)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(0)); + while (DSPCheckMailToDSP()) + ; + } + else { + DSPSendMailToDSP((u32)(next->dsp_resume_vector)); + while (DSPCheckMailToDSP()) + ; + DSPSendMailToDSP((u32)(next->dram_mmem_addr)); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)(next->dram_length)); + while (DSPCheckMailToDSP()) + ; + + DSPSendMailToDSP((u32)(next->dram_addr)); + while (DSPCheckMailToDSP()) + ; + } +} + +#define MSG_BASE 0x80F30000 +void __DSP_boot_task(DSPTaskInfo *task) +{ + + volatile u32 mail; + + while (!DSPCheckMailFromDSP()) + ; + + mail = DSPReadMailFromDSP(); + + DSPSendMailToDSP(MSG_BASE | 0xA001); + while (DSPCheckMailToDSP()) { } + DSPSendMailToDSP((u32)(task->iram_mmem_addr)); + while (DSPCheckMailToDSP()) { } + + DSPSendMailToDSP(MSG_BASE | 0xC002); + while (DSPCheckMailToDSP()) { } + DSPSendMailToDSP((u32)(task->iram_addr & 0xffff)); + while (DSPCheckMailToDSP()) { } + + DSPSendMailToDSP(MSG_BASE | 0xA002); + while (DSPCheckMailToDSP()) { } + DSPSendMailToDSP(task->iram_length); + while (DSPCheckMailToDSP()) { } + + DSPSendMailToDSP(MSG_BASE | 0xB002); + while (DSPCheckMailToDSP()) { } + DSPSendMailToDSP(0x00000000); + while (DSPCheckMailToDSP()) { } + + DSPSendMailToDSP(MSG_BASE | 0xD001); + while (DSPCheckMailToDSP()) { } + DSPSendMailToDSP((u32)(0xffff & task->dsp_init_vector)); + while (DSPCheckMailToDSP()) { } + + __DSP_debug_printf("DSP is booting task: 0x%08X\n", task); + __DSP_debug_printf("__DSP_boot_task() : IRAM MMEM ADDR: 0x%08X\n", (u32)(task->iram_mmem_addr)); + __DSP_debug_printf("__DSP_boot_task() : IRAM DSP ADDR : 0x%08X\n", (u32)(task->iram_addr)); + __DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", (u32)(task->iram_length)); + __DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", (u32)(task->dram_length)); + __DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", (u32)(task->dsp_init_vector)); +} + +void __DSP_insert_task(DSPTaskInfo *task) +{ + + DSPTaskInfo *temp; + + if (__DSP_first_task == NULL) { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = task; + task->next = task->prev = NULL; + } + else { + temp = __DSP_first_task; + + while (temp) { + if (task->priority < temp->priority) { + task->prev = temp->prev; + temp->prev = task; + task->next = temp; + if (task->prev == NULL) { + __DSP_first_task = task; + } + else { + (task->prev)->next = task; + } + break; + } + temp = temp->next; + } + + if (temp == NULL) { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; + } + } +} + +void __DSP_add_task(DSPTaskInfo *task) +{ + if (__DSP_last_task == NULL) { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = task; + task->next = task->prev = NULL; + } + else { + __DSP_last_task->next = task; + task->next = NULL; + task->prev = __DSP_last_task; + __DSP_last_task = task; + } + + task->state = DSP_TASK_STATE_INIT; + + __DSP_debug_printf("__DSP_add_task() : Added task : 0x%08X\n", task); +} + +void __DSP_remove_task(DSPTaskInfo *task) +{ + + task->flags = DSP_TASK_FLAG_CLEARALL; + task->state = DSP_TASK_STATE_DONE; + + if (__DSP_first_task == task) { + if (task->next) { + __DSP_first_task = (task->next); + task->next->prev = NULL; + } + else { + __DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL; + } + } + else if (__DSP_last_task == task) { + __DSP_last_task = (task->prev); + task->prev->next = NULL; + __DSP_curr_task = __DSP_first_task; + } + else { + __DSP_curr_task = task->next; + task->prev->next = task->next; + task->next->prev = task->prev; + } +}