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