int ios_ioctlv(int fd, u32 n, u32 in_count, u32 out_count, struct ioctlv *vec) { u32 i; memset(&ipc, 0, sizeof ipc); for (i = 0; i < in_count + out_count; i++) if (vec[i].data) { sync_after_write(vec[i].data, vec[i].len); vec[i].data = (void *)virt_to_phys(vec[i].data); } sync_after_write(vec, (in_count + out_count) * sizeof *vec); ipc.cmd = 7; ipc.fd = fd; ipc.arg[0] = n; ipc.arg[1] = in_count; ipc.arg[2] = out_count; ipc.arg[3] = virt_to_phys(vec); ipc_send_request(); ipc_recv_reply(); for (i = in_count; i < in_count + out_count; i++) if (vec[i].data) { vec[i].data = phys_to_virt((u32)vec[i].data); sync_before_read(vec[i].data, vec[i].len); } return ipc.result; }
int ios_ioctl(int fd, u32 n, const void *in, u32 inlen, void *out, u32 outlen) { memset(&ipc, 0, sizeof ipc); if (in) sync_after_write(in, inlen); if (out) sync_after_write(out, outlen); ipc.cmd = 6; ipc.fd = fd; ipc.arg[0] = n; ipc.arg[1] = virt_to_phys(in); ipc.arg[2] = inlen; ipc.arg[3] = virt_to_phys(out); ipc.arg[4] = outlen; ipc_send_request(); ipc_recv_reply(); if (out) sync_before_read(out, outlen); return ipc.result; }
void ParseTGC(char *Data, u32 Length, u32 Offset) { if(TGCInfo->isTGC == 0) return; if(Offset == 0x420) /* update internal gcm header with the tgc header */ { *(vu32*)(Data+0x00) = TGCInfo->doloffset; *(vu32*)(Data+0x04) = TGCInfo->fstoffset; *(vu32*)(Data+0x08) = TGCInfo->fstsize; *(vu32*)(Data+0x0C) = TGCInfo->fstsize; *(vu32*)(Data+0x34) = TGCInfo->userpos; *(vu32*)(Data+0x38) = 0x57058000L - (TGCInfo->userpos); sync_after_write(Data, Length); } else if(Offset == TGCInfo->fstoffset) /* update internal gcm fst with correct tgc positions */ { char *FSTable = Data; u32 FSTEnt = *(u32*)(FSTable+0x08); FST *fst = (FST *)(FSTable); u32 i; for(i = 1; i < FSTEnt; ++i) { if(fst[i].Type == 0) /* update file offset */ fst[i].FileOffset -= TGCInfo->fstupdate; } sync_after_write(Data, Length); } }
void nand_write(u32 pageno, void *data, void *ecc) { if (data) sync_after_write(data, 0x800); if (ecc) sync_after_write(ecc, 0x40); ipc_exchange(IPC_NAND_WRITE, 3, pageno, (!data ? (u32)-1 : virt_to_phys(data)), (!ecc ? (u32)-1 : virt_to_phys(ecc))); }
int sd_write(u32 start_block, u32 blk_cnt, const void *buffer) { int retval; sync_after_write(buffer, blk_cnt * 512); retval = ipc_exchange(IPC_SDMMC_WRITE, 3, start_block, blk_cnt, virt_to_phys(buffer))->args[0]; return retval; }
int ipc_powerpc_boot(const void *addr, u32 len) { ipc_request *req; sync_after_write(addr, len); req = ipc_exchange(IPC_PPC_BOOT, 3, 0, virt_to_phys(addr), len); return req->args[0]; }
void _main(void) { #if DEBUG usbgecko_init(); usbgecko_printf("_main()\n"); #endif ios_reload(); #if DEBUG usbgecko_printf("ios_reload()\n"); #endif sync_before_read((void*)0x93010010, 0x1800); _memcpy((void*)0x80001800, (void*)0x93010010, 0x1800); sync_after_write((void*)0x80001800, 0x1800); if(*(vu32*)0xC0001804 == 0x53545542 && *(vu32*)0xC0001808 == 0x48415858) //stubhaxx { __asm( "sync ; isync\n" "lis %r3, 0x8000\n" "ori %r3, %r3, 0x1800\n" "mtlr %r3\n" "blr\n" ); } #if DEBUG usbgecko_printf("no loader stub, using internal\n"); #endif ios_cleanup(); #if DEBUG usbgecko_printf("ios_cleanup()\n"); #endif es_init(); #if DEBUG usbgecko_printf("es_init()\n"); #endif u64 ios_titleid = TITLE_ID(1, 35); //just to get away from the kernel es_launchtitle(ios_titleid); #if DEBUG usbgecko_printf("es_launchtitle()\n"); #endif es_init(); #if DEBUG usbgecko_printf("es_init()\n"); #endif es_launchtitle(HBC_LULZ); es_launchtitle(HBC_108); es_launchtitle(HBC_JODI); es_launchtitle(HBC_HAXX); es_launchtitle(SYSTEM_MENU); #if DEBUG usbgecko_printf("es_launchtitle()\n"); #endif while (1); }
static void ipc_send_request(void) { sync_after_write(&ipc, 0x40); ipc_write(0, virt_to_phys(&ipc)); ipc_bell(1); ipc_wait_ack(); ipc_bell(2); ipc_irq_ack(); }
void TRIReset() { //Reset GCAM status GCAMInit(); //F-Zero AX uses Clean CARD after 150 uses if(TRIGame == TRI_AX && TRI_BackupAvailable == 1) { //if we dont set it to 150 it'll beep a lot sync_before_read(OUR_SETTINGS_LOC, 0x20); W16((u32)OUR_SETTINGS_LOC+0x16,150); sync_after_write(OUR_SETTINGS_LOC, 0x20); } }
static s32 BTHandleData(void *arg,void *buffer,u16 len) { sync_before_read(arg, sizeof(struct BTPadStat)); struct BTPadStat *stat = (struct BTPadStat*)arg; u32 chan = stat->channel; if(*(u8*)buffer == 0x3D) //21 expansion bytes report { if(stat->transferstate == TRANSFER_CALIBRATE) { stat->xAxisLmid = bswap16(R16((u32)(((u8*)buffer)+1))); stat->xAxisRmid = bswap16(R16((u32)(((u8*)buffer)+3))); stat->yAxisLmid = bswap16(R16((u32)(((u8*)buffer)+5))); stat->yAxisRmid = bswap16(R16((u32)(((u8*)buffer)+7))); stat->transferstate = TRANSFER_DONE; sync_after_write(arg, sizeof(struct BTPadStat)); sync_before_read(arg, sizeof(struct BTPadStat)); } if(chan == CHAN_NOT_SET) return ERR_OK; sync_before_read(&BTPad[chan], sizeof(struct BTPadCont)); BTPad[chan].xAxisL = ((bswap16(R16((u32)(((u8*)buffer)+1))) - stat->xAxisLmid) *3) >>5; BTPad[chan].xAxisR = ((bswap16(R16((u32)(((u8*)buffer)+3))) - stat->xAxisRmid) *3) >>5; BTPad[chan].yAxisL = ((bswap16(R16((u32)(((u8*)buffer)+5))) - stat->yAxisLmid) *3) >>5; BTPad[chan].yAxisR = ((bswap16(R16((u32)(((u8*)buffer)+7))) - stat->yAxisRmid) *3) >>5; u32 prevButton = BTPad[chan].button; BTPad[chan].button = ~(R16((u32)(((u8*)buffer)+9))); if((!(prevButton & BT_BUTTON_SELECT)) && BTPad[chan].button & BT_BUTTON_SELECT) { //dbgprintf("Using %s control scheme\n", (stat->controller & C_SWAP) ? "orginal" : "swapped"); stat->controller = (stat->controller & C_SWAP) ? (stat->controller & ~C_SWAP) : (stat->controller | C_SWAP); sync_after_write(arg, sizeof(struct BTPadStat)); sync_before_read(arg, sizeof(struct BTPadStat)); } BTPad[chan].used = stat->controller; sync_after_write(&BTPad[chan], sizeof(struct BTPadCont)); } else if(*(u8*)buffer == 0x34) //core buttons with 19 exptension bytes report
static void releasse_old_stm_callback(void) { *((u32 *)0x80000018) = 0x00000014; sync_after_write((void*)0x80000014, 8); int fd = ios_open("/dev/stm/immediate",0); if (fd < 0) { return; } //int err = ios_ioctl(fd, 0x3002, 0, 0, 0, 0); ios_close(fd); }
int ios_open(const char *filename, u32 mode) { sync_after_write(filename, strlen(filename) + 1); memset(&ipc, 0, sizeof ipc); ipc.cmd = 1; ipc.fd = 0; ipc.arg[0] = virt_to_phys(filename); ipc.arg[1] = mode; ipc_send_request(); ipc_recv_reply(); return ipc.result; }
void __init_syscall() { u8* sc_vector = SYSCALL_VECTOR; u32 bytes = (u32)DCFlashInvalidate - (u32)__temp_abe; u8* from = (u8*)__temp_abe; for ( ; bytes != 0 ; --bytes ) { *sc_vector = *from; sc_vector++; from++; } sync_after_write(SYSCALL_VECTOR, 0x100); ICInvalidateRange(SYSCALL_VECTOR, 0x100); }
void ConfigInit( void ) { FIL cfg; u32 read; dbgprintf("CFGInit()\r\n"); ConfigSyncBeforeRead(); if (ncfg->Magicbytes != 0x01070CF6) { dbgprintf("Cfg not in memory, trying file\r\n"); if (f_open_char(&cfg, "/nincfg.bin", FA_OPEN_EXISTING | FA_READ) != FR_OK) { dbgprintf("CFG:Failed to open config\r\n"); Shutdown(); } f_read( &cfg, ncfg, sizeof(NIN_CFG), &read ); sync_after_write(ncfg, sizeof(NIN_CFG)); f_close( &cfg ); if( read != sizeof(NIN_CFG) ) { dbgprintf("CFG:Failed to read config\r\n"); Shutdown(); } ConfigSyncBeforeRead(); } if( IsWiiU() ) { //ncfg->Config |= NIN_CFG_HID; ncfg->MaxPads = 0; // Disable debugging and the drive access LED. ncfg->Config &= ~(NIN_CFG_DEBUGGER | NIN_CFG_DEBUGWAIT | NIN_CFG_LED); } //if( (read32(0) >> 8) == 0x47504F ) // PSO 1&2 disable cheats/debugging //{ // ncfg->Config &= ~(NIN_CFG_CHEATS|NIN_CFG_DEBUGGER|NIN_CFG_DEBUGWAIT); //} }
void GCAMInit( void ) { if(BufsAllocated == 0) { Bufo= (char*)malloca( 0x80, 32 ); Bufi= (char*)malloca( 0x80, 32 ); Buf = (char*)malloca( 0x80, 32 ); res = (u8*) malloca( 0x80, 32 ); CARDMemory = (u8*)malloca( 0xD0, 32 ); CARDReadPacket = (u8*)malloca( 0xDB, 32 ); CARDBuffer = (u8*)malloca( 0x100, 32 ); BufsAllocated = 1; } memset32( Bufo, 0, 0x80 ); memset32( Bufi, 0, 0x80 ); memset32( Buf, 0, 0x80 ); memset32( res, 0, 0x80 ); memset32( CARDMemory, 0, 0xD0 ); memset32( CARDReadPacket, 0, 0xDB ); memset32( CARDBuffer, 0, 0x100 ); memset32( (void*)GCAM_BASE, 0xdeadbeef, 0x40 ); sync_after_write( (void*)GCAM_BASE, 0x40 ); CARDMemorySize = 0; CARDIsInserted = 0; CARDCommand = 0; CARDClean = 0; CARDWriteLength = 0; CARDWrote = 0; CARDReadLength = 0; CARDRead = 0; CARDBit = 0; CARDStateCallCount = 0; CARDOffset = 0; FirstCMD = 0; }
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 aes_decrypt(u8 *src, u8 *dst, u32 blocks, u8 keep_iv) { sync_after_write(src, (blocks+1)*16); ipc_exchange(IPC_AES_DECRYPT, 4, virt_to_phys(src), virt_to_phys(dst), blocks, keep_iv); sync_before_read(dst, (blocks+1)*16); }
void GCAMCARDCommand( char *DataIn, char *DataOut ) { if( DataIn[DataPos] == 1 && DataIn[DataPos+1] == 0x05 ) { // dbgprintf("CARDGetReply(%02X)\n", CARDCommand ); if( CARDReadLength ) { res[resp++] = 0x32; u32 ReadLength = CARDReadLength - CARDRead; if( TRIGame == TRI_AX ) { if( ReadLength > 0x2F ) ReadLength = 0x2F; } res[resp++] = ReadLength; // 0x2F (max size per packet) memcpy( res+resp, CARDReadPacket+CARDRead, ReadLength ); resp += ReadLength; CARDRead += ReadLength; // dbgprintf("CARDRead: %u/%u\n", CARDRead, CARDReadLength ); if( CARDRead >= CARDReadLength ) CARDReadLength = 0; // hexdump( res, 0x80 ); DataPos += DataIn[DataPos] + 1; return; } res[resp++] = 0x32; u32 CMDLenO = resp; res[resp++] = 0x00; // len res[resp++] = 0x02; // u32 ChkStart = resp; res[resp++] = 0x00; // 0x00 len switch(CARDCommand) { case CARD_INIT: { res[resp++] = 0x10; // 0x01 res[resp++] = 0x00; // 0x02 res[resp++] = 0x30; // 0x03 } break; case CARD_IS_PRESENT: { res[resp++] = 0x40; // 0x01 res[resp++] = 0x22; // 0x02 res[resp++] = 0x30; // 0x03 } break; case CARD_GET_CARD_STATE: { res[resp++] = 0x20; // 0x01 res[resp++] = 0x20|CARDBit; // 0x02 /* bit 0: PLease take your card bit 1: endless waiting casues UNK_E to be called */ res[resp++] = 0x00; // 0x03 } break; case CARD_7A: { res[resp++] = 0x7A; // 0x01 res[resp++] = 0x00; // 0x02 res[resp++] = 0x00; // 0x03 } break; case CARD_78: { res[resp++] = 0x78; // 0x01 res[resp++] = 0x00; // 0x02 res[resp++] = 0x00; // 0x03 } break; case CARD_WRITE_INFO: { res[resp++] = 0x7C; // 0x01 res[resp++] = 0x02; // 0x02 res[resp++] = 0x00; // 0x03 } break; case CARD_D0: { res[resp++] = 0xD0; // 0x01 res[resp++] = 0x00; // 0x02 res[resp++] = 0x00; // 0x03 } break; case CARD_80: { res[resp++] = 0x80; // 0x01 if( TRIGame == TRI_AX ) res[resp++] = 0x01; // 0x02 else res[resp++] = 0x31; // 0x02 res[resp++] = 0x30; // 0x03 } break; case CARD_CLEAN_CARD: { res[resp++] = 0xA0; // 0x01 res[resp++] = 0x02; // 0x02 res[resp++] = 0x00; // 0x03 } break; case CARD_LOAD_CARD: { res[resp++] = 0xB0; // 0x01 res[resp++] = 0x02; // 0x02 res[resp++] = 0x30; // 0x03 } break; case CARD_WRITE: { res[resp++] = 0x53; // 0x01 res[resp++] = 0x02; // 0x02 res[resp++] = 0x00; // 0x03 } break; case CARD_READ: { res[resp++] = 0x33; // 0x01 res[resp++] = 0x02; // 0x02 res[resp++] = 0x53; // 0x03 } break; } res[resp++] = 0x30; // 0x04 res[resp++] = 0x00; // 0x05 res[resp++] = 0x03; // 0x06 res[ChkStart] = resp-ChkStart; // 0x00 len u32 i; res[resp] = 0; // 0x07 for( i=0; i < res[ChkStart]; ++i ) res[resp] ^= res[ChkStart+i]; resp++; res[CMDLenO] = res[ChkStart] + 2; } else { memcpy( CARDBuffer + CARDOffset, DataIn+DataPos+1, DataIn[DataPos] ); CARDOffset += DataIn[DataPos]; //Check if we got complete CMD if( CARDBuffer[0] == 0x02 ) { if( CARDBuffer[1] == CARDOffset - 2 ) { if( CARDBuffer[CARDOffset-2] == 0x03 ) { u32 cmd = CARDBuffer[2] << 24; cmd|= CARDBuffer[3] << 16; cmd|= CARDBuffer[4] << 8; cmd|= CARDBuffer[5] << 0; switch(cmd) { default: { // dbgprintf("CARD:Unhandled cmd!\n"); // dbgprintf("CARD:[%08X]\n", cmd ); // hexdump( CARDBuffer, CARDOffset ); } break; case 0x10000000: { #ifdef DEBUG_CARD dbgprintf("CARDInit()\n"); #endif CARDCommand = CARD_INIT; CARDWriteLength = 0; CARDBit = 0; CARDMemorySize = 0; CARDStateCallCount = 0; } break; case 0x20000000: { #ifdef DEBUG_CARD dbgprintf("CARDGetState(%02X)\n", CARDBit ); #endif CARDCommand = CARD_GET_CARD_STATE; if( TRIGame == TRI_AX && CARDMemorySize ) { CARDStateCallCount++; if( CARDStateCallCount > 10 ) { if( CARDBit & 2 ) CARDBit &= ~2; else CARDBit |= 2; CARDStateCallCount = 0; } } if( CARDClean == 1 ) { CARDClean = 2; } else if( CARDClean == 2 ) { DIFinishAsync(); //DONT ever try todo file i/o async FIL fi; if( f_open_char( &fi, GCAMGetCARDName(), FA_READ|FA_OPEN_EXISTING ) == FR_OK ) { if( fi.fsize > 0 ) { CARDMemorySize = fi.fsize; if( TRIGame == TRI_AX ) CARDBit = 2; else CARDBit = 1; } f_close(&fi); } CARDClean = 0; } } break; case 0x40000000: { #ifdef DEBUG_CARD dbgprintf("CARDIsPresent()\n"); #endif CARDCommand = CARD_IS_PRESENT; } break; case 0x7A000000: { #ifdef DEBUG_CARD dbgprintf("CARDUnknown7A()\n"); #endif CARDCommand = CARD_7A; //hexdump( CARDBuffer+2, CARDOffset-2 ); } break; case 0xB0000000: { #ifdef DEBUG_CARD dbgprintf("CARDLoadCard()\n"); #endif CARDCommand = CARD_LOAD_CARD; } break; case 0xA0000000: { #ifdef DEBUG_CARD dbgprintf("CARDIsCleanCard?()\n"); #endif CARDCommand = CARD_CLEAN_CARD; CARDClean = 1; } break; case 0x33000000: { #ifdef DEBUG_CARD dbgprintf("CARDRead()\n"); #endif CARDCommand = CARD_READ; //Prepare read packet memset( CARDReadPacket, 0, 0xDB ); u32 POff=0; DIFinishAsync(); //DONT ever try todo file i/o async FIL cf; if( f_open_char( &cf, GCAMGetCARDName(), FA_READ|FA_OPEN_EXISTING ) == FR_OK ) { if( CARDMemorySize == 0 ) CARDMemorySize = cf.fsize; u32 read; f_read( &cf, CARDMemory, CARDMemorySize, &read ); f_close( &cf ); sync_after_write(CARDMemory, CARDMemorySize); CARDIsInserted = 1; } CARDReadPacket[POff++] = 0x02; // SUB CMD CARDReadPacket[POff++] = 0x00; // SUB CMDLen CARDReadPacket[POff++] = 0x33; // CARD CMD if( CARDIsInserted ) { CARDReadPacket[POff++] = '1'; // CARD Status } else { CARDReadPacket[POff++] = '0'; // CARD Status } CARDReadPacket[POff++] = '0'; // CARDReadPacket[POff++] = '0'; // //Data reply sync_before_read(CARDMemory, CARDMemorySize); memcpy( CARDReadPacket + POff, CARDMemory, CARDMemorySize ); POff += CARDMemorySize; CARDReadPacket[POff++] = 0x03; CARDReadPacket[1] = POff-1; // SUB CMDLen u32 i; for( i=0; i < POff-1; ++i ) CARDReadPacket[POff] ^= CARDReadPacket[1+i]; POff++; // hexdump( CARDReadPacket, POff ); CARDReadLength = POff; CARDRead = 0; } break; case 0x53000000: { CARDCommand = CARD_WRITE; CARDMemorySize = CARDBuffer[1] - 9; memcpy( CARDMemory, CARDBuffer+9, CARDMemorySize ); #ifdef DEBUG_CARD dbgprintf("CARDWrite: %u\n", CARDMemorySize ); #endif u32 CARDIsValid; switch(TRIGame) { case TRI_GP1: case TRI_GP2: CARDIsValid = (memcmp(CARDMemory, "MKA", 3) == 0); break; case TRI_AX: CARDIsValid = (memcmp(CARDMemory+0x8A, "SEGABGG", 7) == 0); break; default: CARDIsValid = 0; break; } if(CARDIsValid) { DIFinishAsync(); //DONT ever try todo file i/o async FIL cf; if( f_open_char( &cf, GCAMGetCARDName(), FA_WRITE|FA_CREATE_ALWAYS ) == FR_OK ) { u32 wrote; f_write( &cf, CARDMemory, CARDMemorySize, &wrote ); f_close( &cf ); } } CARDBit = 2; sync_after_write(CARDMemory, CARDMemorySize); CARDStateCallCount = 0; } break; case 0x78000000: { #ifdef DEBUG_CARD dbgprintf("CARDUnknown78()\n"); #endif CARDCommand = CARD_78; } break; case 0x7C000000: { #ifdef DEBUG_CARD dbgprintf("CARDWriteCardInfo()\n"); #endif CARDCommand = CARD_WRITE_INFO; // hexdump( CARDBuffer, CARDOffset ); } break; case 0x7D000000: { #ifdef DEBUG_CARD dbgprintf("CARDPrint?()\n"); #endif CARDCommand = CARD_7D; } break; case 0x80000000: { #ifdef DEBUG_CARD dbgprintf("CARDUnknown80()\n"); #endif CARDCommand = CARD_80; if( TRIGame != TRI_AX ) CARDBit = 0; } break; case 0xD0000000: { #ifdef DEBUG_CARD dbgprintf("CARDUnknownD0()\n"); #endif CARDCommand = CARD_D0; if( TRIGame != TRI_AX ) CARDBit = 0; } break; } // hexdump( CARDBuffer, CARDOffset ); CARDOffset = 0; } } } res[resp++] = 0x32; res[resp++] = 0x01; // len res[resp++] = 0x06; // OK } }
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; }
//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 GCAMUpdateRegisters( void ) { u32 i; u32 *GInterface = (u32*)(GCAM_BASE); u32 *GInterfaceS = (u32*)(GCAM_SHADOW); sync_before_read( (void*)GCAM_BASE, 0x40 ); if( read32(GCAM_CONTROL) != 0xdeadbeef ) { if( read32( GCAM_CONTROL ) & (~3) ) { write32( GCAM_CONTROL, 0xdeadbeef ); sync_after_write( (void*)GCAM_BASE, 0x40 ); return; } /*write32( GCAM_SCONTROL, read32(GCAM_CONTROL) & 3 ); clear32( GCAM_SSTATUS, 0x14 ); write32( GCAM_CONTROL, 0xdeadbeef ); write32( GCAM_RETURN, 0xdeadbeef ); write32( GCAM_STATUS, 0xdeadbeef ); sync_after_write( (void*)GCAM_BASE, 0x40 );*/ for( i=0; i < 5; ++i ) { if( GInterface[i] != 0xdeadbeef ) { GInterfaceS[i] = GInterface[i]; GInterface[i] = 0xdeadbeef; } } switch( read32(GCAM_SCMD) >> 24 ) { case 0x00: { //dbgprintf("CARD:Warning unknown command!\n"); } break; case 0x50: { char *datain = (char*)P2C( read32(GCAM_SCMD_1) ); u32 lenin = read32(GCAM_SCMD_2); char *dataout = (char*)P2C( read32(GCAM_SCMD_3) ); u32 lenout = read32(GCAM_SCMD_4); #ifdef DEBUG_GCAM dbgprintf("SI:Transfer( %p, %u, %p, %u )\n", datain, lenin, dataout, lenout ); hexdump( datain, lenin ); #endif sync_before_read_align32(datain, lenin); switch( datain[0] ) { // dbgprintf("[%02X]", datain[0] ); case 0x00: { W32( (u32)dataout, 0x10110800 ); // dbgprintf("Reset(0x%p)\n", dataout ); } break; default: // CMD_DIRECT case 0x40: // CMD_ORIGIN case 0x41: // CMD_RECALIBRATE case 0x42: { memset( dataout, 0, lenout ); } break; } sync_after_write_align32(dataout, lenout); //hexdump( dataout, lenout ); //while( read32(GCAM_CONTROL) & 1 ) // clear32( GCAM_CONTROL, 1 ); //while( (read32(GCAM_SSTATUS) & 0x10) != 0x10 ) // set32( GCAM_SSTATUS, 0x10 ); } break; case 0x70: { char *datain = (char*)P2C( read32(GCAM_SCMD_1) ); char *dataout = (char*)P2C( read32(GCAM_SCMD_2) ); //dbgprintf("GC-AM:Command( %p, %u, %p, %u )\n", datain, 0x80, dataout, 0x80 ); sync_before_read_align32(datain, 0x80); memcpy( Bufi, datain, 0x80 ); GCAMCommand( Bufi, Buf ); if( FirstCMD == 0 ) { memset32( dataout, 0, 0x80 ); FirstCMD = 1; } else { memcpy( dataout, Bufo, 0x80 ); memcpy( Bufo, Buf, 0x80 ); } sync_after_write_align32(dataout, 0x80); //hexdump( dataout, 0x10 ); //while( read32(GCAM_CONTROL) & 1 ) // clear32( GCAM_CONTROL, 1 ); //while( (read32(GCAM_SSTATUS) & 0x10) != 0x10 ) // set32( GCAM_SSTATUS, 0x10 ); } break; default: { dbgprintf("Unhandled cmd:%02X\n", read32(GCAM_SCMD) ); Shutdown(); } break; } //to be 100% sure we dont ever read a still cached block in ppc write32( GCAM_CONTROL, 0xdeadbeef ); sync_after_write( (void*)GCAM_BASE, 0x40 ); } }