summaryrefslogtreecommitdiff
path: root/src/Dolphin/dsp/dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Dolphin/dsp/dsp.c')
-rw-r--r--src/Dolphin/dsp/dsp.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/src/Dolphin/dsp/dsp.c b/src/Dolphin/dsp/dsp.c
new file mode 100644
index 0000000..cab7a39
--- /dev/null
+++ b/src/Dolphin/dsp/dsp.c
@@ -0,0 +1,145 @@
+#include "dolphin/dsp.h"
+#include "dolphin/os.h"
+
+#include "dolphin/dsp_regs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static const char* __DSPVersion =
+ "<< Dolphin SDK - DSP\trelease build: Sep 5 2002 05:35:13 (0x2301) >>";
+
+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", "Sep 5 2002", "05:35:13");
+
+ if (__DSP_init_flag == 1) {
+ return;
+ }
+ OSRegisterVersion(__DSPVersion);
+ 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; }
+
+#ifdef FULL_FRANK
+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;
+}
+#else
+#pragma push
+#include "__ppc_eabi_linker.h"
+/* clang-format off */
+#pragma optimization_level 0
+#pragma optimizewithasm off
+extern void __DSP_insert_task(DSPTaskInfo* task);
+asm DSPTaskInfo* DSPAddTask(DSPTaskInfo* task) {
+ nofralloc
+ mflr r0
+ stw r0, 4(r1)
+ stwu r1, -0x18(r1)
+ stw r31, 0x14(r1)
+ stw r30, 0x10(r1)
+ mr r30, r3
+ bl OSDisableInterrupts
+ addi r31, r3, 0
+ addi r3, r30, 0
+ bl __DSP_insert_task
+ li r0, 0
+ stw r0, 0(r30)
+ li r0, 1
+ addi r3, r31, 0
+ stw r0, 8(r30)
+ bl OSRestoreInterrupts
+ lwz r0, __DSP_first_task
+ cmplw r30, r0
+ bne lbl_8036FBB4
+ mr r3, r30
+ bl __DSP_boot_task
+lbl_8036FBB4:
+ mr r3, r30
+ lwz r0, 0x1c(r1)
+ lwz r31, 0x14(r1)
+ lwz r30, 0x10(r1)
+ addi r1, r1, 0x18
+ mtlr r0
+ blr
+}
+#pragma pop
+#endif
+/* clang-format on */
+#ifdef __cplusplus
+}
+#endif