u32 relocateDol (u8 *buffer, struct __argv *argv) { int loop; dolheader *hdr = (dolheader *)buffer; memset((void *)hdr->bssmem, 0, hdr->bsssize); printf("BSS @ %08x (%08x)\n", hdr->bssmem, hdr->bsssize); for (loop = 0; loop < maxTextSections; loop++) { if (hdr->textsize[loop]) { printf("Text @ %08x (%08x)\n", hdr->textmem[loop], hdr->textsize[loop]); memcpy((void *)hdr->textmem[loop], buffer + hdr->textoff[loop], hdr->textsize[loop]); DCFlushRange((void *)hdr->textmem[loop], hdr->textsize[loop]); ICInvalidateRange((void *)hdr->textmem[loop], hdr->textsize[loop]); } } for (loop = 0; loop < maxDataSections; loop++) { if (hdr->datasize[loop]) { printf("Data @ %08x (%08x)\n", hdr->datamem[loop], hdr->datasize[loop]); memcpy((void *)hdr->datamem[loop], buffer + hdr->dataoff[loop], hdr->datasize[loop]); DCFlushRange((void *)hdr->datamem[loop], hdr->datasize[loop]); } } if (argv && argv->argvMagic == ARGV_MAGIC) { memmove((void *)(hdr->entry + 8), argv, sizeof(*argv)); DCFlushRange((void *)(hdr->entry + 8), sizeof(*argv)); } printf("entry %08x\n", hdr->entry); return hdr->entry; }
u32 load_dol_image(void *dolstart) { u32 i; if (dolstart) { dolfile = (dolheader *) dolstart; for (i = 0; i < 7; i++) { if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue; VIDEO_WaitVSync(); ICInvalidateRange ((void *) dolfile->text_start[i],dolfile->text_size[i]); memmove ((void *) dolfile->text_start[i],dolstart+dolfile->text_pos[i],dolfile->text_size[i]); } for(i = 0; i < 11; i++) { if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue; VIDEO_WaitVSync(); memmove ((void *) dolfile->data_start[i],dolstart+dolfile->data_pos[i],dolfile->data_size[i]); DCFlushRangeNoSync ((void *) dolfile->data_start[i],dolfile->data_size[i]); } /* memset ((void *) dolfile->bss_start, 0, dolfile->bss_size); DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size); */ return dolfile->entry_point; } return 0; }
u32 load_dol_image (void *dolstart, struct __argv *argv) { u32 i; dolheader *dolfile; if (dolstart) { dolfile = (dolheader *) dolstart; for (i = 0; i < 7; i++) { if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) continue; VIDEO_WaitVSync(); ICInvalidateRange ((void *) dolfile->text_start[i],dolfile->text_size[i]); memmove ((void *) dolfile->text_start[i],dolstart+dolfile->text_pos[i],dolfile->text_size[i]); } for(i = 0; i < 11; i++) { if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) continue; VIDEO_WaitVSync(); memmove ((void *) dolfile->data_start[i],dolstart+dolfile->data_pos[i],dolfile->data_size[i]); DCFlushRangeNoSync ((void *) dolfile->data_start[i],dolfile->data_size[i]); } memset ((void *) dolfile->bss_start, 0, dolfile->bss_size); DCFlushRange((void *) dolfile->bss_start, dolfile->bss_size); if (argv && argv->argvMagic == ARGV_MAGIC) { void *new_argv = (void *)(dolfile->entry_point + 8); memmove(new_argv, argv, sizeof(*argv)); DCFlushRange(new_argv, sizeof(*argv)); } return dolfile->entry_point; } return 0; }
static u32 remove_bp(void *mem) { struct bp_entry *e = p_bpentries; struct bp_entry *f = NULL; if(!e) return 0; if(e->address==mem) { p_bpentries = e->next; f = e; } else { for(; e->next; e=e->next) { if(e->next->address==mem) { f = e->next; e->next = f->next; break; } } } if(!f) return 0; *(f->address) = f->instr; f->instr = 0xffffffff; f->address = NULL; DCStoreRangeNoSync((void*)((u32)mem&~0x1f),32); ICInvalidateRange((void*)((u32)mem&~0x1f),32); _sync(); return 1; }
u32 Apploader_Run(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio) { void *dst = NULL; int len = 0; int offset = 0; u32 appldr_len; s32 ret; app_entry appldr_entry; app_init appldr_init; app_main appldr_main; app_final appldr_final; ret = WDVD_Read(&apploader_hdr, 0x20, APPLDR_OFFSET); wifi_printf("apploader_Apploader_Run: WDVD_Read() return value = %d\n", ret); if(ret < 0) return 0; appldr_len = apploader_hdr.size + apploader_hdr.trailersize; wifi_printf("apploader_Apploader_Run: appldr_len value = %08X\n", appldr_len); ret = WDVD_Read(appldr, appldr_len, APPLDR_CODE); wifi_printf("apploader_Apploader_Run: WDVD_Read() return value = %d\n", ret); if(ret < 0) return 0; DCFlushRange(appldr, appldr_len); ICInvalidateRange(appldr, appldr_len); appldr_entry = apploader_hdr.entry; appldr_entry(&appldr_init, &appldr_main, &appldr_final); appldr_init(gprintf); while(appldr_main(&dst, &len, &offset)) { WDVD_Read(dst, len, offset); wifi_printf("apploader_Apploader_Run: dst = %08X len = %08X offset = %08X\n", (u32)dst, (u32)len, (u32)offset); maindolpatches(dst, len, vidMode, vmode, vipatch, countryString, patchVidModes, aspectRatio); DCFlushRange(dst, len); ICInvalidateRange(dst, len); prog(10); } return (u32)appldr_final(); }
void gamepatches(u8 videoSelected, u8 videoPatchDol, u8 aspectForce, u8 languageChoice, u8 patchcountrystring, u8 vipatch, u8 sneekVideoPatch, u8 hooktype, u64 returnTo, u8 privateServer) { int i; /* If a wip file is loaded for this game this does nothing - Dimok */ PoPPatch(); NSMBPatch(); for(i = 0; i < dolCount; ++i) { u8 *dst = dolList[i].dst; int len = dolList[i].len; VideoModePatcher(dst, len, videoSelected, videoPatchDol); dogamehooks(hooktype, dst, len); if (vipatch) vidolpatcher(dst, len); if(sneekVideoPatch) sneek_video_patch(dst, len); /*LANGUAGE PATCH - FISHEARS*/ langpatcher(dst, len, languageChoice); /*Thanks to WiiPower*/ if (patchcountrystring == 1) PatchCountryStrings(dst, len); do_wip_code(dst, len); Anti_002_fix(dst, len); if(returnTo) PatchReturnTo(dst, len, (u32) returnTo); if(aspectForce < 2) PatchAspectRatio(dst, len, aspectForce); if(privateServer) PrivateServerPatcher(dst, len, privateServer); DCFlushRange(dst, len); ICInvalidateRange(dst, len); } /* ERROR 002 fix (thanks to WiiPower for sharing this)*/ *(u32 *)0x80003140 = *(u32 *)0x80003188; DCFlushRange((void*) 0x80000000, 0x3f00); free_wip(); ClearDOLList(); }
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); }
u32 relocateDol (u8 *buffer) { int loop; dolheader *hdr = (dolheader *)buffer; memset((void *)hdr->bssmem, 0, hdr->bsssize); for (loop = 0; loop < maxTextSections; loop++) { memcpy((void *)hdr->textmem[loop], buffer + hdr->textoff[loop], hdr->textsize[loop]); DCFlushRange((void *)hdr->textmem[loop], hdr->textsize[loop]); ICInvalidateRange((void *)hdr->textmem[loop], hdr->textsize[loop]); } for (loop = 0; loop < maxDataSections; loop++) { memcpy((void *)hdr->datamem[loop], buffer + hdr->dataoff[loop], hdr->datasize[loop]); DCFlushRange((void *)hdr->datamem[loop], hdr->datasize[loop]); } return hdr->entry; }
s32 StartMIOS (void) { s32 ret; SetGCVideoMode (); tikview view ATTRIBUTE_ALIGN(32); ret = ES_GetTicketViews(BC, &view, 1); if (ret != 0) return -1; // Tell DML to boot the game from sd card *(u32 *)0x80001800 = 0xB002D105; DCFlushRange((void *)(0x80001800), 4); ICInvalidateRange((void *)(0x80001800), 4); *(volatile unsigned int *)0xCC003024 |= 7; ret = ES_LaunchTitle(BC, &view); return -102; }
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length) { *size = 0; s32 fd = ISFS_Open((const char *) path, ISFS_OPEN_READ); u8 *buf = NULL; static fstats stats ATTRIBUTE_ALIGN(32); if(fd >= 0) { if(ISFS_GetFileStats(fd, &stats) >= 0) { if(length <= 0) length = stats.file_length; if(length > 0) buf = (u8 *)MEM2_memalign(32, length); if(buf) { *size = stats.file_length; if(ISFS_Read(fd, (char*)buf, length) != length) { *size = 0; MEM2_free(buf); } } } ISFS_Close(fd); } if(*size > 0) { DCFlushRange(buf, *size); ICInvalidateRange(buf, *size); } return buf; }
// Installs the GeckoOS (kenobiGC) cheats engine and sets up variables/copies cheats void kenobi_install_engine() { int isDebug = swissSettings.wiirdDebug; // If high memory is in use, we'll use low, otherwise high. u8 *ptr = isDebug ? kenobigc_dbg_bin : kenobigc_bin; u32 size = isDebug ? kenobigc_dbg_bin_size : kenobigc_bin_size; print_gecko("Copying kenobi%s to %08X\r\n", (isDebug?"_dbg":""),(u32)CHEATS_ENGINE); memcpy(CHEATS_ENGINE, ptr, size); memcpy(CHEATS_GAMEID, (void*)0x80000000, CHEATS_GAMEID_LEN); if(!isDebug) { CHEATS_ENABLE_CHEATS = CHEATS_TRUE; } CHEATS_START_PAUSED = isDebug ? CHEATS_TRUE : CHEATS_FALSE; memset(CHEATS_LOCATION(size), 0, kenobi_get_maxsize()); print_gecko("Copying %i bytes of cheats to %08X\r\n", getEnabledCheatsSize(),(u32)CHEATS_LOCATION(size)); u32 *cheatsLocation = (u32*)CHEATS_LOCATION(size); cheatsLocation[0] = 0x00D0C0DE; cheatsLocation[1] = 0x00D0C0DE; cheatsLocation+=2; int i = 0, j = 0; for(i = 0; i < _cheats.num_cheats; i++) { CheatEntry *cheat = &_cheats.cheat[i]; if(cheat->enabled) { for(j = 0; j < cheat->num_codes; j++) { // Copy & fix cheats that want to jump to the old cheat engine location 0x800018A8 -> CHEATS_ENGINE+0xA8 cheatsLocation[0] = cheat->codes[j][0]; cheatsLocation[1] = cheat->codes[j][1] == 0x800018A8 ? (u32)(CHEATS_ENGINE+0xA8) : cheat->codes[j][1]; cheatsLocation+=2; } } } cheatsLocation[0] = 0xFF000000; DCFlushRange((void*)CHEATS_ENGINE, WIIRD_ENGINE_SPACE); ICInvalidateRange((void*)CHEATS_ENGINE, WIIRD_ENGINE_SPACE); }
static u32 insert_bp(void *mem) { u32 i; struct bp_entry *p; for(i=0; i<GEKKO_MAX_BP; i++) { if(bp_entries[i].address == NULL) break; } if(i==GEKKO_MAX_BP) return 0; p = &bp_entries[i]; p->next = p_bpentries; p->address = mem; p_bpentries = p; p->instr = *(p->address); *(p->address) = BPCODE; DCStoreRangeNoSync((void*)((u32)mem&~0x1f),32); ICInvalidateRange((void*)((u32)mem&~0x1f),32); _sync(); return 1; }
virtual void flushDataCache(void *ptr, uint32 len) const { DCFlushRange(ptr, len); ICInvalidateRange(ptr, len); }
void load_handler() { if(debuggerselect == 0x01) { wifi_printf("fst_load_handler: debugger selected\n"); memcpy((void*)0x80001800, codehandler, codehandler_size); if(code_size > 0 && code_buf) { wifi_printf("fst_load_handler: codes found\n"); memcpy((void*)0x80001CDE, &codelist, 2); memcpy((void*)0x80001CE2, ((u8*) &codelist) + 2, 2); memcpy((void*)0x80001F5A, &codelist, 2); memcpy((void*)0x80001F5E, ((u8*) &codelist) + 2, 2); } else wifi_printf("fst_load_handler: no codes found\n"); DCFlushRange((void*)0x80001800, codehandler_size); ICInvalidateRange((void*)0x80001800, codehandler_size); } else { wifi_printf("fst_load_handler: no debugger selected\n"); memcpy((void*)0x80001800, codehandleronly, codehandleronly_size); if(code_size > 0 && code_buf) { wifi_printf("fst_load_handler: codes found\n"); memcpy((void*)0x80001906, &codelist, 2); memcpy((void*)0x8000190A, ((u8*) &codelist) + 2, 2); } else wifi_printf("fst_load_handler: no codes found\n"); DCFlushRange((void*)0x80001800, codehandleronly_size); ICInvalidateRange((void*)0x80001800, codehandleronly_size); } // Load multidol handler memcpy((void*)0x80001000, multidol, multidol_size); DCFlushRange((void*)0x80001000, multidol_size); ICInvalidateRange((void*)0x80001000, multidol_size); switch(hooktype) { case 0x01: memcpy((void*)0x8000119C,viwiihooks,12); memcpy((void*)0x80001198,viwiihooks+3,4); break; case 0x02: memcpy((void*)0x8000119C,kpadhooks,12); memcpy((void*)0x80001198,kpadhooks+3,4); break; case 0x03: memcpy((void*)0x8000119C,joypadhooks,12); memcpy((void*)0x80001198,joypadhooks+3,4); break; case 0x04: memcpy((void*)0x8000119C,gxdrawhooks,12); memcpy((void*)0x80001198,gxdrawhooks+3,4); break; case 0x05: memcpy((void*)0x8000119C,gxflushhooks,12); memcpy((void*)0x80001198,gxflushhooks+3,4); break; case 0x06: memcpy((void*)0x8000119C,ossleepthreadhooks,12); memcpy((void*)0x80001198,ossleepthreadhooks+3,4); break; case 0x07: memcpy((void*)0x8000119C,axnextframehooks,12); memcpy((void*)0x80001198,axnextframehooks+3,4); break; } DCFlushRange((void*)0x80001198,16); }