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