From c44e56d12f44d801d05b59c36b0bfedd896b8872 Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Wed, 18 Jun 2025 08:01:51 -0400 Subject: [PATCH] Actually link rest of Dolphin SDK (db, dsb) & OdemuExi2 --- configure.py | 6 +- include/dolphin/odemuexi/DebuggerDriver.h | 24 ++ src/static/dolphin/OdemuExi2/DebuggerDriver.c | 322 ++++++++++++++++++ src/static/dolphin/db/db.c | 44 +++ src/static/dolphin/dsp/__dsp.h | 12 + src/static/dolphin/dsp/dsp.c | 64 ++++ 6 files changed, 469 insertions(+), 3 deletions(-) create mode 100644 include/dolphin/odemuexi/DebuggerDriver.h create mode 100644 src/static/dolphin/OdemuExi2/DebuggerDriver.c create mode 100644 src/static/dolphin/db/db.c create mode 100644 src/static/dolphin/dsp/__dsp.h create mode 100644 src/static/dolphin/dsp/dsp.c diff --git a/configure.py b/configure.py index 993f253d..e60f7fda 100644 --- a/configure.py +++ b/configure.py @@ -492,13 +492,13 @@ config.libs = [ DolphinLib( "db", [ - Object(NonMatching, "dolphin/db/db.c"), + Object(Matching, "dolphin/db/db.c"), ], ), DolphinLib( "dsp", [ - Object(NonMatching, "dolphin/dsp/dsp.c"), + Object(Matching, "dolphin/dsp/dsp.c"), ], ), DolphinLib( @@ -562,7 +562,7 @@ config.libs = [ DolphinLib( "OdemuExi2", [ - Object(NonMatching, "dolphin/OdemuExi2/DebuggerDriver.c"), + Object(Matching, "dolphin/OdemuExi2/DebuggerDriver.c", extra_cflags=["-inline deferred"]), ], ), DolphinLib( diff --git a/include/dolphin/odemuexi/DebuggerDriver.h b/include/dolphin/odemuexi/DebuggerDriver.h new file mode 100644 index 00000000..71a27ed3 --- /dev/null +++ b/include/dolphin/odemuexi/DebuggerDriver.h @@ -0,0 +1,24 @@ +#ifndef ODEMUEXI_DEBUGGER_DRIVER_H +#define ODEMUEXI_DEBUGGER_DRIVER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int Hu_IsStub(); + +void DBInitComm(volatile u8** param_1, __OSInterruptHandler param_2); +void DBInitInterrupts(void); +u32 DBQueryData(void); +int DBRead(void* data, u32 size); +int DBWrite(const void* data, u32 size); +void DBOpen(void); +void DBClose(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/static/dolphin/OdemuExi2/DebuggerDriver.c b/src/static/dolphin/OdemuExi2/DebuggerDriver.c new file mode 100644 index 00000000..398103e7 --- /dev/null +++ b/src/static/dolphin/OdemuExi2/DebuggerDriver.c @@ -0,0 +1,322 @@ +#include +#include +#include + +static __OSInterruptHandler MTRCallback; +// not __OSInterruptHandler because f u that's why +static void (*DBGCallback)(u32, OSContext*); +static u32 SendMailData; +static s32 RecvDataLeng; +static u8* pEXIInputFlag; +static u8 EXIInputFlag; + +static u8 SendCount = 0x80; + +static void DBGHandler(__OSInterrupt interrupt, OSContext* context); +static void MWCallback(u32 interrupt, OSContext* context); +static void DBGEXIInit(void); +static BOOL DBGEXISelect(u32); +static BOOL DBGEXIDeselect(void); +static BOOL DBGReadStatus(void*); +static BOOL DBGWrite(u32, u32*, s32); +static BOOL DBGRead(u32, u32*, s32); +static BOOL DBGWriteMailbox(u32); +static BOOL DBGReadMailbox(void*); +static BOOL DBGEXIImm(void*, s32, u32); + +static void DBGEXIInit(void) +{ + __OSMaskInterrupts(0x18000); + __EXIRegs[10] = 0; +} + +static BOOL DBGEXISelect(u32 v) +{ + u32 regs = __EXIRegs[10]; + regs &= 0x405; + regs |= 0x80 | (v << 4); + __EXIRegs[10] = regs; + return TRUE; +} + +static BOOL DBGEXIDeselect(void) +{ + __EXIRegs[10] &= 0x405; + return TRUE; +} + +static BOOL DBGEXISync(void) +{ + while (__EXIRegs[13] & 1) + ; + return TRUE; +} + +static BOOL DBGEXIImm(void* data, s32 byte_size, u32 write) +{ + u32 writeVal; + u32 readVal; + int i; + + if (write) { + writeVal = 0; + for (i = 0; i < byte_size; ++i) { + u8* nextWordPtr = (u8*)data + i; + writeVal |= *nextWordPtr << ((3 - i) << 3); + } + __EXIRegs[14] = writeVal; + } + + __EXIRegs[13] = 1 | (write << 2) | ((byte_size - 1U) << 4); + + DBGEXISync(); + if (!write) { + u8* dataPtr = (u8*)data; + readVal = __EXIRegs[14]; + for (i = 0; i < byte_size; ++i) { + *dataPtr++ = readVal >> ((3 - i) << 3); + } + } + + return TRUE; +} + +static BOOL DBGReadMailbox(void* param1) +{ + BOOL error = FALSE; + u32 local_c; + + if (!DBGEXISelect(4)) { + return FALSE; + } + + local_c = 0x60000000; + error |= !DBGEXIImm((u8*)&local_c, 2, 1); + error |= !DBGEXISync(); + error |= !DBGEXIImm(param1, sizeof(param1), 0); + error |= !DBGEXISync(); + error |= !DBGEXIDeselect(); + + return !error; +} + +static BOOL DBGWriteMailbox(u32 param_1) +{ + BOOL error = FALSE; + u32 value; + + if (!DBGEXISelect(4)) { + return FALSE; + } + + value = (param_1 & 0x1fffffff) | 0xc0000000; + error |= !DBGEXIImm((u8*)&value, sizeof(value), 1); + error |= !DBGEXISync(); + error |= !DBGEXIDeselect(); + + return !error; +} + +static BOOL DBGRead(u32 param1, u32* data, s32 byte_size) +{ + BOOL error = FALSE; + u32* dataPtr = (u32*)data; + u32 writeValue; + u32 readValue; + + if (!DBGEXISelect(4)) { + return FALSE; + } + + writeValue = (u32)(param1 << 8) & 0x1fffc00 | 0x20000000; + error |= !DBGEXIImm((u8*)&writeValue, sizeof(writeValue), 1); + error |= !DBGEXISync(); + + while (byte_size != 0) { + error |= !DBGEXIImm((u8*)&readValue, sizeof(readValue), 0); + error |= !DBGEXISync(); + + *dataPtr++ = readValue; + + byte_size -= 4; + if (byte_size < 0) { + byte_size = 0; + } + } + error |= !DBGEXIDeselect(); + + return !error; +} + +static BOOL DBGWrite(u32 param1, u32* data, s32 byte_size) +{ + BOOL error = FALSE; + u32* dataPtr = (u32*)data; + u32 value; + u32 nextWord; + + if (!DBGEXISelect(4)) { + return FALSE; + } + + value = (param1 & 0x1fffc) << 8 | 0xa0000000; + error = !DBGEXIImm((u8*)&value, sizeof(value), 1); + error |= !DBGEXISync(); + + while (byte_size != 0) { + nextWord = *dataPtr++; + + error |= !DBGEXIImm((u8*)&nextWord, sizeof(nextWord), 1); + error |= !DBGEXISync(); + + byte_size -= 4; + if (byte_size < 0) + byte_size = 0; + } + + error |= !DBGEXIDeselect(); + + return !error; +} + +static BOOL DBGReadStatus(void* param_1) +{ + BOOL error = FALSE; + u32 value; + + if (!DBGEXISelect(4)) { + return FALSE; + } + + value = 0x40000000; + error |= !DBGEXIImm((u8*)&value, 2, 1); + error |= !DBGEXISync(); + error |= !DBGEXIImm(param_1, sizeof(param_1), 0); + error |= !DBGEXISync(); + error |= !DBGEXIDeselect(); + + return !error; +} + +static void MWCallback(u32 interrupt, OSContext* context) +{ + EXIInputFlag = 1; + if (MTRCallback) { + (*MTRCallback)(0, context); + } +} + +static void DBGHandler(__OSInterrupt interrupt, OSContext* context) +{ + __PIRegs[0] = 0x1000; + if (DBGCallback) { + (*DBGCallback)(interrupt, context); + } +} + +static void CheckMailBox(void) +{ + u32 local_8[2]; + + DBGReadStatus(local_8); + if (local_8[0] & 1) { + DBGReadMailbox(local_8); + local_8[0] &= ~0xE0000000; + if ((local_8[0] & 0x1f000000) == 0x1f000000) { + SendMailData = local_8[0]; + RecvDataLeng = local_8[0] & 0x7fff; + EXIInputFlag = 1; + } + } +} + +void DBInitComm(volatile u8** param_1, __OSInterruptHandler param_2) +{ + BOOL enabled; + + enabled = OSDisableInterrupts(); + pEXIInputFlag = &EXIInputFlag; + *param_1 = pEXIInputFlag; + MTRCallback = param_2; + DBGEXIInit(); + OSRestoreInterrupts(enabled); +} + +void DBInitInterrupts(void) +{ + __OSMaskInterrupts(0x18000); + __OSMaskInterrupts(0x40); + DBGCallback = MWCallback; + __OSSetInterruptHandler(0x19, DBGHandler); + __OSUnmaskInterrupts(0x40); +} + +u32 DBQueryData(void) +{ + BOOL enable; + + EXIInputFlag = 0; + if (RecvDataLeng == 0) { + enable = OSDisableInterrupts(); + CheckMailBox(); + OSRestoreInterrupts(enable); + } + return RecvDataLeng; +} + +int DBRead(void* param1, u32 param2) +{ + BOOL enabled; + u32 lVar3; + + enabled = OSDisableInterrupts(); + if (SendMailData & 0x10000) { + lVar3 = 0x1000; + } else { + lVar3 = 0; + } + DBGRead(lVar3 + 0x1e000, param1, param2 + 3U & 0xfffffffc); + RecvDataLeng = 0; + EXIInputFlag = 0; + OSRestoreInterrupts(enabled); + return 0; +} + +int DBWrite(const void* data, u32 size) +{ + u32 value; + u32 busyFlag; + BOOL enabled; + + enabled = OSDisableInterrupts(); + do { + DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + ++SendCount; + + value = ((SendCount & 1) ? 0x1000 : 0); + while (!DBGWrite(value | 0x1c000, data, ALIGN_NEXT(size, 4))) + ; + + do { + DBGReadStatus(&busyFlag); + } while (busyFlag & 2); + + value = (SendCount << 0x10) | 0x1f000000 | size; + while (!DBGWriteMailbox(value)) + ; + + do { + while (!DBGReadStatus(&busyFlag)) + ; + } while (busyFlag & 2); + + OSRestoreInterrupts(enabled); + + return 0; +} + +void DBOpen(void) { } + +void DBClose(void) { } diff --git a/src/static/dolphin/db/db.c b/src/static/dolphin/db/db.c new file mode 100644 index 00000000..433c2916 --- /dev/null +++ b/src/static/dolphin/db/db.c @@ -0,0 +1,44 @@ +#include +#include +#include + +BOOL DBVerbose; +struct DBInterface* __DBInterface; + +void DBInit(void) +{ + __DBInterface = OSPhysicalToCached(0x40); + __DBInterface->ExceptionDestination + = (void*)OSCachedToPhysical(__DBExceptionDestination); + DBVerbose = TRUE; +} + +void __DBExceptionDestinationAux(void) +{ + u32* contextAddr; + OSContext* context; + + contextAddr = (void*)0xC0; + context = OSPhysicalToCached(*contextAddr); + OSReport("DBExceptionDestination\n"); + OSDumpContext(context); + PPCHalt(); +} + +asm void __DBExceptionDestination(void) { +#ifdef __MWERKS__ // clang-format off + nofralloc + mfmsr r3 + ori r3, r3, 0x30 + mtmsr r3 + b __DBExceptionDestinationAux +#endif // clang-format on +} + +BOOL __DBIsExceptionMarked(__OSException exception) +{ + u32 mask = (1 << exception); + return __DBInterface->exceptionMask & mask; +} + +void DBPrintf(char* str, ...) { } diff --git a/src/static/dolphin/dsp/__dsp.h b/src/static/dolphin/dsp/__dsp.h new file mode 100644 index 00000000..5342f990 --- /dev/null +++ b/src/static/dolphin/dsp/__dsp.h @@ -0,0 +1,12 @@ +extern DSPTaskInfo* __DSP_curr_task; +extern DSPTaskInfo* __DSP_last_task; +extern DSPTaskInfo* __DSP_first_task; +extern DSPTaskInfo* __DSP_tmp_task; + +void __DSPHandler(__OSInterrupt, OSContext*); +void __DSP_exec_task(DSPTaskInfo*, DSPTaskInfo*); +void __DSP_boot_task(DSPTaskInfo*); +void __DSP_insert_task(DSPTaskInfo*); +void __DSP_add_task(DSPTaskInfo* task); +void __DSP_remove_task(DSPTaskInfo* task); +void __DSP_debug_printf(const char* fmt, ...); diff --git a/src/static/dolphin/dsp/dsp.c b/src/static/dolphin/dsp/dsp.c new file mode 100644 index 00000000..e8f4d313 --- /dev/null +++ b/src/static/dolphin/dsp/dsp.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include + +#include "dsp/__dsp.h" + +#define BUILD_DATE "Dec 17 2001" +#define BUILD_TIME "18:25:00" + +u32 DSPCheckMailToDSP(void) { return (__DSPRegs[0] & (1 << 15)) >> 15; } + +u32 DSPCheckMailFromDSP(void) { return (__DSPRegs[2] & (1 << 15)) >> 15; } + +u32 DSPReadMailFromDSP(void) { return (__DSPRegs[2] << 16) | __DSPRegs[3]; } + +void DSPSendMailToDSP(u32 mail) +{ + __DSPRegs[0] = mail >> 16; + __DSPRegs[1] = mail & 0xFFFF; +} + +// void DSPAssertInt(void) +// { +// BOOL old; +// u16 tmp; + +// old = OSDisableInterrupts(); +// tmp = __DSPRegs[5]; +// tmp = (tmp & ~0xA8) | 2; +// __DSPRegs[5] = tmp; +// OSRestoreInterrupts(old); +// } + +// static int __DSP_init_flag; + +// void DSPInit(void) +// { +// BOOL old; +// u16 tmp; + +// __DSP_debug_printf("DSPInit(): Build Date: %s %s\n", BUILD_DATE, +// BUILD_TIME); + +// if (__DSP_init_flag == 1) +// return; + +// old = OSDisableInterrupts(); +// __OSSetInterruptHandler(7, __DSPHandler); +// __OSUnmaskInterrupts(OS_INTERRUPTMASK_DSP_DSP); + +// tmp = __DSPRegs[5]; +// tmp = (tmp & ~0xA8) | 0x800; +// __DSPRegs[5] = tmp; + +// tmp = __DSPRegs[5]; +// __DSPRegs[5] = tmp = tmp & ~0xAC; + +// __DSP_first_task = __DSP_last_task = __DSP_curr_task = __DSP_tmp_task +// = NULL; +// __DSP_init_flag = 1; + +// OSRestoreInterrupts(old); +// }