From 9fa0a7f1da1b70bee995f53c6c96c43189018772 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Wed, 1 Feb 2023 18:45:02 -0400 Subject: global: Import Dolphin SDK This version comes from the Metroid Prime decompilation project. https://github.com/PrimeDecomp/prime --- src/Dolphin/os/OSReset.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 2 deletions(-) (limited to 'src/Dolphin/os/OSReset.c') diff --git a/src/Dolphin/os/OSReset.c b/src/Dolphin/os/OSReset.c index a9cc186..ebd0b04 100644 --- a/src/Dolphin/os/OSReset.c +++ b/src/Dolphin/os/OSReset.c @@ -1,5 +1,190 @@ -#include "dolphin/OSReset.h" +#include "dolphin/OSRtcPriv.h" +#include "dolphin/os.h" +#include "dolphin/vi.h" -void OSResetSystem(int reset, unsigned int resetCode, int forceMenu) { +volatile u8 DAT_800030e2 : 0x800030e2; +typedef struct Unk { + u8 pad[0x24]; + u32 resetCode; +} Unk; +volatile Unk DAT_cc003000 : 0xcc003000; +typedef struct Unk2 { + u16 _0; + u16 _2; +} Unk2; + +volatile Unk2 DAT_cc002000 : 0xcc002000; + +typedef struct OSResetQueue { + OSResetFunctionInfo* first; + OSResetFunctionInfo* last; +} OSResetQueue; + +OSResetQueue ResetFunctionQueue; + +void OSRegisterResetFunction(OSResetFunctionInfo* func) { + OSResetFunctionInfo* tmp; + OSResetFunctionInfo* iter; + + for (iter = ResetFunctionQueue.first; iter && iter->priority <= func->priority; iter = iter->next) + ; + + if (iter == NULL) { + tmp = ResetFunctionQueue.last; + if (tmp == NULL) { + ResetFunctionQueue.first = func; + } else { + tmp->next = func; + } + func->prev = tmp; + func->next = NULL; + ResetFunctionQueue.last = func; + return; + } + + func->next = iter; + tmp = iter->prev; + iter->prev = func; + func->prev = tmp; + if (tmp == NULL) { + ResetFunctionQueue.first = func; + return; + } + tmp->next = func; +} + +BOOL __OSCallResetFunctions(u32 arg0) { + OSResetFunctionInfo* iter; + s32 retCode = 0; + + for (iter = ResetFunctionQueue.first; iter != NULL; iter = iter->next) { + retCode |= !iter->func(arg0); + } + retCode |= !__OSSyncSram(); + if (retCode) { + return 0; + } + return 1; +} + +asm void Reset(register s32 resetCode) { + // clang-format off + nofralloc + b lbl_8038315C +lbl_80383140: + mfspr r8, HID0 + ori r8, r8, 8 + mtspr HID0, r8 + isync + sync + nop + b lbl_80383160 +lbl_8038315C: + b lbl_8038317C +lbl_80383160: + mftb r5, 268 +lbl_80383164: + mftb r6, 268 + subf r7, r5, r6 + cmplwi r7, 0x1124 + blt lbl_80383164 + nop + b lbl_80383180 +lbl_8038317C: + b lbl_8038319C +lbl_80383180: + lis r8, 0xCC003000@h + ori r8, r8, 0xCC003000@l + li r4, 3 + stw r4, 0x24(r8) + stw r3, 0x24(r8) + nop + b lbl_803831A0 +lbl_8038319C: + b lbl_803831A8 +lbl_803831A0: + nop + b lbl_803831A0 +lbl_803831A8: + b lbl_80383140 + // clang-format on +} + +OSThreadQueue __OSActiveThreadQueue : (OS_BASE_CACHED | 0x00DC); + +static void KillThreads(void) { + OSThread* thread; + OSThread* next; + + for (thread = __OSActiveThreadQueue.head; thread; thread = next) { + next = thread->linkActive.next; + switch (thread->state) { + case 1: + case 4: + OSCancelThread(thread); + break; + default: + break; + } + } +} + +void __OSDoHotReset(s32 arg0) { + OSDisableInterrupts(); + __VIRegs[1] = 0; + ICFlashInvalidate(); + Reset(arg0 * 8); +} + +void OSResetSystem(int reset, u32 resetCode, BOOL forceMenu) { + BOOL rc; + BOOL disableRecalibration; + u32 unk[3]; + OSDisableScheduler(); + __OSStopAudioSystem(); + + if (reset == OS_RESET_SHUTDOWN) { + disableRecalibration = __PADDisableRecalibration(TRUE); + } + + while (!__OSCallResetFunctions(FALSE)) + ; + + if (reset == OS_RESET_HOTRESET && forceMenu) { + OSSram* sram; + + sram = __OSLockSram(); + sram->flags |= 0x40; + __OSUnlockSram(TRUE); + + while (!__OSSyncSram()) + ; + } + OSDisableInterrupts(); + __OSCallResetFunctions(TRUE); + LCDisable(); + if (reset == OS_RESET_HOTRESET) { + __OSDoHotReset(resetCode); + } else if (reset == OS_RESET_RESTART) { + KillThreads(); + OSEnableScheduler(); + __OSReboot(resetCode, forceMenu); + } + KillThreads(); + memset(OSPhysicalToCached(0x40), 0, 0xcc - 0x40); + memset(OSPhysicalToCached(0xd4), 0, 0xe8 - 0xd4); + memset(OSPhysicalToCached(0xf4), 0, 0xf8 - 0xf4); + memset(OSPhysicalToCached(0x3000), 0, 0xc0); + memset(OSPhysicalToCached(0x30c8), 0, 0xd4 - 0xc8); + memset(OSPhysicalToCached(0x30e2), 0, 1); + + __PADDisableRecalibration(disableRecalibration); +} + +u32 OSGetResetCode(void) { + if (DAT_800030e2 != 0) { + return 0x80000000; + } + return ((DAT_cc003000.resetCode & ~7) >> 3); } -- cgit v1.2.3-13-gbd6f