You've already forked smb-decomp
mirror of
https://github.com/encounter/smb-decomp.git
synced 2026-03-30 11:38:28 -07:00
340 lines
10 KiB
C
340 lines
10 KiB
C
#include <stddef.h>
|
|
#include <dolphin.h>
|
|
|
|
#include "__dsp.h"
|
|
|
|
DSPTaskInfo *__DSP_rude_task;
|
|
int __DSP_rude_task_pending;
|
|
|
|
void __DSPHandler(__OSInterrupt intr, OSContext *ctx)
|
|
{
|
|
u8 dummy[8];
|
|
OSContext sp10;
|
|
u32 msg;
|
|
u16 temp;
|
|
|
|
temp = __DSPRegs[5];
|
|
__DSPRegs[5] = (temp & -41) | 0x80;
|
|
OSClearContext(&sp10);
|
|
OSSetCurrentContext(&sp10);
|
|
while (DSPCheckMailFromDSP() == 0)
|
|
;
|
|
msg = DSPReadMailFromDSP();
|
|
if ((__DSP_curr_task->flags & (1<<(31-0x1E)))
|
|
&& (msg + 0x232F0000) == 2)
|
|
msg = 0xDCD10003;
|
|
switch (msg)
|
|
{
|
|
case 0xDCD10000:
|
|
__DSP_curr_task->state = 1;
|
|
if (__DSP_curr_task->init_cb != NULL)
|
|
__DSP_curr_task->init_cb(__DSP_curr_task);
|
|
break;
|
|
case 0xDCD10001:
|
|
__DSP_curr_task->state = 1;
|
|
if (__DSP_curr_task->res_cb != NULL)
|
|
__DSP_curr_task->res_cb(__DSP_curr_task);
|
|
break;
|
|
case 0xDCD10002:
|
|
if (__DSP_rude_task_pending)
|
|
{
|
|
if (__DSP_curr_task == __DSP_rude_task)
|
|
{
|
|
DSPSendMailToDSP(0xCDD10003);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_rude_task = NULL;
|
|
__DSP_rude_task_pending = 0;
|
|
if (__DSP_curr_task->res_cb != NULL)
|
|
__DSP_curr_task->res_cb(__DSP_curr_task);
|
|
}
|
|
else
|
|
{
|
|
DSPSendMailToDSP(0xCDD10001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_exec_task(__DSP_curr_task, __DSP_rude_task);
|
|
__DSP_curr_task->state = 2;
|
|
__DSP_curr_task = __DSP_rude_task;
|
|
__DSP_rude_task_pending = 0;
|
|
__DSP_rude_task = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (__DSP_curr_task->next == NULL)
|
|
{
|
|
if (__DSP_curr_task == __DSP_first_task)
|
|
{
|
|
DSPSendMailToDSP(0xCDD10003);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
if (__DSP_curr_task->res_cb != NULL)
|
|
__DSP_curr_task->res_cb(__DSP_curr_task);
|
|
}
|
|
else
|
|
{
|
|
DSPSendMailToDSP(0xCDD10001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_exec_task(__DSP_curr_task, __DSP_first_task);
|
|
__DSP_curr_task->state = 2;
|
|
__DSP_curr_task = __DSP_first_task;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DSPSendMailToDSP(0xCDD10001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_exec_task(__DSP_curr_task, __DSP_curr_task->next);
|
|
__DSP_curr_task->state = 2;
|
|
__DSP_curr_task = __DSP_curr_task->next;
|
|
}
|
|
}
|
|
break;
|
|
case 0xDCD10003:
|
|
if (__DSP_rude_task_pending)
|
|
{
|
|
if (__DSP_curr_task->done_cb != NULL)
|
|
__DSP_curr_task->done_cb(__DSP_curr_task);
|
|
DSPSendMailToDSP(0xCDD10001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_exec_task(NULL, __DSP_rude_task);
|
|
__DSP_remove_task(__DSP_curr_task);
|
|
__DSP_curr_task = __DSP_rude_task;
|
|
__DSP_rude_task_pending = 0;
|
|
__DSP_rude_task = NULL;
|
|
}
|
|
else
|
|
{
|
|
if (__DSP_curr_task->next == NULL)
|
|
{
|
|
if (__DSP_curr_task == __DSP_first_task)
|
|
{
|
|
if (__DSP_curr_task->done_cb != NULL)
|
|
__DSP_curr_task->done_cb(__DSP_curr_task);
|
|
DSPSendMailToDSP(0xCDD10002);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_curr_task->state = 3;
|
|
__DSP_remove_task(__DSP_curr_task);
|
|
}
|
|
else
|
|
{
|
|
if (__DSP_curr_task->done_cb != NULL)
|
|
__DSP_curr_task->done_cb(__DSP_curr_task);
|
|
DSPSendMailToDSP(0xCDD10001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_curr_task->state = 3;
|
|
__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 != NULL)
|
|
__DSP_curr_task->done_cb(__DSP_curr_task);
|
|
DSPSendMailToDSP(0xCDD10001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_curr_task->state = 3;
|
|
__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 != NULL)
|
|
__DSP_curr_task->req_cb(__DSP_curr_task);
|
|
break;
|
|
}
|
|
OSClearContext(&sp10);
|
|
OSSetCurrentContext(ctx);
|
|
}
|
|
|
|
void __DSP_exec_task(DSPTaskInfo *a, DSPTaskInfo *b)
|
|
{
|
|
if (a != NULL)
|
|
{
|
|
DSPSendMailToDSP((u32)a->dram_mmem_addr);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(a->dram_length);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(a->dram_addr);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
}
|
|
else
|
|
{
|
|
DSPSendMailToDSP(0);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
}
|
|
DSPSendMailToDSP((u32)b->iram_mmem_addr);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(b->iram_length);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(b->iram_addr);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
if (b->state == 0)
|
|
{
|
|
DSPSendMailToDSP(b->dsp_init_vector);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
}
|
|
else
|
|
{
|
|
DSPSendMailToDSP(b->dsp_resume_vector);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP((u32)b->dram_mmem_addr);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(b->dram_length);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(b->dram_addr);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
}
|
|
}
|
|
|
|
void __DSP_boot_task(DSPTaskInfo *task)
|
|
{
|
|
volatile u32 spC;
|
|
|
|
while (DSPCheckMailFromDSP() == 0)
|
|
;
|
|
spC = DSPReadMailFromDSP();
|
|
DSPSendMailToDSP(0x80F3A001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP((u32)task->iram_mmem_addr);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0x80F3C002);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(task->iram_addr & 0xFFFF);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0x80F3A002);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(task->iram_length);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0x80F3B002);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(0x80F3D001);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
DSPSendMailToDSP(task->dsp_init_vector);
|
|
while (DSPCheckMailToDSP() != 0)
|
|
;
|
|
__DSP_debug_printf("DSP is booting task: 0x%08X\n", (u32)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", task->iram_addr);
|
|
__DSP_debug_printf("__DSP_boot_task() : IRAM LENGTH : 0x%08X\n", task->iram_length);
|
|
__DSP_debug_printf("__DSP_boot_task() : DRAM MMEM ADDR: 0x%08X\n", task->dram_length);
|
|
__DSP_debug_printf("__DSP_boot_task() : Start Vector : 0x%08X\n", task->dsp_init_vector);
|
|
}
|
|
|
|
#pragma force_active on
|
|
char string___DSP_add_task_____Added_task______0x_08X_n[] =
|
|
"__DSP_add_task() : Added task : 0x%08X\n";
|
|
#pragma force_active reset
|
|
|
|
void __DSP_insert_task(DSPTaskInfo *task)
|
|
{
|
|
DSPTaskInfo *t;
|
|
|
|
if (__DSP_first_task == NULL)
|
|
{
|
|
__DSP_curr_task = task;
|
|
__DSP_first_task = __DSP_last_task = task;
|
|
task->prev = NULL;
|
|
task->next = NULL;
|
|
return;
|
|
}
|
|
t = __DSP_first_task;
|
|
while (t != NULL)
|
|
{
|
|
if (task->priority < t->priority)
|
|
{
|
|
task->prev = t->prev;
|
|
t->prev = task;
|
|
task->next = t;
|
|
if (task->prev == NULL)
|
|
__DSP_first_task = task;
|
|
else
|
|
task->prev->next = task;
|
|
break;
|
|
}
|
|
t = t->next;
|
|
}
|
|
if (t == NULL)
|
|
{
|
|
__DSP_last_task->next = task;
|
|
task->next = NULL;
|
|
task->prev = __DSP_last_task;
|
|
__DSP_last_task = task;
|
|
}
|
|
}
|
|
|
|
void __DSP_remove_task(DSPTaskInfo *task)
|
|
{
|
|
task->flags = 0;
|
|
task->state = 3;
|
|
if (__DSP_first_task == task)
|
|
{
|
|
if (task->next != NULL)
|
|
{
|
|
__DSP_first_task = task->next;
|
|
task->next->prev = NULL;
|
|
}
|
|
else
|
|
__DSP_first_task = __DSP_last_task = __DSP_curr_task = NULL;
|
|
return;
|
|
}
|
|
if (__DSP_last_task == task)
|
|
{
|
|
__DSP_last_task = task->prev;
|
|
task->prev->next = NULL;
|
|
__DSP_curr_task = __DSP_first_task;
|
|
return;
|
|
}
|
|
__DSP_curr_task = task->next;
|
|
task->prev->next = task->next;
|
|
task->next->prev = task->prev;
|
|
}
|