mirror of
https://github.com/encounter/mkdd.git
synced 2026-07-10 12:18:37 -07:00
finish OS
This commit is contained in:
+1
-1
@@ -642,7 +642,7 @@ config.libs = [
|
||||
Object(Matching, "dolphin/os/OSMessage.c"),
|
||||
Object(Matching, "dolphin/os/OSMemory.c"),
|
||||
Object(Matching, "dolphin/os/OSMutex.c"),
|
||||
Object(NonMatching, "dolphin/os/OSReboot.c"),
|
||||
Object(Matching, "dolphin/os/OSReboot.c"),
|
||||
Object(Matching, "dolphin/os/OSReset.c"),
|
||||
Object(Matching, "dolphin/os/OSResetSW.c"),
|
||||
Object(Matching, "dolphin/os/OSRtc.c"),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _DOLPHIN_OSBOOTINFO
|
||||
#define _DOLPHIN_OSBOOTINFO
|
||||
|
||||
#define OS_BOOTROM_ADDR 0x81300000
|
||||
|
||||
typedef struct OSBootInfo {
|
||||
DVDDiskID DVDDiskID;
|
||||
u32 magic;
|
||||
|
||||
@@ -26,6 +26,8 @@ extern "C" {
|
||||
#define OS_RESET_PRIO_GX 127
|
||||
#define OS_RESET_PRIO_ALARM 4294967295
|
||||
|
||||
extern BOOL __OSIsGcam;
|
||||
|
||||
typedef BOOL (*OSResetFunction)(BOOL final);
|
||||
typedef struct OSResetFunctionInfo OSResetFunctionInfo;
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ BOOL EXISync(s32 chan)
|
||||
if (exi->state & STATE_SELECTED)
|
||||
{
|
||||
CompleteTransfer(chan);
|
||||
if (__OSGetDIConfig() != 0xff || ((OSGetConsoleType() & 0xF0000000) == OS_CONSOLE_TDEV) || exi->immLen != 4 ||
|
||||
if (__OSGetDIConfig() != 0xff || ((OSGetConsoleType() & OS_CONSOLE_MASK) == OS_CONSOLE_TDEV) || exi->immLen != 4 ||
|
||||
(REG(chan, 0) & 0x00000070) != (EXI_FREQ_1M << 4) ||
|
||||
(REG(chan, 4) != EXI_USB_ADAPTER && REG(chan, 4) != EXI_IS_VIEWER &&
|
||||
REG(chan, 4) != 0x04220001) ||
|
||||
@@ -816,7 +816,6 @@ s32 EXIGetType(s32 chan, u32 dev, u32 *type) {
|
||||
}
|
||||
*type = _type;
|
||||
return probe;
|
||||
|
||||
}
|
||||
|
||||
char* EXIGetTypeString(u32 type)
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "dolphin/dvd.h"
|
||||
#include "dolphin/os.h"
|
||||
#include "dolphin/os/OSBootInfo.h"
|
||||
#include "dolphin/ai.h"
|
||||
|
||||
// Struct for Apploader header (size 0x20).
|
||||
typedef struct _ApploaderHeader {
|
||||
char date[16]; // _00
|
||||
u32 entry; // _10
|
||||
u32 size; // _14
|
||||
u32 rebootSize; // _18
|
||||
u32 reserved2; // _1C
|
||||
} ApploaderHeader;
|
||||
|
||||
static ApploaderHeader Header ALIGN(32);
|
||||
|
||||
extern void* __OSSavedRegionStart;
|
||||
extern void* __OSSavedRegionEnd;
|
||||
|
||||
static void* SaveStart = NULL;
|
||||
static void* SaveEnd = NULL;
|
||||
|
||||
extern u32 UNK_817FFFF8 AT_ADDRESS(0x817FFFF8);
|
||||
extern u32 UNK_817FFFFC AT_ADDRESS(0x817FFFFC);
|
||||
extern u32 BOOT_REGION_START AT_ADDRESS(0x812FDFF0);
|
||||
extern u32 BOOT_REGION_END AT_ADDRESS(0x812FDFEC);
|
||||
extern u32 OS_RESET_CODE AT_ADDRESS(0x800030F0);
|
||||
extern u8 OS_REBOOT_BOOL AT_ADDRESS(0x800030E2); // unknown function, set to true by __OSReboot
|
||||
|
||||
static BOOL Prepared = FALSE;
|
||||
|
||||
void __OSDoHotReset(int);
|
||||
|
||||
inline void ReadApploader(OSTime time1) {
|
||||
if (DVDCheckDisk() == DVD_RESULT_GOOD || OSGetTime() - time1 > OS_TIMER_CLOCK) {
|
||||
__OSDoHotReset(UNK_817FFFFC);
|
||||
}
|
||||
}
|
||||
|
||||
ASM void Run() {
|
||||
#ifdef __MWERKS__ // clang-format off
|
||||
nofralloc
|
||||
sync
|
||||
isync
|
||||
mtlr r3
|
||||
blr
|
||||
#endif // clang-format on
|
||||
}
|
||||
|
||||
static void Callback() { Prepared = TRUE; }
|
||||
|
||||
inline BOOL IsStreamEnabled(void) {
|
||||
if (DVDGetCurrentDiskID()->streaming) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void __OSReboot(u32 resetCode, u32 bootDol) {
|
||||
OSContext exceptionContext;
|
||||
OSTime time;
|
||||
DVDCommandBlock dvdCmd;
|
||||
DVDCommandBlock dvdCmd2;
|
||||
DVDCommandBlock dvdCmd3;
|
||||
u32 numBytes;
|
||||
u32 offset;
|
||||
|
||||
OSDisableInterrupts();
|
||||
UNK_817FFFFC = 0;
|
||||
UNK_817FFFF8 = 0;
|
||||
OS_REBOOT_BOOL = TRUE;
|
||||
BOOT_REGION_START = (u32)SaveStart;
|
||||
BOOT_REGION_END = (u32)SaveEnd;
|
||||
OSClearContext(&exceptionContext);
|
||||
OSSetCurrentContext(&exceptionContext);
|
||||
DVDInit();
|
||||
DVDSetAutoInvalidation(TRUE);
|
||||
DVDResume();
|
||||
Prepared = FALSE;
|
||||
__DVDPrepareResetAsync(Callback);
|
||||
__OSMaskInterrupts(~0x1F);
|
||||
__OSUnmaskInterrupts(0x400);
|
||||
OSEnableInterrupts();
|
||||
|
||||
time = OSGetTime();
|
||||
while (Prepared != TRUE) {
|
||||
ReadApploader(time);
|
||||
}
|
||||
|
||||
if (!__OSIsGcam && IsStreamEnabled()) {
|
||||
AISetStreamVolLeft(0);
|
||||
AISetStreamVolRight(0);
|
||||
DVDCancelStreamAsync(&dvdCmd, NULL);
|
||||
time = OSGetTime();
|
||||
while (DVDGetCommandBlockStatus(&dvdCmd)) {
|
||||
ReadApploader(time);
|
||||
}
|
||||
AISetStreamPlayState(0);
|
||||
}
|
||||
|
||||
DVDReadAbsAsyncPrio(&dvdCmd2, &Header, 32, 0x2440, NULL, 0);
|
||||
time = OSGetTime();
|
||||
while (DVDGetCommandBlockStatus(&dvdCmd2)) {
|
||||
ReadApploader(time);
|
||||
}
|
||||
|
||||
offset = Header.size + 0x20;
|
||||
numBytes = OSRoundUp32B(Header.rebootSize);
|
||||
DVDReadAbsAsyncPrio(&dvdCmd3, (void*)(OS_BOOTROM_ADDR), numBytes, offset + 0x2440, NULL, 0);
|
||||
time = OSGetTime();
|
||||
while (DVDGetCommandBlockStatus(&dvdCmd3)) {
|
||||
ReadApploader(time);
|
||||
}
|
||||
|
||||
ICInvalidateRange((void*)(OS_BOOTROM_ADDR), numBytes);
|
||||
OSDisableInterrupts();
|
||||
ICFlashInvalidate();
|
||||
Run((void*)OS_BOOTROM_ADDR);
|
||||
}
|
||||
Reference in New Issue
Block a user