diff --git a/source/loader/apploader.c b/source/loader/apploader.c index f8202c15..150ee687 100644 --- a/source/loader/apploader.c +++ b/source/loader/apploader.c @@ -17,9 +17,6 @@ typedef int (*app_main)(void **dst, int *size, int *offset); typedef void (*app_init)(void (*report)(const char *fmt, ...)); typedef void *(*app_final)(); typedef void (*app_entry)(void (**init)(void (*report)(const char *fmt, ...)), int (**main)(), void *(**final)()); - -/* Apploader pointers */ -static u8 *appldr = (u8 *) 0x81200000; /* Constants */ #define APPLDR_OFFSET 0x2440 @@ -50,10 +47,14 @@ s32 Apploader_Run(entry_point *entry, u8 vidMode, GXRModeObj *vmode, bool vipatc /* Calculate apploader length */ appldr_len = buffer[5] + buffer[6]; + SYS_SetArena1Hi(APPLOADER_END); + /* Read apploader code */ - ret = WDVD_Read(appldr, appldr_len, APPLDR_OFFSET + 0x20); + ret = WDVD_Read(APPLOADER_START, appldr_len, APPLDR_OFFSET + 0x20); if (ret < 0) return ret; + + DCFlushRange(APPLOADER_START, appldr_len); /* Set apploader entry function */ app_entry appldr_entry = (app_entry)buffer[4]; diff --git a/source/loader/disc.c b/source/loader/disc.c index 195da4fb..34937ec6 100644 --- a/source/loader/disc.c +++ b/source/loader/disc.c @@ -362,10 +362,9 @@ s32 Disc_BootPartition() /* Set an appropriate video mode */ __Disc_SetVMode(); - usleep(100 * 1000); - /* Shutdown IOS subsystems */ u32 level = IRQ_Disable(); + __dsp_shutdown(); __IOS_ShutdownSubsystems(); __exception_closeall(); diff --git a/source/loader/sys.c b/source/loader/sys.c index 09ded458..9adf23f0 100644 --- a/source/loader/sys.c +++ b/source/loader/sys.c @@ -26,6 +26,10 @@ static bool return_to_priiloader = false; static bool return_to_disable = false; static bool return_to_bootmii = false; +extern void __exception_closeall(); +static vu16* const _dspReg = (u16*)0xCC005000; +extern u32 __PADDisableRecalibration(s32 disable); + void __Wpad_PowerCallback() { /* Poweroff console */ @@ -138,3 +142,23 @@ void Sys_LoadMenu(void) /* Return to the Wii system menu */ WII_ReturnToMenu(); //SYS_ResetSystem doesnt work properly with new libogc } + +void __dsp_shutdown(void) +{ + u32 tick; + + _dspReg[5] = (DSPCR_DSPRESET|DSPCR_HALT); + _dspReg[27] &= ~0x8000; + while(_dspReg[5]&0x400); + while(_dspReg[5]&0x200); + + _dspReg[5] = (DSPCR_DSPRESET|DSPCR_DSPINT|DSPCR_ARINT|DSPCR_AIINT|DSPCR_HALT); + _dspReg[0] = 0; + while((_SHIFTL(_dspReg[2],16,16)|(_dspReg[3]&0xffff))&0x80000000); + + tick = gettick(); + while((gettick()-tick)<44); + + _dspReg[5] |= DSPCR_RES; + while(_dspReg[5]&DSPCR_RES); +} diff --git a/source/loader/sys.h b/source/loader/sys.h index 6402a0a3..e6b3a2cb 100644 --- a/source/loader/sys.h +++ b/source/loader/sys.h @@ -18,6 +18,17 @@ extern "C" { #define EXIT_TO_DISABLE 4 #define EXIT_TO_BOOTMII 5 +// DSPCR bits +#define DSPCR_DSPRESET 0x0800 // Reset DSP +#define DSPCR_DSPINT 0x0080 // * interrupt active (RWC) +#define DSPCR_ARINT 0x0020 +#define DSPCR_AIINT 0x0008 +#define DSPCR_HALT 0x0004 // halt DSP +#define DSPCR_RES 0x0001 // reset DSP + +#define _SHIFTL(v, s, w) \ + ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s))) + /* Prototypes */ void Sys_Init(void); void Sys_LoadMenu(void); @@ -25,7 +36,7 @@ extern "C" { void Sys_Test(void); void Sys_Exit(void); void Sys_ExitTo(int); - void Sys_Shutdown(void); + void __dsp_shutdown(void); void Open_Inputs(void); void Close_Inputs(void); diff --git a/source/memory/mem2.cpp b/source/memory/mem2.cpp index 6f31612e..4ee2dccd 100644 --- a/source/memory/mem2.cpp +++ b/source/memory/mem2.cpp @@ -48,6 +48,9 @@ void MEM2_init(unsigned int mem2Size) { g_mem2gp.init(mem2Size); g_mem2gp.clear(); + + /* Protect space reserved for apploader */ + SYS_SetArena1Hi(APPLOADER_START); } void MEM2_cleanup(void)