#include #include #include #include #include #include "draw.h" #include "GBApatch.h" #include "gba_nes_patch.h" #include "ezkernel.h" #include "reset_table.h" #include "lang.h" #include "showcht.h" #define _UnusedVram 0x06012c00 u32 windows_offset; u32 is_NORpatch; u32 g_Offset; u32 is_Nes; u32 Nes_index; u32 Nes_index_17_patch; u32 iTrimSize; u32 EA_offset; u32 w_reset_on; u32 w_rts_on; u32 w_sleep_on; u32 w_cheat_on; SPatchInfo2 iPatchInfo2[EMax]; u32 iCount2; extern ST_entry pCHEAT[256]; #define sizeofa(array) (sizeof(array)/sizeof(array[0])) u32 spend_address; //------------------------------------------------------------------ void Write(u32 romaddress, const u8* buffer, u32 size) { u32 x; if(is_NORpatch) { if((romaddress >= windows_offset) && (romaddress < windows_offset+0x20000)) { for(x=0;x=0x800000) { Address-=0x800000; page+=0x1000; } SetPSRampage(page); for(x=0;x PATCH_LENGTH){ top=bottom-PATCH_LENGTH-16; } else{ top = 0; } alignedSize=romsize+(16-(romsize&15)); for(u32 ii=bottom;ii>=top;ii--) { if(buffer[ii]!=byte||ii==top) { iTrimSize=ii+4; iTrimSize=iTrimSize+ ((romsize-1)&0xFFFE0000); iTrimSize=iTrimSize+(16-(iTrimSize&15)); if(iTrimSize>alignedSize) iTrimSize=alignedSize; break; } } } //DEBUG_printf("iTrimSize %08X ", iTrimSize); if(mode ==1)//nor { if( ((iTrimSize&0x1FFFF)+PATCH_LENGTH) > 0x20000)//Greater than one flash sector { iTrimSize = ((romsize+0x1FFFF)/0x20000)*0x20000; } if(romsize <=0x1000000) { if((iTrimSize + PATCH_LENGTH) > 16 * 1024 * 1024) { if((saveMODE==0x21 )||(saveMODE==0x22 ) )//eeprom game { iTrimSize = 0x1000000-PATCH_LENGTH;//can not greater 16MB } else{//sram and flash iTrimSize = 0x1000000; //page } } } } else { if(romsize <=0x800000) { if((iTrimSize + PATCH_LENGTH) > 8 * 1024 * 1024) iTrimSize = 0x800000; //page } else if(romsize <=0x1000000) { if((iTrimSize + PATCH_LENGTH) > 16 * 1024 * 1024) { if((saveMODE==0x21 )||(saveMODE==0x22 ) )//eeprom game { iTrimSize = 0x1000000-PATCH_LENGTH;//can not greater 16MB } else{//sram and flash iTrimSize = 0x1000000; //page } } } else { if((iTrimSize + PATCH_LENGTH) > 32 * 1024 * 1024) iTrimSize = 0x2000000-PATCH_LENGTH; //page } } Patch_SpecialROM_TrimSize(); } //------------------------------------------------------------------ void Patch_B_address(void) { if (!iCount2) return; u32 B_install_handler; B_install_handler = 0xEA000000|((iTrimSize-8)/4); Write(0,(u8*)&B_install_handler , 4); //B for (u32 ii = 0; ii= 0x40000) { *(vu32*)(patchbuffer+cheat_offset+8*ii) = ((pCHEAT[ii].address)&0x7FFF) + 0x3000000; } else { *(vu32*)(patchbuffer+cheat_offset+8*ii) = ((pCHEAT[ii].address)&0x3FFFF) + 0x2000000; } *(vu32*)(patchbuffer+cheat_offset+8*ii+4) = pCHEAT[ii].VAL; //DEBUG_printf("%x=%x", *(vu32*)(patchbuffer+cheat_offset+8*ii),*(vu32*)(patchbuffer+cheat_offset+8*ii+4)); } u32 copysize = p_no_cheat_end-p_patch_start ; copysize = copysize + gl_cheat_count*8; if( iTrimSize+copysize > 0x2000000){ copysize = 0x2000000 - iTrimSize; } //DEBUG_printf("iTrimSize =%x %x", iTrimSize,copysize); Write(iTrimSize, patchbuffer,copysize); } //------------------------------------------------------------------ void GBApatch_Cleanrom(u32* address,int filesize)//Only once { windows_offset = 0; is_NORpatch = 0; CheckNes(address); PatchNes(address); PatchDragonBallZ(address); } //------------------------------------------------------------------ u32 Get_spend_address(u32* Data) { u32 ii; u32 offset; u32 updown; u32 search_size=0x5000/4; for(ii=0;ii 0x03007E80) /*|| (Data[address/4] == 0x03007E00)*/ || (Data[address/4] == 0x0203FFFC) ) { Data[address/4] = Data[address/4] - 0x80; return (Data[address/4]); } else return 0; } //------------------------------------------------------------------ void GBApatch_PSRAM(u32* address,int filesize)//Only once { windows_offset = 0; is_NORpatch = 0; EA_offset = address[0] & 0xFFFFFF; CheckNes(address); PatchNes(address); PatchDragonBallZ(address); if((gl_rts_on==1) || ((gl_cheat_on==1)&& (gl_cheat_count>0) ) ) { spend_address = Get_spend_address(address); //DEBUG_printf("spend_address =%x",spend_address); Patch_RTS_Cheat(address); } else { Patch_Reset_Sleep(address); } } //------------------------------------------------------------------ void GBApatch_Cleanrom_NOR(u32* address,u32 offset) { windows_offset = offset; is_NORpatch = 1; if(offset==0) { CheckNes(address); } PatchNes(address); PatchDragonBallZ(address); } //------------------------------------------------------------------ void GBApatch_NOR(u32* address,int filesize,u32 offset) { windows_offset = offset; is_NORpatch = 1; if(offset==0) { CheckNes(address); EA_offset = address[0] & 0xFFFFFF; u32 B_install_handler; B_install_handler = 0xEA000000|((iTrimSize-8)/4); Write(0,(u8*)&B_install_handler , 4); //B spend_address = Get_spend_address(address); } PatchNes(address); PatchDragonBallZ(address); if((gl_rts_on==1) || ((gl_cheat_on==1)&& (gl_cheat_count>0) ) ) { Patch_RTS_Cheat(address); } else { Patch_Reset_Sleep(address); } } //------------------------------------------------------------------ void make_pat_name(TCHAR*patnamebuf,TCHAR* gamefilename) { memcpy(patnamebuf,gamefilename,100); u32 len=strlen(patnamebuf); patnamebuf[len-3] = 'p'; patnamebuf[len-2] = 'a'; patnamebuf[len-1] = 't'; } //------------------------------------------------------------------ void GBA_patch_init(void) { is_NORpatch = 0; windows_offset = 0; is_Nes = 0; Nes_index = 0; g_Offset = 0; iCount2 = 0; iTrimSize = 0; EA_offset = 0; w_reset_on = 0; w_rts_on = 0; w_sleep_on = 0; w_cheat_on = 0; memset(iPatchInfo2, 0x00, sizeof(iPatchInfo2)); } //------------------------------------------------------------------ void GBA_patch_init_buffer(u32* buffer) { memcpy(iPatchInfo2, buffer, sizeof(iPatchInfo2)); u32 start = sizeof(iPatchInfo2)/4; is_NORpatch = buffer[start+0]; windows_offset = buffer[start+1]; is_Nes = buffer[start+2]; Nes_index = buffer[start+3]; g_Offset = buffer[start+4]; iCount2 = buffer[start+5]; iTrimSize = buffer[start+6]; EA_offset = buffer[start+7]; w_reset_on = buffer[start+8]; w_rts_on = buffer[start+9]; w_sleep_on = buffer[start+10]; w_cheat_on = buffer[start+11]; } //------------------------------------------------------------------ u32 Check_pat(TCHAR* gamefilename) { UINT ret; u32 find_the_patfile; u32 patfilesize; u32 res; TCHAR patnamebuf[100]; make_pat_name(patnamebuf,gamefilename); res=f_chdir("/PATCH"); if(res == FR_OK) { res = f_open(&gfile,patnamebuf, FA_READ); if(res == FR_OK)//have a old file { patfilesize = f_size(&gfile); f_read(&gfile, pReadCache, patfilesize, &ret); f_close(&gfile); find_the_patfile = 1; } else { find_the_patfile = 0; } //res=f_chdir("/"); } else//no PATCH folder { find_the_patfile = 0; } if(find_the_patfile) { //read patch information GBA_patch_init_buffer((u32*)pReadCache); if( (w_reset_on !=gl_reset_on) || (w_rts_on !=gl_rts_on) || (w_sleep_on !=gl_sleep_on) || (w_cheat_on !=gl_cheat_on)) { GBA_patch_init(); find_the_patfile = 0; } } else { GBA_patch_init(); } return find_the_patfile; } //------------------------------------------------------------------ void Make_pat_file(TCHAR* gamefilename) { u32 res; u32 written; u32 w_buffer[16]; res = f_mkdir("/PATCH"); res=f_chdir("/PATCH"); memset(w_buffer, 0x00, sizeof(w_buffer)); if(res == FR_OK){ TCHAR patnamebuf[100]; make_pat_name(patnamebuf,gamefilename); res = f_open(&gfile,patnamebuf, FA_WRITE | FA_OPEN_ALWAYS); if(res == FR_OK) { f_lseek(&gfile, 0x0000); res=f_write(&gfile, (void*)iPatchInfo2, sizeof(iPatchInfo2), &written); w_buffer[0] = is_NORpatch; w_buffer[1] = windows_offset; w_buffer[2] = is_Nes; w_buffer[3] = Nes_index; w_buffer[4] = g_Offset; w_buffer[5] = iCount2; w_buffer[6] = iTrimSize; w_buffer[7] = EA_offset; w_buffer[8] = gl_reset_on; w_buffer[9] = gl_rts_on; w_buffer[10] = gl_sleep_on; w_buffer[11] = gl_cheat_on; res=f_write(&gfile, (void*)w_buffer, sizeof(w_buffer), &written); f_close(&gfile); } } res=f_chdir("/"); } //------------------------------------------------------------------ void make_mde_name(TCHAR*mdenamebuf,TCHAR* gamefilename) { memcpy(mdenamebuf,gamefilename,100); u32 len=strlen(mdenamebuf); mdenamebuf[len-3] = 'm'; mdenamebuf[len-2] = 'd'; mdenamebuf[len-1] = 'e'; } //------------------------------------------------------------------ u8 Check_mde_file(TCHAR* gamefilename) { UINT ret; u32 find_the_mdefile; u32 mdefilesize; u32 res; TCHAR mdenamebuf[100]; make_mde_name(mdenamebuf,gamefilename); res=f_chdir("/SAVER"); if(res == FR_OK) { res = f_open(&gfile,mdenamebuf, FA_OPEN_EXISTING); if(res == FR_OK)//have a old file { f_open(&gfile,mdenamebuf, FA_READ); mdefilesize = f_size(&gfile); f_read(&gfile, pReadCache, mdefilesize, &ret); f_close(&gfile); find_the_mdefile = 1; } else { find_the_mdefile = 0; } } else//cant fine folder { find_the_mdefile = 0; } if(find_the_mdefile) { //read return (pReadCache[0]); } else { return 0; } } //------------------------------------------------------------------ void Make_mde_file(TCHAR* gamefilename,u8 Save_num) { u32 res; u32 written; u8 w_buffer[16]; TCHAR currentpath[256]; memset(currentpath,00,256); res = f_getcwd(currentpath, sizeof currentpath / sizeof *currentpath); res = f_mkdir("/SAVER"); res=f_chdir("/SAVER"); memset(w_buffer, 0x00, sizeof(w_buffer)); if(res == FR_OK){ TCHAR mdenamebuf[100]; make_mde_name(mdenamebuf,gamefilename); res = f_open(&gfile,mdenamebuf, FA_WRITE | FA_OPEN_ALWAYS); if(res == FR_OK) { f_lseek(&gfile, 0x0000); w_buffer[0] = Save_num; res=f_write(&gfile, (void*)w_buffer, sizeof(w_buffer), &written); f_close(&gfile); } } res=f_chdir(currentpath); } //------------------------------------------------------------------ u32 Check_RTS(TCHAR* gamefilename) { UINT ret; u32 find_the_patfile; u32 rtsfilesize; u32 res; TCHAR rtsnamebuf[100]; memcpy(rtsnamebuf,gamefilename,100); u32 len=strlen(rtsnamebuf); rtsnamebuf[len-3] = 'r'; rtsnamebuf[len-2] = 't'; rtsnamebuf[len-1] = 's'; res = f_mkdir("/RTS"); res=f_chdir("/RTS"); if(res != FR_OK){ return 0; } res = f_open(&gfile,rtsnamebuf, FA_OPEN_EXISTING); if(res == FR_OK)//have a old rts file { rtsfilesize = f_size(&gfile); f_close(&gfile); } else //make a new one { ShowbootProgress(gl_make_RTS); res=f_open(&gfile, rtsnamebuf, FA_WRITE | FA_OPEN_ALWAYS); if(res==FR_OK) { int i; unsigned int written; memset(pReadCache,0xFF,0x200*4); for(i=0;i<(0x70000)/0x800 ;i++) { f_write(&gfile, pReadCache, 0x200*4, &written); if(written != 0x200*4) break; } f_close(&gfile); rtsfilesize = 0x70000; } else rtsfilesize = 0; } LoadRTSfile(rtsnamebuf); if(rtsfilesize) { res = Check_game_save_FAT(rtsnamebuf,3);//rts FAT if(res == 0xffffffff){ rtsfilesize = 0; } } return rtsfilesize; } //------------------------------------------------------------------ u32 use_internal_engine(u8 gamecode[]) { u32 i; u32 count0x3007FFC=0; g_Offset = 0; dmaCopy((void*)reset_table, (void*)pReadCache, sizeof(reset_table)); for(i=0;i