/* DIOS MIOS - Gamecube USB loader for Nintendo Wii Copyright (C) 2010-2012 crediar */ #include "string.h" #include "global.h" #include "alloc.h" #include "ff.h" #include "diskio.h" #include "dol.h" #include "GCPad.h" #include "HW.h" #include "Patches.h" #include "Config.h" #include "Card.h" #include "DVD.h" #include "Drive.h" #include "dip.h" #include "Patches.h" extern u32 DiscChangeIRQ; char __aeabi_unwind_cpp_pr0[0]; void Syscall( u32 a, u32 b, u32 c, u32 d ) { //dbgprintf("Syscall,%d,%d,%d,%d\n", a, b, c, d); return; } void SWI( u32 a, u32 b ) { //dbgprintf("SWI:%X,%X\n", a, b ); return; } void PrefetchAbort( void ) { EXIControl(1); dbgprintf("PrefetchAbort\n"); while(1); return; } void DataAbort( u32 a, u32 b, u32 c, u32 d, u32 e, u32 f, u32 g, u32 h ) { u32 val; __asm("mov %0,lr": "=r" (val) ); *(vu32*)0xD800070 |= 1; dbgprintf("DataAbort: LR:%08x, %x, %x, %x, %x, %x, %x, %x\n",val,b,c,d,e,f,g,h); Shutdown(); } void IRQHandler( void ) { u32 IRQs = read32(HW_ARMIRQFLAG) /*& read32(HW_ARMIRQMASK)*/; if( IRQs & IRQ_GPIO1 ) // Starlet GPIO IRQ { if( read32(HW_GPIO_INTFLAG) & (1) ) { set32( HW_EXICTRL, 1 ); int i; for( i = 0; i < 0x20; i+=4 ) dbgprintf("0x%08X:0x%08X\t0x%08X\n", i, read32( CARD_BASE + i ), read32( CARD_SHADOW + i ) ); dbgprintf("\n"); for( i = 0; i < 0x30; i+=4 ) dbgprintf("0x%08X:0x%08X\t0x%08X\n", i, read32( 0x00002F00 + i ), read32( 0x00002F30 + i ) ); dbgprintf("\n"); for( i = 0; i < 0x30; i+=4 ) dbgprintf("0x%08X:0x%08X\t0x%08X\n", 0x0D806000 + i, read32( 0x0D806000 + i ), read32( 0x0D006000 + i ) ); dbgprintf("DVD:Error:%08X\n", DVDLowGetError() ); udelay(10000); set32( HW_GPIO_ENABLE, GPIO_POWER ); set32( HW_GPIO_OUT, GPIO_POWER ); while(1); } } //Clear IRQ Flags write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); write32( HW_GPIO_INTFLAG, read32(HW_GPIO_INTFLAG) ); return; } void FIQHandler( void ) { //dbgprintf("FIQHandler\n"); return; } void DebugPoke( u8 Value ) { clear32( 0xD8000E0, 0xFF0000 ); set32( 0xD8000E0, Value<<16 ); } void SysReset( void ) { write32( HW_RESETS, (read32( HW_RESETS ) | 0x20 ) & (~1) ); } void SysShutdown( void ) { set32( HW_GPIO_ENABLE, GPIO_POWER ); set32( HW_GPIO_OUT, GPIO_POWER ); while(1); } u32 fail; int main( int argc, char *argv[] ) { udelay(800); #ifndef REALNAND PPCReset(); clear32( HW_RESETS, 0x48000 ); clear32( 0xD800184, 0x438E ); ChangeClock(); DRAMInit(1,0); set32( HW_RESETS, 0x48000 ); set32( 0xD800184, 0x438E ); UNKInit( 1, 1 ); #endif set32( 0xD800038, IRQ_RESET|IRQ_GPIO1 ); set32( 0xD80003C, IRQ_RESET|IRQ_GPIO1 ); udelay(200); u32 SP[2]; GetRevision( SP+1, SP ); if( SP[1] == 0 ) { write32( HW_MEMIRR, 0x67 ); } else { write32( HW_MEMIRR, 0x27 ); } MIOSInit(); #ifdef DEBUG dbgprintf("DIOS-MIOS [DEBUG] v%d.%d\n", DM_VERSION>>16, DM_VERSION & 0xFFFF ); #else #ifdef REALNAND dbgprintf("DIOS-MIOS v%d.%db\n", DM_VERSION>>16, DM_VERSION & 0xFFFF ); #else dbgprintf("DIOS-MIOS v%d.%da\n", DM_VERSION>>16, DM_VERSION & 0xFFFF ); #endif #endif dbgprintf("Built: " __DATE__ " " __TIME__ "\n"); dbgprintf("This software is licensed under GPLv3, for more details visit:\nhttp://code.google.com/p/diosmios\n"); //dbgprintf("MEMInitLow()...\n"); MEMInitLow(); // EHCI *(vu32*)0x0D0400A4 = 0x00004026; *(vu32*)0x0D0400B0 = 0x0002422E; *(vu32*)0x0D0400B4 = 0x03802E14; // DDR control *(vu16*)0x0D8B4034 = 0x0000; *(vu16*)0x0D8B403C = 0x0000; *(vu16*)0x0D8B4034 = 0x0000; *(vu16*)0x0D8B403C = 0x0000; *(vu16*)0x0D8B4040 = 0x0000; *(vu16*)0x0D8B4044 = 0x0000; *(vu16*)0x0D8B4048 = 0x0000; *(vu16*)0x0D8B404C = 0x0000; *(vu16*)0x0D8B4050 = 0x0000; *(vu16*)0x0D8B4054 = 0x13EB; *(vu16*)0x0D8B4058 = 0x09B5; *(vu16*)0x0D8B4060 = 0x0000; *(vu16*)0x0D8B4064 = 0x0000; *(vu16*)0x0D8B420C = 0x3620; *(vu16*)0x0D8B4220 = 0xF000; udelay(8000); HeapInit( (u8*)0x13600000 ); set32( HW_EXICTRL, 1 ); DVDInit(); ConfigInit( (DML_CFG*)0x01200000 ); ConfigSetConfig( DML_CFG_BOOT_DISC2 ); if( !ConfigGetConfig(DML_CFG_BOOT_DISC) ) { if( DVDSelectGame() == DI_SUCCESS ) { if( ConfigGetConfig(DML_CFG_NMM) ) CardInit(); } else { dbgprintf("Loading disc\n"); ((DML_CFG*)0x01200000)->Version = CONFIG_VERSION; ((DML_CFG*)0x01200000)->Magicbytes = 0xD1050CF6; ((DML_CFG*)0x01200000)->VideoMode = DML_VID_DML_AUTO; ((DML_CFG*)0x01200000)->Config = DML_CFG_BOOT_DISC; } } DIInit(); //Switch mem2 to ARAM DRAMCTRLWrite( 0x49, 0x0E ); udelay(2); DRAMCTRLWrite( 0x49, 0x0F ); udelay(2); HeapInit( (u8*)0xFFFE5000 ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( HW_PPCIRQMASK, (1<<31) ); set32( HW_IPC_PPCCTRL, 0x30 ); write32( 0x0D806008, 0 ); EXIControl(0); write32( 0x1860, 0xdeadbeef ); // Clear OSReport area write32( 0x30F8, 0 ); // Tell PPC side to start ahb_flush_to( AHB_PPC ); u32 PADLock = 0; while (1) { ahb_flush_from( AHB_STARLET ); //flush to arm if( (((read32(0x12F8) >> 16) & 0x30) == 0x30 ) ) { if( !PADLock ) { ScreenShot(); PADLock = 1; } } else { PADLock = 0; } if( DiscChangeIRQ ) if( read32(HW_TIMER) * 128 / 243000000 > 2 ) { // dbgprintf("DIP:IRQ mon!\n"); //DVDGetDriveStatus //write32( 0x01576D4, 0x38600000 ); while( read32(DI_SCONTROL) & 1 ) clear32( DI_SCONTROL, 1 ); set32( DI_SSTATUS, 0x3A ); write32( 0x0d80000C, (1<<0) | (1<<4) ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( 0x0d80000C, (1<<2) ); DiscChangeIRQ = 0; } if( (((read32(0x12FC) >> 16) & 0x1030) == 0x1030 ) ) { SysReset(); } if( (((read32(0x12FC) >> 16) & 0x234) == 0x234 ) ) { SysShutdown(); } //Baten Kaitos save hax if( read32(0) == 0x474B4245 ) { if( read32( 0x0073E640 ) == 0xFFFFFFFF ) { write32( 0x0073E640, 0 ); } } //if( read32(0x1860) != 0xdeadbeef ) //{ // if( read32(0x1860) != 0 ) // { // dbgprintf( (char*)(P2C(read32(0x1860))), // (char*)(P2C(read32(0x1864))), // (char*)(P2C(read32(0x1868))), // (char*)(P2C(read32(0x186C))), // (char*)(P2C(read32(0x1870))), // (char*)(P2C(read32(0x1864))) // ); // } // write32(0x1860, 0xdeadbeef); //} SMenuAddFramebuffer(); DIUpdateRegisters(); if( ConfigGetConfig(DML_CFG_NMM) ) CARDUpdateRegisters(); ahb_flush_to( AHB_PPC ); //flush to ppc } }