1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
// license:BSD-3-Clause
// copyright-holders:S. Smith,David Haywood,Fabio Priuli
#include "emu.h"
#include "prot_pcm2.h"
DEFINE_DEVICE_TYPE(NG_PCM2_PROT, pcm2_prot_device, "ng_pcm2_prot", "Neo Geo NEOPCM2 Protection")
pcm2_prot_device::pcm2_prot_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, NG_PCM2_PROT, tag, owner, clock)
{
}
void pcm2_prot_device::device_start()
{
}
void pcm2_prot_device::device_reset()
{
}
/***************************************************************************
NeoGeo 'V' (PCM) ROM encryption
NEOPCM2 chip
***************************************************************************/
// Neo-Pcm2 Drivers for Encrypted V Roms
void pcm2_prot_device::decrypt(uint8_t* ymrom, uint32_t ymsize, int value)
{
// thanks to Elsemi for the NEO-PCM2 info
uint16_t *rom = (uint16_t *)ymrom;
int size = ymsize;
if (rom != nullptr)
{
// swap address lines on the whole ROMs
std::vector<uint16_t> buffer(value / 2);
for (int i = 0; i < size / 2; i += (value / 2))
{
memcpy(&buffer[0], &rom[i], value);
for (int j = 0; j < (value / 2); j++)
{
rom[i + j] = buffer[j ^ (value/4)];
}
}
}
}
// the later PCM2 games have additional scrambling
void pcm2_prot_device::swap(uint8_t* ymrom, uint32_t ymsize, int value)
{
static const uint32_t addrs[7][2]={
{0x000000,0xa5000},
{0xffce20,0x01000},
{0xfe2cf6,0x4e001},
{0xffac28,0xc2000},
{0xfeb2c0,0x0a000},
{0xff14ea,0xa7001},
{0xffb440,0x02000}};
static const uint8_t xordata[7][8]={
{0xf9,0xe0,0x5d,0xf3,0xea,0x92,0xbe,0xef},
{0xc4,0x83,0xa8,0x5f,0x21,0x27,0x64,0xaf},
{0xc3,0xfd,0x81,0xac,0x6d,0xe7,0xbf,0x9e},
{0xc3,0xfd,0x81,0xac,0x6d,0xe7,0xbf,0x9e},
{0xcb,0x29,0x7d,0x43,0xd2,0x3a,0xc2,0xb4},
{0x4b,0xa4,0x63,0x46,0xf0,0x91,0xea,0x62},
{0x4b,0xa4,0x63,0x46,0xf0,0x91,0xea,0x62}};
std::vector<uint8_t> buf(0x1000000);
int j, d;
uint8_t* src = ymrom;
memcpy(&buf[0], src, 0x1000000);
for (int i = 0; i < 0x1000000; i++)
{
j = bitswap<24>(i,23,22,21,20,19,18,17,0,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,16);
j ^= addrs[value][1];
d = ((i + addrs[value][0]) & 0xffffff);
src[j] = buf[d] ^ xordata[value][j & 0x7];
}
}
|