void PatchGXWideMulti(u32 BufferPos, u32 dstReg) { u32 wide = PatchCopy(CalcGXWidescreen, CalcGXWidescreen_size); /* Copy original instruction and jump */ write32(wide+CalcGXWidescreen_size-8, read32(BufferPos)); PatchB(wide, BufferPos); /* Jump back to original code */ PatchB(BufferPos+4, wide+CalcGXWidescreen_size-4); }
void PatchWideMulti(u32 BufferPos, u32 dstReg) { u32 wide = PatchCopy(CalcWidescreen, CalcWidescreen_size); /* Copy original instruction and jump */ write32(wide, read32(BufferPos)); PatchB(wide, BufferPos); /* Modify destination register */ write32(wide+0x28, (read32(wide+0x28) & 0xFC1FF83F) | (dstReg << 6) | (dstReg << 21)); /* Jump back to original code */ PatchB(BufferPos+4, wide+CalcWidescreen_size-4); }
void TRISetupGames() { if( read32(0x023D240) == 0x386000A8 ) { dbgprintf("TRI:Mario Kart Arcade GP (Feb 14 2006 13:09:48)\r\n"); TRIGame = TRI_GP1; SystemRegion = REGION_JAPAN; //Unlimited CARD uses write32( 0x01F5C44, 0x60000000 ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuGP, CheckTestMenuGP_size), 0x31BE8 ); //dont wait for other cabinets to link up write32( 0x00328F4, 0x38600000 ); //Disable wheel/handle //write32( 0x007909C, 0x98650022 ); //Disable cam write32( 0x00790A0, 0x98650025 ); //VS wait write32( 0x00BE10C, 0x4800002C ); //Remove some menu timers write32( 0x0019BFF8, 0x60000000 ); //card check write32( 0x001BCAA8, 0x60000000 ); //want to make a card write32( 0x00195748, 0x60000000 ); //card view write32( 0x000CFABC, 0x60000000 ); //select game mode write32( 0x000D9F14, 0x60000000 ); //select character write32( 0x001A8CF8, 0x60000000 ); //select cup write32( 0x001A89B8, 0x60000000 ); //select round write32( 0x001A36CC, 0x60000000 ); //select item pack (card) write32( 0x001A2A10, 0x60000000 ); //select item (card) write32( 0x001B9724, 0x60000000 ); //continue write32( 0x001E61B4, 0x60000000 ); //rewrite rank write32( 0x001A822C, 0x60000000 ); //select course p1 (time attack) write32( 0x001A7F0C, 0x60000000 ); //select course p2 (time attack) write32( 0x000D6234, 0x60000000 ); //enter name (time attack, card) write32( 0x001BF1DC, 0x60000000 ); //save record p1 (time attack on card) write32( 0x001BF1DC, 0x60000000 ); //save record p2 (time attack on card) write32( 0x000E01B4, 0x60000000 ); //select record place (time attack on card) //Make some menu timers invisible PatchB( 0x000B12EC, 0x000B12E0 ); //Make coin count (layer 7) invisible write32( 0x0008650C, 0x4E800020 ); //Modify to regular GX pattern to patch later write32( 0x363660, 0x00 ); //NTSC Interlaced //Test Menu Interlaced //memcpy( (void*)0x036369C, (void*)0x040EB88, 0x3C ); //PAD Hook for control updates PatchBL( PatchCopy(PADReadGP, PADReadGP_size), 0x3C2A0 ); // Game specific rumble hook PatchBL( PatchCopy(PADControlMotorGP, PADControlMotorGP_size), 0x3AA40 ); //some report check skip //write32( 0x00307CC, 0x60000000 ); //memcpy( (void*)0x00330BC, OSReportDM, sizeof(OSReportDM) ); //memcpy( (void*)0x0030710, OSReportDM, sizeof(OSReportDM) ); //memcpy( (void*)0x0030760, OSReportDM, sizeof(OSReportDM) ); //memcpy( (void*)0x020CBCC, OSReportDM, sizeof(OSReportDM) ); // UNkReport //memcpy( (void*)0x02281B8, OSReportDM, sizeof(OSReportDM) ); // UNkReport4 } else if( read32(0x02856EC) == 0x386000A8 ) { dbgprintf("TRI:Mario Kart Arcade GP 2 (Feb 7 2007 02:47:24)\r\n"); TRIGame = TRI_GP2; SystemRegion = REGION_JAPAN; //Unlimited CARD uses write32( 0x00A02F8, 0x60000000 ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuGP, CheckTestMenuGP_size), 0x2E338 ); //dont wait for other cabinets to link up write32( 0x002F054, 0x38600000 ); //Disable wheel //write32( 0x0073BD4, 0x98650022 ); //Disable cam write32( 0x0073BD8, 0x98650025 ); //Disable red item button write32( 0x0073C98, 0x98BF0045 ); //VS wait patch write32( 0x0084FC4, 0x4800000C ); write32( 0x0085000, 0x60000000 ); //Remove some menu timers (thanks conanac) write32( 0x001C1074, 0x60000000 ); //card check write32( 0x001C0174, 0x60000000 ); //want to make a card write32( 0x00232818, 0x60000000 ); //card view write32( 0x001C1A08, 0x60000000 ); //select game mode write32( 0x001C3380, 0x60000000 ); //select character write32( 0x001D7594, 0x60000000 ); //select kart write32( 0x001C7A7C, 0x60000000 ); //select cup write32( 0x001C9ED8, 0x60000000 ); //select round write32( 0x00237B3C, 0x60000000 ); //select item (card) write32( 0x0024D35C, 0x60000000 ); //continue write32( 0x0015F2F4, 0x60000000 ); //rewrite rank write32( 0x001CF5DC, 0x60000000 ); //select course (time attack) write32( 0x001BE248, 0x60000000 ); //enter name (time attack, card) write32( 0x0021DFF0, 0x60000000 ); //save record (time attack on card) //Make some menu timers invisible write32( 0x001B7D2C, 0x60000000 ); write32( 0x00231CA0, 0x60000000 ); //Make coin count (layer 7) invisible write32( 0x001B87A8, 0x60000000 ); write32( 0x00247A68, 0x60000000 ); //Modify to regular GX pattern to patch later write32( 0x3F1FD0, 0x00 ); //NTSC Interlaced //PAD Hook for control updates PatchBL( PatchCopy(PADReadGP, PADReadGP_size), 0x38A34 ); // Game specific rumble hook PatchBL( PatchCopy(PADControlMotorGP, PADControlMotorGP_size), 0x3717C ); //memcpy( (void*)0x002CE3C, OSReportDM, sizeof(OSReportDM) ); //memcpy( (void*)0x002CE8C, OSReportDM, sizeof(OSReportDM) ); //write32( 0x002CEF8, 0x60000000 ); } else if( read32(0x0184E60) == 0x386000A8 ) { dbgprintf("TRI:F-Zero AX (Rev C)\r\n"); TRIGame = TRI_AX; SystemRegion = REGION_JAPAN; AXTimerOffset = 0x003CD1C0; TRISettingsName = SETTINGS_AX_RVC; TRISettingsLoc = 0x3CF6F0; TRISettingsSize = 0x2A; DISetDIMMVersion(0x12301777); //Reset loop write32( 0x01B50AC, 0x60000000 ); //DBGRead fix write32( 0x01BEAAC, 0x60000000 ); //Motor init patch write32( 0x01753BC, 0x60000000 ); write32( 0x01753C0, 0x60000000 ); write32( 0x0175358, 0x60000000 ); //patching system waiting stuff write32( 0x0180A54, 0x48000054 ); write32( 0x0180AB8, 0x48000054 ); //Network waiting write32( 0x0180C74, 0x4800004C ); //Goto Test menu write32( 0x00DF168, 0x60000000 ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenu, CheckTestMenu_size), 0xDF16C ); //Remove Overscan on first VIConfigure write32( 0x001FB998, 0x38C00000 ); //English write32( 0x000DF430, 0x38000000 ); //Remove some menu timers (thanks dj_skual) // (menu gets constantly removed in JVSIO.c) write32( 0x0015AE40, 0x60000000 ); //after race //Make some menu timers invisible (thanks dj_skual) write32( 0x002370DC, 0x40200000 ); //menu inner write32( 0x00237114, 0x40200000 ); //menu outer write32( 0x00236E74, 0x00000000 ); //after race inner write32( 0x00236EAC, 0x00000000 ); //after race outer //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsAX_RVC, RestoreSettingsAX_RVC_size), 0x17B12C); //Replace Motor Init with Controller Setup write32( 0x0024DB74, 0x801809F8 ); write32( 0x0024DB78, 0x8018085C ); //Call Important Init Function PatchB( 0x000DA46C, 0x00180A38 ); //Modify to regular GX pattern to patch later u32 NTSC480ProgTri = 0x21CF2C; write32(NTSC480ProgTri, 0x00); //NTSC Interlaced write32(NTSC480ProgTri + 0x14, 0x01); //Mode DF NTSC480ProgTri = 0x302600; write32(NTSC480ProgTri, 0x00); //NTSC Interlaced write32(NTSC480ProgTri + 0x14, 0x01); //Mode DF //PAD Hook for control updates PatchBL( PatchCopy(PADReadF, PADReadF_size), 0x1B4004 ); } else if( read32(0x01851C4) == 0x386000A8 ) { dbgprintf("TRI:F-Zero AX (Rev D)\r\n"); TRIGame = TRI_AX; SystemRegion = REGION_JAPAN; AXTimerOffset = 0x003CD6A0; TRISettingsName = SETTINGS_AX_RVD; TRISettingsLoc = 0x3CFBD0; TRISettingsSize = 0x2A; DISetDIMMVersion(0x12301777); //Reset loop write32( 0x01B5410, 0x60000000 ); //DBGRead fix write32( 0x01BEF38, 0x60000000 ); //Disable CARD //write32( 0x017B2BC, 0x38C00000 ); //Motor init patch write32( 0x0175710, 0x60000000 ); write32( 0x0175714, 0x60000000 ); write32( 0x01756AC, 0x60000000 ); //patching system waiting stuff write32( 0x0180DB8, 0x48000054 ); write32( 0x0180E1C, 0x48000054 ); //Network waiting write32( 0x0180FD8, 0x4800004C ); //Goto Test menu write32( 0x00DF3D0, 0x60000000 ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenu, CheckTestMenu_size), 0xDF3D4 ); //Replace Motor Init with Controller Setup write32( 0x0024E034, 0x80180D5C ); write32( 0x0024E038, 0x80180BC0 ); //Call Important Init Function PatchB( 0x000DA6D4, 0x00180D9C ); //Remove Overscan on first VIConfigure write32( 0x001FBE54, 0x38C00000 ); //English write32( 0x000DF698, 0x38000000 ); //Remove some menu timers (thanks dj_skual) // (menu gets constantly removed in JVSIO.c) write32( 0x0015B148, 0x60000000 ); //after race //Make some menu timers invisible (thanks dj_skual) write32( 0x0023759C, 0x40200000 ); //menu inner write32( 0x002375D4, 0x40200000 ); //menu outer write32( 0x00237334, 0x00000000 ); //after race inner write32( 0x0023736C, 0x00000000 ); //after race outer //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsAX_RVD, RestoreSettingsAX_RVD_size), 0x17B490); //Modify to regular GX pattern to patch later u32 NTSC480ProgTri = 0x21D3EC; write32(NTSC480ProgTri, 0x00); //NTSC Interlaced write32(NTSC480ProgTri + 0x14, 0x01); //Mode DF NTSC480ProgTri = 0x302AC0; write32(NTSC480ProgTri, 0x00); //NTSC Interlaced write32(NTSC480ProgTri + 0x14, 0x01); //Mode DF //PAD Hook for control updates PatchBL( PatchCopy(PADReadF, PADReadF_size), 0x1B4368 ); //memcpy( (void*)0x01CAACC, patch_fwrite_GC, sizeof(patch_fwrite_GC) ); //memcpy( (void*)0x01882C0, OSReportDM, sizeof(OSReportDM) ); //Unkreport //PatchB( 0x01882C0, 0x0191B54 ); //PatchB( 0x01882C0, 0x01C53CC ); //PatchB( 0x01882C0, 0x01CC684 ); } else if( read32(0x018575C) == 0x386000A8 ) { dbgprintf("TRI:F-Zero AX (Rev E)\r\n"); TRIGame = TRI_AX; SystemRegion = REGION_JAPAN; AXTimerOffset = 0x003CDC20; TRISettingsName = SETTINGS_AX_RVE; TRISettingsLoc = 0x3D0150; TRISettingsSize = 0x2A; DISetDIMMVersion(0x12301777); //Reset loop write32( 0x01B59A8, 0x60000000 ); //DBGRead fix write32( 0x01BF3A8, 0x60000000 ); //Motor init patch write32( 0x0175C00, 0x60000000 ); write32( 0x0175C04, 0x60000000 ); write32( 0x0175B9C, 0x60000000 ); //patching system waiting stuff write32( 0x0181344, 0x48000054 ); write32( 0x01813A8, 0x48000054 ); //Network waiting write32( 0x0181564, 0x4800004C ); //Goto Test menu write32( 0x00DF550, 0x60000000 ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenu, CheckTestMenu_size), 0xDF554 ); //Replace Motor Init with Controller Setup write32( 0x0024E4B4, 0x801812E8 ); write32( 0x0024E4B8, 0x8018114C ); //Call Important Init Function PatchB( 0x000DA81C, 0x00181328 ); //Remove Overscan on first VIConfigure write32( 0x001FC2C4, 0x38C00000 ); //English write32( 0x000DF818, 0x38000000 ); //Remove some menu timers (thanks dj_skual) // (menu gets constantly removed in JVSIO.c) write32( 0x0015B638, 0x60000000 ); //after race //Make some menu timers invisible (thanks dj_skual) write32( 0x00237A1C, 0x40200000 ); //menu inner write32( 0x00237A54, 0x40200000 ); //menu outer write32( 0x002377B4, 0x00000000 ); //after race inner write32( 0x002377EC, 0x00000000 ); //after race outer //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsAX_RVE, RestoreSettingsAX_RVE_size), 0x17B980); //Modify to regular GX pattern to patch later u32 NTSC480ProgTri = 0x21D86C; write32(NTSC480ProgTri, 0x00); //NTSC Interlaced write32(NTSC480ProgTri + 0x14, 0x01); //Mode DF NTSC480ProgTri = 0x303040; write32(NTSC480ProgTri, 0x00); //NTSC Interlaced write32(NTSC480ProgTri + 0x14, 0x01); //Mode DF //PAD Hook for control updates PatchBL( PatchCopy(PADReadF, PADReadF_size), 0x1B4900 ); } else if( read32( 0x01C6EF4 ) == 0x386000A8 ) { dbgprintf("TRI:Virtua Striker 3 Ver 2002\r\n"); TRIGame = TRI_VS3; if(GAME_ID == 0x47565333 && GAME_ID6 == 0x324A) { //Japanese Language SystemRegion = REGION_JAPAN; } else { //English Language SystemRegion = REGION_EXPORT; } TRISettingsName = SETTINGS_VS3V02; TRISettingsLoc = 0x05D25C0-0x1408; TRISettingsSize = 0x12; //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuVS, CheckTestMenuVS_size), 0x541E4 ); //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsVS3V02, RestoreSettingsVS3V02_size), 0x1C60FC); //make one instruction free for out custom call to store settings write32( 0x1C5E38, read32(0x1C5E40) ); //lwz r4, -0x1408(r13) //dcbst r7 (0 from memset), r4 (0x05D25C0-0x1408 from write32 above) write32( 0x1C5E40, 0x7C07206C ); /* all of the 6 patches below are needed to make the media board i/o conform to our emulation in DI.c */ //do write to media board first PatchB(0x2356D8,0x23563C); //do read from media board next PatchB(0x23564C,0x235778); //make sure to read into the correct area write32(0x23564C,0x3BDEFFE0); //also make sure to read back the correct media board offset write32(0x235660,0x8366000C); //done reading from media board, jump to successful end PatchB(0x2357B8,0x2356C0); //dont start media board threads which would only mess up write32(0x23790C,0x60000000); //Modify to regular GX pattern to patch later write32( 0x26E7E8, 0x00 ); //NTSC Interlaced //PAD Hook for control updates PatchBL(PatchCopy(PADReadVS3, PADReadVS3_size), 0x5472C ); } else if( read32( 0x01D2564 ) == 0x386000A8 ) { dbgprintf("TRI:Virtua Striker 4 (Japan)\r\n"); TRIGame = TRI_VS4; SystemRegion = REGION_JAPAN; TRISettingsName = SETTINGS_VS4JAP; TRISettingsLoc = 0x0602520-0x14C4; TRISettingsSize = 0x2B; //Set menu timer to about 51 days write32( 0x00C1D0C, 0x3C800FFF ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuVS, CheckTestMenuVS_size), 0x3B444 ); //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsVS4JAP, RestoreSettingsVS4JAP_size), 0x12698); //Modify to regular GX pattern to patch later write32( 0x231310, 0x00 ); //NTSC Interlaced //PAD Hook for control updates PatchBL(PatchCopy(PADReadVS, PADReadVS_size), 0x3C230 ); } else if( read32( 0x01C88B4 ) == 0x386000A8 ) { dbgprintf("TRI:Virtua Striker 4 (Export)\r\n"); TRIGame = TRI_VS4; SystemRegion = REGION_USA; TRISettingsName = SETTINGS_VS4EXP; TRISettingsLoc = 0x05C5FE0-0x2CA8; //NOTE:logic turned around! TRISettingsSize = 0x2B; //Set menu timer to about 51 days write32( 0x00C1564, 0x3C800FFF ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuVS, CheckTestMenuVS_size), 0x3B3E8 ); //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsVS4EXP, RestoreSettingsVS4EXP_size), 0x12454); //Modify to regular GX pattern to patch later write32( 0x21D7A8, 0x00 ); //NTSC Interlaced //PAD Hook for control updates PatchBL(PatchCopy(PADReadVS, PADReadVS_size), 0x3C174 ); } else if( read32( 0x024E888 ) == 0x386000A8 ) { dbgprintf("TRI:Virtua Striker 4 Ver 2006 (Japan)\r\n"); TRIGame = TRI_VS4; SystemRegion = REGION_JAPAN; TRISettingsName = SETTINGS_VS4V06JAP; TRISettingsLoc = 0x06D5A40-0xCDC; TRISettingsSize = 0x2E; DISetDIMMVersion(0xA3A479); //DIMM memory format skip (saves 2 minutes bootup time) write32( 0x0013950, 0x60000000 ); //dont wait for other cabinets to link up write32( 0x0056114, 0x38600001 ); //Set menu timer to about 51 days write32( 0x00D7420, 0x3C800FFF ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuVS, CheckTestMenuVS_size), 0x3ECD8 ); //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsVS4V06JAP, RestoreSettingsVS4V06JAP_size), 0x13C10); //Modify to regular GX pattern to patch later write32( 0x2BD598, 0x00 ); //NTSC Interlaced //PAD Hook for control updates PatchBL(PatchCopy(PADReadVS, PADReadVS_size), 0x3F9C8 ); } else if( read32( 0x0210C08 ) == 0x386000A8 ) { dbgprintf("TRI:Virtua Striker 4 Ver 2006 (Export)\r\n"); TRIGame = TRI_VS4; SystemRegion = REGION_USA; TRISettingsName = SETTINGS_VS4V06EXP; TRISettingsLoc = 0x0684B40-0xEE4; TRISettingsSize = 0x2B; DISetDIMMVersion(0xA3A479); //Set menu timer to about 51 days write32( 0x00CBB7C, 0x3C800FFF ); //Hide timer updater (red font) PatchBL( 0x011BDEC, 0x001738E0 ); PatchBL( 0x011BDEC, 0x00173950 ); //Hide timer updater (blue font) PatchBL( 0x011BDEC, 0x001739D4 ); PatchBL( 0x011BDEC, 0x00173A44 ); //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuVS, CheckTestMenuVS_size), 0x3B804 ); //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchB(PatchCopy(RestoreSettingsVS4V06EXP, RestoreSettingsVS4V06EXP_size), 0x12BD4); //Modify to regular GX pattern to patch later write32( 0x26DD38, 0x00 ); //NTSC Interlaced //PAD Hook for control updates PatchBL(PatchCopy(PADReadVS, PADReadVS_size), 0x3C504 ); //memcpy( (void*)0x001C2B80, OSReportDM, sizeof(OSReportDM) ); } else if(read32(0x2995F4) == 0x386000A8) { dbgprintf("TRI:Gekitou Pro Yakyuu (Rev B)\r\n"); TRIGame = TRI_YAK; SystemRegion = REGION_JAPAN; TRISettingsName = SETTINGS_YAKRVB; TRISettingsLoc = 0x03D3D0C; TRISettingsSize = 0xF5; //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuYakyuu, CheckTestMenuYakyuu_size), 0x1D1EF8 ); //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchBL(PatchCopy(RestoreSettingsYAKRVB, RestoreSettingsYAKRVB_size), 0x1D21F8); //PAD Hook for control updates PatchBL(PatchCopy(PADReadGP, PADReadGP_size), 0x1C380C ); } else if(read32(0x29BC94) == 0x386000A8) { dbgprintf("TRI:Gekitou Pro Yakyuu (Rev C)\r\n"); TRIGame = TRI_YAK; SystemRegion = REGION_JAPAN; TRISettingsName = SETTINGS_YAKRVC; TRISettingsLoc = 0x03D67AC; TRISettingsSize = 0x100; //Allow test menu if requested PatchBL( PatchCopy(CheckTestMenuYakyuu, CheckTestMenuYakyuu_size), 0x1D455C ); //Check for already existing settings if(TRI_BackupAvailable == 0) TRIReadSettings(); //Custom backup handler if(TRI_BackupAvailable == 1) PatchBL(PatchCopy(RestoreSettingsYAKRVC, RestoreSettingsYAKRVC_size), 0x1D486C); //PAD Hook for control updates PatchBL(PatchCopy(PADReadGP, PADReadGP_size), 0x1C575C ); } else if(useipltri) { dbgprintf("TRI:SegaBoot\r\n"); TRIGame = TRI_SB; } //actual game is booting up, prepare if(TRIGame != TRI_NONE && TRIGame != TRI_SB) EXIPrepareTRIGameStart(); }