1 // license:BSD-3-Clause
2 // copyright-holders:S. Smith,David Haywood,Fabio Priuli
3
4 /***************************************************************************
5
6 Neo-Geo hardware encryption and protection used on bootleg cartridges
7
8 Many of the NeoGeo bootlegs use their own form of encryption and
9 protection, presumably to make them harder for other bootleggers to
10 copy. This encryption often involves non-trivial scrambling of the
11 program roms and the games are protected using an Altera chip which
12 provides some kind of rom overlay, patching parts of the code.
13 The graphics roms are usually scrambled in a different way to the
14 official SNK cartridges too.
15
16 Here we collect functions to emulate some of the protection devices used.
17
18 TODO: split different devices according to the chip responsible for them!
19
20 ***************************************************************************/
21
22 #include "emu.h"
23 #include "prot_misc.h"
24
25
26 DEFINE_DEVICE_TYPE(NEOBOOT_PROT, neoboot_prot_device, "ngboot_prot", "Neo Geo Bootleg Protection(s)")
27
28
neoboot_prot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)29 neoboot_prot_device::neoboot_prot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
30 device_t(mconfig, NEOBOOT_PROT, tag, owner, clock)
31 {
32 }
33
34
device_start()35 void neoboot_prot_device::device_start()
36 {
37 }
38
device_reset()39 void neoboot_prot_device::device_reset()
40 {
41 }
42
43
44
45
46 /* General Bootleg Functions - used by more than 1 game */
47
cx_decrypt(uint8_t * sprrom,uint32_t sprrom_size)48 void neoboot_prot_device::cx_decrypt(uint8_t*sprrom, uint32_t sprrom_size)
49 {
50 int cx_size = sprrom_size;
51 uint8_t *rom = sprrom;
52 std::vector<uint8_t> buf(cx_size);
53
54 memcpy(&buf[0], rom, cx_size);
55
56 for (int i = 0; i < cx_size / 0x40; i++)
57 memcpy(&rom[i * 0x40], &buf[(i ^ 1) * 0x40], 0x40);
58 }
59
60
sx_decrypt(uint8_t * fixed,uint32_t fixed_size,int value)61 void neoboot_prot_device::sx_decrypt(uint8_t* fixed, uint32_t fixed_size, int value)
62 {
63 int sx_size = fixed_size;
64 uint8_t *rom = fixed;
65
66 if (value == 1)
67 {
68 std::vector<uint8_t> buf(sx_size);
69 memcpy(&buf[0], rom, sx_size);
70
71 for (int i = 0; i < sx_size; i += 0x10)
72 {
73 memcpy(&rom[i], &buf[i + 8], 8);
74 memcpy(&rom[i + 8], &buf[i], 8);
75 }
76 }
77 else if (value == 2)
78 {
79 for (int i = 0; i < sx_size; i++)
80 rom[i] = bitswap<8>(rom[i], 7, 6, 0, 4, 3, 2, 1, 5);
81 }
82 }
83
84
85
86 /* The King of Fighters '97 Oroshi Plus 2003 (bootleg) */
87
kof97oro_px_decode(uint8_t * cpurom,uint32_t cpurom_size)88 void neoboot_prot_device::kof97oro_px_decode(uint8_t* cpurom, uint32_t cpurom_size)
89 {
90 std::vector<uint16_t> tmp(0x500000);
91 uint16_t *src = (uint16_t*)cpurom;
92
93 for (int i = 0; i < 0x500000/2; i++)
94 tmp[i] = src[i ^ 0x7ffef];
95
96 memcpy(src, &tmp[0], 0x500000);
97 }
98
99
100
101 /* The King of Fighters 10th Anniversary Extra Plus (The King of Fighters 2002 bootleg) */
102
kf10thep_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)103 void neoboot_prot_device::kf10thep_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
104 {
105 uint16_t *rom = (uint16_t*)cpurom;
106 std::vector<uint16_t> buf(0x100000/2);
107
108 memcpy(&buf[0x000000/2], &rom[0x060000/2], 0x20000);
109 memcpy(&buf[0x020000/2], &rom[0x100000/2], 0x20000);
110 memcpy(&buf[0x040000/2], &rom[0x0e0000/2], 0x20000);
111 memcpy(&buf[0x060000/2], &rom[0x180000/2], 0x20000);
112 memcpy(&buf[0x080000/2], &rom[0x020000/2], 0x20000);
113 memcpy(&buf[0x0a0000/2], &rom[0x140000/2], 0x20000);
114 memcpy(&buf[0x0c0000/2], &rom[0x0c0000/2], 0x20000);
115 memcpy(&buf[0x0e0000/2], &rom[0x1a0000/2], 0x20000);
116 memcpy(&buf[0x0002e0/2], &rom[0x0402e0/2], 0x6a); // copy banked code to a new memory region
117 memcpy(&buf[0x0f92bc/2], &rom[0x0492bc/2], 0xb9e); // copy banked code to a new memory region
118 memcpy(rom, &buf[0], 0x100000);
119
120 for (int i = 0xf92bc/2; i < 0xf9e58/2; i++)
121 {
122 if (rom[i+0] == 0x4eb9 && rom[i+1] == 0x0000) rom[i+1] = 0x000F; // correct JSR in moved code
123 if (rom[i+0] == 0x4ef9 && rom[i+1] == 0x0000) rom[i+1] = 0x000F; // correct JMP in moved code
124 }
125 rom[0x00342/2] = 0x000f;
126
127 memmove(&rom[0x100000/2], &rom[0x200000/2], 0x600000);
128 }
129
130
131 /* The King of Fighters 10th Anniversary 2005 Unique (The King of Fighters 2002 bootleg) */
132
kf2k5uni_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)133 void neoboot_prot_device::kf2k5uni_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
134 {
135 uint8_t *src = cpurom;
136 uint8_t dst[0x80];
137
138 for (int i = 0; i < 0x800000; i += 0x80)
139 {
140 for (int j = 0; j < 0x80; j += 2)
141 {
142 int ofst = bitswap<8>(j, 0, 3, 4, 5, 6, 1, 2, 7);
143 memcpy(&dst[j], src + i + ofst, 2);
144 }
145 memcpy(src + i, &dst[0], 0x80);
146 }
147
148 memcpy(src, src + 0x600000, 0x100000); // Seems to be the same as kof10th
149 }
150
151
kf2k5uni_sx_decrypt(uint8_t * fixedrom,uint32_t fixedrom_size)152 void neoboot_prot_device::kf2k5uni_sx_decrypt(uint8_t* fixedrom, uint32_t fixedrom_size)
153 {
154 uint8_t *srom = fixedrom;
155
156 for (int i = 0; i < 0x20000; i++)
157 srom[i] = bitswap<8>(srom[i], 4, 5, 6, 7, 0, 1, 2, 3);
158 }
159
kf2k5uni_mx_decrypt(uint8_t * audiorom,uint32_t audiorom_size)160 void neoboot_prot_device::kf2k5uni_mx_decrypt(uint8_t* audiorom, uint32_t audiorom_size)
161 {
162 uint8_t *mrom = audiorom;
163
164 for (int i = 0; i < 0x30000; i++)
165 mrom[i] = bitswap<8>(mrom[i], 4, 5, 6, 7, 0, 1, 2, 3);
166 }
167
168
169
170 /* King of Fighters Special Edition 2004 (bootleg of King of Fighters 2002) */
171
decrypt_kof2k4se_68k(uint8_t * cpurom,uint32_t cpurom_size)172 void neoboot_prot_device::decrypt_kof2k4se_68k(uint8_t* cpurom, uint32_t cpurom_size)
173 {
174 uint8_t *src = cpurom + 0x100000;
175 std::vector<uint8_t> dst(0x400000);
176 static const int sec[] = {0x300000,0x200000,0x100000,0x000000};
177 memcpy(&dst[0], src, 0x400000);
178
179 for (int i = 0; i < 4; ++i)
180 memcpy(src + i * 0x100000, &dst[sec[i]], 0x100000);
181 }
182
183
184 /* Lansquenet 2004 (Shock Troopers - 2nd Squad bootleg) */
185
lans2004_vx_decrypt(uint8_t * ymsndrom,uint32_t ymsndrom_size)186 void neoboot_prot_device::lans2004_vx_decrypt(uint8_t* ymsndrom, uint32_t ymsndrom_size)
187 {
188 uint8_t *rom = ymsndrom;
189 for (int i = 0; i < 0xA00000; i++)
190 rom[i] = bitswap<8>(rom[i], 0, 1, 5, 4, 3, 2, 6, 7);
191 }
192
lans2004_decrypt_68k(uint8_t * cpurom,uint32_t cpurom_size)193 void neoboot_prot_device::lans2004_decrypt_68k(uint8_t* cpurom, uint32_t cpurom_size)
194 {
195 // Descrambling P ROMs - Thanks to Razoola for the info
196 uint8_t *src = cpurom;
197 uint16_t *rom = (uint16_t*)cpurom;
198
199 static const int sec[] = { 0x3, 0x8, 0x7, 0xc, 0x1, 0xa, 0x6, 0xd };
200 std::vector<uint8_t> dst(0x600000);
201
202 for (int i = 0; i < 8; i++)
203 memcpy (&dst[i * 0x20000], src + sec[i] * 0x20000, 0x20000);
204
205 memcpy (&dst[0x0bbb00], src + 0x045b00, 0x001710);
206 memcpy (&dst[0x02fff0], src + 0x1a92be, 0x000010);
207 memcpy (&dst[0x100000], src + 0x200000, 0x400000);
208 memcpy (src, &dst[0], 0x600000);
209
210 for (int i = 0xbbb00/2; i < 0xbe000/2; i++)
211 {
212 if ((((rom[i] & 0xffbf)==0x4eb9) || ((rom[i] & 0xffbf)==0x43b9)) && (rom[i+1]==0x0000))
213 {
214 rom[i + 1] = 0x000b;
215 rom[i + 2] += 0x6000;
216 }
217 }
218
219 /* Patched by protection chip (Altera) ? */
220 rom[0x2d15c/2] = 0x000b;
221 rom[0x2d15e/2] = 0xbb00;
222 rom[0x2d1e4/2] = 0x6002;
223 rom[0x2ea7e/2] = 0x6002;
224 rom[0xbbcd0/2] = 0x6002;
225 rom[0xbbdf2/2] = 0x6002;
226 rom[0xbbe42/2] = 0x6002;
227 }
228
229
230 /* Samurai Shodown V / Samurai Spirits Zero (bootleg) */
231
samsho5b_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)232 void neoboot_prot_device::samsho5b_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
233 {
234 int px_size = cpurom_size;
235 uint8_t *rom = cpurom;
236 std::vector<uint8_t> buf(px_size);
237
238 memcpy(&buf[0], rom, px_size);
239
240 for (int i = 0; i < px_size / 2; i++)
241 {
242 int ofst = bitswap<8>((i & 0x000ff), 7, 6, 5, 4, 3, 0, 1, 2);
243 ofst += (i & 0xfffff00);
244 ofst ^= 0x060005;
245
246 memcpy(&rom[i * 2], &buf[ofst * 2], 0x02);
247 }
248
249 memcpy(&buf[0], rom, px_size);
250
251 memcpy(&rom[0x000000], &buf[0x700000], 0x100000);
252 memcpy(&rom[0x100000], &buf[0x000000], 0x700000);
253 }
254
255
samsho5b_vx_decrypt(uint8_t * ymsndrom,uint32_t ymsndrom_size)256 void neoboot_prot_device::samsho5b_vx_decrypt(uint8_t* ymsndrom, uint32_t ymsndrom_size)
257 {
258 int vx_size = ymsndrom_size;
259 uint8_t *rom = ymsndrom;
260
261 for (int i = 0; i < vx_size; i++)
262 rom[i] = bitswap<8>(rom[i], 0, 1, 5, 4, 3, 2, 6, 7);
263 }
264
265
266
267
268 /* Metal Slug 5 Plus (bootleg) */
269
mslug5p_prot_r()270 uint16_t neoboot_prot_device::mslug5p_prot_r()
271 {
272 logerror("%s access protected\n", machine().describe_context());
273 return 0xa0;
274 }
275
276 // FIXME: temporarily moved to the driver, through mslug5p_bank_base() below
277 /*
278 void neoboot_prot_device::ms5plus_bankswitch_w(offs_t offset, uint16_t data)
279 {
280 int bankaddress;
281 logerror("offset: %06x %s set banking %04x\n",offset,machine().describe_context(),data);
282 if ((offset == 0) && (data == 0xa0))
283 {
284 bankaddress = 0xa0;
285 m_bankdev->neogeo_set_main_cpu_bank_address(bankaddress);
286 logerror("offset: %06x %s set banking %04x\n\n",offset,machine().describe_context(),bankaddress);
287 }
288 else if(offset == 2)
289 {
290 data = data >> 4;
291 //data = data & 7;
292 bankaddress = data * 0x100000;
293 m_bankdev->neogeo_set_main_cpu_bank_address(bankaddress);
294 logerror("offset: %06x %s set banking %04x\n\n",offset,machine().describe_context(),bankaddress);
295 }
296 }
297 */
298
mslug5p_bank_base(uint16_t sel)299 uint32_t neoboot_prot_device::mslug5p_bank_base(uint16_t sel)
300 {
301 sel = sel >> 4;
302 //sel = sel & 7;
303 return sel * 0x100000;
304 }
305
306
307 /* Metal Slug 5 (bootleg) */
308
mslug5b_vx_decrypt(uint8_t * ymsndrom,uint32_t ymsndrom_size)309 void neoboot_prot_device::mslug5b_vx_decrypt(uint8_t* ymsndrom, uint32_t ymsndrom_size)
310 {
311 // only odd bytes are scrambled
312 int ym_size = ymsndrom_size;
313 uint8_t *rom = ymsndrom;
314 for (int i = 1; i < ym_size; i += 2)
315 rom[i] = bitswap<8>(rom[i], 3, 2, 4, 1, 5, 0, 6, 7);
316 }
317
mslug5b_cx_decrypt(uint8_t * sprrom,uint32_t sprrom_size)318 void neoboot_prot_device::mslug5b_cx_decrypt(uint8_t* sprrom, uint32_t sprrom_size)
319 {
320 // rom a18/a19 lines are swapped
321 int cx_size = sprrom_size;
322 uint8_t *rom = sprrom;
323 std::vector<uint8_t> buf(cx_size);
324
325 memcpy(&buf[0], rom, cx_size);
326
327 for (int i = 1; i < 128; i += 4)
328 {
329 memcpy(&rom[i * 0x80000], &buf[(i + 1) * 0x80000], 0x80000);
330 memcpy(&rom[(i + 1) * 0x80000], &buf[i * 0x80000], 0x80000);
331 }
332 }
333
334
335 /* The King of Gladiator (The King of Fighters '97 bootleg) */
336
337 // The protection patching here may be incomplete - Thanks to Razoola for the info
338
kog_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)339 void neoboot_prot_device::kog_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
340 {
341 // the protection chip does some *very* strange things to the rom
342 uint8_t *src = cpurom;
343 std::vector<uint8_t> dst(0x600000);
344 uint16_t *rom = (uint16_t *)cpurom;
345 static const int sec[] = { 0x3, 0x8, 0x7, 0xc, 0x1, 0xa, 0x6, 0xd };
346
347 for (int i = 0; i < 8; i++)
348 memcpy (&dst[i * 0x20000], src + sec[i] * 0x20000, 0x20000);
349
350 memcpy (&dst[0x0007a6], src + 0x0407a6, 0x000006);
351 memcpy (&dst[0x0007c6], src + 0x0407c6, 0x000006);
352 memcpy (&dst[0x0007e6], src + 0x0407e6, 0x000006);
353 memcpy (&dst[0x090000], src + 0x040000, 0x004000);
354 memcpy (&dst[0x100000], src + 0x200000, 0x400000);
355 memcpy (src, &dst[0], 0x600000);
356
357 for (int i = 0x90000/2; i < 0x94000/2; i++)
358 {
359 if (((rom[i] & 0xffbf) == 0x4eb9 || rom[i] == 0x43f9) && !rom[i + 1])
360 rom[i + 1] = 0x0009;
361
362 if (rom[i] == 0x4eb8)
363 rom[i] = 0x6100;
364 }
365
366 rom[0x007a8/2] = 0x0009;
367 rom[0x007c8/2] = 0x0009;
368 rom[0x007e8/2] = 0x0009;
369 rom[0x93408/2] = 0xf168;
370 rom[0x9340c/2] = 0xfb7a;
371 rom[0x924ac/2] = 0x0009;
372 rom[0x9251c/2] = 0x0009;
373 rom[0x93966/2] = 0xffda;
374 rom[0x93974/2] = 0xffcc;
375 rom[0x93982/2] = 0xffbe;
376 rom[0x93990/2] = 0xffb0;
377 rom[0x9399e/2] = 0xffa2;
378 rom[0x939ac/2] = 0xff94;
379 rom[0x939ba/2] = 0xff86;
380 rom[0x939c8/2] = 0xff78;
381 rom[0x939d4/2] = 0xfa5c;
382 rom[0x939e0/2] = 0xfa50;
383 rom[0x939ec/2] = 0xfa44;
384 rom[0x939f8/2] = 0xfa38;
385 rom[0x93a04/2] = 0xfa2c;
386 rom[0x93a10/2] = 0xfa20;
387 rom[0x93a1c/2] = 0xfa14;
388 rom[0x93a28/2] = 0xfa08;
389 rom[0x93a34/2] = 0xf9fc;
390 rom[0x93a40/2] = 0xf9f0;
391 rom[0x93a4c/2] = 0xfd14;
392 rom[0x93a58/2] = 0xfd08;
393 rom[0x93a66/2] = 0xf9ca;
394 rom[0x93a72/2] = 0xf9be;
395
396 }
397
398 /* SNK vs. CAPCOM SVC CHAOS (bootleg) */
399
svcboot_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)400 void neoboot_prot_device::svcboot_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
401 {
402 static const uint8_t sec[] = { 0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00 };
403 int size = cpurom_size;
404 uint8_t *src = cpurom;
405 std::vector<uint8_t> dst(size);
406
407 for (int i = 0; i < size / 0x100000; i++)
408 memcpy(&dst[i * 0x100000], &src[sec[i] * 0x100000], 0x100000);
409
410 for (int i = 0; i < size / 2; i++)
411 {
412 int ofst = bitswap<8>((i & 0x0000ff), 7, 6, 1, 0, 3, 2, 5, 4);
413 ofst += (i & 0xffff00);
414 memcpy(&src[i * 2], &dst[ofst * 2], 0x02);
415 }
416 }
417
svcboot_cx_decrypt(uint8_t * sprrom,uint32_t sprrom_size)418 void neoboot_prot_device::svcboot_cx_decrypt(uint8_t* sprrom, uint32_t sprrom_size)
419 {
420 static const uint8_t idx_tbl[ 0x10 ] = { 0, 1, 0, 1, 2, 3, 2, 3, 3, 4, 3, 4, 4, 5, 4, 5, };
421 static const uint8_t bitswap4_tbl[ 6 ][ 4 ] = {
422 { 3, 0, 1, 2 },
423 { 2, 3, 0, 1 },
424 { 1, 2, 3, 0 },
425 { 0, 1, 2, 3 },
426 { 3, 2, 1, 0 },
427 { 3, 0, 2, 1 },
428 };
429 int size = sprrom_size;
430 uint8_t *src = sprrom;
431 std::vector<uint8_t> dst(size);
432
433 memcpy(&dst[0], src, size);
434 for (int i = 0; i < size / 0x80; i++)
435 {
436 int idx = idx_tbl[(i & 0xf00) >> 8];
437 int bit0 = bitswap4_tbl[idx][0];
438 int bit1 = bitswap4_tbl[idx][1];
439 int bit2 = bitswap4_tbl[idx][2];
440 int bit3 = bitswap4_tbl[idx][3];
441 int ofst = bitswap<8>((i & 0x0000ff), 7, 6, 5, 4, bit3, bit2, bit1, bit0);
442 ofst += (i & 0xfffff00);
443 memcpy(&src[i * 0x80], &dst[ofst * 0x80], 0x80);
444 }
445 }
446
447
448 /* SNK vs. CAPCOM SVC CHAOS Plus (bootleg set 1) */
449
svcplus_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)450 void neoboot_prot_device::svcplus_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
451 {
452 static const int sec[] = { 0x00, 0x03, 0x02, 0x05, 0x04, 0x01 };
453 int size = cpurom_size;
454 uint8_t *src = cpurom;
455 std::vector<uint8_t> dst(size);
456
457 memcpy(&dst[0], src, size);
458 for (int i = 0; i < size / 2; i++)
459 {
460 int ofst = bitswap<24>((i & 0xfffff), 0x17, 0x16, 0x15, 0x14, 0x13, 0x00, 0x01, 0x02,
461 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
462 0x07, 0x06, 0x05, 0x04, 0x03, 0x10, 0x11, 0x12);
463 ofst ^= 0x0f0007;
464 ofst += (i & 0xff00000);
465 memcpy(&src[i * 0x02], &dst[ofst * 0x02], 0x02);
466 }
467
468 memcpy(&dst[0], src, size);
469 for (int i = 0; i < 6; i++)
470 memcpy(&src[i * 0x100000], &dst[sec[i] * 0x100000], 0x100000);
471 }
472
473
svcplus_px_hack(uint8_t * cpurom,uint32_t cpurom_size)474 void neoboot_prot_device::svcplus_px_hack(uint8_t* cpurom, uint32_t cpurom_size)
475 {
476 /* patched by the protection chip? */
477 uint16_t *mem16 = (uint16_t *)cpurom;
478 mem16[0x0f8016/2] = 0x33c1;
479 }
480
481
482 /* SNK vs. CAPCOM SVC CHAOS Plus (bootleg set 2) */
483
svcplusa_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)484 void neoboot_prot_device::svcplusa_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
485 {
486 static const int sec[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x00 };
487 int size = cpurom_size;
488 uint8_t *src = cpurom;
489 std::vector<uint8_t> dst(size);
490
491 memcpy(&dst[0], src, size);
492 for (int i = 0; i < 6; i++)
493 memcpy(&src[i * 0x100000], &dst[sec[i] * 0x100000], 0x100000);
494 }
495
496
497 /* SNK vs. CAPCOM SVC CHAOS Super Plus (bootleg) */
498
svcsplus_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)499 void neoboot_prot_device::svcsplus_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
500 {
501 static const int sec[] = { 0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00 };
502 int size = cpurom_size;
503 uint8_t *src = cpurom;
504 std::vector<uint8_t> dst(size);
505
506 memcpy(&dst[0], src, size);
507 for (int i = 0; i < size / 2; i++)
508 {
509 int ofst = bitswap<16>((i & 0x007fff), 0x0f, 0x00, 0x08, 0x09, 0x0b, 0x0a, 0x0c, 0x0d,
510 0x04, 0x03, 0x01, 0x07, 0x06, 0x02, 0x05, 0x0e);
511
512 ofst += (i & 0x078000);
513 ofst += sec[(i & 0xf80000) >> 19] << 19;
514 memcpy(&src[i * 2], &dst[ofst * 2], 0x02);
515 }
516 }
517
svcsplus_px_hack(uint8_t * cpurom,uint32_t cpurom_size)518 void neoboot_prot_device::svcsplus_px_hack(uint8_t* cpurom, uint32_t cpurom_size)
519 {
520 /* patched by the protection chip? */
521 uint16_t *mem16 = (uint16_t *)cpurom;
522 mem16[0x9e90/2] = 0x000f;
523 mem16[0x9e92/2] = 0xc9c0;
524 mem16[0xa10c/2] = 0x4eb9;
525 mem16[0xa10e/2] = 0x000e;
526 mem16[0xa110/2] = 0x9750;
527 }
528
529
530 /* The King of Fighters 2002 (bootleg) */
531
kof2002b_gfx_decrypt(uint8_t * src,int size)532 void neoboot_prot_device::kof2002b_gfx_decrypt(uint8_t *src, int size)
533 {
534 static const uint8_t t[8][6] =
535 {
536 { 0, 8, 7, 6, 2, 1 },
537 { 1, 0, 8, 7, 6, 2 },
538 { 2, 1, 0, 8, 7, 6 },
539 { 6, 2, 1, 0, 8, 7 },
540 { 7, 6, 2, 1, 0, 8 },
541 { 0, 1, 2, 6, 7, 8 },
542 { 2, 1, 0, 6, 7, 8 },
543 { 8, 0, 7, 6, 2, 1 },
544 };
545
546 std::vector<uint8_t> dst(0x10000);
547
548 for (int i = 0; i < size; i += 0x10000)
549 {
550 memcpy(&dst[0], src + i, 0x10000);
551
552 for (int j = 0; j < 0x200; j++)
553 {
554 int n = (j & 0x38) >> 3;
555 int ofst = bitswap<16>(j, 15, 14, 13, 12, 11, 10, 9, t[n][0], t[n][1], t[n][2], 5, 4, 3, t[n][3], t[n][4], t[n][5]);
556 memcpy(src + i + ofst * 128, &dst[j * 128], 128);
557 }
558 }
559 }
560
561
562 /* The King of Fighters 2002 Magic Plus (bootleg) */
563
kf2k2mp_decrypt(uint8_t * cpurom,uint32_t cpurom_size)564 void neoboot_prot_device::kf2k2mp_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
565 {
566 uint8_t *src = cpurom;
567 uint8_t dst[0x80];
568
569 memmove(src, src + 0x300000, 0x500000);
570
571 for (int i = 0; i < 0x800000; i+=0x80)
572 {
573 for (int j = 0; j < 0x80 / 2; j++)
574 {
575 int ofst = bitswap<8>( j, 6, 7, 2, 3, 4, 5, 0, 1 );
576 memcpy(dst + j * 2, src + i + ofst * 2, 2);
577 }
578 memcpy(src + i, dst, 0x80);
579 }
580 }
581
582
583 /* The King of Fighters 2002 Magic Plus II (bootleg) */
584
kf2k2mp2_px_decrypt(uint8_t * cpurom,uint32_t cpurom_size)585 void neoboot_prot_device::kf2k2mp2_px_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
586 {
587 uint8_t *src = cpurom;
588 std::vector<uint8_t> dst(0x600000);
589
590 memcpy(&dst[0x000000], &src[0x1C0000], 0x040000);
591 memcpy(&dst[0x040000], &src[0x140000], 0x080000);
592 memcpy(&dst[0x0C0000], &src[0x100000], 0x040000);
593 memcpy(&dst[0x100000], &src[0x200000], 0x400000);
594 memcpy(&src[0x000000], &dst[0x000000], 0x600000);
595 }
596
597
598
599 /* The King of Fighters 10th Anniversary (The King of Fighters 2002 bootleg) */
600
kof10th_decrypt(uint8_t * cpurom,uint32_t cpurom_size)601 void neoboot_prot_device::kof10th_decrypt(uint8_t* cpurom, uint32_t cpurom_size)
602 {
603 std::vector<uint8_t> dst(0x900000);
604 uint8_t *src = cpurom;
605
606 memcpy(&dst[0x000000], src + 0x700000, 0x100000); // Correct (Verified in Uni-bios)
607 memcpy(&dst[0x100000], src + 0x000000, 0x800000);
608
609 for (int i = 0; i < 0x900000; i++)
610 {
611 int j = bitswap<24>(i,23,22,21,20,19,18,17,16,15,14,13,12,11,2,9,8,7,1,5,4,3,10,6,0);
612 src[j] = dst[i];
613 }
614
615 // Altera protection chip patches these over P ROM
616 ((uint16_t*)src)[0x0124/2] = 0x000d; // Enables XOR for RAM moves, forces SoftDIPs, and USA region
617 ((uint16_t*)src)[0x0126/2] = 0xf7a8;
618
619 ((uint16_t*)src)[0x8bf4/2] = 0x4ef9; // Run code to change "S" data
620 ((uint16_t*)src)[0x8bf6/2] = 0x000d;
621 ((uint16_t*)src)[0x8bf8/2] = 0xf980;
622 }
623