void panic2(int mode, ...) { int arg; va_list ap; clear32(HW_GPIO1OUT, HW_GPIO1_SLOT); clear32(HW_GPIO1DIR, HW_GPIO1_SLOT); clear32(HW_GPIO1OWNER, HW_GPIO1_SLOT); while(1) { va_start(ap, mode); while(1) { arg = va_arg(ap, int); if(arg < 0) break; set32(HW_GPIO1OUT, HW_GPIO1_SLOT); udelay(arg * PANIC_ON); clear32(HW_GPIO1OUT, HW_GPIO1_SLOT); udelay(PANIC_OFF); } va_end(ap); udelay(PANIC_INTER); } }
void MIOSUnkInit( void ) { u32 value = read32( HW_DIFLAGS ); value &= 0xFFFFFEFF; value &= ~0x80; write32( HW_DIFLAGS, value ); clear32( 0xD8001D0, 0x80000000 ); udelay(2); clear32( 0xD8001D0, 0x40000000 ); if( SP[1] <= 1 ) { value = read32( 0xD8001CC ); value&= 0xFFFC003F; value|= 0x00000FC0; value&=~0x0000003F; value&= 0xF803FFFF; value|= 0x04640000; write32( 0xD8001CC, value ); } else { value = read32( 0xD8001A8 ); value&= 0xFFFC003F; value|= 0x00000FC0; value&=~0x0000003F; value&= 0xF803FFFF; value|= 0x04640000; write32( 0xD8001A8, value ); } udelay(10); value = read32( 0xD8001D0 ); value&= 0xBFFFFFFF; value|= 0x40000000; write32( 0xD8001D0, value ); udelay(500); value = read32( 0xD8001D0 ); value&= 0x7FFFFFFF; value|= 0x80000000; write32( 0xD8001D0, value ); udelay(2); }
void powerpc_upload_stub(u32 entry) { u32 i; set32(HW_EXICTRL, EXICTRL_ENABLE_EXI); // lis r3, entry@h write32(EXI_BOOT_BASE + 4 * 0, 0x3c600000 | entry >> 16); // ori r3, r3, entry@l write32(EXI_BOOT_BASE + 4 * 1, 0x60630000 | (entry & 0xffff)); // mtsrr0 r3 write32(EXI_BOOT_BASE + 4 * 2, 0x7c7a03a6); // li r3, 0 write32(EXI_BOOT_BASE + 4 * 3, 0x38600000); // mtsrr1 r3 write32(EXI_BOOT_BASE + 4 * 4, 0x7c7b03a6); // rfi write32(EXI_BOOT_BASE + 4 * 5, 0x4c000064); for (i = 6; i < 0x10; ++i) write32(EXI_BOOT_BASE + 4 * i, 0); set32(HW_DIFLAGS, DIFLAGS_BOOT_CODE); set32(HW_AHBPROT, 0xFFFFFFFF); gecko_printf("disabling EXI now...\n"); clear32(HW_EXICTRL, EXICTRL_ENABLE_EXI); }
void powerpc_hang(void) { clear32(HW_RESETS, 0x30); udelay(100); set32(HW_RESETS, 0x20); udelay(100); }
void powerpc_hang(void) { gecko_printf("Hanging PPC. End debug output.\n\n"); gecko_enable(0); clear32(HW_RESETS, 0x30); udelay(100); set32(HW_RESETS, 0x20); udelay(100); }
void panic(u8 v) { while(1) { debug_output(v); set32(HW_GPIO1BOUT, GP_SLOTLED); udelay(500000); debug_output(0); clear32(HW_GPIO1BOUT, GP_SLOTLED); udelay(500000); } }
void powerpc_reset(void) { // enable the broadway IPC interrupt write32(HW_PPCIRQMASK, (1<<30)); clear32(HW_RESETS, 0x30); udelay(100); set32(HW_RESETS, 0x20); udelay(100); set32(HW_RESETS, 0x10); udelay(100000); set32(HW_EXICTRL, EXICTRL_ENABLE_EXI); }
void powerpc_reset(void) { gecko_printf("Resetting PPC. End debug output.\n\n"); gecko_enable(0); // enable the broadway IPC interrupt write32(HW_PPCIRQMASK, (1<<30)); clear32(HW_RESETS, 0x30); udelay(100); set32(HW_RESETS, 0x20); udelay(100); set32(HW_RESETS, 0x10); udelay(100000); set32(HW_EXICTRL, EXICTRL_ENABLE_EXI); }
int _main( int argc, char *argv[] ) { //BSS is in DATA section so IOS doesnt touch it, we need to manually clear it //dbgprintf("memset32(%08x, 0, %08x)\n", &__bss_start, &__bss_end - &__bss_start); memset32(&__bss_start, 0, &__bss_end - &__bss_start); sync_after_write(&__bss_start, &__bss_end - &__bss_start); s32 ret = 0; u32 DI_Thread = 0; u8 MessageHeap[0x10]; BootStatus(0, 0, 0); thread_set_priority( 0, 0x79 ); // do not remove this, this waits for FS to be ready! thread_set_priority( 0, 0x50 ); thread_set_priority( 0, 0x79 ); //Disable AHBPROT EnableAHBProt(-1); //Load IOS Modules ES_Init( MessageHeap ); //Early HID for loader HIDInit(); //Enable DVD Access write32(HW_DIFLAGS, read32(HW_DIFLAGS) & ~DI_DISABLEDVD); dbgprintf("Sending signal to loader\r\n"); BootStatus(1, 0, 0); mdelay(10); //Loader running, selects games while(1) { sync_before_read((void*)RESET_STATUS, 0x20); vu32 reset_status = read32(RESET_STATUS); if(reset_status != 0) { if(reset_status == 0x0DEA) break; //game selected else if(reset_status == 0x1DEA) goto DoIOSBoot; //exit write32(RESET_STATUS, 0); sync_after_write((void*)RESET_STATUS, 0x20); } HIDUpdateRegisters(1); mdelay(10); } ConfigSyncBeforeRead(); u32 UseUSB = ConfigGetConfig(NIN_CFG_USB); SetDiskFunctions(UseUSB); BootStatus(2, 0, 0); if(UseUSB) { ret = USBStorage_Startup(); dbgprintf("USB:Drive size: %dMB SectorSize:%d\r\n", s_cnt / 1024 * s_size / 1024, s_size); } else { s_size = PAGE_SIZE512; //manually set s_size ret = SDHCInit(); } if(ret != 1) { dbgprintf("Device Init failed:%d\r\n", ret ); BootStatusError(-2, ret); mdelay(4000); Shutdown(); } //Verification if we can read from disc if(memcmp(ConfigGetGamePath(), "di", 3) == 0) RealDI_Init(); //will shutdown on fail BootStatus(3, 0, 0); fatfs = (FATFS*)malloca( sizeof(FATFS), 32 ); s32 res = f_mount( fatfs, fatDevName, 1 ); if( res != FR_OK ) { dbgprintf("ES:f_mount() failed:%d\r\n", res ); BootStatusError(-3, res); mdelay(4000); Shutdown(); } BootStatus(4, 0, 0); BootStatus(5, 0, 0); FIL fp; s32 fres = f_open_char(&fp, "/bladie", FA_READ|FA_OPEN_EXISTING); switch(fres) { case FR_OK: f_close(&fp); case FR_NO_PATH: case FR_NO_FILE: { fres = FR_OK; } break; default: case FR_DISK_ERR: { BootStatusError(-5, fres); mdelay(4000); Shutdown(); } break; } if(!UseUSB) //Use FAT values for SD s_cnt = fatfs->n_fatent * fatfs->csize; BootStatus(6, s_size, s_cnt); BootStatus(7, s_size, s_cnt); ConfigInit(); if (ConfigGetConfig(NIN_CFG_LOG)) SDisInit = 1; // Looks okay after threading fix dbgprintf("Game path: %s\r\n", ConfigGetGamePath()); BootStatus(8, s_size, s_cnt); memset32((void*)RESET_STATUS, 0, 0x20); sync_after_write((void*)RESET_STATUS, 0x20); memset32((void*)0x13002800, 0, 0x30); sync_after_write((void*)0x13002800, 0x30); memset32((void*)0x13160000, 0, 0x20); sync_after_write((void*)0x13160000, 0x20); memset32((void*)0x13026500, 0, 0x100); sync_after_write((void*)0x13026500, 0x100); BootStatus(9, s_size, s_cnt); DIRegister(); DI_Thread = thread_create(DIReadThread, NULL, ((u32*)&__di_stack_addr), ((u32)(&__di_stack_size)) / sizeof(u32), 0x78, 1); thread_continue(DI_Thread); DIinit(true); BootStatus(10, s_size, s_cnt); GCAMInit(); EXIInit(); BootStatus(11, s_size, s_cnt); SIInit(); StreamInit(); PatchInit(); //Tell PPC side we are ready! cc_ahbMemFlush(1); mdelay(1000); BootStatus(0xdeadbeef, s_size, s_cnt); mdelay(1000); //wait before hw flag changes dbgprintf("Kernel Start\r\n"); //write32( 0x1860, 0xdeadbeef ); // Clear OSReport area //sync_after_write((void*)0x1860, 0x20); u32 Now = read32(HW_TIMER); u32 PADTimer = Now; u32 DiscChangeTimer = Now; u32 ResetTimer = Now; u32 InterruptTimer = Now; USBReadTimer = Now; u32 Reset = 0; bool SaveCard = false; if( ConfigGetConfig(NIN_CFG_LED) ) { set32(HW_GPIO_ENABLE, GPIO_SLOT_LED); clear32(HW_GPIO_DIR, GPIO_SLOT_LED); clear32(HW_GPIO_OWNER, GPIO_SLOT_LED); } set32(HW_GPIO_ENABLE, GPIO_SENSOR_BAR); clear32(HW_GPIO_DIR, GPIO_SENSOR_BAR); clear32(HW_GPIO_OWNER, GPIO_SENSOR_BAR); set32(HW_GPIO_OUT, GPIO_SENSOR_BAR); //turn on sensor bar write32( HW_PPCIRQMASK, (1<<30) ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); //This bit seems to be different on japanese consoles u32 ori_ppcspeed = read32(HW_PPCSPEED); if((ConfigGetGameID() & 0xFF) == 'J') set32(HW_PPCSPEED, (1<<17)); else clear32(HW_PPCSPEED, (1<<17)); u32 ori_widesetting = read32(0xd8006a0); if(IsWiiU) { if( ConfigGetConfig(NIN_CFG_WIIU_WIDE) ) write32(0xd8006a0, 0x30000004); else write32(0xd8006a0, 0x30000002); mask32(0xd8006a8, 0, 2); } while (1) { _ahbMemFlush(0); //Does interrupts again if needed if(TimerDiffTicks(InterruptTimer) > 15820) //about 120 times a second { sync_before_read((void*)INT_BASE, 0x80); if((read32(RSW_INT) & 2) || (read32(DI_INT) & 4) || (read32(SI_INT) & 8) || (read32(EXI_INT) & 0x10)) write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq InterruptTimer = read32(HW_TIMER); } #ifdef PATCHALL if (EXI_IRQ == true) { if(EXICheckTimer()) EXIInterrupt(); } #endif if (SI_IRQ != 0) { if ((TimerDiffTicks(PADTimer) > 7910) || (SI_IRQ & 0x2)) // about 240 times a second { SIInterrupt(); PADTimer = read32(HW_TIMER); } } if(DI_IRQ == true) { if(DiscCheckAsync()) DIInterrupt(); else udelay(200); //let the driver load data } else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */ { if(TimerDiffSeconds(Now) > 2) /* after 3 second earliest */ { EXISaveCard(); SaveCard = false; } } else if(UseUSB && TimerDiffSeconds(USBReadTimer) > 149) /* Read random sector every 2 mins 30 secs */ { DIFinishAsync(); //if something is still running DI_CallbackMsg.result = -1; sync_after_write(&DI_CallbackMsg, 0x20); IOS_IoctlAsync( DI_Handle, 2, NULL, 0, NULL, 0, DI_MessageQueue, &DI_CallbackMsg ); DIFinishAsync(); USBReadTimer = read32(HW_TIMER); } udelay(10); //wait for other threads //Baten Kaitos save hax /*if( read32(0) == 0x474B4245 ) { if( read32( 0x0073E640 ) == 0xFFFFFFFF ) { write32( 0x0073E640, 0 ); } }*/ if( WaitForRealDisc == 1 ) { if(RealDI_NewDisc()) { DiscChangeTimer = read32(HW_TIMER); WaitForRealDisc = 2; //do another flush round, safety! } } else if( WaitForRealDisc == 2 ) { if(TimerDiffSeconds(DiscChangeTimer)) { //identify disc after flushing everything RealDI_Identify(false); //clear our fake regs again sync_before_read((void*)DI_BASE, 0x40); write32(DI_IMM, 0); write32(DI_COVER, 0); sync_after_write((void*)DI_BASE, 0x40); //mask and clear interrupts write32( DIP_STATUS, 0x54 ); //disable cover irq which DIP enabled write32( DIP_COVER, 4 ); DIInterrupt(); WaitForRealDisc = 0; } } if ( DiscChangeIRQ == 1 ) { DiscChangeTimer = read32(HW_TIMER); DiscChangeIRQ = 2; } else if ( DiscChangeIRQ == 2 ) { if ( TimerDiffSeconds(DiscChangeTimer) > 2 ) { DIInterrupt(); DiscChangeIRQ = 0; } } _ahbMemFlush(1); DIUpdateRegisters(); #ifdef PATCHALL EXIUpdateRegistersNEW(); GCAMUpdateRegisters(); BTUpdateRegisters(); HIDUpdateRegisters(0); if(DisableSIPatch == 0) SIUpdateRegisters(); #endif StreamUpdateRegisters(); CheckOSReport(); if(EXICheckCard()) { Now = read32(HW_TIMER); SaveCard = true; } sync_before_read((void*)RESET_STATUS, 0x20); vu32 reset_status = read32(RESET_STATUS); if (reset_status == 0x1DEA) { write32(RESET_STATUS, 0); sync_after_write((void*)RESET_STATUS, 0x20); DIFinishAsync(); break; } if (reset_status == 0x3DEA) { if (Reset == 0) { dbgprintf("Fake Reset IRQ\n"); write32( RSW_INT, 0x2 ); // Reset irq sync_after_write( (void*)RSW_INT, 0x20 ); write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq Reset = 1; } } else if (Reset == 1) { write32( RSW_INT, 0x10000 ); // send pressed sync_after_write( (void*)RSW_INT, 0x20 ); ResetTimer = read32(HW_TIMER); Reset = 2; } /* The cleanup is not connected to the button press */ if (Reset == 2) { if (TimerDiffTicks(ResetTimer) > 949219) //free after half a second { write32( RSW_INT, 0 ); // done, clear sync_after_write( (void*)RSW_INT, 0x20 ); Reset = 0; } } if(reset_status == 0x4DEA) PatchGame(); if(reset_status == 0x5DEA) { SetIPL(); PatchGame(); } if(reset_status == 0x6DEA) { SetIPL_TRI(); write32(RESET_STATUS, 0); sync_after_write((void*)RESET_STATUS, 0x20); } if(read32(HW_GPIO_IN) & GPIO_POWER) { DIFinishAsync(); #ifdef PATCHALL BTE_Shutdown(); #endif Shutdown(); } //sync_before_read( (void*)0x1860, 0x20 ); //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(0x1874))) // ); // } // write32(0x1860, 0xdeadbeef); // sync_after_write( (void*)0x1860, 0x20 ); //} cc_ahbMemFlush(1); } //if( UseHID ) HIDClose(); IOS_Close(DI_Handle); //close game thread_cancel(DI_Thread, 0); DIUnregister(); /* reset time */ while(1) { sync_before_read( (void*)RESET_STATUS, 0x20 ); if(read32(RESET_STATUS) == 0x2DEA) break; wait_for_ppc(1); } if( ConfigGetConfig(NIN_CFG_LED) ) clear32(HW_GPIO_OUT, GPIO_SLOT_LED); if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) ) EXIShutdown(); if (ConfigGetConfig(NIN_CFG_LOG)) closeLog(); #ifdef PATCHALL BTE_Shutdown(); #endif //unmount FAT device free(fatfs); fatfs = NULL; f_mount(NULL, fatDevName, 1); if(UseUSB) USBStorage_Shutdown(); else SDHCShutdown(); //make sure we set that back to the original write32(HW_PPCSPEED, ori_ppcspeed); if(IsWiiU) { write32(0xd8006a0, ori_widesetting); mask32(0xd8006a8, 0, 2); } DoIOSBoot: sync_before_read((void*)0x13003000, 0x420); IOSBoot((char*)0x13003020, 0, read32(0x13003000)); return 0; }
void PPCReset( void ) { clear32( HW_RESETS, 0x30 ); udelay(15); set32( HW_RESETS, 0x20 ); }
void irq_disable(u32 irq) { clear32(HW_ARMIRQMASK, 1<<irq); }
int _main( int argc, char *argv[] ) { //BSS is in DATA section so IOS doesnt touch it, we need to manually clear it //dbgprintf("memset32(%08x, 0, %08x)\n", &__bss_start, &__bss_end - &__bss_start); memset32(&__bss_start, 0, &__bss_end - &__bss_start); sync_after_write(&__bss_start, &__bss_end - &__bss_start); s32 ret = 0; u32 HID_Thread = 0, DI_Thread = 0; u8 MessageHeap[0x10]; //u32 MessageQueue=0xFFFFFFFF; BootStatus(0, 0, 0); thread_set_priority( 0, 0x79 ); // do not remove this, this waits for FS to be ready! thread_set_priority( 0, 0x50 ); thread_set_priority( 0, 0x79 ); //MessageQueue = ES_Init( MessageHeap ); ES_Init( MessageHeap ); BootStatus(1, 0, 0); #ifndef NINTENDONT_USB BootStatus(2, 0, 0); ret = SDHCInit(); if(!ret) { dbgprintf("SD:SDHCInit() failed:%d\r\n", ret ); BootStatusError(-2, ret); mdelay(2000); Shutdown(); } #endif BootStatus(3, 0, 0); fatfs = (FATFS*)malloca( sizeof(FATFS), 32 ); s32 res = f_mount( 0, fatfs ); if( res != FR_OK ) { dbgprintf("ES:f_mount() failed:%d\r\n", res ); BootStatusError(-3, res); mdelay(2000); Shutdown(); } BootStatus(4, 0, 0); BootStatus(5, 0, 0); int MountFail = 0; s32 fres = -1; FIL fp; while(fres != FR_OK) { fres = f_open(&fp, "/bladie", FA_READ|FA_OPEN_EXISTING); switch(fres) { case FR_OK: f_close(&fp); case FR_NO_PATH: case FR_NO_FILE: { fres = FR_OK; } break; default: case FR_DISK_ERR: { f_mount(0, NULL); //unmount drive todo: retry could never work MountFail++; if(MountFail == 10) { BootStatusError(-5, fres); mdelay(2000); Shutdown(); } mdelay(5); } break; } if(STATUS_ERROR == -7) { // FS check timed out on PPC side dbgprintf("FS check timed out\r\n"); mdelay(3000); Shutdown(); } } #ifndef NINTENDONT_USB s_size = 512; s_cnt = fatfs->n_fatent * fatfs->csize; #endif BootStatus(6, s_size, s_cnt); #ifdef NINTENDONT_USB s32 r = LoadModules(55); //dbgprintf("ES:ES_LoadModules(%d):%d\r\n", 55, r ); if( r < 0 ) { BootStatusError(-6, r); mdelay(2000); Shutdown(); } #endif BootStatus(7, s_size, s_cnt); ConfigInit(); if (ConfigGetConfig(NIN_CFG_LOG)) SDisInit = 1; // Looks okay after threading fix dbgprintf("Game path: %s\r\n", ConfigGetGamePath()); BootStatus(8, s_size, s_cnt); memset32((void*)0x13002800, 0, 0x30); sync_after_write((void*)0x13002800, 0x30); memset32((void*)0x13160000, 0, 0x20); sync_after_write((void*)0x13160000, 0x20); memset32((void*)0x13026500, 0, 0x100); sync_after_write((void*)0x13026500, 0x100); bool UseHID = ConfigGetConfig(NIN_CFG_HID); if( UseHID ) { ret = HIDInit(); if(ret < 0 ) { dbgprintf("ES:HIDInit() failed\r\n" ); BootStatusError(-8, ret); mdelay(2000); Shutdown(); } write32(0x13003004, 0); sync_after_write((void*)0x13003004, 0x20); HID_Thread = thread_create(HID_Run, NULL, HID_ThreadStack, 0x400, 0x78, 1); thread_continue(HID_Thread); } BootStatus(9, s_size, s_cnt); DIRegister(); DI_Thread = thread_create(DIReadThread, NULL, DI_ThreadStack, 0x400, 0x78, 1); thread_continue(DI_Thread); DIinit(true); BootStatus(10, s_size, s_cnt); GCAMInit(); EXIInit(); ret = Check_Cheats(); if(ret < 0 ) { dbgprintf("Check_Cheats failed\r\n" ); BootStatusError(-10, ret); mdelay(4000); Shutdown(); } BootStatus(11, s_size, s_cnt); bool PatchSI = !ConfigGetConfig(NIN_CFG_NATIVE_SI); if (PatchSI) SIInit(); StreamInit(); PatchInit(); //This bit seems to be different on japanese consoles u32 ori_ppcspeed = read32(HW_PPCSPEED); if((ConfigGetGameID() & 0xFF) == 'J') set32(HW_PPCSPEED, (1<<17)); else clear32(HW_PPCSPEED, (1<<17)); //write32( 0x1860, 0xdeadbeef ); // Clear OSReport area //Tell PPC side we are ready! cc_ahbMemFlush(1); mdelay(1000); BootStatus(0xdeadbeef, s_size, s_cnt); u32 Now = read32(HW_TIMER); u32 PADTimer = Now; u32 DiscChangeTimer = Now; u32 ResetTimer = Now; #ifdef NINTENDONT_USB u32 USBReadTimer = Now; #endif u32 Reset = 0; bool SaveCard = false; if( ConfigGetConfig(NIN_CFG_LED) ) { set32(HW_GPIO_ENABLE, GPIO_SLOT_LED); clear32(HW_GPIO_DIR, GPIO_SLOT_LED); clear32(HW_GPIO_OWNER, GPIO_SLOT_LED); } EnableAHBProt(-1); //disable AHBPROT write32(0xd8006a0, 0x30000004), mask32(0xd8006a8, 0, 2); //widescreen fix while (1) { _ahbMemFlush(0); //Check this. Purpose is to send another interrupt if wasn't processed /*if (((read32(0x14) != 0) || (read32(0x13026514) != 0)) && (read32(HW_ARMIRQFLAG) & (1 << 30)) == 0) { write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq }*/ #ifdef PATCHALL if (EXI_IRQ == true) { if(EXICheckTimer()) EXIInterrupt(); } #endif if ((PatchSI) && (SI_IRQ != 0)) { if (((read32(HW_TIMER) - PADTimer) > 7910) || (SI_IRQ & 0x2)) // about 240 times a second { SIInterrupt(); PADTimer = read32(HW_TIMER); } } if(DI_IRQ == true) { if(DI_CallbackMsg.result == 0) DIInterrupt(); } else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */ { if((read32(HW_TIMER) - Now) / 1898437 > 2) /* after 3 second earliest */ { EXISaveCard(); SaveCard = false; } } #ifdef NINTENDONT_USB else if((read32(HW_TIMER) - USBReadTimer) / 1898437 > 9) /* Read random sector after about 10 seconds */ { DI_CallbackMsg.result = -1; sync_after_write(&DI_CallbackMsg, 0x20); IOS_IoctlAsync( DI_Handle, 2, NULL, 0, NULL, 0, DI_MessageQueue, &DI_CallbackMsg ); while(DI_CallbackMsg.result) { udelay(10); //wait for other threads BTUpdateRegisters(); } USBReadTimer = read32(HW_TIMER); } #endif udelay(10); //wait for other threads //Baten Kaitos save hax /*if( read32(0) == 0x474B4245 ) { if( read32( 0x0073E640 ) == 0xFFFFFFFF ) { write32( 0x0073E640, 0 ); } }*/ if ( DiscChangeIRQ == 1 ) { DiscChangeTimer = read32(HW_TIMER); DiscChangeIRQ = 2; } else if ( DiscChangeIRQ == 2 ) { if ( (read32(HW_TIMER) - DiscChangeTimer ) > 2 * 243000000 / 128) { //dbgprintf("DIP:IRQ mon!\r\n"); set32( DI_SSTATUS, 0x3A ); sync_after_write((void*)DI_SSTATUS, 4); DIInterrupt(); DiscChangeIRQ = 0; } } _ahbMemFlush(1); DIUpdateRegisters(); #ifdef PATCHALL EXIUpdateRegistersNEW(); GCAMUpdateRegisters(); BTUpdateRegisters(); #endif StreamUpdateRegisters(); CheckOSReport(); if(EXICheckCard()) { Now = read32(HW_TIMER); SaveCard = true; } if (PatchSI) { SIUpdateRegisters(); if (read32(DIP_IMM) == 0x1DEA) { DIFinishAsync(); break; } if (read32(DIP_IMM) == 0x3DEA) { if (Reset == 0) { dbgprintf("Fake Reset IRQ\n"); write32(EXI2DATA, 0x2); // Reset irq write32(HW_IPC_ARMCTRL, (1 << 0) | (1 << 4)); //throw irq Reset = 1; } } else if (Reset == 1) { write32(EXI2DATA, 0x10000); // send pressed ResetTimer = read32(HW_TIMER); Reset = 2; } /* The cleanup is not connected to the button press */ if (Reset == 2) { if ((read32(HW_TIMER) - ResetTimer) / 949219 > 0) //free after half a second { write32(EXI2DATA, 0); // done, clear write32(DIP_IMM, 0); Reset = 0; } } } if(read32(DIP_IMM) == 0x4DEA) PatchGame(); CheckPatchPrs(); if(read32(HW_GPIO_IN) & GPIO_POWER) { DIFinishAsync(); #ifdef PATCHALL BTE_Shutdown(); #endif Shutdown(); } //sync_before_read( (void*)0x1860, 0x20 ); //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(0x1874))) // ); // } // write32(0x1860, 0xdeadbeef); // sync_after_write( (void*)0x1860, 0x20 ); //} cc_ahbMemFlush(1); } if( UseHID ) { /* we're done reading inputs */ thread_cancel(HID_Thread, 0); } IOS_Close(DI_Handle); //close game thread_cancel(DI_Thread, 0); DIUnregister(); write32( DIP_IMM, 0 ); /* reset time */ while(1) { if(read32(DIP_IMM) == 0x2DEA) break; wait_for_ppc(1); } if( ConfigGetConfig(NIN_CFG_LED) ) clear32(HW_GPIO_OUT, GPIO_SLOT_LED); if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) ) EXIShutdown(); if (ConfigGetConfig(NIN_CFG_LOG)) closeLog(); #ifdef PATCHALL BTE_Shutdown(); #endif //unmount FAT device f_mount(0, NULL); #ifndef NINTENDONT_USB SDHCShutdown(); #endif //make sure we set that back to the original write32(HW_PPCSPEED, ori_ppcspeed); IOSBoot((char*)0x13003020, 0, read32(0x13003000)); return 0; }
void HWResetDisable( void ) { clear32( HW_RESETS, 0x4800 ); }
void HW_184( void ) { clear32( 0xD800184, 0x438E ); }
u32 DIUpdateRegisters( void ) { u32 read,i; static u32 PatchState = 0; static u32 DOLReadSize= 0; if( read32(DI_CONTROL) != 0xdeadbeef ) { write32( DI_SCONTROL, read32(DI_CONTROL) & 3 ); clear32( DI_SSTATUS, 0x14 ); write32( DI_CONTROL, 0xdeadbeef ); if( read32(DI_SCONTROL) & 1 ) { if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) ) set32( HW_GPIO_OUT, 1<<5 ); if( read32(DI_CMD_0) != 0xdeadbeef ) { write32( DI_SCMD_0, read32(DI_CMD_0) ); write32( DI_CMD_0, 0xdeadbeef ); } if( read32(DI_CMD_1) != 0xdeadbeef ) { write32( DI_SCMD_1, read32(DI_CMD_1) ); write32( DI_CMD_1, 0xdeadbeef ); } if( read32(DI_CMD_2) != 0xdeadbeef ) { write32( DI_SCMD_2, read32(DI_CMD_2) ); write32( DI_CMD_2, 0xdeadbeef ); } if( read32(DI_DMA_ADR) != 0xdeadbeef ) { write32( DI_SDMA_ADR, read32(DI_DMA_ADR) ); write32( DI_DMA_ADR, 0xdeadbeef ); } if( read32(DI_DMA_LEN) != 0xdeadbeef ) { write32( DI_SDMA_LEN, read32(DI_DMA_LEN) ); write32( DI_DMA_LEN, 0xdeadbeef ); } if( read32(DI_IMM) != 0xdeadbeef ) { write32( DI_SIMM, read32(DI_IMM) ); write32( DI_IMM, 0xdeadbeef ); } switch( read32(DI_SCMD_0) >> 24 ) { case 0xA7: case 0xA9: //dbgprintf("DIP:Async!\n"); case 0xA8: { u32 Buffer = P2C(read32(DI_SDMA_ADR)); u32 Length = read32(DI_SCMD_2); u32 Offset = read32(DI_SCMD_1) << 2; // dbgprintf("DIP:DVDRead( 0x%08x, 0x%08x, 0x%08x )\n", Offset, Length, Buffer|0x80000000 ); // udelay(250); if( GameFile.fptr != Offset ) if( f_lseek( &GameFile, Offset ) != FR_OK ) { EXIControl(1); dbgprintf("DIP:Failed to seek to 0x%08x\n", Offset ); while(1); } if( f_read( &GameFile, (char*)Buffer, Length, &read ) != FR_OK ) { EXIControl(1); dbgprintf("DIP:Failed to read from 0x%08x to 0x%08X\n", Offset, Buffer ); while(1); } //if( ((read+31)&(~31)) != Length ) //{ // dbgprintf("DIP:DVDLowRead Offset:%08X Size:%08d Dst:%08X\n", Offset, Length, Buffer ); // dbgprintf("DIP:Failed to read %d bytes, only got %d\n", Length, read ); // break; //} if( (u32)Buffer == 0x01300000 ) { DoPatchesLoader( (char*)(0x01300000), Length ); } if( PatchState == 0 ) { if( Length == 0x100 ) { if( read32( (u32)Buffer ) == 0x100 ) { //quickly calc the size DOLSize = sizeof(dolhdr); dolhdr *dol = (dolhdr*)Buffer; for( i=0; i < 7; ++i ) DOLSize += dol->sizeText[i]; for( i=0; i < 11; ++i ) DOLSize += dol->sizeData[i]; DOLReadSize = sizeof(dolhdr); DOLMinOff=0x81800000; DOLMaxOff=0; for( i=0; i < 7; ++i ) { if( dol->addressText[i] == 0 ) continue; if( DOLMinOff > dol->addressText[i]) DOLMinOff = dol->addressText[i]; if( DOLMaxOff < dol->addressText[i] + dol->sizeText[i] ) DOLMaxOff = dol->addressText[i] + dol->sizeText[i]; } DOLMinOff -= 0x80000000; DOLMaxOff -= 0x80000000; dbgprintf("DIP:DOLSize:%d DOLMinOff:0x%08X DOLMaxOff:0x%08X\n", DOLSize, DOLMinOff, DOLMaxOff ); PatchState = 1; } } else if( read32(Buffer) == 0x7F454C46 ) { if (getfilenamebyoffset(Offset) != NULL) { dbgprintf("DIP:The Game is loading %s\n", getfilenamebyoffset(Offset)); } else { dbgprintf("DIP:The Game is loading some .elf that is not in the fst...\n"); } for (i = ((*(u32 *)0x00000038) & ~0x80000000) + 16; i < 0x01800000; i+=12) // Search the fst for the dvd offset of the .elf file { if (*(u32 *)i == Offset) { DOLSize = *(u32 *)(i+4); DOLReadSize = Length; if( DOLReadSize == DOLSize ) // The .elf is read completely already { dbgprintf("DIP:The .elf is read completely, file size: %u bytes\n", DOLSize); DoPatches( (char*)(Buffer), Length, 0x80000000 ); } else // a part of the .elf is read { PatchState = 2; DOLMinOff=Buffer; DOLMaxOff=Buffer+Length; if (Length <= 4096) // The .elf header is read { ELFNumberOfSections = read16(Buffer+0x2c) -2; // Assume that 2 sections are .bss and .sbss which are not read dbgprintf("DIP:The .elf header is read(%u bytes), .elf file size: %u bytes, number of sections to load: %u\n", Length, DOLSize, ELFNumberOfSections); } else // The .elf is read into a buffer { ELFNumberOfSections = -1; // Make sure that ELFNumberOfSections == 0 does not become true dbgprintf("DIP:The .elf is read into a buffer, read progress: %u/%u bytes\n", Length, DOLSize); } } break; } } } } else if ( PatchState != 0 ) { DOLReadSize += Length; if (PatchState == 2) { ELFNumberOfSections--; // DOLMinOff and DOLMaxOff are optimised when loading .dol files if (DOLMinOff > Buffer) DOLMinOff = Buffer; if (DOLMaxOff < Buffer+Length) DOLMaxOff = Buffer+Length; if (ELFNumberOfSections < 0) { dbgprintf("DIP:.elf read progress: %u/%u bytes\n", DOLReadSize, DOLSize); } else { dbgprintf("DIP:.elf read progress: %u/%u bytes, sections left: %u\n", DOLReadSize, DOLSize, ELFNumberOfSections); } } //dbgprintf("DIP:DOLSize:%d DOLReadSize:%d\n", DOLSize, DOLReadSize ); if( DOLReadSize >= DOLSize || (PatchState == 2 && ELFNumberOfSections == 0)) { DoPatches( (char*)(DOLMinOff), DOLMaxOff-DOLMinOff, 0x80000000 ); PatchState = 0; } } write32( DI_SDMA_LEN, 0 ); while( read32(DI_SCONTROL) & 1 ) clear32( DI_SCONTROL, 1 ); set32( DI_SSTATUS, 0x3A ); if( ConfigGetConfig(DML_CFG_NODISC) ) { write32( 0x0d80000C, (1<<0) | (1<<4) ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( 0x0d80000C, (1<<2) ); } else { if( (read32(DI_SCMD_0) >> 24) == 0xA7 ) { write32( 0x0d80000C, (1<<0) | (1<<4) ); write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( 0x0d80000C, (1<<2) ); } } } break; default: { EXIControl(1); dbgprintf("DIP:Unknown CMD:%08X %08X %08X %08X %08X %08X\n", read32(DI_SCMD_0), read32(DI_SCMD_1), read32(DI_SCMD_2), read32(DI_SIMM), read32(DI_SDMA_ADR), read32(DI_SDMA_LEN) ); while(1); } break; } if( ConfigGetConfig(DML_CFG_ACTIVITY_LED) ) clear32( HW_GPIO_OUT, 1<<5 ); return 1; } else {
// this is ripped from IOS, because no one can figure out just WTF this thing is doing void _ahb_flush_to(enum AHBDEV dev) { u32 mask = 10; switch(dev) { case AHB_STARLET: mask = 0x8000; break; case AHB_1: mask = 0x4000; break; //case 2: mask = 0x0001; break; case AHB_NAND: mask = 0x0002; break; case AHB_AES: mask = 0x0004; break; case AHB_SHA1: mask = 0x0008; break; //case 6: mask = 0x0010; break; //case 7: mask = 0x0020; break; //case 8: mask = 0x0040; break; case AHB_SDHC: mask = 0x0080; break; //case 10: mask = 0x0100; break; //case 11: mask = 0x1000; break; //case 12: mask = 0x0000; break; default: gecko_printf("ahb_invalidate(%d): Invalid device\n", dev); return; } //NOTE: 0xd8b000x, not 0xd8b400x! u32 val = _mc_read32(0xd8b0008); if(!(val & mask)) { switch(dev) { // 2 to 10 in IOS, add more case AHB_NAND: case AHB_AES: case AHB_SHA1: case AHB_SDHC: while((read32(HW_18C) & 0xF) == 9) set32(HW_188, 0x10000); clear32(HW_188, 0x10000); set32(HW_188, 0x2000000); mask32(HW_124, 0x7c0, 0x280); set32(HW_134, 0x400); while((read32(HW_18C) & 0xF) != 9); set32(HW_100, 0x400); set32(HW_104, 0x400); set32(HW_108, 0x400); set32(HW_10c, 0x400); set32(HW_110, 0x400); set32(HW_114, 0x400); set32(HW_118, 0x400); set32(HW_11c, 0x400); set32(HW_120, 0x400); write32(0xd8b0008, _mc_read32(0xd8b0008) & (~mask)); write32(0xd8b0008, _mc_read32(0xd8b0008) | mask); clear32(HW_134, 0x400); clear32(HW_100, 0x400); clear32(HW_104, 0x400); clear32(HW_108, 0x400); clear32(HW_10c, 0x400); clear32(HW_110, 0x400); clear32(HW_114, 0x400); clear32(HW_118, 0x400); clear32(HW_11c, 0x400); clear32(HW_120, 0x400); clear32(HW_188, 0x2000000); mask32(HW_124, 0x7c0, 0xc0); //0, 1, 11 in IOS, add more case AHB_STARLET: case AHB_1: write32(0xd8b0008, val & (~mask)); // wtfux write32(0xd8b0008, val | mask); write32(0xd8b0008, val | mask); write32(0xd8b0008, val | mask); } } }
//u32 Loopmode=0; int _main( int argc, char *argv[] ) { s32 ret = 0; u8 MessageHeap[0x10]; //u32 MessageQueue=0xFFFFFFFF; BootStatus(0, 0, 0); thread_set_priority( 0, 0x79 ); // do not remove this, this waits for FS to be ready! thread_set_priority( 0, 0x50 ); thread_set_priority( 0, 0x79 ); //MessageQueue = ES_Init( MessageHeap ); ES_Init( MessageHeap ); BootStatus(1, 0, 0); #ifndef NINTENDONT_USB BootStatus(2, 0, 0); ret = SDHCInit(); if(!ret) { dbgprintf("SD:SDHCInit() failed:%d\r\n", ret ); BootStatusError(-2, ret); mdelay(2000); Shutdown(); } #endif BootStatus(3, 0, 0); fatfs = (FATFS*)malloca( sizeof(FATFS), 32 ); s32 res = f_mount( 0, fatfs ); if( res != FR_OK ) { dbgprintf("ES:f_mount() failed:%d\r\n", res ); BootStatusError(-3, res); mdelay(2000); Shutdown(); } BootStatus(4, 0, 0); BootStatus(5, 0, 0); int MountFail = 0; s32 fres = -1; while(fres != FR_OK) { fres = f_open(&GameFile, "/bladie", FA_READ|FA_OPEN_EXISTING); switch(fres) { case FR_OK: f_close(&GameFile); case FR_NO_PATH: case FR_NO_FILE: { fres = FR_OK; } break; default: case FR_DISK_ERR: { f_mount(0, 0); //unmount drive todo: retry could never work MountFail++; if(MountFail == 10) { BootStatusError(-5, fres); mdelay(2000); Shutdown(); } mdelay(5); } break; } } #ifdef NINTENDONT_USB BootStatus(6, s_size, s_cnt); s32 r = LoadModules(55); //dbgprintf("ES:ES_LoadModules(%d):%d\r\n", 55, r ); if( r < 0 ) { BootStatusError(-6, r); mdelay(2000); Shutdown(); } #endif BootStatus(7, s_size, s_cnt); ConfigInit(); BootStatus(8, s_size, s_cnt); SDisInit = 1; memset32((void*)0x13002800, 0, 0x30); sync_after_write((void*)0x13002800, 0x30); u32 HID_Thread = 0; bool UseHID = ConfigGetConfig(NIN_CFG_HID); if( UseHID ) { ret = HIDInit(); if(ret < 0 ) { dbgprintf("ES:HIDInit() failed\r\n" ); BootStatusError(-8, ret); mdelay(2000); Shutdown(); } write32(0x13003004, 0); sync_after_write((void*)0x13003004, 0x20); memset32((void*)0x13003420, 0, 0x1BE0); sync_after_write((void*)0x13003420, 0x1BE0); HID_Thread = thread_create(HID_Run, NULL, (u32*)0x13003420, 0x1BE0, 0x78, 1); thread_continue(HID_Thread); } BootStatus(9, s_size, s_cnt); DIinit(); BootStatus(10, s_size, s_cnt); EXIInit(); BootStatus(11, s_size, s_cnt); SIInit(); //fixes issues in some japanese games if((ConfigGetGameID() & 0xFF) == 'J') write32(HW_PPCSPEED, 0x2A9E0); //Tell PPC side we are ready! cc_ahbMemFlush(1); mdelay(1000); BootStatus(0xdeadbeef, s_size, s_cnt); /* write32( HW_PPCIRQFLAG, read32(HW_PPCIRQFLAG) ); write32( HW_ARMIRQFLAG, read32(HW_ARMIRQFLAG) ); set32( HW_PPCIRQMASK, (1<<31) ); set32( HW_IPC_PPCCTRL, 0x30 ); */ u32 Now = read32(HW_TIMER); u32 PADTimer = Now; bool SaveCard = false; if( ConfigGetConfig(NIN_CFG_LED) ) { set32(HW_GPIO_ENABLE, GPIO_SLOT_LED); clear32(HW_GPIO_DIR, GPIO_SLOT_LED); clear32(HW_GPIO_OWNER, GPIO_SLOT_LED); } write32(0xd8006a0, 0x30000004), mask32(0xd8006a8, 0, 2); while (1) { _ahbMemFlush(0); if(EXI_IRQ == true) { if(EXICheckTimer()) EXIInterrupt(); } if(SI_IRQ == true) { if((read32(HW_TIMER) - PADTimer) >= 65000) // about 29 times a second { SIInterrupt(); PADTimer = read32(HW_TIMER); } } if(DI_IRQ == true) { if(DI_Args->Buffer == 0xdeadbeef) DIInterrupt(); } else if(SaveCard == true) /* DI IRQ indicates we might read async, so dont write at the same time */ { if((read32(HW_TIMER) - Now) / 1898437 > 2) /* after 3 second earliest */ { EXISaveCard(); SaveCard = false; } } udelay(10); //wait for other threads //Baten Kaitos save hax if( read32(0) == 0x474B4245 ) { if( read32( 0x0073E640 ) == 0xFFFFFFFF ) { write32( 0x0073E640, 0 ); } } if( Streaming ) { if( (read32(HW_TIMER) * 19 / 10) - StreamTimer >= 5000000 ) { // dbgprintf("."); StreamOffset += 64*1024; if( StreamOffset >= StreamSize ) { StreamOffset = StreamSize; Streaming = 0; } StreamTimer = read32(HW_TIMER) * 19 / 10; } } if( DiscChangeIRQ ) { if( read32(HW_TIMER) * 128 / 243000000 > 2 ) { //dbgprintf("DIP:IRQ mon!\r\n"); set32( DI_SSTATUS, 0x3A ); sync_after_write((void*)DI_SSTATUS, 4); DIInterrupt(); DiscChangeIRQ = 0; } } _ahbMemFlush(1); DIUpdateRegisters(); EXIUpdateRegistersNEW(); SIUpdateRegisters(); if(EXICheckCard()) { Now = read32(HW_TIMER); SaveCard = true; } if(read32(DI_SCONFIG) == 0x1DEA) { while(DI_Args->Buffer != 0xdeadbeef) udelay(100); break; } cc_ahbMemFlush(1); } if( UseHID ) { /* we're done reading inputs */ thread_cancel(HID_Thread, 0); } thread_cancel(DI_Thread, 0); write32( DI_SCONFIG, 0 ); sync_after_write( (void*)DI_SCONFIG, 4 ); /* reset time */ while(1) { _ahbMemFlush(0); sync_before_read( (void*)DI_SCONFIG, 4 ); if(read32(DI_SCONFIG) == 0x2DEA) break; wait_for_ppc(1); cc_ahbMemFlush(1); } if( ConfigGetConfig(NIN_CFG_LED) ) clear32(HW_GPIO_OUT, GPIO_SLOT_LED); if( ConfigGetConfig(NIN_CFG_MEMCARDEMU) ) EXIShutdown(); IOSBoot((char*)0x13003020, 0, read32(0x13003000)); return 0; }
void HWMAgic( u32 R0, u32 R1, u32 R2, u32 R3 ) { u32 R10,R11,R7,R8,R9,value; R3 = R3 << 24; SP[1] = R3 >> 24; SP[2] = R0; R10 = (R1<<16)>>16; //if( read32( HW_RESETS ) & 0x800 ) //{ // DRAMCTRLWrite( 0x18, 0 ); // DRAMCTRLWrite( 0x19, 0 ); // DRAMCTRLWrite( 0x17, 0 ); // udelay(10); //} //clear32( HW_RESETS, 0x800 ); //udelay(100); clear32( HW_DIFLAGS, 0x20 ); clear32( HW_RESETS, 0x100 ); udelay(10); write32( HW_RESETS, (read32( HW_RESETS ) & 0xFFFFF7FF) | 0x800 ); udelay(5); write32( HW_RESETS, (read32( HW_RESETS ) & 0xFFFFFEFF) | 0x100 ); udelay(5); value = read32( HW_RESETS ) & 0xFFFFFEFF; write32( HW_RESETS, value ); udelay(100); value |= 0x100; write32( HW_RESETS, value ); udelay(5); //SubD clear32( 0xD8001C0, 0xC0000000 ); udelay(100); value = read32( 0xD8001BC ); value&= ~0x3F; value|= 0; value&=0xFFFC003F; value|= 0x00001240; value&=0xF803FFFF; value|= 0x00100000; value&=0xEFFFFFFF; value|= 0; write32( 0xD8001BC, value ); udelay(100); value = read32( 0xD8001C0 ); value&=0x7FFFFFFF; value&=0xBFFFFFFF; value|=0x40000000; value&=0xEFFFFFFF; value|=0x10000000; value&=0xF7FFFFFF; value|=0x08000000; write32( 0xD8001C0, value ); udelay(1000); value = read32( 0xD8001C0 ); value&=0x7FFFFFFF; value|=0x80000000; write32( 0xD8001C0, value ); udelay(1000); //DRAMWrite( 0x100, 0x24 ); //udelay(5); //DRAMWrite( 0x100, 0x20 ); DRAMCTRLWrite( 0x4B, 0 ); if( SP[0] == 1 ) { DRAMCTRLWrite( 0x0048, 0xD09 ); udelay(50); if( SP[0] == 1 ) { DRAMCTRLWrite( 0x0048, 0x509 ); } else { DRAMCTRLWrite( 0x0048, 0x50B ); } } else { DRAMCTRLWrite( 0x0048, 0xD0B ); udelay(50); if( SP[0] != 1 ) { DRAMCTRLWrite( 0x0048, 0x50B ); } else { DRAMCTRLWrite( 0x0048, 0x509 ); } } udelay(50); //SubJ DRAMCTRLWrite( 0x003E, 0xF0F0 ); DRAMCTRLWrite( 0x003F, 0xF0F0 ); DRAMCTRLWrite( 0x0040, 0x1616 ); DRAMCTRLWrite( 0x0041, 0x1616 ); DRAMCTRLWrite( 0x0042, 0x1616 ); DRAMCTRLWrite( 0x0043, 0x1616 ); udelay(50); //SubO if( SP[0] == 1 ) { DRAMCTRLWrite( 0x0048, 0x0109 ); } else { DRAMCTRLWrite( 0x0048, 0x010B ); } udelay(10); DRAMCTRLWrite( 0x0047, 0x8000 ); DRAMCTRLWrite( 0x0027, 0x0000 ); DRAMWrite( 0x010C, 0x01FF ); DRAMWrite( 0x010D, 0x0FFF ); DRAMWrite( 0x010E, 0x0007 ); DRAMWrite( 0x010B, 0x0001 ); DRAMWrite( 0x0109, 0x0004 ); DRAMWrite( 0x0108, 0x0006 ); DRAMWrite( 0x010A, 0x0002 ); DRAMWrite( 0x015B, 0x0EFF ); DRAMWrite( 0x0134, 0x0008 ); DRAMWrite( 0x0135, 0x000C ); DRAMWrite( 0x0136, 0x0018 ); DRAMWrite( 0x0140, 0x0006 ); DRAMWrite( 0x015A, 0x0005 ); DRAMWrite( 0x0137, 0x0005 ); DRAMWrite( 0x0138, 0x0005 ); DRAMWrite( 0x0139, 0x0005 ); DRAMWrite( 0x013A, 0x0005 ); DRAMWrite( 0x013B, 0x0005 ); DRAMWrite( 0x013C, 0x0005 ); DRAMWrite( 0x013D, 0x0005 ); DRAMWrite( 0x013E, 0x0005 ); DRAMWrite( 0x013F, 0x0005 ); DRAMCTRLWrite( 0x001C, 0x0000 ); DRAMCTRLWrite( 0x001B, 0x0000 ); DRAMCTRLWrite( 0x0000, 0x0000 ); DRAMCTRLWrite( 0x0015, 0x0001 ); DRAMCTRLWrite( 0x0016, 0x0000 ); DRAMCTRLWrite( 0x0025, 0x0001 ); DRAMCTRLWrite( 0x0010, 0x0000 ); DRAMCTRLWrite( 0x0023, 0x0008 ); DRAMCTRLWrite( 0x0001, 0x0007 ); DRAMCTRLWrite( 0x0002, 0x0004 ); DRAMCTRLWrite( 0x0005, 0x0007 ); DRAMCTRLWrite( 0x0008, 0x0004 ); DRAMCTRLWrite( 0x0009, 0x0018 ); DRAMCTRLWrite( 0x000A, 0x001B ); DRAMCTRLWrite( 0x0004, 0x0017 ); DRAMCTRLWrite( 0x0021, 0x000B ); DRAMCTRLWrite( 0x000B, 0x0009 ); DRAMCTRLWrite( 0x000C, 0x000B ); DRAMCTRLWrite( 0x000D, 0x0006 ); DRAMCTRLWrite( 0x000E, 0x000C ); DRAMCTRLWrite( 0x000F, 0x0017 ); DRAMCTRLWrite( 0x0011, 0xFC00 ); DRAMCTRLWrite( 0x0012, 0x001F ); DRAMCTRLWrite( 0x0013, 0x0000 ); DRAMCTRLWrite( 0x0014, 0x0000 ); DRAMCTRLWrite( 0x0006, 0x0002 ); DRAMCTRLWrite( 0x0007, 0x000A ); DRAMCTRLWrite( 0x0022, 0x0008 ); DRAMCTRLWrite( 0x001F, 0x1FE0 ); DRAMCTRLWrite( 0x0020, 0x0000 ); DRAMCTRLWrite( 0x002C, 0x7252 ); DRAMCTRLWrite( 0x002D, 0x4A5E ); DRAMCTRLWrite( 0x002E, 0x7BDE ); DRAMCTRLWrite( 0x002F, 0x00DE ); DRAMCTRLWrite( 0x0030, 0x00CC ); DRAMCTRLWrite( 0x0031, 0x0000 ); DRAMCTRLWrite( 0x0032, 0x00CC ); DRAMCTRLWrite( 0x0033, 0x0000 ); DRAMCTRLWrite( 0x0034, 0x00CC ); DRAMCTRLWrite( 0x0035, 0x0000 ); DRAMCTRLWrite( 0x0036, 0x08EC ); DRAMCTRLWrite( 0x0037, 0x0000 ); DRAMCTRLWrite( 0x0038, 0x0476 ); DRAMCTRLWrite( 0x0039, 0x0000 ); if( SP[0] == 1 ) { DRAMCTRLWrite( 0x3A, 0x800F ); DRAMCTRLWrite( 0x3B, 7 ); DRAMCTRLWrite( 0x3C, 0x800F ); DRAMCTRLWrite( 0x3D, 7 ); } else { DRAMCTRLWrite( 0x3A, 0 ); DRAMCTRLWrite( 0x3B, 0 ); DRAMCTRLWrite( 0x3C, 0 ); DRAMCTRLWrite( 0x3D, 0 ); } DRAMCTRLWrite( 0x45, 0 ); DRAMCTRLWrite( 0x100, 0 ); udelay(5); DRAMCTRLWrite( 0x18, 1 ); udelay(5); DRAMCTRLWrite( 0x17, 1 ); udelay(200); DRAMCTRLWrite( 0x4B, 1 ); DRAMCTRLWrite( 0x4C, 1 ); HWRegWriteBatch( 0xFFFF, 0x20, 0x21, 0x20, 1 ); HWRegWriteBatch( 0x2882, 0x22, 0x23, 0x22, 5 ); HWRegWriteBatch( 0x2882, 0x24, 0x25, 0x24, 5 ); HWRegWriteBatch( 0x2C82, 0x22, 0x23, 0x22, 5 ); u32 r5 = (DRAMCTRLRead(0x29) << 0x10) >> 0x18; HWRegWriteBatch( 0x2882, 0x22, 0x23, 0x22, 5 ); HWRegWriteBatch( 0x2C82, 0x24, 0x25, 0x24, 5 ); u32 r4 = (DRAMCTRLRead(0x29) << 0x10) >> 0x18; HWRegWriteBatch( 0x2882, 0x24, 0x25, 0x24, 5 ); HWRegWriteBatch( 0x0903, 0x22, 0x23, 0x22, 1 ); HWRegWriteBatch( 0x0903, 0x24, 0x25, 0x24, 1 ); DRAMCTRLWrite( 0x4C, 0 ); DRAMCTRLWrite( 0x18, 0 ); DRAMCTRLWrite( 0x17, 0 ); udelay(200); if( r4 == r5 ) { DRAMCTRLWrite( 0x18, 1 ); udelay(5); DRAMCTRLWrite( 0x17, 1 ); } else { DRAMCTRLWrite( 0x17, 1 ); udelay(5); DRAMCTRLWrite( 0x18, 1 ); } udelay(200); DRAMCTRLWrite( 0x4B, 0 ); if( r4 != r5 ) { DRAMWrite( 0x10B, 7 ); DRAMCTRLWrite( 0x15, 0 ); } HWRegWriteBatch( 0xFFFF, 0x20, 0x21, 0x20, 2 ); if( r4 == r5 ) { HWRegWriteBatch( 0x288E, 0x22, 0x23, 0x22, 1 ); } else { HWRegWriteBatch( 0x288A, 0x22, 0x23, 0x22, 1 ); } if( r4 == r5 ) { HWRegWriteBatch( 0x288E, 0x24, 0x25, 0x24, 1 ); } HWRegWriteBatch( 0x903, 0x22, 0x23, 0x22, 1 ); if( r4 == r5 ) { HWRegWriteBatch( 0x903, 0x24, 0x25, 0x24, 1 ); } udelay(70); //SubEND HWRegWriteBatch( 0xFFFF, 0x20, 0x21, 0x20, 2 ); HWRegWriteBatch( 0xFFFF, 2, 3, 2, 5 ); HWRegWriteBatch( 0xFFFF, 2, 3, 2, 5 ); int i; for( i=0; i < 0x10; i+=2 ) write16( 0xD8B4000 + i, 0 ); write16( 0xD8B4026, 65 ); //GC-MODE DRAMCTRLWrite( 0x18, 0 ); DRAMCTRLWrite( 0x19, 1 ); DRAMWrite( 0x113, 631 ); //END DRAMWrite( 0x165, 0x29 ); DRAMWrite( 0x164, r5 ); DRAMWrite( 0x165, 0x2B ); DRAMWrite( 0x164, r4 ); }