1 /***************************************************************************
2
3 Neo-Geo hardware
4
5 Many of the NeoGeo bootlegs use their own form of encryption and
6 protection, presumably to make them harder for other bootleggser to
7 copy. This encryption often involves non-trivial scrambling of the
8 program roms and the games are protected using an Altera chip which
9 provides some kind of rom overlay, patching parts of the code.
10 The graphics roms are usually scrambled in a different way to the
11 official SNK cartridges too.
12
13 NeoGeo 'C' (Graphics) Rom encryption
14 CMC42 and CMC50 protection chips
15 Also contains 'S' (Text Layer) data on these games
16 M1 (Z80) rom is also encrypted for CMC50
17
18 The M1 roms contain some additional data at 0xf800. Some of this
19 is said to be related to the C rom encryption.
20 If CMC50 is used, data located at 0xff00 - 0xffff is required for
21 m1 encryption checksum?.
22
23 Later games use additional basic scrambling on top of the standard
24 CMC scramble.
25
26 NeoGeo 'P' Rom Encryption
27 Used on various games
28
29 kof98
30 - unique early encryption
31 kof99, garou, garouo, mslug3, kof2000
32 - complex SMA chip which appears to contain part of the game rom
33 internally and decrypts the 68k code on the board. Also has a
34 random number generator and custom bankswitching
35 (see machine/neoprot.c)
36 kof2002, matrim, samsho5, samsh5p
37 - some basic block / bank swapping
38 svc, kof2003, mslug5
39 - different scrambling with additional xor
40
41 NeoGeo 'V' Rom encryption
42 NEO-PCM2 chip used on various games
43 type1 used on pnyaa, rotd, mslug4
44 type2 used on kof2002, matrim, mslug5, svc,
45 samsho5, samsh5s, kof2003
46
47 ***************************************************************************/
48
49 //#include "driver.h"
50 //#include "neogeo.h"
51 #include "resfile.h"
52 #include "mame_layer.h"
53 #include "menu.h"
54
55 /***************************************************************************
56
57 NeoGeo 'C' ROM encryption
58
59 Starting with KOF99, all NeoGeo games have encrypted graphics. Additionally
60 to that, the data for the front text layer, which was previously stored in
61 a separate ROM, is stored at the end of the tile data.
62
63 The encryption is one of the nastiest implementation of a XOR scheme ever
64 seen, involving 9 seemingly uncorrelated 256-byte tables. All known games use
65 the same tables except KOF2000 and MS4 which use a different set.
66
67 The 32 data bits of every longword are decrypted in a single step (one byte at
68 a time), but the values to use for the xor are determined in a convoluted way.
69 It's actually so convoluted that it's too difficult to describe - please refer
70 to the source below.
71 Suffice to say that bytes are handled in couples (0&3 and 1&2), and the two xor
72 values are taken from three tables, the indexes inside the tables depending on
73 bits 0-7 and 8-15 of the address, in one case further xored through the table
74 used in step 5) below. Additionally, the bytes in a couple can be swapped,
75 depending either on bit 8 of the address, or on bit 16 xored with the table
76 used in step 4) below.
77
78 The 24 address bits are encrypted in five steps. Each step xors 8 bits with a
79 value taken from a different table; the index inside the table depends on 8
80 other bits.
81 0) xor bits 0-7 with a fixed value that changes from game to game
82 1) xor bits 8-15 depending on bits 16-23
83 2) xor bits 8-15 depending on bits 0-7
84 3) xor bits 16-23 depending on bits 0-7
85 4) xor bits 16-23 depending on bits 8-15
86 5) xor bits 0-7 depending on bits 8-15
87
88 Each step acts on the current value, so e.g. step 4) uses bits 8-15 as modified
89 by step 2).
90
91 [Note: the table used in step 1) is currently incomplete due to lack of data to
92 analyze]
93
94
95 There are two major weaknesses in this encryption algorithm, that exposed it to
96 a known plaintext attack.
97
98 The first weakness is that the data xor depends on the address inside the
99 encrypted ROM instead that on the decrypted address; together with the high
100 concentration of 0x00 and 0xFF in the decrypted data (more than 60% of the
101 total), this exposed easily recognizable patterns in the encrypted data, which
102 could be exploited with some simple statistical checks. The deviousness of the
103 xor scheme was the major difficulty.
104
105 The second weakness is that the address scrambling works on 32-bit words. Since
106 there are a large number of 32-bit values that appear only once in the whole
107 encrypted ROM space, this means that once the xor layer was broken, a large
108 table of encrypted-decrypted address correspondencies could be built and
109 analyzed, quickly leading to the algorithm.
110
111 ***************************************************************************/
112
113 static UINT8 *type0_t03;
114 static UINT8 *type0_t12;
115 static UINT8 *type1_t03;
116 static UINT8 *type1_t12;
117 static UINT8 *address_8_15_xor1;
118 static UINT8 *address_8_15_xor2;
119 static UINT8 *address_16_23_xor1;
120 static UINT8 *address_16_23_xor2;
121 static UINT8 *address_0_7_xor;
122 static UINT8 *m1_address_8_15_xor;
123 static UINT8 *m1_address_0_7_xor;
124 #if 0
125 static const UINT8 kof99_type0_t03[256] =
126 {
127 0xfb, 0x86, 0x9d, 0xf1, 0xbf, 0x80, 0xd5, 0x43, 0xab, 0xb3, 0x9f, 0x6a, 0x33, 0xd9, 0xdb, 0xb6,
128 0x66, 0x08, 0x69, 0x88, 0xcc, 0xb7, 0xde, 0x49, 0x97, 0x64, 0x1f, 0xa6, 0xc0, 0x2f, 0x52, 0x42,
129 0x44, 0x5a, 0xf2, 0x28, 0x98, 0x87, 0x96, 0x8a, 0x83, 0x0b, 0x03, 0x61, 0x71, 0x99, 0x6b, 0xb5,
130 0x1a, 0x8e, 0xfe, 0x04, 0xe1, 0xf7, 0x7d, 0xdd, 0xed, 0xca, 0x37, 0xfc, 0xef, 0x39, 0x72, 0xda,
131 0xb8, 0xbe, 0xee, 0x7f, 0xe5, 0x31, 0x78, 0xf3, 0x91, 0x9a, 0xd2, 0x11, 0x19, 0xb9, 0x09, 0x4c,
132 0xfd, 0x6d, 0x2a, 0x4d, 0x65, 0xa1, 0x89, 0xc7, 0x75, 0x50, 0x21, 0xfa, 0x16, 0x00, 0xe9, 0x12,
133 0x74, 0x2b, 0x1e, 0x4f, 0x14, 0x01, 0x70, 0x3a, 0x4e, 0x3f, 0xf5, 0xf4, 0x1d, 0x3d, 0x15, 0x27,
134 0xa7, 0xff, 0x45, 0xe0, 0x6e, 0xf9, 0x54, 0xc8, 0x48, 0xad, 0xa5, 0x0a, 0xf6, 0x2d, 0x2c, 0xe2,
135 0x68, 0x67, 0xd6, 0x85, 0xb4, 0xc3, 0x34, 0xbc, 0x62, 0xd3, 0x5f, 0x84, 0x06, 0x5b, 0x0d, 0x95,
136 0xea, 0x5e, 0x9e, 0xd4, 0xeb, 0x90, 0x7a, 0x05, 0x81, 0x57, 0xe8, 0x60, 0x2e, 0x20, 0x25, 0x7c,
137 0x46, 0x0c, 0x93, 0xcb, 0xbd, 0x17, 0x7e, 0xec, 0x79, 0xb2, 0xc2, 0x22, 0x41, 0xb1, 0x10, 0xac,
138 0xa8, 0xbb, 0x9b, 0x82, 0x4b, 0x9c, 0x8b, 0x07, 0x47, 0x35, 0x24, 0x56, 0x8d, 0xaf, 0xe6, 0x26,
139 0x40, 0x38, 0xc4, 0x5d, 0x1b, 0xc5, 0xd1, 0x0f, 0x6c, 0x7b, 0xb0, 0xe3, 0xa3, 0x23, 0x6f, 0x58,
140 0xc1, 0xba, 0xcf, 0xd7, 0xa2, 0xe7, 0xd0, 0x63, 0x5c, 0xf8, 0x73, 0xa0, 0x13, 0xdc, 0x29, 0xcd,
141 0xc9, 0x76, 0xae, 0x8f, 0xe4, 0x59, 0x30, 0xaa, 0x94, 0x1c, 0x3c, 0x0e, 0x55, 0x92, 0x77, 0x32,
142 0xc6, 0xce, 0x18, 0x36, 0xdf, 0xa9, 0x8c, 0xd8, 0xa4, 0xf0, 0x3b, 0x51, 0x4a, 0x02, 0x3e, 0x53,
143 };
144
145
146 static const UINT8 kof99_type0_t12[256] =
147 {
148 0x1f, 0xac, 0x4d, 0xcd, 0xca, 0x70, 0x02, 0x6b, 0x18, 0x40, 0x62, 0xb2, 0x3f, 0x9b, 0x5b, 0xef,
149 0x69, 0x68, 0x71, 0x3b, 0xcb, 0xd4, 0x30, 0xbc, 0x47, 0x72, 0x74, 0x5e, 0x84, 0x4c, 0x1b, 0xdb,
150 0x6a, 0x35, 0x1d, 0xf5, 0xa1, 0xb3, 0x87, 0x5d, 0x57, 0x28, 0x2f, 0xc4, 0xfd, 0x24, 0x26, 0x36,
151 0xad, 0xbe, 0x61, 0x63, 0x73, 0xaa, 0x82, 0xee, 0x29, 0xd0, 0xdf, 0x8c, 0x15, 0xb5, 0x96, 0xf3,
152 0xdd, 0x7e, 0x3a, 0x37, 0x58, 0x7f, 0x0c, 0xfc, 0x0b, 0x07, 0xe8, 0xf7, 0xf4, 0x14, 0xb8, 0x81,
153 0xb6, 0xd7, 0x1e, 0xc8, 0x85, 0xe6, 0x9d, 0x33, 0x60, 0xc5, 0x95, 0xd5, 0x55, 0x00, 0xa3, 0xb7,
154 0x7d, 0x50, 0x0d, 0xd2, 0xc1, 0x12, 0xe5, 0xed, 0xd8, 0xa4, 0x9c, 0x8f, 0x2a, 0x4f, 0xa8, 0x01,
155 0x52, 0x83, 0x65, 0xea, 0x9a, 0x6c, 0x44, 0x4a, 0xe2, 0xa5, 0x2b, 0x46, 0xe1, 0x34, 0x25, 0xf8,
156 0xc3, 0xda, 0xc7, 0x6e, 0x48, 0x38, 0x7c, 0x78, 0x06, 0x53, 0x64, 0x16, 0x98, 0x3c, 0x91, 0x42,
157 0x39, 0xcc, 0xb0, 0xf1, 0xeb, 0x13, 0xbb, 0x05, 0x32, 0x86, 0x0e, 0xa2, 0x0a, 0x9e, 0xfa, 0x66,
158 0x54, 0x8e, 0xd3, 0xe7, 0x19, 0x20, 0x77, 0xec, 0xff, 0xbd, 0x6d, 0x43, 0x23, 0x03, 0xab, 0x75,
159 0x3d, 0xcf, 0xd1, 0xde, 0x92, 0x31, 0xa7, 0x45, 0x4b, 0xc2, 0x97, 0xf9, 0x7a, 0x88, 0xd9, 0x1c,
160 0xe9, 0xe4, 0x10, 0xc9, 0x22, 0x2d, 0x90, 0x76, 0x17, 0x79, 0x04, 0x51, 0x1a, 0x5a, 0x5f, 0x2c,
161 0x21, 0x6f, 0x3e, 0xe0, 0xf0, 0xbf, 0xd6, 0x94, 0x0f, 0x80, 0x11, 0xa0, 0x5c, 0xa9, 0x49, 0x2e,
162 0xce, 0xaf, 0xa6, 0x9f, 0x7b, 0x99, 0xb9, 0xb4, 0xe3, 0xfb, 0xf6, 0x27, 0xf2, 0x93, 0xfe, 0x08,
163 0x67, 0xae, 0x09, 0x89, 0xdc, 0x4e, 0xc6, 0xc0, 0x8a, 0xb1, 0x59, 0x8b, 0x41, 0x56, 0x8d, 0xba,
164 };
165
166
167 static const UINT8 kof99_type1_t03[256] =
168 {
169 0xa9, 0x17, 0xaf, 0x0d, 0x34, 0x6e, 0x53, 0xb6, 0x7f, 0x58, 0xe9, 0x14, 0x5f, 0x55, 0xdb, 0xd4,
170 0x42, 0x80, 0x99, 0x59, 0xa8, 0x3a, 0x57, 0x5d, 0xd5, 0x6f, 0x4c, 0x68, 0x35, 0x46, 0xa6, 0xe7,
171 0x7b, 0x71, 0xe0, 0x93, 0xa2, 0x1f, 0x64, 0x21, 0xe3, 0xb1, 0x98, 0x26, 0xab, 0xad, 0xee, 0xe5,
172 0xbb, 0xd9, 0x1e, 0x2e, 0x95, 0x36, 0xef, 0x23, 0x79, 0x45, 0x04, 0xed, 0x13, 0x1d, 0xf4, 0x85,
173 0x96, 0xec, 0xc2, 0x32, 0xaa, 0x7c, 0x15, 0xd8, 0xda, 0x92, 0x90, 0x9d, 0xb7, 0x56, 0x6a, 0x66,
174 0x41, 0xfc, 0x00, 0xf6, 0x50, 0x24, 0xcf, 0xfb, 0x11, 0xfe, 0x82, 0x48, 0x9b, 0x27, 0x1b, 0x67,
175 0x4e, 0x84, 0x69, 0x97, 0x6d, 0x8c, 0xd2, 0xba, 0x74, 0xf9, 0x8f, 0xa5, 0x54, 0x5c, 0xcd, 0x73,
176 0x07, 0xd1, 0x01, 0x09, 0xf1, 0x19, 0x3b, 0x5e, 0x87, 0x30, 0x76, 0xcc, 0xc0, 0x5a, 0xa7, 0x49,
177 0x22, 0xfa, 0x16, 0x02, 0xdf, 0xa4, 0xff, 0xb3, 0x75, 0x33, 0xbd, 0x88, 0x2f, 0xcb, 0x2a, 0x44,
178 0xb8, 0xbf, 0x1c, 0x0f, 0x81, 0x10, 0x43, 0xb4, 0xc8, 0x7e, 0x9a, 0x25, 0xea, 0x83, 0x4b, 0x38,
179 0x7a, 0xd7, 0x3d, 0x1a, 0x4f, 0x62, 0x51, 0xc9, 0x47, 0x0e, 0xce, 0x3f, 0xc7, 0x4d, 0x2c, 0xa1,
180 0x86, 0xb9, 0xc5, 0xca, 0xdd, 0x6b, 0x70, 0x6c, 0x91, 0x9c, 0xbe, 0x0a, 0x9f, 0xf5, 0x94, 0xbc,
181 0x18, 0x2b, 0x60, 0x20, 0x29, 0xf7, 0xf2, 0x28, 0xc4, 0xa0, 0x0b, 0x65, 0xde, 0x8d, 0x78, 0x12,
182 0x3e, 0xd0, 0x77, 0x08, 0x8b, 0xae, 0x05, 0x31, 0x3c, 0xd6, 0xa3, 0x89, 0x06, 0xdc, 0x52, 0x72,
183 0xb0, 0xb5, 0x37, 0xd3, 0xc3, 0x8a, 0xc6, 0xf0, 0xc1, 0x61, 0xfd, 0x4a, 0x5b, 0x7d, 0x9e, 0xf3,
184 0x63, 0x40, 0x2d, 0xe8, 0xb2, 0xe6, 0x39, 0x03, 0xeb, 0x8e, 0xe1, 0x0c, 0xe4, 0xe2, 0xf8, 0xac,
185 };
186
187
188 static const UINT8 kof99_type1_t12[256] =
189 {
190 0xea, 0xe6, 0x5e, 0xa7, 0x8e, 0xac, 0x34, 0x03, 0x30, 0x97, 0x52, 0x53, 0x76, 0xf2, 0x62, 0x0b,
191 0x0a, 0xfc, 0x94, 0xb8, 0x67, 0x36, 0x11, 0xbc, 0xae, 0xca, 0xfa, 0x15, 0x04, 0x2b, 0x17, 0xc4,
192 0x3e, 0x5b, 0x59, 0x01, 0x57, 0xe2, 0xba, 0xb7, 0xd1, 0x3f, 0xf0, 0x6a, 0x9c, 0x2a, 0xcb, 0xa9,
193 0xe3, 0x2c, 0xc0, 0x0f, 0x46, 0x91, 0x8a, 0xd0, 0x98, 0xc5, 0xa6, 0x1b, 0x96, 0x29, 0x12, 0x09,
194 0x63, 0xed, 0xe0, 0xa2, 0x86, 0x77, 0xbe, 0xe5, 0x65, 0xdb, 0xbd, 0x50, 0xb3, 0x9d, 0x1a, 0x4e,
195 0x79, 0x0c, 0x00, 0x43, 0xdf, 0x3d, 0x54, 0x33, 0x8f, 0x89, 0xa8, 0x7b, 0xf9, 0xd5, 0x27, 0x82,
196 0xbb, 0xc2, 0x8c, 0x47, 0x88, 0x6b, 0xb4, 0xc3, 0xf8, 0xaa, 0x06, 0x1e, 0x83, 0x7d, 0x05, 0x78,
197 0x85, 0xf6, 0x6e, 0x2e, 0xec, 0x5a, 0x31, 0x45, 0x38, 0x14, 0x16, 0x8b, 0x02, 0xe4, 0x4f, 0xb0,
198 0xbf, 0xab, 0xa4, 0x9e, 0x48, 0x60, 0x19, 0x35, 0x08, 0xde, 0xdd, 0x66, 0x90, 0x51, 0xcc, 0xa3,
199 0xaf, 0x70, 0x9b, 0x75, 0x95, 0x49, 0x6c, 0x64, 0x72, 0x7e, 0x44, 0xa0, 0x73, 0x25, 0x68, 0x55,
200 0x1f, 0x40, 0x7a, 0x74, 0x0e, 0x8d, 0xdc, 0x1c, 0x71, 0xc8, 0xcf, 0xd7, 0xe8, 0xce, 0xeb, 0x32,
201 0x3a, 0xee, 0x07, 0x61, 0x4d, 0xfe, 0x5c, 0x7c, 0x56, 0x2f, 0x2d, 0x5f, 0x6f, 0x9f, 0x81, 0x22,
202 0x58, 0x4b, 0xad, 0xda, 0xb9, 0x10, 0x18, 0x23, 0xe1, 0xf3, 0x6d, 0xe7, 0xe9, 0x28, 0xd6, 0xd8,
203 0xf4, 0x4c, 0x39, 0x21, 0xb2, 0x84, 0xc1, 0x24, 0x26, 0xf1, 0x93, 0x37, 0xc6, 0x4a, 0xcd, 0x20,
204 0xc9, 0xd9, 0xc7, 0xb1, 0xff, 0x99, 0xd4, 0x5d, 0xb5, 0xa1, 0x87, 0x0d, 0x69, 0x92, 0x13, 0x80,
205 0xd2, 0xd3, 0xfd, 0x1d, 0xf5, 0x3b, 0xa5, 0x7f, 0xef, 0x9a, 0xb6, 0x42, 0xfb, 0x3c, 0xf7, 0x41,
206 };
207
208
209 /* underlined values are wrong (not enough evidence, FF fill in kof99 and garou) */
210 /* they correspond to tiles 7d000-7efff */
211 static const UINT8 kof99_address_8_15_xor1[256] =
212 {
213 0x00, 0xb1, 0x1e, 0xc5, 0x3d, 0x40, 0x45, 0x5e, 0xf2, 0xf8, 0x04, 0x63, 0x36, 0x87, 0x88, 0xbf,
214 0xab, 0xcc, 0x78, 0x08, 0xdd, 0x20, 0xd4, 0x35, 0x09, 0x8e, 0x44, 0xae, 0x33, 0xa9, 0x9e, 0xcd,
215 0xb3, 0xe5, 0xad, 0x41, 0xda, 0xbe, 0xf4, 0x16, 0x57, 0x2e, 0x53, 0x67, 0xaf, 0xdb, 0x8a, 0xd8,
216 0x34, 0x17, 0x3c, 0x01, 0x55, 0x73, 0xcf, 0xe3, 0xe8, 0xc7, 0x0d, 0xe9, 0xa3, 0x13, 0x0c, 0xf6,
217 0x90, 0x4e, 0xfb, 0x97, 0x6d, 0x5f, 0xa8, 0x71, 0x11, 0xfc, 0xd1, 0x95, 0x81, 0xba, 0x8c, 0x1b,
218 0x39, 0xfe, 0xa2, 0x15, 0xa6, 0x52, 0x4d, 0x5b, 0x59, 0xa5, 0xe0, 0x96, 0xd9, 0x8f, 0x7b, 0xed,
219 0x29, 0xd3, 0x1f, 0x0e, 0xec, 0x23, 0x0f, 0xb8, 0x6c, 0x6f, 0x7d, 0x18, 0x46, 0xd6, 0xe4, 0xb5,
220 0x9a, 0x79, 0x02, 0xf5, 0x03, 0xc0, 0x60, 0x66, 0x5c, 0x2f, 0x76, 0x85, 0x9d, 0x54, 0x1a, 0x6a,
221 0x28, 0xce, 0x7f, 0x7c, 0x91, 0x99, 0x4c, 0x83, 0x3e, 0xb4, 0x1d, 0x05, 0xc1, 0xc3, 0xd7, 0x47,
222 0xde, 0xbc, 0x62, 0x6e, 0x86, 0x14, 0x80, 0x77, 0xeb, 0xf3, 0x07, 0x31, 0x56, 0xd2, 0xc2, 0xc6,
223 0x6b, 0xdc, 0xfd, 0x22, 0x92, 0xf0, 0x06, 0x51, 0x2d, 0x38, 0xe6, 0xa0, 0x25, 0xdf, 0xd5, 0x2c,
224 0x1c, 0x94, 0x12, 0x9c, 0xb0, 0x9b, 0xc4, 0x0b, 0xc8, 0xd0, 0xf7, 0x30, 0xcb, 0x27, 0xfa, 0x7a,
225 0x10, 0x61, 0xaa, 0xa4, 0x70, 0xb7, 0x2a, 0x5a, 0xc9, 0xf1, 0x0a, 0x49, 0x65, 0xee, 0x69, 0x4b,
226 0x3a, 0x8d, 0x32, 0x5d, 0x68, 0xb9, 0x9f, 0x75, 0x19, 0x3f, 0xac, 0x37, 0x4f, 0xe7, 0x93, 0x89,
227 0x7e, 0x4a, 0x3b, 0xea, 0x74, 0x72, 0x43, 0xbd, 0x24, 0xef, 0xb6, 0xff, 0x64, 0x58, 0x84, 0x8b,
228 0xa7, 0xbb, 0xb2, 0xe1, 0x26, 0x2b, 0x50, 0xca, 0x21, 0xf9, 0x98, 0xa1, 0xe2, 0x42, 0x82, 0x48,
229 // ^^^^ ^^^^ ^^^^ ^^^^
230 };
231
232
233 static const UINT8 kof99_address_8_15_xor2[256] =
234 {
235 0x9b, 0x9d, 0xc1, 0x3d, 0xa9, 0xb8, 0xf4, 0x6f, 0xf6, 0x25, 0xc7, 0x47, 0xd5, 0x97, 0xdf, 0x6b,
236 0xeb, 0x90, 0xa4, 0xb2, 0x5d, 0xf5, 0x66, 0xb0, 0xb9, 0x8b, 0x93, 0x64, 0xec, 0x7b, 0x65, 0x8c,
237 0xf1, 0x43, 0x42, 0x6e, 0x45, 0x9f, 0xb3, 0x35, 0x06, 0x71, 0x96, 0xdb, 0xa0, 0xfb, 0x0b, 0x3a,
238 0x1f, 0xf8, 0x8e, 0x69, 0xcd, 0x26, 0xab, 0x86, 0xa2, 0x0c, 0xbd, 0x63, 0xa5, 0x7a, 0xe7, 0x6a,
239 0x5f, 0x18, 0x9e, 0xbf, 0xad, 0x55, 0xb1, 0x1c, 0x5c, 0x03, 0x30, 0xc6, 0x37, 0x20, 0xe3, 0xc9,
240 0x52, 0xe8, 0xee, 0x4f, 0x01, 0x70, 0xc4, 0x77, 0x29, 0x2a, 0xba, 0x53, 0x12, 0x04, 0x7d, 0xaf,
241 0x33, 0x8f, 0xa8, 0x4d, 0xaa, 0x5b, 0xb4, 0x0f, 0x92, 0xbb, 0xed, 0xe1, 0x2f, 0x50, 0x6c, 0xd2,
242 0x2c, 0x95, 0xd9, 0xf9, 0x98, 0xc3, 0x76, 0x4c, 0xf2, 0xe4, 0xe5, 0x2b, 0xef, 0x9c, 0x49, 0xb6,
243 0x31, 0x3b, 0xbc, 0xa1, 0xca, 0xde, 0x62, 0x74, 0xea, 0x81, 0x00, 0xdd, 0xa6, 0x46, 0x88, 0x3f,
244 0x39, 0xd6, 0x23, 0x54, 0x24, 0x4a, 0xd8, 0xdc, 0xd7, 0xd1, 0xcc, 0xbe, 0x57, 0x7c, 0xda, 0x44,
245 0x61, 0xce, 0xd3, 0xd4, 0xe9, 0x28, 0x80, 0xe0, 0x56, 0x8a, 0x09, 0x05, 0x9a, 0x89, 0x1b, 0xf7,
246 0xf3, 0x99, 0x6d, 0x5e, 0x48, 0x91, 0xc0, 0xd0, 0xc5, 0x79, 0x78, 0x41, 0x59, 0x21, 0x2e, 0xff,
247 0xc2, 0x4b, 0x38, 0x83, 0x32, 0xe6, 0xe2, 0x7f, 0x1e, 0x17, 0x58, 0x1d, 0x1a, 0xfa, 0x85, 0x82,
248 0x94, 0xc8, 0x72, 0x7e, 0xb7, 0xac, 0x0e, 0xfc, 0xfd, 0x16, 0x27, 0x75, 0x8d, 0xcb, 0x08, 0xfe,
249 0x0a, 0x02, 0x0d, 0x36, 0x11, 0x22, 0x84, 0x40, 0x34, 0x3e, 0x2d, 0x68, 0x5a, 0xa7, 0x67, 0xae,
250 0x87, 0x07, 0x10, 0x60, 0x14, 0x73, 0x3c, 0x51, 0x19, 0xa3, 0xb5, 0xcf, 0x13, 0xf0, 0x15, 0x4e,
251 };
252
253
254 static const UINT8 kof99_address_16_23_xor1[256] =
255 {
256 0x00, 0x5f, 0x03, 0x52, 0xce, 0xe3, 0x7d, 0x8f, 0x6b, 0xf8, 0x20, 0xde, 0x7b, 0x7e, 0x39, 0xbe,
257 0xf5, 0x94, 0x18, 0x78, 0x80, 0xc9, 0x7f, 0x7a, 0x3e, 0x63, 0xf2, 0xe0, 0x4e, 0xf7, 0x87, 0x27,
258 0x69, 0x6c, 0xa4, 0x1d, 0x85, 0x5b, 0xe6, 0x44, 0x25, 0x0c, 0x98, 0xc7, 0x01, 0x02, 0xa3, 0x26,
259 0x09, 0x38, 0xdb, 0xc3, 0x1e, 0xcf, 0x23, 0x45, 0x68, 0x76, 0xd6, 0x22, 0x5d, 0x5a, 0xae, 0x16,
260 0x9f, 0xa2, 0xb5, 0xcd, 0x81, 0xea, 0x5e, 0xb8, 0xb9, 0x9d, 0x9c, 0x1a, 0x0f, 0xff, 0xe1, 0xe7,
261 0x74, 0xaa, 0xd4, 0xaf, 0xfc, 0xc6, 0x33, 0x29, 0x5c, 0xab, 0x95, 0xf0, 0x19, 0x47, 0x59, 0x67,
262 0xf3, 0x96, 0x60, 0x1f, 0x62, 0x92, 0xbd, 0x89, 0xee, 0x28, 0x13, 0x06, 0xfe, 0xfa, 0x32, 0x6d,
263 0x57, 0x3c, 0x54, 0x50, 0x2c, 0x58, 0x49, 0xfb, 0x17, 0xcc, 0xef, 0xb2, 0xb4, 0xf9, 0x07, 0x70,
264 0xc5, 0xa9, 0xdf, 0xd5, 0x3b, 0x86, 0x2b, 0x0d, 0x6e, 0x4d, 0x0a, 0x90, 0x43, 0x31, 0xc1, 0xf6,
265 0x88, 0x0b, 0xda, 0x53, 0x14, 0xdc, 0x75, 0x8e, 0xb0, 0xeb, 0x99, 0x46, 0xa1, 0x15, 0x71, 0xc8,
266 0xe9, 0x3f, 0x4a, 0xd9, 0x73, 0xe5, 0x7c, 0x30, 0x77, 0xd3, 0xb3, 0x4b, 0x37, 0x72, 0xc2, 0x04,
267 0x97, 0x08, 0x36, 0xb1, 0x3a, 0x61, 0xec, 0xe2, 0x1c, 0x9a, 0x8b, 0xd1, 0x1b, 0x2e, 0x9e, 0x8a,
268 0xd8, 0x41, 0xe4, 0xc4, 0x40, 0x2f, 0xad, 0xc0, 0xb6, 0x84, 0x51, 0x66, 0xbb, 0x12, 0xe8, 0xdd,
269 0xcb, 0xbc, 0x6f, 0xd0, 0x11, 0x83, 0x56, 0x4c, 0xca, 0xbf, 0x05, 0x10, 0xd7, 0xba, 0xfd, 0xed,
270 0x8c, 0x0e, 0x4f, 0x3d, 0x35, 0x91, 0xb7, 0xac, 0x34, 0x64, 0x2a, 0xf1, 0x79, 0x6a, 0x9b, 0x2d,
271 0x65, 0xf4, 0x42, 0xa0, 0x8d, 0xa7, 0x48, 0x55, 0x21, 0x93, 0x24, 0xd2, 0xa6, 0xa5, 0xa8, 0x82,
272 };
273
274
275 static const UINT8 kof99_address_16_23_xor2[256] =
276 {
277 0x29, 0x97, 0x1a, 0x2c, 0x0b, 0x94, 0x3e, 0x75, 0x01, 0x0d, 0x1b, 0xe1, 0x4d, 0x38, 0x39, 0x8f,
278 0xe7, 0xd0, 0x60, 0x90, 0xb2, 0x0f, 0xbb, 0x70, 0x1f, 0xe6, 0x5b, 0x87, 0xb4, 0x43, 0xfd, 0xf5,
279 0xf6, 0xf9, 0xad, 0xc0, 0x98, 0x17, 0x9f, 0x91, 0x15, 0x51, 0x55, 0x64, 0x6c, 0x18, 0x61, 0x0e,
280 0xd9, 0x93, 0xab, 0xd6, 0x24, 0x2f, 0x6a, 0x3a, 0x22, 0xb1, 0x4f, 0xaa, 0x23, 0x48, 0xed, 0xb9,
281 0x88, 0x8b, 0xa3, 0x6b, 0x26, 0x4c, 0xe8, 0x2d, 0x1c, 0x99, 0xbd, 0x5c, 0x58, 0x08, 0x50, 0xf2,
282 0x2a, 0x62, 0xc1, 0x72, 0x66, 0x04, 0x10, 0x37, 0x6e, 0xfc, 0x44, 0xa9, 0xdf, 0xd4, 0x20, 0xdd,
283 0xee, 0x41, 0xdb, 0x73, 0xde, 0x54, 0xec, 0xc9, 0xf3, 0x4b, 0x2e, 0xae, 0x5a, 0x4a, 0x5e, 0x47,
284 0x07, 0x2b, 0x76, 0xa4, 0xe3, 0x28, 0xfe, 0xb0, 0xf0, 0x02, 0x06, 0xd1, 0xaf, 0x42, 0xc2, 0xa5,
285 0xe0, 0x67, 0xbf, 0x16, 0x8e, 0x35, 0xce, 0x8a, 0xe5, 0x3d, 0x7b, 0x96, 0xd7, 0x79, 0x52, 0x1e,
286 0xa1, 0xfb, 0x9b, 0xbe, 0x21, 0x9c, 0xe9, 0x56, 0x14, 0x7f, 0xa0, 0xe4, 0xc3, 0xc4, 0x46, 0xea,
287 0xf7, 0xd2, 0x1d, 0x31, 0x0a, 0x5f, 0xeb, 0xa2, 0x68, 0x8d, 0xb5, 0xc5, 0x74, 0x0c, 0xdc, 0x82,
288 0x80, 0x09, 0x19, 0x95, 0x71, 0x9a, 0x11, 0x57, 0x77, 0x4e, 0xc6, 0xff, 0x12, 0x03, 0xa7, 0xc7,
289 0xf4, 0xc8, 0xb6, 0x7a, 0x59, 0x36, 0x3c, 0x53, 0xe2, 0x69, 0x8c, 0x25, 0x05, 0x45, 0x63, 0xf8,
290 0x34, 0x89, 0x33, 0x3f, 0x85, 0x27, 0xbc, 0x65, 0xfa, 0xa8, 0x6d, 0x84, 0x5d, 0xba, 0x40, 0x32,
291 0x30, 0xef, 0x83, 0x13, 0xa6, 0x78, 0xcc, 0x81, 0x9e, 0xda, 0xca, 0xd3, 0x7e, 0x9d, 0x6f, 0xcd,
292 0xb7, 0xb3, 0xd8, 0xcf, 0x3b, 0x00, 0x92, 0xb8, 0x86, 0xac, 0x49, 0x7c, 0xf1, 0xd5, 0xcb, 0x7d,
293 };
294
295
296 static const UINT8 kof99_address_0_7_xor[256] =
297 {
298 0x74, 0xad, 0x5d, 0x1d, 0x9e, 0xc3, 0xfa, 0x4e, 0xf7, 0xdb, 0xca, 0xa2, 0x64, 0x36, 0x56, 0x0c,
299 0x4f, 0xcf, 0x43, 0x66, 0x1e, 0x91, 0xe3, 0xa5, 0x58, 0xc2, 0xc1, 0xd4, 0xb9, 0xdd, 0x76, 0x16,
300 0xce, 0x61, 0x75, 0x01, 0x2b, 0x22, 0x38, 0x55, 0x50, 0xef, 0x6c, 0x99, 0x05, 0xe9, 0xe8, 0xe0,
301 0x2d, 0xa4, 0x4b, 0x4a, 0x42, 0xae, 0xba, 0x8c, 0x6f, 0x93, 0x14, 0xbd, 0x71, 0x21, 0xb0, 0x02,
302 0x15, 0xc4, 0xe6, 0x60, 0xd7, 0x44, 0xfd, 0x85, 0x7e, 0x78, 0x8f, 0x00, 0x81, 0xf1, 0xa7, 0x3b,
303 0xa0, 0x10, 0xf4, 0x9f, 0x39, 0x88, 0x35, 0x62, 0xcb, 0x19, 0x31, 0x11, 0x51, 0xfb, 0x2a, 0x20,
304 0x45, 0xd3, 0x7d, 0x92, 0x1b, 0xf2, 0x09, 0x0d, 0x97, 0xa9, 0xb5, 0x3c, 0xee, 0x5c, 0xaf, 0x7b,
305 0xd2, 0x3a, 0x49, 0x8e, 0xb6, 0xcd, 0xd9, 0xde, 0x8a, 0x29, 0x6e, 0xd8, 0x0b, 0xe1, 0x69, 0x87,
306 0x1a, 0x96, 0x18, 0xcc, 0xdf, 0xe7, 0xc5, 0xc7, 0xf8, 0x52, 0xc9, 0xf0, 0xb7, 0xe5, 0x33, 0xda,
307 0x67, 0x9d, 0xa3, 0x03, 0x0e, 0x72, 0x26, 0x79, 0xe2, 0xb8, 0xfc, 0xaa, 0xfe, 0xb4, 0x86, 0xc8,
308 0xd1, 0xbc, 0x12, 0x08, 0x77, 0xeb, 0x40, 0x8d, 0x04, 0x25, 0x4d, 0x5a, 0x6a, 0x7a, 0x2e, 0x41,
309 0x65, 0x1c, 0x13, 0x94, 0xb2, 0x63, 0x28, 0x59, 0x5e, 0x9a, 0x30, 0x07, 0xc6, 0xbf, 0x17, 0xf5,
310 0x0f, 0x89, 0xf3, 0x1f, 0xea, 0x6d, 0xb3, 0xc0, 0x70, 0x47, 0xf9, 0x53, 0xf6, 0xd6, 0x54, 0xed,
311 0x6b, 0x4c, 0xe4, 0x8b, 0x83, 0x24, 0x90, 0xb1, 0x7c, 0xbb, 0x73, 0xab, 0xd5, 0x2f, 0x5f, 0xec,
312 0x9c, 0x2c, 0xa8, 0x34, 0x46, 0x37, 0x27, 0xa1, 0x0a, 0x06, 0x80, 0x68, 0x82, 0x32, 0x84, 0xff,
313 0x48, 0xac, 0x7f, 0x3f, 0x95, 0xdc, 0x98, 0x9b, 0xbe, 0x23, 0x57, 0x3e, 0x5b, 0xd0, 0x3d, 0xa6,
314 };
315
316
317 static const UINT8 kof2000_type0_t03[256] =
318 {
319 0x10, 0x61, 0xf1, 0x78, 0x85, 0x52, 0x68, 0xe3, 0x12, 0x0d, 0xfa, 0xf0, 0xc9, 0x36, 0x5e, 0x3d,
320 0xf9, 0xa6, 0x01, 0x2e, 0xc7, 0x84, 0xea, 0x2b, 0x6d, 0x14, 0x38, 0x4f, 0x55, 0x1c, 0x9d, 0xa7,
321 0x7a, 0xc6, 0xf8, 0x9a, 0xe6, 0x42, 0xb5, 0xed, 0x7d, 0x3a, 0xb1, 0x05, 0x43, 0x4a, 0x22, 0xfd,
322 0xac, 0xa4, 0x31, 0xc3, 0x32, 0x76, 0x95, 0x9e, 0x7e, 0x88, 0x8e, 0xa2, 0x97, 0x18, 0xbe, 0x2a,
323 0xf5, 0xd6, 0xca, 0xcc, 0x72, 0x3b, 0x87, 0x6c, 0xde, 0x75, 0xd7, 0x21, 0xcb, 0x0b, 0xdd, 0xe7,
324 0xe1, 0x65, 0xaa, 0xb9, 0x44, 0xfb, 0x66, 0x15, 0x1a, 0x3c, 0x98, 0xcf, 0x8a, 0xdf, 0x37, 0xa5,
325 0x2f, 0x67, 0xd2, 0x83, 0xb6, 0x6b, 0xfc, 0xe0, 0xb4, 0x7c, 0x08, 0xdc, 0x93, 0x30, 0xab, 0xe4,
326 0x19, 0xc2, 0x8b, 0xeb, 0xa0, 0x0a, 0xc8, 0x03, 0xc0, 0x4b, 0x64, 0x71, 0x86, 0x9c, 0x9b, 0x16,
327 0x79, 0xff, 0x70, 0x09, 0x8c, 0xd0, 0xf6, 0x53, 0x07, 0x73, 0xd4, 0x89, 0xb3, 0x00, 0xe9, 0xfe,
328 0xec, 0x8f, 0xbc, 0xb2, 0x1e, 0x5d, 0x11, 0x35, 0xa9, 0x06, 0x59, 0x9f, 0xc1, 0xd3, 0x7b, 0xf2,
329 0xc5, 0x77, 0x4e, 0x39, 0x20, 0xd5, 0x6a, 0x82, 0xda, 0x45, 0xf3, 0x33, 0x81, 0x23, 0xba, 0xe2,
330 0x1d, 0x5f, 0x5c, 0x51, 0x49, 0xae, 0x8d, 0xc4, 0xa8, 0xf7, 0x1f, 0x0f, 0x34, 0x28, 0xa1, 0xd9,
331 0x27, 0xd8, 0x4c, 0x2c, 0xbf, 0x91, 0x3e, 0x69, 0x57, 0x41, 0x25, 0x0c, 0x5a, 0x90, 0x92, 0xb0,
332 0x63, 0x6f, 0x40, 0xaf, 0x74, 0xb8, 0x2d, 0x80, 0xbb, 0x46, 0x94, 0xe5, 0x29, 0xee, 0xb7, 0x1b,
333 0x96, 0xad, 0x13, 0x0e, 0x58, 0x99, 0x60, 0x4d, 0x17, 0x26, 0xce, 0xe8, 0xdb, 0xef, 0x24, 0xa3,
334 0x6e, 0x7f, 0x54, 0x3f, 0x02, 0xd1, 0x5b, 0x50, 0x56, 0x48, 0xf4, 0xbd, 0x62, 0x47, 0x04, 0xcd,
335 };
336
337
338 static const UINT8 kof2000_type0_t12[256] =
339 {
340 0xf4, 0x28, 0xb4, 0x8f, 0xfa, 0xeb, 0x8e, 0x54, 0x2b, 0x49, 0xd1, 0x76, 0x71, 0x47, 0x8b, 0x57,
341 0x92, 0x85, 0x7c, 0xb8, 0x5c, 0x22, 0xf9, 0x26, 0xbc, 0x5b, 0x6d, 0x67, 0xae, 0x5f, 0x6f, 0xf5,
342 0x9f, 0x48, 0x66, 0x40, 0x0d, 0x11, 0x4e, 0xb2, 0x6b, 0x35, 0x15, 0x0f, 0x18, 0x25, 0x1d, 0xba,
343 0xd3, 0x69, 0x79, 0xec, 0xa8, 0x8c, 0xc9, 0x7f, 0x4b, 0xdb, 0x51, 0xaf, 0xca, 0xe2, 0xb3, 0x81,
344 0x12, 0x5e, 0x7e, 0x38, 0xc8, 0x95, 0x01, 0xff, 0xfd, 0xfb, 0xf2, 0x74, 0x62, 0x14, 0xa5, 0x98,
345 0xa6, 0xda, 0x80, 0x53, 0xe8, 0x56, 0xac, 0x1b, 0x52, 0xd0, 0xf1, 0x45, 0x42, 0xb6, 0x1a, 0x4a,
346 0x3a, 0x99, 0xfc, 0xd2, 0x9c, 0xcf, 0x31, 0x2d, 0xdd, 0x86, 0x2f, 0x29, 0xe1, 0x03, 0x19, 0xa2,
347 0x41, 0x33, 0x83, 0x90, 0xc1, 0xbf, 0x0b, 0x08, 0x3d, 0xd8, 0x8d, 0x6c, 0x39, 0xa0, 0xe3, 0x55,
348 0x02, 0x50, 0x46, 0xe6, 0xc3, 0x82, 0x36, 0x13, 0x75, 0xab, 0x27, 0xd7, 0x1f, 0x0a, 0xd4, 0x89,
349 0x59, 0x4f, 0xc0, 0x5d, 0xc6, 0xf7, 0x88, 0xbd, 0x3c, 0x00, 0xef, 0xcd, 0x05, 0x1c, 0xaa, 0x9b,
350 0xed, 0x7a, 0x61, 0x17, 0x93, 0xfe, 0x23, 0xb9, 0xf3, 0x68, 0x78, 0xf6, 0x5a, 0x7b, 0xe0, 0xe4,
351 0xa3, 0xee, 0x16, 0x72, 0xc7, 0x3b, 0x8a, 0x37, 0x2a, 0x70, 0xa9, 0x2c, 0x21, 0xf8, 0x24, 0x09,
352 0xce, 0x20, 0x9e, 0x06, 0x87, 0xc5, 0x04, 0x64, 0x43, 0x7d, 0x4d, 0x10, 0xd6, 0xa4, 0x94, 0x4c,
353 0x60, 0xde, 0xdf, 0x58, 0xb1, 0x44, 0x3f, 0xb0, 0xd9, 0xe5, 0xcb, 0xbb, 0xbe, 0xea, 0x07, 0x34,
354 0x73, 0x6a, 0x77, 0xf0, 0x9d, 0x0c, 0x2e, 0x0e, 0x91, 0x9a, 0xcc, 0xc2, 0xb7, 0x63, 0x97, 0xd5,
355 0xdc, 0xc4, 0x32, 0xe7, 0x84, 0x3e, 0x30, 0xa1, 0x1e, 0xb5, 0x6e, 0x65, 0xe9, 0xad, 0xa7, 0x96,
356 };
357
358
359 static const UINT8 kof2000_type1_t03[256] =
360 {
361 0x9a, 0x2f, 0xcc, 0x4e, 0x40, 0x69, 0xac, 0xca, 0xa5, 0x7b, 0x0a, 0x61, 0x91, 0x0d, 0x55, 0x74,
362 0xcd, 0x8b, 0x0b, 0x80, 0x09, 0x5e, 0x38, 0xc7, 0xda, 0xbf, 0xf5, 0x37, 0x23, 0x31, 0x33, 0xe9,
363 0xae, 0x87, 0xe5, 0xfa, 0x6e, 0x5c, 0xad, 0xf4, 0x76, 0x62, 0x9f, 0x2e, 0x01, 0xe2, 0xf6, 0x47,
364 0x8c, 0x7c, 0xaa, 0x98, 0xb5, 0x92, 0x51, 0xec, 0x5f, 0x07, 0x5d, 0x6f, 0x16, 0xa1, 0x1d, 0xa9,
365 0x48, 0x45, 0xf0, 0x6a, 0x9c, 0x1e, 0x11, 0xa0, 0x06, 0x46, 0xd5, 0xf1, 0x73, 0xed, 0x94, 0xf7,
366 0xc3, 0x57, 0x1b, 0xe0, 0x97, 0xb1, 0xa4, 0xa7, 0x24, 0xe7, 0x2b, 0x05, 0x5b, 0x34, 0x0c, 0xb8,
367 0x0f, 0x9b, 0xc8, 0x4d, 0x5a, 0xa6, 0x86, 0x3e, 0x14, 0x29, 0x84, 0x58, 0x90, 0xdb, 0x2d, 0x54,
368 0x9d, 0x82, 0xd4, 0x7d, 0xc6, 0x67, 0x41, 0x89, 0xc1, 0x13, 0xb0, 0x9e, 0x81, 0x6d, 0xa8, 0x59,
369 0xbd, 0x39, 0x8e, 0xe6, 0x25, 0x8f, 0xd9, 0xa2, 0xe4, 0x53, 0xc5, 0x72, 0x7e, 0x36, 0x4a, 0x4f,
370 0x52, 0xc2, 0x22, 0x2a, 0xce, 0x3c, 0x21, 0x2c, 0x00, 0xd7, 0x75, 0x8a, 0x27, 0xee, 0x43, 0xfe,
371 0xcb, 0x6b, 0xb9, 0xa3, 0x78, 0xb7, 0x85, 0x02, 0x20, 0xd0, 0x83, 0xc4, 0x12, 0xf9, 0xfd, 0xd8,
372 0x79, 0x64, 0x3a, 0x49, 0x03, 0xb4, 0xc0, 0xf2, 0xdf, 0x15, 0x93, 0x08, 0x35, 0xff, 0x70, 0xdd,
373 0x28, 0x6c, 0x0e, 0x04, 0xde, 0x7a, 0x65, 0xd2, 0xab, 0x42, 0x95, 0xe1, 0x3f, 0x3b, 0x7f, 0x66,
374 0xd1, 0x8d, 0xe3, 0xbb, 0x1c, 0xfc, 0x77, 0x1a, 0x88, 0x18, 0x19, 0x68, 0x1f, 0x56, 0xd6, 0xe8,
375 0xb6, 0xbc, 0xd3, 0xea, 0x3d, 0x26, 0xb3, 0xc9, 0x44, 0xdc, 0xf3, 0x32, 0x30, 0xef, 0x96, 0x4c,
376 0xaf, 0x17, 0xf8, 0xfb, 0x60, 0x50, 0xeb, 0x4b, 0x99, 0x63, 0xba, 0xb2, 0x71, 0xcf, 0x10, 0xbe,
377 };
378
379
380 static const UINT8 kof2000_type1_t12[256] =
381 {
382 0xda, 0xa7, 0xd6, 0x6e, 0x2f, 0x5e, 0xf0, 0x3f, 0xa4, 0xce, 0xd3, 0xfd, 0x46, 0x2a, 0xac, 0xc9,
383 0xbe, 0xeb, 0x9f, 0xd5, 0x3c, 0x61, 0x96, 0x11, 0xd0, 0x38, 0xca, 0x06, 0xed, 0x1b, 0x65, 0xe7,
384 0x23, 0xdd, 0xd9, 0x05, 0xbf, 0x5b, 0x5d, 0xa5, 0x95, 0x00, 0xec, 0xf1, 0x01, 0xa9, 0xa6, 0xfc,
385 0xbb, 0x54, 0xe3, 0x2e, 0x92, 0x58, 0x0a, 0x7b, 0xb6, 0xcc, 0xb1, 0x5f, 0x14, 0x35, 0x72, 0xff,
386 0xe6, 0x52, 0xd7, 0x8c, 0xf3, 0x43, 0xaf, 0x9c, 0xc0, 0x4f, 0x0c, 0x42, 0x8e, 0xef, 0x80, 0xcd,
387 0x1d, 0x7e, 0x88, 0x3b, 0x98, 0xa1, 0xad, 0xe4, 0x9d, 0x8d, 0x2b, 0x56, 0xb5, 0x50, 0xdf, 0x66,
388 0x6d, 0xd4, 0x60, 0x09, 0xe1, 0xee, 0x4a, 0x47, 0xf9, 0xfe, 0x73, 0x07, 0x89, 0xa8, 0x39, 0xea,
389 0x82, 0x9e, 0xcf, 0x26, 0xb2, 0x4e, 0xc3, 0x59, 0xf2, 0x3d, 0x9a, 0xb0, 0x69, 0xf7, 0xbc, 0x34,
390 0xe5, 0x36, 0x22, 0xfb, 0x57, 0x71, 0x99, 0x6c, 0x83, 0x30, 0x55, 0xc2, 0xbd, 0xf4, 0x77, 0xe9,
391 0x76, 0x97, 0xa0, 0xe0, 0xb9, 0x86, 0x6b, 0xa3, 0x84, 0x67, 0x1a, 0x70, 0x02, 0x5a, 0x41, 0x5c,
392 0x25, 0x81, 0xaa, 0x28, 0x78, 0x4b, 0xc6, 0x64, 0x53, 0x16, 0x4d, 0x8b, 0x20, 0x93, 0xae, 0x0f,
393 0x94, 0x2c, 0x3a, 0xc7, 0x62, 0xe8, 0xc4, 0xdb, 0x04, 0xc5, 0xfa, 0x29, 0x48, 0xd1, 0x08, 0x24,
394 0x0d, 0xe2, 0xd8, 0x10, 0xb4, 0x91, 0x8a, 0x13, 0x0e, 0xdc, 0xd2, 0x79, 0xb8, 0xf8, 0xba, 0x2d,
395 0xcb, 0xf5, 0x7d, 0x37, 0x51, 0x40, 0x31, 0xa2, 0x0b, 0x18, 0x63, 0x7f, 0xb3, 0xab, 0x9b, 0x87,
396 0xf6, 0x90, 0xde, 0xc8, 0x27, 0x45, 0x7c, 0x1c, 0x85, 0x68, 0x33, 0x19, 0x03, 0x75, 0x15, 0x7a,
397 0x1f, 0x49, 0x8f, 0x4c, 0xc1, 0x44, 0x17, 0x12, 0x6f, 0x32, 0xb7, 0x3e, 0x74, 0x1e, 0x21, 0x6a,
398 };
399
400
401 static const UINT8 kof2000_address_8_15_xor1[256] =
402 {
403 0xfc, 0x9b, 0x1c, 0x35, 0x72, 0x53, 0xd6, 0x7d, 0x84, 0xa4, 0xc5, 0x93, 0x7b, 0xe7, 0x47, 0xd5,
404 0x24, 0xa2, 0xfa, 0x19, 0x0c, 0xb1, 0x8c, 0xb9, 0x9d, 0xd8, 0x59, 0x4f, 0x3c, 0xb2, 0x78, 0x4a,
405 0x2a, 0x96, 0x9a, 0xf1, 0x1f, 0x22, 0xa8, 0x5b, 0x67, 0xa3, 0x0f, 0x00, 0xfb, 0xdf, 0xeb, 0x0a,
406 0x57, 0xb8, 0x25, 0xd7, 0xf0, 0x6b, 0x0b, 0x31, 0x95, 0x23, 0x2d, 0x5c, 0x27, 0xc7, 0xf4, 0x55,
407 0x1a, 0xf7, 0x74, 0xbe, 0xd3, 0xac, 0x3d, 0xc1, 0x7f, 0xbd, 0x28, 0x01, 0x10, 0xe5, 0x09, 0x37,
408 0x1e, 0x58, 0xaf, 0x17, 0xf2, 0x16, 0x30, 0x92, 0x36, 0x68, 0xe6, 0xd4, 0xea, 0xb7, 0x75, 0x54,
409 0x77, 0x41, 0xb4, 0x8d, 0xe0, 0xf3, 0x51, 0x03, 0xa9, 0xe8, 0x66, 0xab, 0x29, 0xa5, 0xed, 0xcb,
410 0xd1, 0xaa, 0xf5, 0xdb, 0x4c, 0x42, 0x97, 0x8a, 0xae, 0xc9, 0x6e, 0x04, 0x33, 0x85, 0xdd, 0x2b,
411 0x6f, 0xef, 0x12, 0x21, 0x7a, 0xa1, 0x5a, 0x91, 0xc8, 0xcc, 0xc0, 0xa7, 0x60, 0x3e, 0x56, 0x2f,
412 0xe4, 0x71, 0x99, 0xc2, 0xa0, 0x45, 0x80, 0x65, 0xbb, 0x87, 0x69, 0x81, 0x73, 0xca, 0xf6, 0x46,
413 0x43, 0xda, 0x26, 0x7e, 0x8f, 0xe1, 0x8b, 0xfd, 0x50, 0x79, 0xba, 0xc6, 0x63, 0x4b, 0xb3, 0x8e,
414 0x34, 0xe2, 0x48, 0x14, 0xcd, 0xe3, 0xc4, 0x05, 0x13, 0x40, 0x06, 0x6c, 0x88, 0xb0, 0xe9, 0x1b,
415 0x4d, 0xf8, 0x76, 0x02, 0x44, 0x94, 0xcf, 0x32, 0xfe, 0xce, 0x3b, 0x5d, 0x2c, 0x89, 0x5f, 0xdc,
416 0xd2, 0x9c, 0x6a, 0xec, 0x18, 0x6d, 0x0e, 0x86, 0xff, 0x5e, 0x9e, 0xee, 0x11, 0xd0, 0x49, 0x52,
417 0x4e, 0x61, 0x90, 0x0d, 0xc3, 0x39, 0x15, 0x83, 0xb5, 0x62, 0x3f, 0x70, 0x7c, 0xad, 0x20, 0xbf,
418 0x2e, 0x08, 0x1d, 0xf9, 0xb6, 0xa6, 0x64, 0x07, 0x82, 0x38, 0x98, 0x3a, 0x9f, 0xde, 0xbc, 0xd9,
419 };
420
421
422 static const UINT8 kof2000_address_8_15_xor2[256] =
423 {
424 0x00, 0xbe, 0x06, 0x5a, 0xfa, 0x42, 0x15, 0xf2, 0x3f, 0x0a, 0x84, 0x93, 0x4e, 0x78, 0x3b, 0x89,
425 0x32, 0x98, 0xa2, 0x87, 0x73, 0xdd, 0x26, 0xe5, 0x05, 0x71, 0x08, 0x6e, 0x9b, 0xe0, 0xdf, 0x9e,
426 0xfc, 0x83, 0x81, 0xef, 0xb2, 0xc0, 0xc3, 0xbf, 0xa7, 0x6d, 0x1b, 0x95, 0xed, 0xb9, 0x3e, 0x13,
427 0xb0, 0x47, 0x9c, 0x7a, 0x24, 0x41, 0x68, 0xd0, 0x36, 0x0b, 0xb5, 0xc2, 0x67, 0xf7, 0x54, 0x92,
428 0x1e, 0x44, 0x86, 0x2b, 0x94, 0xcc, 0xba, 0x23, 0x0d, 0xca, 0x6b, 0x4c, 0x2a, 0x9a, 0x2d, 0x8b,
429 0xe3, 0x52, 0x29, 0xf0, 0x21, 0xbd, 0xbb, 0x1f, 0xa3, 0xab, 0xf8, 0x46, 0xb7, 0x45, 0x82, 0x5e,
430 0xdb, 0x07, 0x5d, 0xe9, 0x9d, 0x1a, 0x48, 0xce, 0x91, 0x12, 0xd4, 0xee, 0xa9, 0x39, 0xf1, 0x18,
431 0x2c, 0x22, 0x8a, 0x7e, 0x34, 0x4a, 0x8c, 0xc1, 0x14, 0xf3, 0x20, 0x35, 0xd9, 0x96, 0x33, 0x77,
432 0x9f, 0x76, 0x7c, 0x90, 0xc6, 0xd5, 0xa1, 0x5b, 0xac, 0x75, 0xc7, 0x0c, 0xb3, 0x17, 0xd6, 0x99,
433 0x56, 0xa6, 0x3d, 0x1d, 0xb1, 0x2e, 0xd8, 0xbc, 0x2f, 0xde, 0x60, 0x55, 0x6c, 0x40, 0xcd, 0x43,
434 0xff, 0xad, 0x38, 0x79, 0x51, 0xc8, 0x0e, 0x5f, 0xc4, 0x66, 0xcb, 0xa8, 0x7d, 0xa4, 0x3a, 0xea,
435 0x27, 0x7b, 0x70, 0x8e, 0x5c, 0x19, 0x0f, 0x80, 0x6f, 0x8f, 0x10, 0xf9, 0x49, 0x85, 0x69, 0x7f,
436 0xeb, 0x1c, 0x01, 0x65, 0x37, 0xa5, 0x28, 0xe4, 0x6a, 0x03, 0x04, 0xd1, 0x31, 0x11, 0x30, 0xfb,
437 0x88, 0x97, 0xd3, 0xf6, 0xc5, 0x4d, 0xf5, 0x3c, 0xe8, 0x61, 0xdc, 0xd2, 0xb4, 0xb8, 0xa0, 0xae,
438 0x16, 0x25, 0x02, 0x09, 0xfe, 0xcf, 0x53, 0x63, 0xaf, 0x59, 0xf4, 0xe1, 0xec, 0xd7, 0xe7, 0x50,
439 0xe2, 0xc9, 0xaa, 0x4b, 0x8d, 0x4f, 0xe6, 0x64, 0xda, 0x74, 0xb6, 0x72, 0x57, 0x62, 0xfd, 0x58,
440 };
441
442
443 static const UINT8 kof2000_address_16_23_xor1[256] =
444 {
445 0x45, 0x9f, 0x6e, 0x2f, 0x28, 0xbc, 0x5e, 0x6d, 0xda, 0xb5, 0x0d, 0xb8, 0xc0, 0x8e, 0xa2, 0x32,
446 0xee, 0xcd, 0x8d, 0x48, 0x8c, 0x27, 0x14, 0xeb, 0x65, 0xd7, 0xf2, 0x93, 0x99, 0x90, 0x91, 0xfc,
447 0x5f, 0xcb, 0xfa, 0x75, 0x3f, 0x26, 0xde, 0x72, 0x33, 0x39, 0xc7, 0x1f, 0x88, 0x79, 0x73, 0xab,
448 0x4e, 0x36, 0x5d, 0x44, 0xd2, 0x41, 0xa0, 0x7e, 0xa7, 0x8b, 0xa6, 0xbf, 0x03, 0xd8, 0x86, 0xdc,
449 0x2c, 0xaa, 0x70, 0x3d, 0x46, 0x07, 0x80, 0x58, 0x0b, 0x2b, 0xe2, 0xf0, 0xb1, 0xfe, 0x42, 0xf3,
450 0xe9, 0xa3, 0x85, 0x78, 0xc3, 0xd0, 0x5a, 0xdb, 0x1a, 0xfb, 0x9d, 0x8a, 0xa5, 0x12, 0x0e, 0x54,
451 0x8f, 0xc5, 0x6c, 0xae, 0x25, 0x5b, 0x4b, 0x17, 0x02, 0x9c, 0x4a, 0x24, 0x40, 0xe5, 0x9e, 0x22,
452 0xc6, 0x49, 0x62, 0xb6, 0x6b, 0xbb, 0xa8, 0xcc, 0xe8, 0x81, 0x50, 0x47, 0xc8, 0xbe, 0x5c, 0xa4,
453 0xd6, 0x94, 0x4f, 0x7b, 0x9a, 0xcf, 0xe4, 0x59, 0x7a, 0xa1, 0xea, 0x31, 0x37, 0x13, 0x2d, 0xaf,
454 0x21, 0x69, 0x19, 0x1d, 0x6f, 0x16, 0x98, 0x1e, 0x08, 0xe3, 0xb2, 0x4d, 0x9b, 0x7f, 0xa9, 0x77,
455 0xed, 0xbd, 0xd4, 0xd9, 0x34, 0xd3, 0xca, 0x09, 0x18, 0x60, 0xc9, 0x6a, 0x01, 0xf4, 0xf6, 0x64,
456 0xb4, 0x3a, 0x15, 0xac, 0x89, 0x52, 0x68, 0x71, 0xe7, 0x82, 0xc1, 0x0c, 0x92, 0xf7, 0x30, 0xe6,
457 0x1c, 0x3e, 0x0f, 0x0a, 0x67, 0x35, 0xba, 0x61, 0xdd, 0x29, 0xc2, 0xf8, 0x97, 0x95, 0xb7, 0x3b,
458 0xe0, 0xce, 0xf9, 0xd5, 0x06, 0x76, 0xb3, 0x05, 0x4c, 0x04, 0x84, 0x3c, 0x87, 0x23, 0x63, 0x7c,
459 0x53, 0x56, 0xe1, 0x7d, 0x96, 0x1b, 0xd1, 0xec, 0x2a, 0x66, 0xf1, 0x11, 0x10, 0xff, 0x43, 0x2e,
460 0xdf, 0x83, 0x74, 0xf5, 0x38, 0x20, 0xfd, 0xad, 0xc4, 0xb9, 0x55, 0x51, 0xb0, 0xef, 0x00, 0x57,
461 };
462
463
464 static const UINT8 kof2000_address_16_23_xor2[256] =
465 {
466 0x00, 0xb8, 0xf0, 0x34, 0xca, 0x21, 0x3c, 0xf9, 0x01, 0x8e, 0x75, 0x70, 0xec, 0x13, 0x27, 0x96,
467 0xf4, 0x5b, 0x88, 0x1f, 0xeb, 0x4a, 0x7d, 0x9d, 0xbe, 0x02, 0x14, 0xaf, 0xa2, 0x06, 0xc6, 0xdb,
468 0x35, 0x6b, 0x74, 0x45, 0x7b, 0x29, 0xd2, 0xfe, 0xb6, 0x15, 0xd0, 0x8a, 0xa9, 0x2d, 0x19, 0xf6,
469 0x5e, 0x5a, 0x90, 0xe9, 0x11, 0x33, 0xc2, 0x47, 0x37, 0x4c, 0x4f, 0x59, 0xc3, 0x04, 0x57, 0x1d,
470 0xf2, 0x63, 0x6d, 0x6e, 0x31, 0x95, 0xcb, 0x3e, 0x67, 0xb2, 0xe3, 0x98, 0xed, 0x8d, 0xe6, 0xfb,
471 0xf8, 0xba, 0x5d, 0xd4, 0x2a, 0xf5, 0x3b, 0x82, 0x05, 0x16, 0x44, 0xef, 0x4d, 0xe7, 0x93, 0xda,
472 0x9f, 0xbb, 0x61, 0xc9, 0x53, 0xbd, 0x76, 0x78, 0x52, 0x36, 0x0c, 0x66, 0xc1, 0x10, 0xdd, 0x7a,
473 0x84, 0x69, 0xcd, 0xfd, 0x58, 0x0d, 0x6c, 0x89, 0x68, 0xad, 0x3a, 0xb0, 0x4b, 0x46, 0xc5, 0x03,
474 0xb4, 0xf7, 0x30, 0x8c, 0x4e, 0x60, 0x73, 0xa1, 0x8b, 0xb1, 0x62, 0xcc, 0xd1, 0x08, 0xfc, 0x77,
475 0x7e, 0xcf, 0x56, 0x51, 0x07, 0xa6, 0x80, 0x92, 0xdc, 0x0b, 0xa4, 0xc7, 0xe8, 0xe1, 0xb5, 0x71,
476 0xea, 0xb3, 0x2f, 0x94, 0x18, 0xe2, 0x3d, 0x49, 0x65, 0xaa, 0xf1, 0x91, 0xc8, 0x99, 0x55, 0x79,
477 0x86, 0xa7, 0x26, 0xa0, 0xac, 0x5f, 0xce, 0x6a, 0x5c, 0xf3, 0x87, 0x8f, 0x12, 0x1c, 0xd8, 0xe4,
478 0x9b, 0x64, 0x2e, 0x1e, 0xd7, 0xc0, 0x17, 0xbc, 0xa3, 0xa8, 0x9a, 0x0e, 0x25, 0x40, 0x41, 0x50,
479 0xb9, 0xbf, 0x28, 0xdf, 0x32, 0x54, 0x9e, 0x48, 0xd5, 0x2b, 0x42, 0xfa, 0x9c, 0x7f, 0xd3, 0x85,
480 0x43, 0xde, 0x81, 0x0f, 0x24, 0xc4, 0x38, 0xae, 0x83, 0x1b, 0x6f, 0x7c, 0xe5, 0xff, 0x1a, 0xd9,
481 0x3f, 0xb7, 0x22, 0x97, 0x09, 0xe0, 0xa5, 0x20, 0x23, 0x2c, 0x72, 0xd6, 0x39, 0xab, 0x0a, 0xee,
482 };
483
484
485 static const UINT8 kof2000_address_0_7_xor[256] =
486 {
487 0x26, 0x48, 0x06, 0x9b, 0x21, 0xa9, 0x1b, 0x76, 0xc9, 0xf8, 0xb4, 0x67, 0xe4, 0xff, 0x99, 0xf7,
488 0x15, 0x9e, 0x62, 0x00, 0x72, 0x4d, 0xa0, 0x4f, 0x02, 0xf1, 0xea, 0xef, 0x0b, 0xf3, 0xeb, 0xa6,
489 0x93, 0x78, 0x6f, 0x7c, 0xda, 0xd4, 0x7b, 0x05, 0xe9, 0xc6, 0xd6, 0xdb, 0x50, 0xce, 0xd2, 0x01,
490 0xb5, 0xe8, 0xe0, 0x2a, 0x08, 0x1a, 0xb8, 0xe3, 0xf9, 0xb1, 0xf4, 0x8b, 0x39, 0x2d, 0x85, 0x9c,
491 0x55, 0x73, 0x63, 0x40, 0x38, 0x96, 0xdc, 0xa3, 0xa2, 0xa1, 0x25, 0x66, 0x6d, 0x56, 0x8e, 0x10,
492 0x0f, 0x31, 0x1c, 0xf5, 0x28, 0x77, 0x0a, 0xd1, 0x75, 0x34, 0xa4, 0xfe, 0x7d, 0x07, 0x51, 0x79,
493 0x41, 0x90, 0x22, 0x35, 0x12, 0xbb, 0xc4, 0xca, 0xb2, 0x1f, 0xcb, 0xc8, 0xac, 0xdd, 0xd0, 0x0d,
494 0xfc, 0xc5, 0x9d, 0x14, 0xbc, 0x83, 0xd9, 0x58, 0xc2, 0x30, 0x9a, 0x6a, 0xc0, 0x0c, 0xad, 0xf6,
495 0x5d, 0x74, 0x7f, 0x2f, 0xbd, 0x1d, 0x47, 0xd5, 0xe6, 0x89, 0xcf, 0xb7, 0xd3, 0x59, 0x36, 0x98,
496 0xf0, 0xfb, 0x3c, 0xf2, 0x3f, 0xa7, 0x18, 0x82, 0x42, 0x5c, 0xab, 0xba, 0xde, 0x52, 0x09, 0x91,
497 0xaa, 0x61, 0xec, 0xd7, 0x95, 0x23, 0xcd, 0x80, 0xa5, 0x68, 0x60, 0x27, 0x71, 0xe1, 0x2c, 0x2e,
498 0x8d, 0x2b, 0x57, 0x65, 0xbf, 0xc1, 0x19, 0xc7, 0x49, 0x64, 0x88, 0x4a, 0xcc, 0x20, 0x4e, 0xd8,
499 0x3b, 0x4c, 0x13, 0x5f, 0x9f, 0xbe, 0x5e, 0x6e, 0xfd, 0xe2, 0xfa, 0x54, 0x37, 0x0e, 0x16, 0x7a,
500 0x6c, 0x33, 0xb3, 0x70, 0x84, 0x7e, 0xc3, 0x04, 0xb0, 0xae, 0xb9, 0x81, 0x03, 0x29, 0xdf, 0x46,
501 0xe5, 0x69, 0xe7, 0x24, 0x92, 0x5a, 0x4b, 0x5b, 0x94, 0x11, 0x3a, 0x3d, 0x87, 0xed, 0x97, 0xb6,
502 0x32, 0x3e, 0x45, 0xaf, 0x1e, 0x43, 0x44, 0x8c, 0x53, 0x86, 0x6b, 0xee, 0xa8, 0x8a, 0x8f, 0x17,
503 };
504
505 #endif
506
decrypt(UINT8 * r0,UINT8 * r1,UINT8 c0,UINT8 c1,const UINT8 * table0hi,const UINT8 * table0lo,const UINT8 * table1,int base,int invert)507 static void decrypt(UINT8 *r0, UINT8 *r1,
508 UINT8 c0, UINT8 c1,
509 const UINT8 *table0hi,
510 const UINT8 *table0lo,
511 const UINT8 *table1,
512 int base,
513 int invert)
514 {
515 UINT8 tmp,xor0,xor1;
516
517 tmp = table1[(base & 0xff) ^ address_0_7_xor[(base >> 8) & 0xff]];
518 xor0 = (table0hi[(base >> 8) & 0xff] & 0xfe) | (tmp & 0x01);
519 xor1 = (tmp & 0xfe) | (table0lo[(base >> 8) & 0xff] & 0x01);
520
521 if (invert)
522 {
523 *r0 = c1 ^ xor0;
524 *r1 = c0 ^ xor1;
525 }
526 else
527 {
528 *r0 = c0 ^ xor0;
529 *r1 = c1 ^ xor1;
530 }
531 }
532
533
neogeo_gfx_decrypt(running_machine * machine,int extra_xor)534 static void neogeo_gfx_decrypt(running_machine *machine, int extra_xor)
535 {
536 int rom_size;
537 UINT8 *buf;
538 UINT8 *rom;
539 int rpos;
540 int cnt;
541 rom_size = memory_region_length(machine, "sprites");
542
543 buf = alloc_array_or_die(UINT8, rom_size);
544
545 rom = memory_region(machine, "sprites");
546 gn_init_pbar("Decrypting...", rom_size/2);
547 // Data xor
548 cnt=0;
549 for (rpos = 0;rpos < rom_size/4;rpos++)
550 {
551 decrypt(buf+4*rpos+0, buf+4*rpos+3, rom[4*rpos+0], rom[4*rpos+3], type0_t03, type0_t12, type1_t03, rpos, (rpos>>8) & 1);
552 decrypt(buf+4*rpos+1, buf+4*rpos+2, rom[4*rpos+1], rom[4*rpos+2], type0_t12, type0_t03, type1_t12, rpos, ((rpos>>16) ^ address_16_23_xor2[(rpos>>8) & 0xff]) & 1);
553 if (cnt++ > 32768) {
554 cnt=0;
555 gn_update_pbar(rpos);
556 }
557 }
558 cnt=0;
559 // Address xor
560 for (rpos = 0;rpos < rom_size/4;rpos++)
561 {
562 int baser;
563 if (cnt++>32768) {
564 gn_update_pbar(rpos + (rom_size >> 2));
565 cnt++;
566 }
567 baser = rpos;
568
569 baser ^= extra_xor;
570
571 baser ^= address_8_15_xor1[(baser >> 16) & 0xff] << 8;
572 baser ^= address_8_15_xor2[baser & 0xff] << 8;
573 baser ^= address_16_23_xor1[baser & 0xff] << 16;
574 baser ^= address_16_23_xor2[(baser >> 8) & 0xff] << 16;
575 baser ^= address_0_7_xor[(baser >> 8) & 0xff];
576
577
578 if (rom_size == 0x3000000) /* special handling for preisle2 */
579 {
580 if (rpos < 0x2000000/4)
581 baser &= (0x2000000/4)-1;
582 else
583 baser = 0x2000000/4 + (baser & ((0x1000000/4)-1));
584 }
585 else if (rom_size == 0x6000000) /* special handling for kf2k3pcb */
586 {
587 if (rpos < 0x4000000/4)
588 baser &= (0x4000000/4)-1;
589 else
590 baser = 0x4000000/4 + (baser & ((0x1000000/4)-1));
591 }
592 else /* Clamp to the real rom size */
593 baser &= (rom_size/4)-1;
594
595 rom[4*rpos+0] = buf[4*baser+0];
596 rom[4*rpos+1] = buf[4*baser+1];
597 rom[4*rpos+2] = buf[4*baser+2];
598 rom[4*rpos+3] = buf[4*baser+3];
599 }
600 gn_terminate_pbar();
601 free(buf);
602 }
603
604
605 /* the S data comes from the end of the C data */
neogeo_sfix_decrypt(running_machine * machine)606 void neogeo_sfix_decrypt(running_machine *machine)
607 {
608 int i;
609 int rom_size = memory_region_length(machine, "sprites");
610 int tx_size = memory_region_length(machine, "fixed");
611 UINT8 *src = memory_region(machine, "sprites")+rom_size-tx_size;
612 UINT8 *dst = memory_region(machine, "fixed");
613
614 for (i = 0;i < tx_size;i++)
615 dst[i] = src[(i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4)];
616 }
617
load_cmc42_table(void)618 void load_cmc42_table(void) {
619 /*
620 FILE *f;
621 type0_t03=malloc(0x950);
622 f=fopen("/home/mathieu/.gngeo/cmc42.xor","rb");
623 fread(type0_t03,0xB00,1,f);
624 fclose(f);
625 */
626 type0_t03=(UINT8*)res_load_data("rom/cmc42.xor");
627 type0_t12 = type0_t03 +256;
628 type1_t03 = type0_t12 +256;
629 type1_t12 = type1_t03 +256;
630 address_8_15_xor1 = type1_t12 +256;
631 address_8_15_xor2 = address_8_15_xor1 +256;
632 address_16_23_xor1 = address_8_15_xor2 +256;
633 address_16_23_xor2 = address_16_23_xor1 +256;
634 address_0_7_xor = address_16_23_xor2 +256;
635 }
load_cmc50_table(void)636 void load_cmc50_table(void) {
637 /*
638 FILE *f;
639 type0_t03=malloc(0xB00);
640 f=fopen("/home/mathieu/.gngeo/cmc50.xor","rb");
641 fread(type0_t03,0xB00,1,f);
642 fclose(f);
643 */
644 type0_t03=(UINT8*)res_load_data("rom/cmc50.xor");
645 type0_t12 = type0_t03 +256;
646 type1_t03 = type0_t12 +256;
647 type1_t12 = type1_t03 +256;
648 address_8_15_xor1 = type1_t12 +256;
649 address_8_15_xor2 = address_8_15_xor1 +256;
650 address_16_23_xor1 = address_8_15_xor2 +256;
651 address_16_23_xor2 = address_16_23_xor1 +256;
652 address_0_7_xor = address_16_23_xor2 +256;
653
654 m1_address_8_15_xor = address_0_7_xor +256;
655 m1_address_0_7_xor = m1_address_8_15_xor +256;
656 }
657
658 /* CMC42 protection chip */
kof99_neogeo_gfx_decrypt(running_machine * machine,int extra_xor)659 void kof99_neogeo_gfx_decrypt(running_machine *machine, int extra_xor)
660 {
661 /*
662 type0_t03 = kof99_type0_t03;
663 type0_t12 = kof99_type0_t12;
664 type1_t03 = kof99_type1_t03;
665 type1_t12 = kof99_type1_t12;
666 address_8_15_xor1 = kof99_address_8_15_xor1;
667 address_8_15_xor2 = kof99_address_8_15_xor2;
668 address_16_23_xor1 = kof99_address_16_23_xor1;
669 address_16_23_xor2 = kof99_address_16_23_xor2;
670 address_0_7_xor = kof99_address_0_7_xor;
671 */
672 load_cmc42_table();
673 neogeo_gfx_decrypt(machine, extra_xor);
674 neogeo_sfix_decrypt(machine);
675 free(type0_t03);
676 }
677
678
679 /* CMC50 protection chip */
kof2000_neogeo_gfx_decrypt(running_machine * machine,int extra_xor)680 void kof2000_neogeo_gfx_decrypt(running_machine *machine, int extra_xor)
681 {
682 /*
683 type0_t03 = kof2000_type0_t03;
684 type0_t12 = kof2000_type0_t12;
685 type1_t03 = kof2000_type1_t03;
686 type1_t12 = kof2000_type1_t12;
687 address_8_15_xor1 = kof2000_address_8_15_xor1;
688 address_8_15_xor2 = kof2000_address_8_15_xor2;
689 address_16_23_xor1 = kof2000_address_16_23_xor1;
690 address_16_23_xor2 = kof2000_address_16_23_xor2;
691 address_0_7_xor = kof2000_address_0_7_xor;
692 */
693 load_cmc50_table();
694 neogeo_gfx_decrypt(machine, extra_xor);
695 neogeo_sfix_decrypt(machine);
696 free(type0_t03);
697 }
698
699
700 /* CMC42 protection chip */
cmc42_neogeo_gfx_decrypt(running_machine * machine,int extra_xor)701 void cmc42_neogeo_gfx_decrypt(running_machine *machine, int extra_xor)
702 {
703 /*
704 type0_t03 = kof99_type0_t03;
705 type0_t12 = kof99_type0_t12;
706 type1_t03 = kof99_type1_t03;
707 type1_t12 = kof99_type1_t12;
708 address_8_15_xor1 = kof99_address_8_15_xor1;
709 address_8_15_xor2 = kof99_address_8_15_xor2;
710 address_16_23_xor1 = kof99_address_16_23_xor1;
711 address_16_23_xor2 = kof99_address_16_23_xor2;
712 address_0_7_xor = kof99_address_0_7_xor;
713 */
714 load_cmc42_table();
715 neogeo_gfx_decrypt(machine, extra_xor);
716 free(type0_t03);
717 }
718
719
720 /* CMC50 protection chip */
cmc50_neogeo_gfx_decrypt(running_machine * machine,int extra_xor)721 void cmc50_neogeo_gfx_decrypt(running_machine *machine, int extra_xor)
722 {
723 /*
724 type0_t03 = kof2000_type0_t03;
725 type0_t12 = kof2000_type0_t12;
726 type1_t03 = kof2000_type1_t03;
727 type1_t12 = kof2000_type1_t12;
728 address_8_15_xor1 = kof2000_address_8_15_xor1;
729 address_8_15_xor2 = kof2000_address_8_15_xor2;
730 address_16_23_xor1 = kof2000_address_16_23_xor1;
731 address_16_23_xor2 = kof2000_address_16_23_xor2;
732 address_0_7_xor = kof2000_address_0_7_xor;
733 */
734 load_cmc50_table();
735 neogeo_gfx_decrypt(machine, extra_xor);
736 free(type0_t03);
737 }
738
739
740 /* ms5pcb and svcpcb have an additional scramble on top of the standard CMC scrambling */
svcpcb_gfx_decrypt(running_machine * machine)741 void svcpcb_gfx_decrypt(running_machine *machine)
742 {
743 static const UINT8 xorval[ 4 ] = { 0x34, 0x21, 0xc4, 0xe9 };
744 int i;
745 int ofst;
746 int rom_size = memory_region_length( machine, "sprites" );
747 UINT8 *rom = memory_region( machine, "sprites" );
748 UINT8 *buf = alloc_array_or_die(UINT8, rom_size );
749
750 for( i = 0; i < rom_size; i++ )
751 {
752 rom[ i ] ^= xorval[ (i % 4) ];
753 }
754 for( i = 0; i < rom_size; i += 4 )
755 {
756 UINT32 rom32 = rom[i] | rom[i+1]<<8 | rom[i+2]<<16 | rom[i+3]<<24;
757 rom32 = BITSWAP32( rom32, 0x09, 0x0d, 0x13, 0x00, 0x17, 0x0f, 0x03, 0x05, 0x04, 0x0c, 0x11, 0x1e, 0x12, 0x15, 0x0b, 0x06, 0x1b, 0x0a, 0x1a, 0x1c, 0x14, 0x02, 0x0e, 0x1d, 0x18, 0x08, 0x01, 0x10, 0x19, 0x1f, 0x07, 0x16 );
758 rom[i] = rom32&0xff;
759 rom[i+1] = (rom32>>8)&0xff;
760 rom[i+2] = (rom32>>16)&0xff;
761 rom[i+3] = (rom32>>24)&0xff;
762 }
763 memcpy( buf, rom, rom_size );
764 for( i = 0; i < rom_size / 4; i++ )
765 {
766 ofst = BITSWAP24( (i & 0x1fffff), 0x17, 0x16, 0x15, 0x04, 0x0b, 0x0e, 0x08, 0x0c, 0x10, 0x00, 0x0a, 0x13, 0x03, 0x06, 0x02, 0x07, 0x0d, 0x01, 0x11, 0x09, 0x14, 0x0f, 0x12, 0x05 );
767 ofst ^= 0x0c8923;
768 ofst += (i & 0xffe00000);
769 memcpy( &rom[ i * 4 ], &buf[ ofst * 4 ], 0x04 );
770 }
771 free( buf );
772 }
773
774
775 /* and a further swap on the s1 data */
svcpcb_s1data_decrypt(running_machine * machine)776 void svcpcb_s1data_decrypt(running_machine *machine)
777 {
778 int i;
779 UINT8 *s1 = memory_region( machine, "fixed" );
780 size_t s1_size = memory_region_length( machine, "fixed" );
781
782 for( i = 0; i < s1_size; i++ ) // Decrypt S
783 {
784 s1[ i ] = BITSWAP8( s1[ i ] ^ 0xd2, 4, 0, 7, 2, 5, 1, 6, 3 );
785 }
786 }
787
788
789 /* kf2k3pcb has an additional scramble on top of the standard CMC scrambling */
790 /* Thanks to Razoola & Halrin for the info */
kf2k3pcb_gfx_decrypt(running_machine * machine)791 void kf2k3pcb_gfx_decrypt(running_machine *machine)
792 {
793 static const UINT8 xorval[ 4 ] = { 0x34, 0x21, 0xc4, 0xe9 };
794 int i;
795 int ofst;
796 int rom_size = memory_region_length( machine, "sprites" );
797 UINT8 *rom = memory_region( machine, "sprites" );
798 UINT8 *buf = alloc_array_or_die(UINT8, rom_size );
799
800 for ( i = 0; i < rom_size; i++ )
801 {
802 rom[ i ] ^= xorval[ (i % 4) ];
803 }
804 for ( i = 0; i < rom_size; i+=4 )
805 {
806 UINT32 *rom32 = (UINT32*)&rom[ i ];
807 *rom32 = BITSWAP32( *rom32, 0x09, 0x0d, 0x13, 0x00, 0x17, 0x0f, 0x03, 0x05, 0x04, 0x0c, 0x11, 0x1e, 0x12, 0x15, 0x0b, 0x06, 0x1b, 0x0a, 0x1a, 0x1c, 0x14, 0x02, 0x0e, 0x1d, 0x18, 0x08, 0x01, 0x10, 0x19, 0x1f, 0x07, 0x16 );
808 }
809 memcpy( buf, rom, rom_size );
810 for ( i = 0; i < rom_size; i+=4 )
811 {
812 ofst = BITSWAP24( (i & 0x7fffff), 0x17, 0x15, 0x0a, 0x14, 0x13, 0x16, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 );
813 ofst ^= 0x000000;
814 ofst += (i & 0xff800000);
815 memcpy( &rom[ ofst ], &buf[ i ], 0x04 );
816 }
817 free( buf );
818 }
819
820
821 /* and a further swap on the s1 data */
kf2k3pcb_decrypt_s1data(running_machine * machine)822 void kf2k3pcb_decrypt_s1data(running_machine *machine)
823 {
824 UINT8 *src;
825 UINT8 *dst;
826 int i;
827 int tx_size = memory_region_length( machine, "fixed" );
828 int srom_size = memory_region_length( machine, "sprites" );
829
830 src = memory_region( machine, "sprites" ) + srom_size - 0x1000000 - 0x80000; // Decrypt S
831 dst = memory_region( machine, "fixed" );
832
833 for( i = 0; i < tx_size / 2; i++ )
834 {
835 dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
836 }
837
838 src = memory_region( machine, "sprites" ) + srom_size - 0x80000;
839 dst = memory_region( machine, "fixed" ) + 0x80000;
840
841 for( i = 0; i < tx_size / 2; i++ )
842 {
843 dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
844 }
845
846 dst = memory_region( machine, "fixed" );
847
848 for( i = 0; i < tx_size; i++ )
849 {
850 dst[ i ] = BITSWAP8( dst[ i ] ^ 0xd2, 4, 0, 7, 2, 5, 1, 6, 3 );
851 }
852 }
853
854
855 /***************************************************************************
856
857 NeoGeo 'M' ROM encryption
858 CMC50 protection chip
859
860 ***************************************************************************/
861
862 /*
863 static const UINT8 m1_address_8_15_xor[256] =
864 {
865 0x0a, 0x72, 0xb7, 0xaf, 0x67, 0xde, 0x1d, 0xb1, 0x78, 0xc4, 0x4f, 0xb5, 0x4b, 0x18, 0x76, 0xdd,
866 0x11, 0xe2, 0x36, 0xa1, 0x82, 0x03, 0x98, 0xa0, 0x10, 0x5f, 0x3f, 0xd6, 0x1f, 0x90, 0x6a, 0x0b,
867 0x70, 0xe0, 0x64, 0xcb, 0x9f, 0x38, 0x8b, 0x53, 0x04, 0xca, 0xf8, 0xd0, 0x07, 0x68, 0x56, 0x32,
868 0xae, 0x1c, 0x2e, 0x48, 0x63, 0x92, 0x9a, 0x9c, 0x44, 0x85, 0x41, 0x40, 0x09, 0xc0, 0xc8, 0xbf,
869 0xea, 0xbb, 0xf7, 0x2d, 0x99, 0x21, 0xf6, 0xba, 0x15, 0xce, 0xab, 0xb0, 0x2a, 0x60, 0xbc, 0xf1,
870 0xf0, 0x9e, 0xd5, 0x97, 0xd8, 0x4e, 0x14, 0x9d, 0x42, 0x4d, 0x2c, 0x5c, 0x2b, 0xa6, 0xe1, 0xa7,
871 0xef, 0x25, 0x33, 0x7a, 0xeb, 0xe7, 0x1b, 0x6d, 0x4c, 0x52, 0x26, 0x62, 0xb6, 0x35, 0xbe, 0x80,
872 0x01, 0xbd, 0xfd, 0x37, 0xf9, 0x47, 0x55, 0x71, 0xb4, 0xf2, 0xff, 0x27, 0xfa, 0x23, 0xc9, 0x83,
873 0x17, 0x39, 0x13, 0x0d, 0xc7, 0x86, 0x16, 0xec, 0x49, 0x6f, 0xfe, 0x34, 0x05, 0x8f, 0x00, 0xe6,
874 0xa4, 0xda, 0x7b, 0xc1, 0xf3, 0xf4, 0xd9, 0x75, 0x28, 0x66, 0x87, 0xa8, 0x45, 0x6c, 0x20, 0xe9,
875 0x77, 0x93, 0x7e, 0x3c, 0x1e, 0x74, 0xf5, 0x8c, 0x3e, 0x94, 0xd4, 0xc2, 0x5a, 0x06, 0x0e, 0xe8,
876 0x3d, 0xa9, 0xb2, 0xe3, 0xe4, 0x22, 0xcf, 0x24, 0x8e, 0x6b, 0x8a, 0x8d, 0x84, 0x4a, 0xd2, 0x91,
877 0x88, 0x79, 0x57, 0xa5, 0x0f, 0xcd, 0xb9, 0xac, 0x3b, 0xaa, 0xb3, 0xd1, 0xee, 0x31, 0x81, 0x7c,
878 0xd7, 0x89, 0xd3, 0x96, 0x43, 0xc5, 0xc6, 0xc3, 0x69, 0x7f, 0x46, 0xdf, 0x30, 0x5b, 0x6e, 0xe5,
879 0x08, 0x95, 0x9b, 0xfb, 0xb8, 0x58, 0x0c, 0x61, 0x50, 0x5d, 0x3a, 0xa2, 0x29, 0x12, 0xfc, 0x51,
880 0x7d, 0x1a, 0x02, 0x65, 0x54, 0x5e, 0x19, 0xcc, 0xdc, 0xdb, 0x73, 0xed, 0xad, 0x59, 0x2f, 0xa3,
881 };
882
883 static const UINT8 m1_address_0_7_xor[256] =
884 {
885 0xf4, 0xbc, 0x02, 0xf7, 0x2c, 0x3d, 0xe8, 0xd9, 0x50, 0x62, 0xec, 0xbd, 0x53, 0x73, 0x79, 0x61,
886 0x00, 0x34, 0xcf, 0xa2, 0x63, 0x28, 0x90, 0xaf, 0x44, 0x3b, 0xc5, 0x8d, 0x3a, 0x46, 0x07, 0x70,
887 0x66, 0xbe, 0xd8, 0x8b, 0xe9, 0xa0, 0x4b, 0x98, 0xdc, 0xdf, 0xe2, 0x16, 0x74, 0xf1, 0x37, 0xf5,
888 0xb7, 0x21, 0x81, 0x01, 0x1c, 0x1b, 0x94, 0x36, 0x09, 0xa1, 0x4a, 0x91, 0x30, 0x92, 0x9b, 0x9a,
889 0x29, 0xb1, 0x38, 0x4d, 0x55, 0xf2, 0x56, 0x18, 0x24, 0x47, 0x9d, 0x3f, 0x80, 0x1f, 0x22, 0xa4,
890 0x11, 0x54, 0x84, 0x0d, 0x25, 0x48, 0xee, 0xc6, 0x59, 0x15, 0x03, 0x7a, 0xfd, 0x6c, 0xc3, 0x33,
891 0x5b, 0xc4, 0x7b, 0x5a, 0x05, 0x7f, 0xa6, 0x40, 0xa9, 0x5d, 0x41, 0x8a, 0x96, 0x52, 0xd3, 0xf0,
892 0xab, 0x72, 0x10, 0x88, 0x6f, 0x95, 0x7c, 0xa8, 0xcd, 0x9c, 0x5f, 0x32, 0xae, 0x85, 0x39, 0xac,
893 0xe5, 0xd7, 0xfb, 0xd4, 0x08, 0x23, 0x19, 0x65, 0x6b, 0xa7, 0x93, 0xbb, 0x2b, 0xbf, 0xb8, 0x35,
894 0xd0, 0x06, 0x26, 0x68, 0x3e, 0xdd, 0xb9, 0x69, 0x2a, 0xb2, 0xde, 0x87, 0x45, 0x58, 0xff, 0x3c,
895 0x9e, 0x7d, 0xda, 0xed, 0x49, 0x8c, 0x14, 0x8e, 0x75, 0x2f, 0xe0, 0x6e, 0x78, 0x6d, 0x20, 0xd2,
896 0xfa, 0x2d, 0x51, 0xcc, 0xc7, 0xe7, 0x1d, 0x27, 0x97, 0xfc, 0x31, 0xdb, 0xf8, 0x42, 0xe3, 0x99,
897 0x5e, 0x83, 0x0e, 0xb4, 0x2e, 0xf6, 0xc0, 0x0c, 0x4c, 0x57, 0xb6, 0x64, 0x0a, 0x17, 0xa3, 0xc1,
898 0x77, 0x12, 0xfe, 0xe6, 0x8f, 0x13, 0x71, 0xe4, 0xf9, 0xad, 0x9f, 0xce, 0xd5, 0x89, 0x7e, 0x0f,
899 0xc2, 0x86, 0xf3, 0x67, 0xba, 0x60, 0x43, 0xc9, 0x04, 0xb3, 0xb0, 0x1e, 0xb5, 0xc8, 0xeb, 0xa5,
900 0x76, 0xea, 0x5c, 0x82, 0x1a, 0x4f, 0xaa, 0xca, 0xe1, 0x0b, 0x4e, 0xcb, 0x6a, 0xef, 0xd1, 0xd6,
901 };
902 */
903
904 /* The CMC50 hardware does a checksum of the first 64kb of the M1 rom,
905 ,and uses this checksum as the basis of the key with which to decrypt
906 the rom */
907
generate_cs16(UINT8 * rom,int size)908 static UINT16 generate_cs16(UINT8 *rom, int size)
909 {
910 UINT16 cs16;
911 int i;
912 cs16 = 0x0000;
913 for (i=0;i<size;i++ )
914 {
915 cs16 += rom[i];
916 }
917 return cs16&0xFFFF;
918 }
919
920
m1_address_scramble(int address,UINT16 key)921 static int m1_address_scramble(int address, UINT16 key)
922 {
923 int block;
924 int aux;
925
926 const int p1[8][16] = {
927 {15,14,10,7,1,2,3,8,0,12,11,13,6,9,5,4},
928 {7,1,8,11,15,9,2,3,5,13,4,14,10,0,6,12},
929 {8,6,14,3,10,7,15,1,4,0,2,5,13,11,12,9},
930 {2,8,15,9,3,4,11,7,13,6,0,10,1,12,14,5},
931 {1,13,6,15,14,3,8,10,9,4,7,12,5,2,0,11},
932 {11,15,3,4,7,0,9,2,6,14,12,1,8,5,10,13},
933 {10,5,13,8,6,15,1,14,11,9,3,0,12,7,4,2},
934 {9,3,7,0,2,12,4,11,14,10,5,8,15,13,1,6},
935 };
936
937 block = (address>>16)&7;
938 aux = address&0xffff;
939
940 aux ^= BITSWAP16(key,12,0,2,4,8,15,7,13,10,1,3,6,11,9,14,5);
941 aux = BITSWAP16(aux,
942 p1[block][15],p1[block][14],p1[block][13],p1[block][12],
943 p1[block][11],p1[block][10],p1[block][9],p1[block][8],
944 p1[block][7],p1[block][6],p1[block][5],p1[block][4],
945 p1[block][3],p1[block][2],p1[block][1],p1[block][0]);
946 aux ^= m1_address_0_7_xor[(aux>>8)&0xff];
947 aux ^= m1_address_8_15_xor[aux&0xff]<<8;
948 aux = BITSWAP16(aux, 7,15,14,6,5,13,12,4,11,3,10,2,9,1,8,0);
949
950 return (block<<16)|aux;
951 }
952
953
neogeo_cmc50_m1_decrypt(running_machine * machine)954 void neogeo_cmc50_m1_decrypt(running_machine *machine)
955 {
956 UINT8* rom = memory_region(machine, "audiocrypt");
957 size_t rom_size = 0x80000;
958 //size_t rom_size = memory_region_length(machine, "audiocrypt");;
959 UINT8* rom2 = memory_region(machine, "audiocpu");
960
961 UINT8* buffer = alloc_array_or_die(UINT8, rom_size);
962
963 UINT32 i;
964
965 UINT16 key=generate_cs16(rom,0x10000);
966
967 /* TODO don't open it 2 times... */
968 load_cmc50_table();
969 //printf("key %04x\n",key);
970
971 for (i=0; i<rom_size; i++)
972 {
973 buffer[i] = rom[m1_address_scramble(i,key)];
974 }
975
976 memcpy(rom,buffer,rom_size);
977
978 memcpy(rom2,rom,0x10000);
979 memcpy(rom2+0x10000,rom,0x80000);
980
981 #if 0
982 {
983 FILE *fp;
984 const char *gamename = machine->gamedrv->name;
985 char filename[256];
986 sprintf(filename, "%s_m1.dump", gamename);
987
988 fp=fopen(filename, "w+b");
989 if (fp)
990 {
991 fwrite(rom, rom_size, 1, fp);
992 fclose(fp);
993 }
994 }
995 #endif
996
997
998 #if 0
999 {
1000 FILE *fp;
1001 const char *gamename = machine->gamedrv->name;
1002 char filename[256];
1003 sprintf(filename, "%s_m1extra.dump", gamename);
1004
1005 fp=fopen(filename, "w+b");
1006 if (fp)
1007 {
1008 fwrite(&rom[0xf800], 0x800, 1, fp);
1009 fclose(fp);
1010 }
1011 }
1012 #endif
1013
1014 free( buffer );
1015 free(type0_t03);
1016 }
1017
1018
1019 /***************************************************************************
1020
1021 NeoGeo 'P' ROM encryption
1022
1023 ***************************************************************************/
1024
1025
1026 /* Kof98 uses an early encryption, quite different from the others */
kof98_decrypt_68k(running_machine * machine)1027 void kof98_decrypt_68k(running_machine *machine)
1028 {
1029 UINT8 *src = memory_region(machine, "maincpu");
1030 UINT8 *dst = alloc_array_or_die(UINT8, 0x200000);
1031 int i, j, k;
1032 static const UINT32 sec[]={0x000000,0x100000,0x000004,0x100004,0x10000a,0x00000a,0x10000e,0x00000e};
1033 static const UINT32 pos[]={0x000,0x004,0x00a,0x00e};
1034
1035 memcpy( dst, src, 0x200000);
1036 for( i=0x800; i<0x100000; i+=0x200 )
1037 {
1038 for( j=0; j<0x100; j+=0x10 )
1039 {
1040 for( k=0; k<16; k+=2)
1041 {
1042 memcpy( &src[i+j+k], &dst[ i+j+sec[k/2]+0x100 ], 2 );
1043 memcpy( &src[i+j+k+0x100], &dst[ i+j+sec[k/2] ], 2 );
1044 }
1045 if( i >= 0x080000 && i < 0x0c0000)
1046 {
1047 for( k=0; k<4; k++ )
1048 {
1049 memcpy( &src[i+j+pos[k]], &dst[i+j+pos[k]], 2 );
1050 memcpy( &src[i+j+pos[k]+0x100], &dst[i+j+pos[k]+0x100], 2 );
1051 }
1052 }
1053 else if( i >= 0x0c0000 )
1054 {
1055 for( k=0; k<4; k++ )
1056 {
1057 memcpy( &src[i+j+pos[k]], &dst[i+j+pos[k]+0x100], 2 );
1058 memcpy( &src[i+j+pos[k]+0x100], &dst[i+j+pos[k]], 2 );
1059 }
1060 }
1061 }
1062 memcpy( &src[i+0x000000], &dst[i+0x000000], 2 );
1063 memcpy( &src[i+0x000002], &dst[i+0x100000], 2 );
1064 memcpy( &src[i+0x000100], &dst[i+0x000100], 2 );
1065 memcpy( &src[i+0x000102], &dst[i+0x100100], 2 );
1066 }
1067 memcpy( &src[0x100000], &src[0x200000], 0x400000 );
1068
1069 free(dst);
1070 }
1071
1072
1073 /* kof99, garou, garouo, mslug3 and kof2000 have and SMA chip which contains program code and decrypts the 68k roms */
kof99_decrypt_68k(running_machine * machine)1074 void kof99_decrypt_68k(running_machine *machine)
1075 {
1076 UINT16 *rom;
1077 int i,j;
1078
1079 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1080 /* swap data lines on the whole ROMs */
1081 for (i = 0;i < 0x800000/2;i++)
1082 {
1083 rom[i] = BITSWAP16(rom[i],13,7,3,0,9,4,5,6,1,12,8,14,10,11,2,15);
1084 }
1085
1086 /* swap address lines for the banked part */
1087 for (i = 0;i < 0x600000/2;i+=0x800/2)
1088 {
1089 UINT16 buffer[0x800/2];
1090 memcpy(buffer,&rom[i],0x800);
1091 for (j = 0;j < 0x800/2;j++)
1092 {
1093 rom[i+j] = buffer[BITSWAP24(j,23,22,21,20,19,18,17,16,15,14,13,12,11,10,6,2,4,9,8,3,1,7,0,5)];
1094 }
1095 }
1096
1097 /* swap address lines & relocate fixed part */
1098 rom = (UINT16 *)memory_region(machine, "maincpu");
1099 for (i = 0;i < 0x0c0000/2;i++)
1100 {
1101 rom[i] = rom[0x700000/2 + BITSWAP24(i,23,22,21,20,19,18,11,6,14,17,16,5,8,10,12,0,4,3,2,7,9,15,13,1)];
1102 }
1103 }
1104
1105
garou_decrypt_68k(running_machine * machine)1106 void garou_decrypt_68k(running_machine *machine)
1107 {
1108 UINT16 *rom;
1109 int i,j;
1110
1111 /* thanks to Razoola and Mr K for the info */
1112 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1113 /* swap data lines on the whole ROMs */
1114 for (i = 0;i < 0x800000/2;i++)
1115 {
1116 rom[i] = BITSWAP16(rom[i],13,12,14,10,8,2,3,1,5,9,11,4,15,0,6,7);
1117 }
1118
1119 /* swap address lines & relocate fixed part */
1120 rom = (UINT16 *)memory_region(machine, "maincpu");
1121 for (i = 0;i < 0x0c0000/2;i++)
1122 {
1123 rom[i] = rom[0x710000/2 + BITSWAP24(i,23,22,21,20,19,18,4,5,16,14,7,9,6,13,17,15,3,1,2,12,11,8,10,0)];
1124 }
1125
1126 /* swap address lines for the banked part */
1127 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1128 for (i = 0;i < 0x800000/2;i+=0x8000/2)
1129 {
1130 UINT16 buffer[0x8000/2];
1131 memcpy(buffer,&rom[i],0x8000);
1132 for (j = 0;j < 0x8000/2;j++)
1133 {
1134 rom[i+j] = buffer[BITSWAP24(j,23,22,21,20,19,18,17,16,15,14,9,4,8,3,13,6,2,7,0,12,1,11,10,5)];
1135 }
1136 }
1137 }
1138
1139
garouo_decrypt_68k(running_machine * machine)1140 void garouo_decrypt_68k(running_machine *machine)
1141 {
1142 UINT16 *rom;
1143 int i,j;
1144
1145 /* thanks to Razoola and Mr K for the info */
1146 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1147 /* swap data lines on the whole ROMs */
1148 for (i = 0;i < 0x800000/2;i++)
1149 {
1150 rom[i] = BITSWAP16(rom[i],14,5,1,11,7,4,10,15,3,12,8,13,0,2,9,6);
1151 }
1152
1153 /* swap address lines & relocate fixed part */
1154 rom = (UINT16 *)memory_region(machine, "maincpu");
1155 for (i = 0;i < 0x0c0000/2;i++)
1156 {
1157 rom[i] = rom[0x7f8000/2 + BITSWAP24(i,23,22,21,20,19,18,5,16,11,2,6,7,17,3,12,8,14,4,0,9,1,10,15,13)];
1158 }
1159
1160 /* swap address lines for the banked part */
1161 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1162 for (i = 0;i < 0x800000/2;i+=0x8000/2)
1163 {
1164 UINT16 buffer[0x8000/2];
1165 memcpy(buffer,&rom[i],0x8000);
1166 for (j = 0;j < 0x8000/2;j++)
1167 {
1168 rom[i+j] = buffer[BITSWAP24(j,23,22,21,20,19,18,17,16,15,14,12,8,1,7,11,3,13,10,6,9,5,4,0,2)];
1169 }
1170 }
1171 }
1172
1173
mslug3_decrypt_68k(running_machine * machine)1174 void mslug3_decrypt_68k(running_machine *machine)
1175 {
1176 UINT16 *rom;
1177 int i,j;
1178
1179 /* thanks to Razoola and Mr K for the info */
1180 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1181 /* swap data lines on the whole ROMs */
1182 for (i = 0;i < 0x800000/2;i++)
1183 {
1184 rom[i] = BITSWAP16(rom[i],4,11,14,3,1,13,0,7,2,8,12,15,10,9,5,6);
1185 }
1186
1187 /* swap address lines & relocate fixed part */
1188 rom = (UINT16 *)memory_region(machine, "maincpu");
1189 for (i = 0;i < 0x0c0000/2;i++)
1190 {
1191 rom[i] = rom[0x5d0000/2 + BITSWAP24(i,23,22,21,20,19,18,15,2,1,13,3,0,9,6,16,4,11,5,7,12,17,14,10,8)];
1192 }
1193
1194 /* swap address lines for the banked part */
1195 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1196 for (i = 0;i < 0x800000/2;i+=0x10000/2)
1197 {
1198 UINT16 buffer[0x10000/2];
1199 memcpy(buffer,&rom[i],0x10000);
1200 for (j = 0;j < 0x10000/2;j++)
1201 {
1202 rom[i+j] = buffer[BITSWAP24(j,23,22,21,20,19,18,17,16,15,2,11,0,14,6,4,13,8,9,3,10,7,5,12,1)];
1203 }
1204 }
1205 }
1206
1207
kof2000_decrypt_68k(running_machine * machine)1208 void kof2000_decrypt_68k(running_machine *machine)
1209 {
1210 UINT16 *rom;
1211 int i,j;
1212
1213 /* thanks to Razoola and Mr K for the info */
1214 rom = (UINT16 *)(memory_region(machine, "maincpu") + 0x100000);
1215 /* swap data lines on the whole ROMs */
1216 for (i = 0;i < 0x800000/2;i++)
1217 {
1218 rom[i] = BITSWAP16(rom[i],12,8,11,3,15,14,7,0,10,13,6,5,9,2,1,4);
1219 }
1220
1221 /* swap address lines for the banked part */
1222 for (i = 0;i < 0x63a000/2;i+=0x800/2)
1223 {
1224 UINT16 buffer[0x800/2];
1225 memcpy(buffer,&rom[i],0x800);
1226 for (j = 0;j < 0x800/2;j++)
1227 {
1228 rom[i+j] = buffer[BITSWAP24(j,23,22,21,20,19,18,17,16,15,14,13,12,11,10,4,1,3,8,6,2,7,0,9,5)];
1229 }
1230 }
1231
1232 /* swap address lines & relocate fixed part */
1233 rom = (UINT16 *)memory_region(machine, "maincpu");
1234 for (i = 0;i < 0x0c0000/2;i++)
1235 {
1236 rom[i] = rom[0x73a000/2 + BITSWAP24(i,23,22,21,20,19,18,8,4,15,13,3,14,16,2,6,17,7,12,10,0,5,11,1,9)];
1237 }
1238 }
1239
1240
1241 /* kof2002, matrim, samsho5, samsh5sp have some simple block swapping */
kof2002_decrypt_68k(running_machine * machine)1242 void kof2002_decrypt_68k(running_machine *machine)
1243 {
1244 int i;
1245 static const int sec[]={0x100000,0x280000,0x300000,0x180000,0x000000,0x380000,0x200000,0x080000};
1246 UINT8 *src = memory_region(machine, "maincpu")+0x100000;
1247 UINT8 *dst = alloc_array_or_die(UINT8, 0x400000);
1248 memcpy( dst, src, 0x400000 );
1249 for( i=0; i<8; ++i )
1250 {
1251 memcpy( src+i*0x80000, dst+sec[i], 0x80000 );
1252 }
1253 free(dst);
1254 }
1255
1256
matrim_decrypt_68k(running_machine * machine)1257 void matrim_decrypt_68k(running_machine *machine)
1258 {
1259 int i;
1260 static const int sec[]={0x100000,0x280000,0x300000,0x180000,0x000000,0x380000,0x200000,0x080000};
1261 UINT8 *src = memory_region(machine, "maincpu")+0x100000;
1262 UINT8 *dst = alloc_array_or_die(UINT8, 0x400000);
1263 memcpy( dst, src, 0x400000);
1264 for( i=0; i<8; ++i )
1265 {
1266 memcpy( src+i*0x80000, dst+sec[i], 0x80000 );
1267 }
1268 free(dst);
1269 }
1270
1271
samsho5_decrypt_68k(running_machine * machine)1272 void samsho5_decrypt_68k(running_machine *machine)
1273 {
1274 int i;
1275 static const int sec[]={0x000000,0x080000,0x700000,0x680000,0x500000,0x180000,0x200000,0x480000,0x300000,0x780000,0x600000,0x280000,0x100000,0x580000,0x400000,0x380000};
1276 UINT8 *src = memory_region(machine, "maincpu");
1277 UINT8 *dst = alloc_array_or_die(UINT8, 0x800000);
1278
1279 memcpy( dst, src, 0x800000 );
1280 for( i=0; i<16; ++i )
1281 {
1282 memcpy( src+i*0x80000, dst+sec[i], 0x80000 );
1283 }
1284 free(dst);
1285 }
1286
1287
samsh5sp_decrypt_68k(running_machine * machine)1288 void samsh5sp_decrypt_68k(running_machine *machine)
1289 {
1290 int i;
1291 static const int sec[]={0x000000,0x080000,0x500000,0x480000,0x600000,0x580000,0x700000,0x280000,0x100000,0x680000,0x400000,0x780000,0x200000,0x380000,0x300000,0x180000};
1292 UINT8 *src = memory_region(machine, "maincpu");
1293 UINT8 *dst = alloc_array_or_die(UINT8, 0x800000);
1294
1295 memcpy( dst, src, 0x800000 );
1296 for( i=0; i<16; ++i )
1297 {
1298 memcpy( src+i*0x80000, dst+sec[i], 0x80000 );
1299 }
1300 free(dst);
1301 }
1302
1303
1304 /* kf2k3pcb, kof2003, kof2003h, mslug5 and svc have updated P rom scramble */
mslug5_decrypt_68k(running_machine * machine)1305 void mslug5_decrypt_68k(running_machine *machine)
1306 {
1307 static const UINT8 xor1[ 0x20 ] = { 0xc2, 0x4b, 0x74, 0xfd, 0x0b, 0x34, 0xeb, 0xd7, 0x10, 0x6d, 0xf9, 0xce, 0x5d, 0xd5, 0x61, 0x29, 0xf5, 0xbe, 0x0d, 0x82, 0x72, 0x45, 0x0f, 0x24, 0xb3, 0x34, 0x1b, 0x99, 0xea, 0x09, 0xf3, 0x03 };
1308 static const UINT8 xor2[ 0x20 ] = { 0x36, 0x09, 0xb0, 0x64, 0x95, 0x0f, 0x90, 0x42, 0x6e, 0x0f, 0x30, 0xf6, 0xe5, 0x08, 0x30, 0x64, 0x08, 0x04, 0x00, 0x2f, 0x72, 0x09, 0xa0, 0x13, 0xc9, 0x0b, 0xa0, 0x3e, 0xc2, 0x00, 0x40, 0x2b };
1309 int i;
1310 int ofst;
1311 int rom_size = 0x800000;
1312 UINT8 *rom = memory_region( machine, "maincpu" );
1313 UINT8 *buf = alloc_array_or_die(UINT8, rom_size );
1314
1315 for( i = 0; i < 0x100000; i++ )
1316 {
1317 rom[ i ] ^= xor1[ (BYTE_XOR_LE(i) % 0x20) ];
1318 }
1319 for( i = 0x100000; i < 0x800000; i++ )
1320 {
1321 rom[ i ] ^= xor2[ (BYTE_XOR_LE(i) % 0x20) ];
1322 }
1323
1324 for( i = 0x100000; i < 0x0800000; i += 4 )
1325 {
1326 UINT16 rom16;
1327 rom16 = rom[BYTE_XOR_LE(i+1)] | rom[BYTE_XOR_LE(i+2)]<<8;
1328 rom16 = BITSWAP16( rom16, 15, 14, 13, 12, 10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1, 0 );
1329 rom[BYTE_XOR_LE(i+1)] = rom16&0xff;
1330 rom[BYTE_XOR_LE(i+2)] = rom16>>8;
1331 }
1332 memcpy( buf, rom, rom_size );
1333 for( i = 0; i < 0x0100000 / 0x10000; i++ )
1334 {
1335 ofst = (i & 0xf0) + BITSWAP8( (i & 0x0f), 7, 6, 5, 4, 1, 0, 3, 2 );
1336 memcpy( &rom[ i * 0x10000 ], &buf[ ofst * 0x10000 ], 0x10000 );
1337 }
1338 for( i = 0x100000; i < 0x800000; i += 0x100 )
1339 {
1340 ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00700) + (BITSWAP8( ((i & 0x0ff000) >> 12), 5, 4, 7, 6, 1, 0, 3, 2 ) << 12);
1341 memcpy( &rom[ i ], &buf[ ofst ], 0x100 );
1342 }
1343 memcpy( buf, rom, rom_size );
1344 memcpy( &rom[ 0x100000 ], &buf[ 0x700000 ], 0x100000 );
1345 memcpy( &rom[ 0x200000 ], &buf[ 0x100000 ], 0x600000 );
1346 free( buf );
1347 }
1348
1349
svc_px_decrypt(running_machine * machine)1350 void svc_px_decrypt(running_machine *machine)
1351 {
1352 static const UINT8 xor1[ 0x20 ] = { 0x3b, 0x6a, 0xf7, 0xb7, 0xe8, 0xa9, 0x20, 0x99, 0x9f, 0x39, 0x34, 0x0c, 0xc3, 0x9a, 0xa5, 0xc8, 0xb8, 0x18, 0xce, 0x56, 0x94, 0x44, 0xe3, 0x7a, 0xf7, 0xdd, 0x42, 0xf0, 0x18, 0x60, 0x92, 0x9f };
1353 static const UINT8 xor2[ 0x20 ] = { 0x69, 0x0b, 0x60, 0xd6, 0x4f, 0x01, 0x40, 0x1a, 0x9f, 0x0b, 0xf0, 0x75, 0x58, 0x0e, 0x60, 0xb4, 0x14, 0x04, 0x20, 0xe4, 0xb9, 0x0d, 0x10, 0x89, 0xeb, 0x07, 0x30, 0x90, 0x50, 0x0e, 0x20, 0x26 };
1354 int i;
1355 int ofst;
1356 int rom_size = 0x800000;
1357 UINT8 *rom = memory_region( machine, "maincpu" );
1358 UINT8 *buf = alloc_array_or_die(UINT8, rom_size );
1359
1360 for( i = 0; i < 0x100000; i++ )
1361 {
1362 rom[ i ] ^= xor1[ (BYTE_XOR_LE(i) % 0x20) ];
1363 }
1364 for( i = 0x100000; i < 0x800000; i++ )
1365 {
1366 rom[ i ] ^= xor2[ (BYTE_XOR_LE(i) % 0x20) ];
1367 }
1368
1369 for( i = 0x100000; i < 0x0800000; i += 4 )
1370 {
1371 UINT16 rom16;
1372 rom16 = rom[BYTE_XOR_LE(i+1)] | rom[BYTE_XOR_LE(i+2)]<<8;
1373 rom16 = BITSWAP16( rom16, 15, 14, 13, 12, 10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1, 0 );
1374 rom[BYTE_XOR_LE(i+1)] = rom16&0xff;
1375 rom[BYTE_XOR_LE(i+2)] = rom16>>8;
1376 }
1377 memcpy( buf, rom, rom_size );
1378 for( i = 0; i < 0x0100000 / 0x10000; i++ )
1379 {
1380 ofst = (i & 0xf0) + BITSWAP8( (i & 0x0f), 7, 6, 5, 4, 2, 3, 0, 1 );
1381 memcpy( &rom[ i * 0x10000 ], &buf[ ofst * 0x10000 ], 0x10000 );
1382 }
1383 for( i = 0x100000; i < 0x800000; i += 0x100 )
1384 {
1385 ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00a00) + (BITSWAP8( ((i & 0x0ff000) >> 12), 4, 5, 6, 7, 1, 0, 3, 2 ) << 12);
1386 memcpy( &rom[ i ], &buf[ ofst ], 0x100 );
1387 }
1388 memcpy( buf, rom, rom_size );
1389 memcpy( &rom[ 0x100000 ], &buf[ 0x700000 ], 0x100000 );
1390 memcpy( &rom[ 0x200000 ], &buf[ 0x100000 ], 0x600000 );
1391 free( buf );
1392 }
1393
1394
kf2k3pcb_decrypt_68k(running_machine * machine)1395 void kf2k3pcb_decrypt_68k(running_machine *machine)
1396 {
1397 static const UINT8 xor2[ 0x20 ] = { 0xb4, 0x0f, 0x40, 0x6c, 0x38, 0x07, 0xd0, 0x3f, 0x53, 0x08, 0x80, 0xaa, 0xbe, 0x07, 0xc0, 0xfa, 0xd0, 0x08, 0x10, 0xd2, 0xf1, 0x03, 0x70, 0x7e, 0x87, 0x0b, 0x40, 0xf6, 0x2a, 0x0a, 0xe0, 0xf9 };
1398 int i;
1399 int ofst;
1400 int rom_size = 0x900000;
1401 UINT8 *rom = memory_region( machine, "maincpu" );
1402 UINT8 *buf = alloc_array_or_die(UINT8, rom_size );
1403
1404 for (i = 0; i < 0x100000; i++)
1405 {
1406 rom[ 0x800000 + i ] ^= rom[ 0x100002 | BYTE_XOR_LE(i) ];
1407 }
1408 for( i = 0x100000; i < 0x800000; i++ )
1409 {
1410 rom[ i ] ^= xor2[ (BYTE_XOR_LE(i) % 0x20) ];
1411 }
1412 for( i = 0x100000; i < 0x800000; i += 4 )
1413 {
1414 UINT16 rom16;
1415 rom16 = rom[BYTE_XOR_LE(i+1)] | rom[BYTE_XOR_LE(i+2)]<<8;
1416 rom16 = BITSWAP16( rom16, 15, 14, 13, 12, 4, 5, 6, 7, 8, 9, 10, 11, 3, 2, 1, 0 );
1417 rom[BYTE_XOR_LE(i+1)] = rom16&0xff;
1418 rom[BYTE_XOR_LE(i+2)] = rom16>>8;
1419 }
1420 for( i = 0; i < 0x0100000 / 0x10000; i++ )
1421 {
1422 ofst = (i & 0xf0) + BITSWAP8( (i & 0x0f), 7, 6, 5, 4, 1, 0, 3, 2 );
1423 memcpy( &buf[ i * 0x10000 ], &rom[ ofst * 0x10000 ], 0x10000 );
1424 }
1425 for( i = 0x100000; i < 0x900000; i += 0x100 )
1426 {
1427 ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00300) + (BITSWAP8( ((i & 0x0ff000) >> 12), 4, 5, 6, 7, 1, 0, 3, 2 ) << 12);
1428 memcpy( &buf[ i ], &rom[ ofst ], 0x100 );
1429 }
1430 memcpy (&rom[0x000000], &buf[0x000000], 0x100000);
1431 memcpy (&rom[0x100000], &buf[0x800000], 0x100000);
1432 memcpy (&rom[0x200000], &buf[0x100000], 0x700000);
1433 free( buf );
1434 }
1435
1436
kof2003_decrypt_68k(running_machine * machine)1437 void kof2003_decrypt_68k(running_machine *machine)
1438 {
1439 static const UINT8 xor1[0x20] = { 0x3b, 0x6a, 0xf7, 0xb7, 0xe8, 0xa9, 0x20, 0x99, 0x9f, 0x39, 0x34, 0x0c, 0xc3, 0x9a, 0xa5, 0xc8, 0xb8, 0x18, 0xce, 0x56, 0x94, 0x44, 0xe3, 0x7a, 0xf7, 0xdd, 0x42, 0xf0, 0x18, 0x60, 0x92, 0x9f };
1440 static const UINT8 xor2[0x20] = { 0x2f, 0x02, 0x60, 0xbb, 0x77, 0x01, 0x30, 0x08, 0xd8, 0x01, 0xa0, 0xdf, 0x37, 0x0a, 0xf0, 0x65, 0x28, 0x03, 0xd0, 0x23, 0xd3, 0x03, 0x70, 0x42, 0xbb, 0x06, 0xf0, 0x28, 0xba, 0x0f, 0xf0, 0x7a };
1441 int i;
1442 int ofst;
1443 int rom_size = 0x900000;
1444 UINT8 *rom = memory_region( machine, "maincpu" );
1445 UINT8 *buf = alloc_array_or_die(UINT8, rom_size );
1446
1447 for (i = 0; i < 0x100000; i++)
1448 {
1449 rom[ 0x800000 + i ] ^= rom[ 0x100002 | BYTE_XOR_LE(i) ];
1450 }
1451 for( i = 0; i < 0x100000; i++)
1452 {
1453 rom[ i ] ^= xor1[ (BYTE_XOR_LE(i) % 0x20) ];
1454 }
1455 for( i = 0x100000; i < 0x800000; i++)
1456 {
1457 rom[ i ] ^= xor2[ (BYTE_XOR_LE(i) % 0x20) ];
1458 }
1459 for( i = 0x100000; i < 0x800000; i += 4)
1460 {
1461 UINT16 rom16;
1462 rom16 = rom[BYTE_XOR_LE(i+1)] | rom[BYTE_XOR_LE(i+2)]<<8;
1463 rom16 = BITSWAP16( rom16, 15, 14, 13, 12, 5, 4, 7, 6, 9, 8, 11, 10, 3, 2, 1, 0 );
1464 rom[BYTE_XOR_LE(i+1)] = rom16&0xff;
1465 rom[BYTE_XOR_LE(i+2)] = rom16>>8;
1466 }
1467 for( i = 0; i < 0x0100000 / 0x10000; i++ )
1468 {
1469 ofst = (i & 0xf0) + BITSWAP8((i & 0x0f), 7, 6, 5, 4, 0, 1, 2, 3);
1470 memcpy( &buf[ i * 0x10000 ], &rom[ ofst * 0x10000 ], 0x10000 );
1471 }
1472 for( i = 0x100000; i < 0x900000; i += 0x100)
1473 {
1474 ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00800) + (BITSWAP8( ((i & 0x0ff000) >> 12), 4, 5, 6, 7, 1, 0, 3, 2 ) << 12);
1475 memcpy( &buf[ i ], &rom[ ofst ], 0x100 );
1476 }
1477 memcpy (&rom[0x000000], &buf[0x000000], 0x100000);
1478 memcpy (&rom[0x100000], &buf[0x800000], 0x100000);
1479 memcpy (&rom[0x200000], &buf[0x100000], 0x700000);
1480 free( buf );
1481 }
1482
1483
1484 // Thanks to IQ_132 for the info
kof2003h_decrypt_68k(running_machine * machine)1485 void kof2003h_decrypt_68k(running_machine *machine)
1486 {
1487 static const UINT8 xor1[0x20] = { 0xc2, 0x4b, 0x74, 0xfd, 0x0b, 0x34, 0xeb, 0xd7, 0x10, 0x6d, 0xf9, 0xce, 0x5d, 0xd5, 0x61, 0x29, 0xf5, 0xbe, 0x0d, 0x82, 0x72, 0x45, 0x0f, 0x24, 0xb3, 0x34, 0x1b, 0x99, 0xea, 0x09, 0xf3, 0x03 };
1488 static const UINT8 xor2[0x20] = { 0x2b, 0x09, 0xd0, 0x7f, 0x51, 0x0b, 0x10, 0x4c, 0x5b, 0x07, 0x70, 0x9d, 0x3e, 0x0b, 0xb0, 0xb6, 0x54, 0x09, 0xe0, 0xcc, 0x3d, 0x0d, 0x80, 0x99, 0x87, 0x03, 0x90, 0x82, 0xfe, 0x04, 0x20, 0x18 };
1489 int i;
1490 int ofst;
1491 int rom_size = 0x900000;
1492 UINT8 *rom = memory_region( machine, "maincpu" );
1493 UINT8 *buf = alloc_array_or_die(UINT8, rom_size );
1494
1495 for (i = 0; i < 0x100000; i++)
1496 {
1497 rom[ 0x800000 + i ] ^= rom[ 0x100002 | BYTE_XOR_LE(i) ];
1498 }
1499 for( i = 0; i < 0x100000; i++)
1500 {
1501 rom[ i ] ^= xor1[ (BYTE_XOR_LE(i) % 0x20) ];
1502 }
1503 for( i = 0x100000; i < 0x800000; i++)
1504 {
1505 rom[ i ] ^= xor2[ (BYTE_XOR_LE(i) % 0x20) ];
1506 }
1507 for( i = 0x100000; i < 0x800000; i += 4)
1508 {
1509 UINT16 rom16;
1510 rom16 = rom[BYTE_XOR_LE(i+1)] | rom[BYTE_XOR_LE(i+2)]<<8;
1511 rom16 = BITSWAP16( rom16, 15, 14, 13, 12, 10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1, 0 );
1512 rom[BYTE_XOR_LE(i+1)] = rom16&0xff;
1513 rom[BYTE_XOR_LE(i+2)] = rom16>>8;
1514 }
1515 for( i = 0; i < 0x0100000 / 0x10000; i++ )
1516 {
1517 ofst = (i & 0xf0) + BITSWAP8((i & 0x0f), 7, 6, 5, 4, 1, 0, 3, 2);
1518 memcpy( &buf[ i * 0x10000 ], &rom[ ofst * 0x10000 ], 0x10000 );
1519 }
1520 for( i = 0x100000; i < 0x900000; i += 0x100)
1521 {
1522 ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00400) + (BITSWAP8( ((i & 0x0ff000) >> 12), 6, 7, 4, 5, 0, 1, 2, 3 ) << 12);
1523 memcpy( &buf[ i ], &rom[ ofst ], 0x100 );
1524 }
1525 memcpy (&rom[0x000000], &buf[0x000000], 0x100000);
1526 memcpy (&rom[0x100000], &buf[0x800000], 0x100000);
1527 memcpy (&rom[0x200000], &buf[0x100000], 0x700000);
1528 free( buf );
1529 }
1530
1531
1532 /***************************************************************************
1533
1534 NeoGeo 'V' (PCM) ROM encryption
1535 NEOPCM2 chip
1536
1537 ***************************************************************************/
1538
1539 /* Neo-Pcm2 Drivers for Encrypted V Roms */
neo_pcm2_snk_1999(running_machine * machine,int value)1540 void neo_pcm2_snk_1999(running_machine *machine, int value)
1541 { /* thanks to Elsemi for the NEO-PCM2 info */
1542 UINT16 *rom = (UINT16 *)memory_region(machine, "ym");
1543 int size = memory_region_length(machine, "ym");
1544 int i, j;
1545
1546 if( rom != NULL )
1547 { /* swap address lines on the whole ROMs */
1548 UINT16 *buffer = alloc_array_or_die(UINT16, value / 2);
1549
1550 for( i = 0; i < size / 2; i += ( value / 2 ) )
1551 {
1552 memcpy( buffer, &rom[ i ], value );
1553 for( j = 0; j < (value / 2); j++ )
1554 {
1555 rom[ i + j ] = buffer[ j ^ (value/4) ];
1556 }
1557 }
1558 free(buffer);
1559 }
1560 }
1561
1562
1563 /* the later PCM2 games have additional scrambling */
neo_pcm2_swap(running_machine * machine,int value)1564 void neo_pcm2_swap(running_machine *machine, int value)
1565 {
1566 static const UINT32 addrs[7][2]={
1567 {0x000000,0xa5000},
1568 {0xffce20,0x01000},
1569 {0xfe2cf6,0x4e001},
1570 {0xffac28,0xc2000},
1571 {0xfeb2c0,0x0a000},
1572 {0xff14ea,0xa7001},
1573 {0xffb440,0x02000}};
1574 static const UINT8 xordata[7][8]={
1575 {0xf9,0xe0,0x5d,0xf3,0xea,0x92,0xbe,0xef},
1576 {0xc4,0x83,0xa8,0x5f,0x21,0x27,0x64,0xaf},
1577 {0xc3,0xfd,0x81,0xac,0x6d,0xe7,0xbf,0x9e},
1578 {0xc3,0xfd,0x81,0xac,0x6d,0xe7,0xbf,0x9e},
1579 {0xcb,0x29,0x7d,0x43,0xd2,0x3a,0xc2,0xb4},
1580 {0x4b,0xa4,0x63,0x46,0xf0,0x91,0xea,0x62},
1581 {0x4b,0xa4,0x63,0x46,0xf0,0x91,0xea,0x62}};
1582 UINT8 *src = memory_region(machine, "ym");
1583 UINT8 *buf = alloc_array_or_die(UINT8, 0x1000000);
1584 int i, j, d;
1585
1586 memcpy(buf,src,0x1000000);
1587 for (i=0;i<0x1000000;i++)
1588 {
1589 j=BITSWAP24(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);
1590 j=j^addrs[value][1];
1591 d=((i+addrs[value][0])&0xffffff);
1592 src[j]=buf[d]^xordata[value][j&0x7];
1593 }
1594 free(buf);
1595 }
1596
1597
1598 /***************************************************************************
1599
1600 NeoGeo 'SP1' (BIOS) ROM encryption
1601
1602 ***************************************************************************/
1603
1604
1605 /* only found on kf2k3pcb */
kof2003biosdecode(running_machine * machine)1606 void kof2003biosdecode(running_machine *machine)
1607 {
1608 static const UINT8 address[0x80]={
1609 0xb9,0xb8,0x36,0x37,0x3d,0x3c,0xb2,0xb3,
1610 0xb9,0xb8,0x36,0x37,0x3d,0x3c,0xb2,0xb3,
1611 0x65,0xea,0x6f,0xe0,0xe1,0x6e,0xeb,0x64,
1612 0x65,0xea,0x6f,0xe0,0xe1,0x6e,0xeb,0x64,
1613 0x45,0xca,0x47,0xc8,0xc9,0x46,0xcb,0x44,
1614 0x45,0xca,0x47,0xc8,0xc9,0x46,0xcb,0x44,
1615 0x9a,0x15,0x98,0x17,0x1e,0x91,0x1c,0x93,
1616 0x9a,0x15,0x98,0x17,0x1e,0x91,0x1c,0x93,
1617 0x7e,0xf1,0x7c,0xf3,0xf0,0x7f,0xf2,0x7d,
1618 0x7e,0xf1,0x7c,0xf3,0xf0,0x7f,0xf2,0x7d,
1619 0x27,0xa8,0x25,0xaa,0xa3,0x2c,0xa1,0x2e,
1620 0x27,0xa8,0x25,0xaa,0xa3,0x2c,0xa1,0x2e,
1621 0x04,0x8b,0x06,0x89,0x80,0x0f,0x82,0x0d,
1622 0x04,0x8b,0x06,0x89,0x80,0x0f,0x82,0x0d,
1623 0xd3,0xd2,0x5c,0x5d,0x57,0x56,0xd8,0xd9,
1624 0xd3,0xd2,0x5c,0x5d,0x57,0x56,0xd8,0xd9,
1625 };
1626 UINT16*src= (UINT16*)memory_region( machine, "mainbios" );
1627 UINT16*buf= alloc_array_or_die(UINT16, 0x80000/2);
1628 int a,addr;
1629
1630 for (a=0;a<0x80000/2;a++)
1631 {
1632 if (src[a] & (0x0004 << (8*BYTE_XOR_LE(0)))) src[a] ^= 0x0001 << (8*BYTE_XOR_LE(0));
1633 if (src[a] & (0x0010 << (8*BYTE_XOR_LE(0)))) src[a] ^= 0x0002 << (8*BYTE_XOR_LE(0));
1634 if (src[a] & (0x0020 << (8*BYTE_XOR_LE(0)))) src[a] ^= 0x0008 << (8*BYTE_XOR_LE(0));
1635 //address xor
1636 addr = a & ~0xff;
1637 addr |= address[BYTE_XOR_LE(a & 0x7f)];
1638 if ( a & 0x00008) addr ^= 0x0008;
1639 if ( a & 0x00080) addr ^= 0x0080;
1640 if ( a & 0x00200) addr ^= 0x0100;
1641 if (~a & 0x02000) addr ^= 0x0400;
1642 if (~a & 0x10000) addr ^= 0x1000;
1643 if ( a & 0x02000) addr ^= 0x8000;
1644 buf[addr]=src[a];
1645 }
1646 memcpy(src,buf,0x80000);
1647 free(buf);
1648 }
1649
1650
1651