mgh: fix for default HDD DMA mode, that wasn't correctly set
[open-ps2-loader.git] / ee_core / src / patches.c
blob9407e74b671ecb4be3f7a43caefe3ac73d9f01a2
1 /*
2 Copyright 2009, Ifcaro, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4 Review OpenUsbLd README & LICENSE files for further details.
5 */
7 #include "ee_core.h"
8 #include "util.h"
10 #define ALL_MODE -1
12 typedef struct {
13 u32 addr;
14 u32 val;
15 u32 check;
16 } game_patch_t;
18 typedef struct {
19 char *game;
20 int mode;
21 game_patch_t patch;
22 } patchlist_t;
24 static patchlist_t patch_list[45] = {
25 { "SLES_524.58", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Disgaea Hour of Darkness PAL - disable cdvd timeout stuff
26 { "SLUS_206.66", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Disgaea Hour of Darkness NTSC U - disable cdvd timeout stuff
27 { "SLPS_202.51", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Makai Senki Disgaea NTSC J - disable cdvd timeout stuff
28 { "SLPS_202.50", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Makai Senki Disgaea (limited edition) NTSC J - disable cdvd timeout stuff
29 { "SLPS_731.03", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Makai Senki Disgaea (PlayStation2 the Best) NTSC J - disable cdvd timeout stuff
30 { "SLES_529.51", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Phantom Brave PAL - disable cdvd timeout stuff
31 { "SLUS_209.55", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Phantom Brave NTSC U - disable cdvd timeout stuff
32 { "SLPS_203.45", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Phantom Brave NTSC J - disable cdvd timeout stuff
33 { "SLPS_203.44", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Phantom Brave (limited edition) NTSC J - disable cdvd timeout stuff
34 { "SLPS_731.08", USB_MODE, { 0xdeadbee0, 0x00000000, 0x00000000 }}, // Phantom Brave: 2-shuume Hajime Mashita (PlayStation 2 the Best) NTSC J - disable cdvd timeout stuff
35 { "SLUS_213.17", ALL_MODE, { 0xbabecafe, 0x00149210, 0x00000000 }}, // SFA anthology US
36 { "SLES_540.85", ALL_MODE, { 0xbabecafe, 0x00148db0, 0x00000000 }}, // SFA anthology EUR
37 { "SLPM_664.09", ALL_MODE, { 0xbabecafe, 0x00149210, 0x00000000 }}, // SFZ Generation JP
38 { "SLPM_659.98", ALL_MODE, { 0xbabecafe, 0x00146fd0, 0x00000000 }}, // Vampire: Darkstakers collection JP
39 { "SLUS_212.00", USB_MODE, { 0xdeadbee1, 0x00000000, 0x00000000 }}, // Armored Core Nine Breaker NTSC U - skip failing case on binding a RPC server
40 { "SLES_538.19", USB_MODE, { 0xdeadbee1, 0x00000000, 0x00000000 }}, // Armored Core Nine Breaker PAL - skip failing case on binding a RPC server
41 { "SLPS_254.08", USB_MODE, { 0xdeadbee1, 0x00000000, 0x00000000 }}, // Armored Core Nine Breaker NTSC J - skip failing case on binding a RPC server
42 { "SLUS_210.05", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001ac514 }}, // Kingdom Hearts 2 US - [Gummi mission freezing fix (check addr is where to patch,
43 { "SLES_541.14", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001ac60c }}, // Kingdom Hearts 2 UK - val is the amount of delay cycles)]
44 { "SLES_542.32", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001ac60c }}, // Kingdom Hearts 2 FR
45 { "SLES_542.33", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001ac60c }}, // Kingdom Hearts 2 DE
46 { "SLES_542.34", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001ac60c }}, // Kingdom Hearts 2 IT
47 { "SLES_542.35", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001ac60c }}, // Kingdom Hearts 2 ES
48 { "SLPM_662.33", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001ac44c }}, // Kingdom Hearts 2 JPN
49 { "SLPM_666.75", ALL_MODE, { 0xdeadbee2, 0x00100000, 0x001adf64 }}, // Kingdom Hearts 2 Final Mix JPN
50 { "SLUS_212.87", ETH_MODE, { 0xdeadbee2, 0x000c0000, 0x006cd15c }}, // Prince of Persia: The Two Thrones NTSC U - slow down cdvd reads
51 { "SLUS_212.87", HDD_MODE, { 0xdeadbee2, 0x00040000, 0x006cd15c }}, // Prince of Persia: The Two Thrones NTSC U - slow down cdvd reads
52 { "SLES_537.77", ETH_MODE, { 0xdeadbee2, 0x000c0000, 0x006cd6dc }}, // Prince of Persia: The Two Thrones PAL - slow down cdvd reads
53 { "SLES_537.77", HDD_MODE, { 0xdeadbee2, 0x00040000, 0x006cd6dc }}, // Prince of Persia: The Two Thrones PAL - slow down cdvd reads
54 { "SLUS_210.22", ETH_MODE, { 0xdeadbee2, 0x000c0000, 0x0060f42c }}, // Prince of Persia: Warrior Within NTSC U - slow down cdvd reads
55 { "SLUS_210.22", HDD_MODE, { 0xdeadbee2, 0x00040000, 0x0060f42c }}, // Prince of Persia: Warrior Within NTSC U - slow down cdvd reads
56 { "SLES_528.22", ETH_MODE, { 0xdeadbee2, 0x000c0000, 0x0060f4dc }}, // Prince of Persia: Warrior Within PAL - slow down cdvd reads
57 { "SLES_528.22", HDD_MODE, { 0xdeadbee2, 0x00040000, 0x0060f4dc }}, // Prince of Persia: Warrior Within PAL - slow down cdvd reads
58 { "SLUS_214.32", ALL_MODE, { 0xdeadbee2, 0x00080000, 0x002baf34 }}, // NRA Gun Club NTSC U
59 { "SLPM_654.05", HDD_MODE, { 0xdeadbee2, 0x00200000, 0x00249b84 }}, // Super Dimensional Fortress Macross JPN
61 { "SCES_525.82", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // EveryBody's Golf PAL
62 { "SCUS_974.01", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Hot Shots Golf FORE! NTSC U
63 { "SCUS_975.15", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Hot Shots Golf FORE! (GH) NTSC U
64 { "SCUS_976.10", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Hot Shots Tennis NTSC U
65 { "SLUS_209.51", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Viewtiful Joe NTSC U
66 { "SLES_526.78", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Viewtiful Joe PAL
67 { "SLPM_656.99", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Viewtiful Joe NTSC J
68 { "SCUS_973.30", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Jak 3 US
69 { "SCUS_975.16", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Jak 3 US (GH)
70 { "SCES_524.60", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Jak 3 PAL
71 { "SCKA_200.40", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Jak 3 NTSC K
72 { "SCUS_974.29", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Jak X NTSC U
73 { "SCES_532.86", ALL_MODE, { 0xdeadbee3, 0x00000000, 0x00000000 }}, // Jak X PAL
74 { "SLES_820.28", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET PAL Disc1
75 { "SLES_820.29", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET PAL Disc2
76 { "SLUS_204.88", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-U Disc1
77 { "SLUS_208.91", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-U Disc2
78 { "SCPS_550.19", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-J
79 { "SLPM_664.78", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-J (Ultimate Hits) Disc1
80 { "SLPM_664.79", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-J (Ultimate Hits) Disc2
81 { "SLPM_652.09", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-J (Limited Edition)
82 { "SLPM_654.38", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-J (Director's Cut) Disc1
83 { "SLPM_654.39", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-J (Director's Cut) Disc2
84 { "SCAJ_200.70", ALL_MODE, { 0xbabecafe, 0x00000000, 0x00000000 }}, // SOTET NTSC-? (Director's Cut)
86 { "SLUS_202.30", ALL_MODE, { 0x00132d14, 0x10000018, 0x0c046744 }}, // Max Payne NTSC U - skip IOP reset before to exec demo elfs
87 { "SLES_503.25", ALL_MODE, { 0x00132ce4, 0x10000018, 0x0c046744 }}, // Max Payne PAL - skip IOP reset before to exec demo elfs
88 { "SLUS_204.40", ALL_MODE, { 0x0021bb00, 0x03e00008, 0x27bdff90 }}, // Kya: Dark Lineage NTSC U - disable game debug prints
89 { "SLES_514.73", ALL_MODE, { 0x0021bd10, 0x03e00008, 0x27bdff90 }}, // Kya: Dark Lineage PAL - disable game debug prints
90 { "SLUS_204.96", ALL_MODE, { 0x00104900, 0x03e00008, 0x27bdff90 }}, // V-Rally 3 NTSC U - disable game debug prints
91 { "SLES_507.25", ALL_MODE, { 0x00104518, 0x03e00008, 0x27bdff70 }}, // V-Rally 3 PAL - disable game debug prints
92 { "SLUS_201.99", ALL_MODE, { 0x0012a6d0, 0x24020001, 0x0c045e0a }}, // Shaun Palmer's Pro Snowboarder NTSC U
93 { "SLUS_201.99", ALL_MODE, { 0x0013c55c, 0x10000012, 0x04400012 }}, // Shaun Palmer's Pro Snowboarder NTSC U
94 { "SLES_553.46", ALL_MODE, { 0x0035414C, 0x2402FFFF, 0x0C0EE74E }}, // Rugby League 2: World Cup Edition PAL
95 { NULL, 0, { 0x00000000, 0x00000000, 0x00000000 }} // terminater
98 static u32 NIScdtimeoutpattern[] = {
99 0x3c010000,
100 0x8c230000,
101 0x24630001,
102 0x3c010000,
103 0xac230000,
104 0x3c010000,
105 0x8c230000,
106 0x2861037b,
107 0x14200000,
108 0x00000000
110 static u32 NIScdtimeoutpattern_mask[] = {
111 0xffff0000,
112 0xffff0000,
113 0xffffffff,
114 0xffff0000,
115 0xffff0000,
116 0xffff0000,
117 0xffff0000,
118 0xffffffff,
119 0xffff0000,
120 0xffffffff
123 static u32 AC9Bpattern[] = {
124 0x8e450000,
125 0x0220202d,
126 0x0c000000,
127 0x0000302d,
128 0x04410003,
129 0x00000000,
130 0x10000005,
131 0x2402ffff,
132 0x8e020000,
133 0x1040fff6
135 static u32 AC9Bpattern_mask[] = {
136 0xffffffff,
137 0xffffffff,
138 0xfc000000,
139 0xffffffff,
140 0xffffffff,
141 0xffffffff,
142 0xffffffff,
143 0xffffffff,
144 0xffffffff,
145 0xffffffff
148 #define JAL(addr) (0x0c000000 | ((addr & 0x03ffffff) >> 2))
149 #define FNADDR(jal) ((jal & 0x03ffffff) << 2)
151 static int (*cdRead)(u32 lsn, u32 nsectors, void *buf, int *mode);
152 static u32 g_delay_cycles;
155 static void NIS_generic_patches(void)
157 u32 *ptr;
159 if (GameMode == USB_MODE) { // Nippon Ichi Sofwtare games generic patch to disable cdvd timeout
160 ptr = find_pattern_with_mask((u32 *)0x100000, 0x01e00000, NIScdtimeoutpattern, NIScdtimeoutpattern_mask, 0x28);
161 if (ptr) {
162 u16 jmp = _lw((u32)ptr+32) & 0xffff;
163 _sw(0x10000000|jmp, (u32)ptr+32);
168 static void AC9B_generic_patches(void)
170 u32 *ptr;
172 if (GameMode == USB_MODE) { // Armored Core 9 Breaker generic USB patch
173 ptr = find_pattern_with_mask((u32 *)0x100000, 0x01e00000, AC9Bpattern, AC9Bpattern_mask, 0x28);
174 if (ptr)
175 _sw(0, (u32)ptr+36);
179 static int delayed_cdRead(u32 lsn, u32 nsectors, void *buf, int *mode)
181 register int r;
182 register u32 count;
184 r = cdRead(lsn, nsectors, buf, mode);
185 count = g_delay_cycles;
186 while(count--)
187 asm("nop\nnop\nnop\nnop");
189 return r;
192 static void generic_delayed_cdRead_patches(u32 patch_addr, u32 delay_cycles)
194 // set configureable delay cycles
195 g_delay_cycles = delay_cycles;
197 // get original cdRead() pointer
198 cdRead = (void *)FNADDR(_lw(patch_addr));
200 // overwrite with a JAL to our delayed_cdRead function
201 _sw(JAL((u32)delayed_cdRead), patch_addr);
205 static int (*capcom_lmb)(void *modpack_addr, int mod_index, int mod_argc, char **mod_argv);
207 static void apply_capcom_protection_patch(void *modpack_addr, int mod_index, int mod_argc, char **mod_argv)
209 u32 iop_addr = _lw((u32)modpack_addr + (mod_index << 3) + 8);
210 u32 opcode = 0x10000025;
211 smem_write((void *)(iop_addr+0x270), (void *)&opcode, sizeof(opcode));
212 FlushCache(0);
213 FlushCache(2);
215 capcom_lmb(modpack_addr, mod_index, mod_argc, mod_argv);
218 static void generic_capcom_protection_patches(u32 patch_addr)
220 capcom_lmb = (void *)FNADDR(_lw(patch_addr));
221 _sw(JAL((u32)apply_capcom_protection_patch), patch_addr);
225 void apply_patches(void)
227 patchlist_t *p = (patchlist_t *)&patch_list[0];
229 // if there are patches matching game name/mode then fill the patch table
230 while (p->game) {
231 if ((!_strcmp(GameID, p->game)) && ((p->mode == ALL_MODE) || (GameMode == p->mode))) {
233 if (p->patch.addr == 0xdeadbee0)
234 NIS_generic_patches(); // Nippon Ichi Software games generic patch
235 else if (p->patch.addr == 0xdeadbee1)
236 AC9B_generic_patches(); // Armored Core 9 Breaker USB generic patch
237 else if (p->patch.addr == 0xdeadbee2)
238 generic_delayed_cdRead_patches(p->patch.check, p->patch.val); // slow reads generic patch
239 else if (p->patch.addr == 0xbabecafe)
240 generic_capcom_protection_patches(p->patch.val); // Capcom anti cdvd emulator protection patch
242 // non-generic patches
243 else if (_lw(p->patch.addr) == p->patch.check)
244 _sw(p->patch.val, p->patch.addr);
246 p++;