1 /***************************************************************************
2 
3 NeoGeo 'C' ROM encryption
4 
5 Starting with KOF99, all NeoGeo games have encrypted graphics. Additionally
6 to that, the data for the front text layer, which was previously stored in
7 a separate ROM, is stored at the end of the tile data.
8 
9 The encryption is one of the nastiest implementation of a XOR scheme ever
10 seen, involving 9 seemingly uncorrelated 256-byte tables. All known games use
11 the same tables except KOF2000 and MS4 which use a different set.
12 
13 The 32 data bits of every longword are decrypted in a single step (one byte at
14 a time), but the values to use for the xor are determined in a convoluted way.
15 It's actually so convoluted that it's too difficult to describe - please refer
16 to the source below.
17 Suffice to say that bytes are handled in couples (0&3 and 1&2), and the two xor
18 values are taken from three tables, the indexes inside the tables depending on
19 bits 0-7 and 8-15 of the address, in one case further xored through the table
20 used in step 5) below. Additionally, the bytes in a couple can be swapped,
21 depending either on bit 8 of the address, or on bit 16 xored with the table
22 used in step 4) below.
23 
24 The 24 address bits are encrypted in five steps. Each step xors 8 bits with a
25 value taken from a different table; the index inside the table depends on 8
26 other bits.
27 0) xor bits  0-7  with a fixed value that changes from game to game
28 1) xor bits  8-15 depending on bits 16-23
29 2) xor bits  8-15 depending on bits  0-7
30 3) xor bits 16-23 depending on bits  0-7
31 4) xor bits 16-23 depending on bits  8-15
32 5) xor bits  0-7  depending on bits  8-15
33 
34 Each step acts on the current value, so e.g. step 4) uses bits 8-15 as modified
35 by step 2).
36 
37 [Note: the table used in step 1) is currently incomplete due to lack of data to
38 analyze]
39 
40 
41 There are two major weaknesses in this encryption algorithm, that exposed it to
42 a known plaintext attack.
43 
44 The first weakness is that the data xor depends on the address inside the
45 encrypted ROM instead that on the decrypted address; together with the high
46 concentration of 0x00 and 0xFF in the decrypted data (more than 60% of the
47 total), this exposed easily recognizable patterns in the encrypted data, which
48 could be exploited with some simple statistical checks. The deviousness of the
49 xor scheme was the major difficulty.
50 
51 The second weakness is that the address scrambling works on 32-bit words. Since
52 there are a large number of 32-bit values that appear only once in the whole
53 encrypted ROM space, this means that once the xor layer was broken, a large
54 table of encrypted-decrypted address correspondencies could be built and
55 analyzed, quickly leading to the algorithm.
56 
57 ***************************************************************************/
58 
59 #include "driver.h"
60 #include "neogeo.h"
61 
62 
63 const unsigned char *type0_t03;
64 const unsigned char *type0_t12;
65 const unsigned char *type1_t03;
66 const unsigned char *type1_t12;
67 const unsigned char *address_8_15_xor1;
68 const unsigned char *address_8_15_xor2;
69 const unsigned char *address_16_23_xor1;
70 const unsigned char *address_16_23_xor2;
71 const unsigned char *address_0_7_xor;
72 
73 
74 const unsigned char kof99_type0_t03[256] =
75 {
76 	0xfb, 0x86, 0x9d, 0xf1, 0xbf, 0x80, 0xd5, 0x43, 0xab, 0xb3, 0x9f, 0x6a, 0x33, 0xd9, 0xdb, 0xb6,
77 	0x66, 0x08, 0x69, 0x88, 0xcc, 0xb7, 0xde, 0x49, 0x97, 0x64, 0x1f, 0xa6, 0xc0, 0x2f, 0x52, 0x42,
78 	0x44, 0x5a, 0xf2, 0x28, 0x98, 0x87, 0x96, 0x8a, 0x83, 0x0b, 0x03, 0x61, 0x71, 0x99, 0x6b, 0xb5,
79 	0x1a, 0x8e, 0xfe, 0x04, 0xe1, 0xf7, 0x7d, 0xdd, 0xed, 0xca, 0x37, 0xfc, 0xef, 0x39, 0x72, 0xda,
80 	0xb8, 0xbe, 0xee, 0x7f, 0xe5, 0x31, 0x78, 0xf3, 0x91, 0x9a, 0xd2, 0x11, 0x19, 0xb9, 0x09, 0x4c,
81 	0xfd, 0x6d, 0x2a, 0x4d, 0x65, 0xa1, 0x89, 0xc7, 0x75, 0x50, 0x21, 0xfa, 0x16, 0x00, 0xe9, 0x12,
82 	0x74, 0x2b, 0x1e, 0x4f, 0x14, 0x01, 0x70, 0x3a, 0x4e, 0x3f, 0xf5, 0xf4, 0x1d, 0x3d, 0x15, 0x27,
83 	0xa7, 0xff, 0x45, 0xe0, 0x6e, 0xf9, 0x54, 0xc8, 0x48, 0xad, 0xa5, 0x0a, 0xf6, 0x2d, 0x2c, 0xe2,
84 	0x68, 0x67, 0xd6, 0x85, 0xb4, 0xc3, 0x34, 0xbc, 0x62, 0xd3, 0x5f, 0x84, 0x06, 0x5b, 0x0d, 0x95,
85 	0xea, 0x5e, 0x9e, 0xd4, 0xeb, 0x90, 0x7a, 0x05, 0x81, 0x57, 0xe8, 0x60, 0x2e, 0x20, 0x25, 0x7c,
86 	0x46, 0x0c, 0x93, 0xcb, 0xbd, 0x17, 0x7e, 0xec, 0x79, 0xb2, 0xc2, 0x22, 0x41, 0xb1, 0x10, 0xac,
87 	0xa8, 0xbb, 0x9b, 0x82, 0x4b, 0x9c, 0x8b, 0x07, 0x47, 0x35, 0x24, 0x56, 0x8d, 0xaf, 0xe6, 0x26,
88 	0x40, 0x38, 0xc4, 0x5d, 0x1b, 0xc5, 0xd1, 0x0f, 0x6c, 0x7b, 0xb0, 0xe3, 0xa3, 0x23, 0x6f, 0x58,
89 	0xc1, 0xba, 0xcf, 0xd7, 0xa2, 0xe7, 0xd0, 0x63, 0x5c, 0xf8, 0x73, 0xa0, 0x13, 0xdc, 0x29, 0xcd,
90 	0xc9, 0x76, 0xae, 0x8f, 0xe4, 0x59, 0x30, 0xaa, 0x94, 0x1c, 0x3c, 0x0e, 0x55, 0x92, 0x77, 0x32,
91 	0xc6, 0xce, 0x18, 0x36, 0xdf, 0xa9, 0x8c, 0xd8, 0xa4, 0xf0, 0x3b, 0x51, 0x4a, 0x02, 0x3e, 0x53,
92 };
93 
94 const unsigned char kof99_type0_t12[256] =
95 {
96 	0x1f, 0xac, 0x4d, 0xcd, 0xca, 0x70, 0x02, 0x6b, 0x18, 0x40, 0x62, 0xb2, 0x3f, 0x9b, 0x5b, 0xef,
97 	0x69, 0x68, 0x71, 0x3b, 0xcb, 0xd4, 0x30, 0xbc, 0x47, 0x72, 0x74, 0x5e, 0x84, 0x4c, 0x1b, 0xdb,
98 	0x6a, 0x35, 0x1d, 0xf5, 0xa1, 0xb3, 0x87, 0x5d, 0x57, 0x28, 0x2f, 0xc4, 0xfd, 0x24, 0x26, 0x36,
99 	0xad, 0xbe, 0x61, 0x63, 0x73, 0xaa, 0x82, 0xee, 0x29, 0xd0, 0xdf, 0x8c, 0x15, 0xb5, 0x96, 0xf3,
100 	0xdd, 0x7e, 0x3a, 0x37, 0x58, 0x7f, 0x0c, 0xfc, 0x0b, 0x07, 0xe8, 0xf7, 0xf4, 0x14, 0xb8, 0x81,
101 	0xb6, 0xd7, 0x1e, 0xc8, 0x85, 0xe6, 0x9d, 0x33, 0x60, 0xc5, 0x95, 0xd5, 0x55, 0x00, 0xa3, 0xb7,
102 	0x7d, 0x50, 0x0d, 0xd2, 0xc1, 0x12, 0xe5, 0xed, 0xd8, 0xa4, 0x9c, 0x8f, 0x2a, 0x4f, 0xa8, 0x01,
103 	0x52, 0x83, 0x65, 0xea, 0x9a, 0x6c, 0x44, 0x4a, 0xe2, 0xa5, 0x2b, 0x46, 0xe1, 0x34, 0x25, 0xf8,
104 	0xc3, 0xda, 0xc7, 0x6e, 0x48, 0x38, 0x7c, 0x78, 0x06, 0x53, 0x64, 0x16, 0x98, 0x3c, 0x91, 0x42,
105 	0x39, 0xcc, 0xb0, 0xf1, 0xeb, 0x13, 0xbb, 0x05, 0x32, 0x86, 0x0e, 0xa2, 0x0a, 0x9e, 0xfa, 0x66,
106 	0x54, 0x8e, 0xd3, 0xe7, 0x19, 0x20, 0x77, 0xec, 0xff, 0xbd, 0x6d, 0x43, 0x23, 0x03, 0xab, 0x75,
107 	0x3d, 0xcf, 0xd1, 0xde, 0x92, 0x31, 0xa7, 0x45, 0x4b, 0xc2, 0x97, 0xf9, 0x7a, 0x88, 0xd9, 0x1c,
108 	0xe9, 0xe4, 0x10, 0xc9, 0x22, 0x2d, 0x90, 0x76, 0x17, 0x79, 0x04, 0x51, 0x1a, 0x5a, 0x5f, 0x2c,
109 	0x21, 0x6f, 0x3e, 0xe0, 0xf0, 0xbf, 0xd6, 0x94, 0x0f, 0x80, 0x11, 0xa0, 0x5c, 0xa9, 0x49, 0x2e,
110 	0xce, 0xaf, 0xa6, 0x9f, 0x7b, 0x99, 0xb9, 0xb4, 0xe3, 0xfb, 0xf6, 0x27, 0xf2, 0x93, 0xfe, 0x08,
111 	0x67, 0xae, 0x09, 0x89, 0xdc, 0x4e, 0xc6, 0xc0, 0x8a, 0xb1, 0x59, 0x8b, 0x41, 0x56, 0x8d, 0xba,
112 };
113 
114 const unsigned char kof99_type1_t03[256] =
115 {
116 	0xa9, 0x17, 0xaf, 0x0d, 0x34, 0x6e, 0x53, 0xb6, 0x7f, 0x58, 0xe9, 0x14, 0x5f, 0x55, 0xdb, 0xd4,
117 	0x42, 0x80, 0x99, 0x59, 0xa8, 0x3a, 0x57, 0x5d, 0xd5, 0x6f, 0x4c, 0x68, 0x35, 0x46, 0xa6, 0xe7,
118 	0x7b, 0x71, 0xe0, 0x93, 0xa2, 0x1f, 0x64, 0x21, 0xe3, 0xb1, 0x98, 0x26, 0xab, 0xad, 0xee, 0xe5,
119 	0xbb, 0xd9, 0x1e, 0x2e, 0x95, 0x36, 0xef, 0x23, 0x79, 0x45, 0x04, 0xed, 0x13, 0x1d, 0xf4, 0x85,
120 	0x96, 0xec, 0xc2, 0x32, 0xaa, 0x7c, 0x15, 0xd8, 0xda, 0x92, 0x90, 0x9d, 0xb7, 0x56, 0x6a, 0x66,
121 	0x41, 0xfc, 0x00, 0xf6, 0x50, 0x24, 0xcf, 0xfb, 0x11, 0xfe, 0x82, 0x48, 0x9b, 0x27, 0x1b, 0x67,
122 	0x4e, 0x84, 0x69, 0x97, 0x6d, 0x8c, 0xd2, 0xba, 0x74, 0xf9, 0x8f, 0xa5, 0x54, 0x5c, 0xcd, 0x73,
123 	0x07, 0xd1, 0x01, 0x09, 0xf1, 0x19, 0x3b, 0x5e, 0x87, 0x30, 0x76, 0xcc, 0xc0, 0x5a, 0xa7, 0x49,
124 	0x22, 0xfa, 0x16, 0x02, 0xdf, 0xa4, 0xff, 0xb3, 0x75, 0x33, 0xbd, 0x88, 0x2f, 0xcb, 0x2a, 0x44,
125 	0xb8, 0xbf, 0x1c, 0x0f, 0x81, 0x10, 0x43, 0xb4, 0xc8, 0x7e, 0x9a, 0x25, 0xea, 0x83, 0x4b, 0x38,
126 	0x7a, 0xd7, 0x3d, 0x1a, 0x4f, 0x62, 0x51, 0xc9, 0x47, 0x0e, 0xce, 0x3f, 0xc7, 0x4d, 0x2c, 0xa1,
127 	0x86, 0xb9, 0xc5, 0xca, 0xdd, 0x6b, 0x70, 0x6c, 0x91, 0x9c, 0xbe, 0x0a, 0x9f, 0xf5, 0x94, 0xbc,
128 	0x18, 0x2b, 0x60, 0x20, 0x29, 0xf7, 0xf2, 0x28, 0xc4, 0xa0, 0x0b, 0x65, 0xde, 0x8d, 0x78, 0x12,
129 	0x3e, 0xd0, 0x77, 0x08, 0x8b, 0xae, 0x05, 0x31, 0x3c, 0xd6, 0xa3, 0x89, 0x06, 0xdc, 0x52, 0x72,
130 	0xb0, 0xb5, 0x37, 0xd3, 0xc3, 0x8a, 0xc6, 0xf0, 0xc1, 0x61, 0xfd, 0x4a, 0x5b, 0x7d, 0x9e, 0xf3,
131 	0x63, 0x40, 0x2d, 0xe8, 0xb2, 0xe6, 0x39, 0x03, 0xeb, 0x8e, 0xe1, 0x0c, 0xe4, 0xe2, 0xf8, 0xac,
132 };
133 
134 const unsigned char kof99_type1_t12[256] =
135 {
136 	0xea, 0xe6, 0x5e, 0xa7, 0x8e, 0xac, 0x34, 0x03, 0x30, 0x97, 0x52, 0x53, 0x76, 0xf2, 0x62, 0x0b,
137 	0x0a, 0xfc, 0x94, 0xb8, 0x67, 0x36, 0x11, 0xbc, 0xae, 0xca, 0xfa, 0x15, 0x04, 0x2b, 0x17, 0xc4,
138 	0x3e, 0x5b, 0x59, 0x01, 0x57, 0xe2, 0xba, 0xb7, 0xd1, 0x3f, 0xf0, 0x6a, 0x9c, 0x2a, 0xcb, 0xa9,
139 	0xe3, 0x2c, 0xc0, 0x0f, 0x46, 0x91, 0x8a, 0xd0, 0x98, 0xc5, 0xa6, 0x1b, 0x96, 0x29, 0x12, 0x09,
140 	0x63, 0xed, 0xe0, 0xa2, 0x86, 0x77, 0xbe, 0xe5, 0x65, 0xdb, 0xbd, 0x50, 0xb3, 0x9d, 0x1a, 0x4e,
141 	0x79, 0x0c, 0x00, 0x43, 0xdf, 0x3d, 0x54, 0x33, 0x8f, 0x89, 0xa8, 0x7b, 0xf9, 0xd5, 0x27, 0x82,
142 	0xbb, 0xc2, 0x8c, 0x47, 0x88, 0x6b, 0xb4, 0xc3, 0xf8, 0xaa, 0x06, 0x1e, 0x83, 0x7d, 0x05, 0x78,
143 	0x85, 0xf6, 0x6e, 0x2e, 0xec, 0x5a, 0x31, 0x45, 0x38, 0x14, 0x16, 0x8b, 0x02, 0xe4, 0x4f, 0xb0,
144 	0xbf, 0xab, 0xa4, 0x9e, 0x48, 0x60, 0x19, 0x35, 0x08, 0xde, 0xdd, 0x66, 0x90, 0x51, 0xcc, 0xa3,
145 	0xaf, 0x70, 0x9b, 0x75, 0x95, 0x49, 0x6c, 0x64, 0x72, 0x7e, 0x44, 0xa0, 0x73, 0x25, 0x68, 0x55,
146 	0x1f, 0x40, 0x7a, 0x74, 0x0e, 0x8d, 0xdc, 0x1c, 0x71, 0xc8, 0xcf, 0xd7, 0xe8, 0xce, 0xeb, 0x32,
147 	0x3a, 0xee, 0x07, 0x61, 0x4d, 0xfe, 0x5c, 0x7c, 0x56, 0x2f, 0x2d, 0x5f, 0x6f, 0x9f, 0x81, 0x22,
148 	0x58, 0x4b, 0xad, 0xda, 0xb9, 0x10, 0x18, 0x23, 0xe1, 0xf3, 0x6d, 0xe7, 0xe9, 0x28, 0xd6, 0xd8,
149 	0xf4, 0x4c, 0x39, 0x21, 0xb2, 0x84, 0xc1, 0x24, 0x26, 0xf1, 0x93, 0x37, 0xc6, 0x4a, 0xcd, 0x20,
150 	0xc9, 0xd9, 0xc7, 0xb1, 0xff, 0x99, 0xd4, 0x5d, 0xb5, 0xa1, 0x87, 0x0d, 0x69, 0x92, 0x13, 0x80,
151 	0xd2, 0xd3, 0xfd, 0x1d, 0xf5, 0x3b, 0xa5, 0x7f, 0xef, 0x9a, 0xb6, 0x42, 0xfb, 0x3c, 0xf7, 0x41,
152 };
153 
154 
155 
156 /* underlined values are wrong (not enough evidence, FF fill in kof99 and garou) */
157 /* they correspond to tiles 7d000-7efff */
158 const unsigned char kof99_address_8_15_xor1[256] =
159 {
160 	0x00, 0xb1, 0x1e, 0xc5, 0x3d, 0x40, 0x45, 0x5e, 0xf2, 0xf8, 0x04, 0x63, 0x36, 0x87, 0x88, 0xbf,
161 	0xab, 0xcc, 0x78, 0x08, 0xdd, 0x20, 0xd4, 0x35, 0x09, 0x8e, 0x44, 0xae, 0x33, 0xa9, 0x9e, 0xcd,
162 	0xb3, 0xe5, 0xad, 0x41, 0xda, 0xbe, 0xf4, 0x16, 0x57, 0x2e, 0x53, 0x67, 0xaf, 0xdb, 0x8a, 0xd8,
163 	0x34, 0x17, 0x3c, 0x01, 0x55, 0x73, 0xcf, 0xe3, 0xe8, 0xc7, 0x0d, 0xe9, 0xa3, 0x13, 0x0c, 0xf6,
164 	0x90, 0x4e, 0xfb, 0x97, 0x6d, 0x5f, 0xa8, 0x71, 0x11, 0xfc, 0xd1, 0x95, 0x81, 0xba, 0x8c, 0x1b,
165 	0x39, 0xfe, 0xa2, 0x15, 0xa6, 0x52, 0x4d, 0x5b, 0x59, 0xa5, 0xe0, 0x96, 0xd9, 0x8f, 0x7b, 0xed,
166 	0x29, 0xd3, 0x1f, 0x0e, 0xec, 0x23, 0x0f, 0xb8, 0x6c, 0x6f, 0x7d, 0x18, 0x46, 0xd6, 0xe4, 0xb5,
167 	0x9a, 0x79, 0x02, 0xf5, 0x03, 0xc0, 0x60, 0x66, 0x5c, 0x2f, 0x76, 0x85, 0x9d, 0x54, 0x1a, 0x6a,
168 	0x28, 0xce, 0x7f, 0x7c, 0x91, 0x99, 0x4c, 0x83, 0x3e, 0xb4, 0x1d, 0x05, 0xc1, 0xc3, 0xd7, 0x47,
169 	0xde, 0xbc, 0x62, 0x6e, 0x86, 0x14, 0x80, 0x77, 0xeb, 0xf3, 0x07, 0x31, 0x56, 0xd2, 0xc2, 0xc6,
170 	0x6b, 0xdc, 0xfd, 0x22, 0x92, 0xf0, 0x06, 0x51, 0x2d, 0x38, 0xe6, 0xa0, 0x25, 0xdf, 0xd5, 0x2c,
171 	0x1c, 0x94, 0x12, 0x9c, 0xb0, 0x9b, 0xc4, 0x0b, 0xc8, 0xd0, 0xf7, 0x30, 0xcb, 0x27, 0xfa, 0x7a,
172 	0x10, 0x61, 0xaa, 0xa4, 0x70, 0xb7, 0x2a, 0x5a, 0xc9, 0xf1, 0x0a, 0x49, 0x65, 0xee, 0x69, 0x4b,
173 	0x3a, 0x8d, 0x32, 0x5d, 0x68, 0xb9, 0x9f, 0x75, 0x19, 0x3f, 0xac, 0x37, 0x4f, 0xe7, 0x93, 0x89,
174 	0x7e, 0x4a, 0x3b, 0xea, 0x74, 0x72, 0x43, 0xbd, 0x24, 0xef, 0xb6, 0xff, 0x64, 0x58, 0x84, 0x8b,
175 	0xa7, 0xbb, 0xb2, 0xe1, 0x26, 0x2b, 0x50, 0xca, 0x21, 0xf9, 0x98, 0xa1, 0xe2, 0x42, 0x82, 0x48,
176 /*	                                                            ^^^^  ^^^^  ^^^^  ^^^^*/
177 };
178 
179 const unsigned char kof99_address_8_15_xor2[256] =
180 {
181 	0x9b, 0x9d, 0xc1, 0x3d, 0xa9, 0xb8, 0xf4, 0x6f, 0xf6, 0x25, 0xc7, 0x47, 0xd5, 0x97, 0xdf, 0x6b,
182 	0xeb, 0x90, 0xa4, 0xb2, 0x5d, 0xf5, 0x66, 0xb0, 0xb9, 0x8b, 0x93, 0x64, 0xec, 0x7b, 0x65, 0x8c,
183 	0xf1, 0x43, 0x42, 0x6e, 0x45, 0x9f, 0xb3, 0x35, 0x06, 0x71, 0x96, 0xdb, 0xa0, 0xfb, 0x0b, 0x3a,
184 	0x1f, 0xf8, 0x8e, 0x69, 0xcd, 0x26, 0xab, 0x86, 0xa2, 0x0c, 0xbd, 0x63, 0xa5, 0x7a, 0xe7, 0x6a,
185 	0x5f, 0x18, 0x9e, 0xbf, 0xad, 0x55, 0xb1, 0x1c, 0x5c, 0x03, 0x30, 0xc6, 0x37, 0x20, 0xe3, 0xc9,
186 	0x52, 0xe8, 0xee, 0x4f, 0x01, 0x70, 0xc4, 0x77, 0x29, 0x2a, 0xba, 0x53, 0x12, 0x04, 0x7d, 0xaf,
187 	0x33, 0x8f, 0xa8, 0x4d, 0xaa, 0x5b, 0xb4, 0x0f, 0x92, 0xbb, 0xed, 0xe1, 0x2f, 0x50, 0x6c, 0xd2,
188 	0x2c, 0x95, 0xd9, 0xf9, 0x98, 0xc3, 0x76, 0x4c, 0xf2, 0xe4, 0xe5, 0x2b, 0xef, 0x9c, 0x49, 0xb6,
189 	0x31, 0x3b, 0xbc, 0xa1, 0xca, 0xde, 0x62, 0x74, 0xea, 0x81, 0x00, 0xdd, 0xa6, 0x46, 0x88, 0x3f,
190 	0x39, 0xd6, 0x23, 0x54, 0x24, 0x4a, 0xd8, 0xdc, 0xd7, 0xd1, 0xcc, 0xbe, 0x57, 0x7c, 0xda, 0x44,
191 	0x61, 0xce, 0xd3, 0xd4, 0xe9, 0x28, 0x80, 0xe0, 0x56, 0x8a, 0x09, 0x05, 0x9a, 0x89, 0x1b, 0xf7,
192 	0xf3, 0x99, 0x6d, 0x5e, 0x48, 0x91, 0xc0, 0xd0, 0xc5, 0x79, 0x78, 0x41, 0x59, 0x21, 0x2e, 0xff,
193 	0xc2, 0x4b, 0x38, 0x83, 0x32, 0xe6, 0xe2, 0x7f, 0x1e, 0x17, 0x58, 0x1d, 0x1a, 0xfa, 0x85, 0x82,
194 	0x94, 0xc8, 0x72, 0x7e, 0xb7, 0xac, 0x0e, 0xfc, 0xfd, 0x16, 0x27, 0x75, 0x8d, 0xcb, 0x08, 0xfe,
195 	0x0a, 0x02, 0x0d, 0x36, 0x11, 0x22, 0x84, 0x40, 0x34, 0x3e, 0x2d, 0x68, 0x5a, 0xa7, 0x67, 0xae,
196 	0x87, 0x07, 0x10, 0x60, 0x14, 0x73, 0x3c, 0x51, 0x19, 0xa3, 0xb5, 0xcf, 0x13, 0xf0, 0x15, 0x4e,
197 };
198 
199 const unsigned char kof99_address_16_23_xor1[256] =
200 {
201 	0x00, 0x5f, 0x03, 0x52, 0xce, 0xe3, 0x7d, 0x8f, 0x6b, 0xf8, 0x20, 0xde, 0x7b, 0x7e, 0x39, 0xbe,
202 	0xf5, 0x94, 0x18, 0x78, 0x80, 0xc9, 0x7f, 0x7a, 0x3e, 0x63, 0xf2, 0xe0, 0x4e, 0xf7, 0x87, 0x27,
203 	0x69, 0x6c, 0xa4, 0x1d, 0x85, 0x5b, 0xe6, 0x44, 0x25, 0x0c, 0x98, 0xc7, 0x01, 0x02, 0xa3, 0x26,
204 	0x09, 0x38, 0xdb, 0xc3, 0x1e, 0xcf, 0x23, 0x45, 0x68, 0x76, 0xd6, 0x22, 0x5d, 0x5a, 0xae, 0x16,
205 	0x9f, 0xa2, 0xb5, 0xcd, 0x81, 0xea, 0x5e, 0xb8, 0xb9, 0x9d, 0x9c, 0x1a, 0x0f, 0xff, 0xe1, 0xe7,
206 	0x74, 0xaa, 0xd4, 0xaf, 0xfc, 0xc6, 0x33, 0x29, 0x5c, 0xab, 0x95, 0xf0, 0x19, 0x47, 0x59, 0x67,
207 	0xf3, 0x96, 0x60, 0x1f, 0x62, 0x92, 0xbd, 0x89, 0xee, 0x28, 0x13, 0x06, 0xfe, 0xfa, 0x32, 0x6d,
208 	0x57, 0x3c, 0x54, 0x50, 0x2c, 0x58, 0x49, 0xfb, 0x17, 0xcc, 0xef, 0xb2, 0xb4, 0xf9, 0x07, 0x70,
209 	0xc5, 0xa9, 0xdf, 0xd5, 0x3b, 0x86, 0x2b, 0x0d, 0x6e, 0x4d, 0x0a, 0x90, 0x43, 0x31, 0xc1, 0xf6,
210 	0x88, 0x0b, 0xda, 0x53, 0x14, 0xdc, 0x75, 0x8e, 0xb0, 0xeb, 0x99, 0x46, 0xa1, 0x15, 0x71, 0xc8,
211 	0xe9, 0x3f, 0x4a, 0xd9, 0x73, 0xe5, 0x7c, 0x30, 0x77, 0xd3, 0xb3, 0x4b, 0x37, 0x72, 0xc2, 0x04,
212 	0x97, 0x08, 0x36, 0xb1, 0x3a, 0x61, 0xec, 0xe2, 0x1c, 0x9a, 0x8b, 0xd1, 0x1b, 0x2e, 0x9e, 0x8a,
213 	0xd8, 0x41, 0xe4, 0xc4, 0x40, 0x2f, 0xad, 0xc0, 0xb6, 0x84, 0x51, 0x66, 0xbb, 0x12, 0xe8, 0xdd,
214 	0xcb, 0xbc, 0x6f, 0xd0, 0x11, 0x83, 0x56, 0x4c, 0xca, 0xbf, 0x05, 0x10, 0xd7, 0xba, 0xfd, 0xed,
215 	0x8c, 0x0e, 0x4f, 0x3d, 0x35, 0x91, 0xb7, 0xac, 0x34, 0x64, 0x2a, 0xf1, 0x79, 0x6a, 0x9b, 0x2d,
216 	0x65, 0xf4, 0x42, 0xa0, 0x8d, 0xa7, 0x48, 0x55, 0x21, 0x93, 0x24, 0xd2, 0xa6, 0xa5, 0xa8, 0x82,
217 };
218 
219 const unsigned char kof99_address_16_23_xor2[256] =
220 {
221 	0x29, 0x97, 0x1a, 0x2c, 0x0b, 0x94, 0x3e, 0x75, 0x01, 0x0d, 0x1b, 0xe1, 0x4d, 0x38, 0x39, 0x8f,
222 	0xe7, 0xd0, 0x60, 0x90, 0xb2, 0x0f, 0xbb, 0x70, 0x1f, 0xe6, 0x5b, 0x87, 0xb4, 0x43, 0xfd, 0xf5,
223 	0xf6, 0xf9, 0xad, 0xc0, 0x98, 0x17, 0x9f, 0x91, 0x15, 0x51, 0x55, 0x64, 0x6c, 0x18, 0x61, 0x0e,
224 	0xd9, 0x93, 0xab, 0xd6, 0x24, 0x2f, 0x6a, 0x3a, 0x22, 0xb1, 0x4f, 0xaa, 0x23, 0x48, 0xed, 0xb9,
225 	0x88, 0x8b, 0xa3, 0x6b, 0x26, 0x4c, 0xe8, 0x2d, 0x1c, 0x99, 0xbd, 0x5c, 0x58, 0x08, 0x50, 0xf2,
226 	0x2a, 0x62, 0xc1, 0x72, 0x66, 0x04, 0x10, 0x37, 0x6e, 0xfc, 0x44, 0xa9, 0xdf, 0xd4, 0x20, 0xdd,
227 	0xee, 0x41, 0xdb, 0x73, 0xde, 0x54, 0xec, 0xc9, 0xf3, 0x4b, 0x2e, 0xae, 0x5a, 0x4a, 0x5e, 0x47,
228 	0x07, 0x2b, 0x76, 0xa4, 0xe3, 0x28, 0xfe, 0xb0, 0xf0, 0x02, 0x06, 0xd1, 0xaf, 0x42, 0xc2, 0xa5,
229 	0xe0, 0x67, 0xbf, 0x16, 0x8e, 0x35, 0xce, 0x8a, 0xe5, 0x3d, 0x7b, 0x96, 0xd7, 0x79, 0x52, 0x1e,
230 	0xa1, 0xfb, 0x9b, 0xbe, 0x21, 0x9c, 0xe9, 0x56, 0x14, 0x7f, 0xa0, 0xe4, 0xc3, 0xc4, 0x46, 0xea,
231 	0xf7, 0xd2, 0x1d, 0x31, 0x0a, 0x5f, 0xeb, 0xa2, 0x68, 0x8d, 0xb5, 0xc5, 0x74, 0x0c, 0xdc, 0x82,
232 	0x80, 0x09, 0x19, 0x95, 0x71, 0x9a, 0x11, 0x57, 0x77, 0x4e, 0xc6, 0xff, 0x12, 0x03, 0xa7, 0xc7,
233 	0xf4, 0xc8, 0xb6, 0x7a, 0x59, 0x36, 0x3c, 0x53, 0xe2, 0x69, 0x8c, 0x25, 0x05, 0x45, 0x63, 0xf8,
234 	0x34, 0x89, 0x33, 0x3f, 0x85, 0x27, 0xbc, 0x65, 0xfa, 0xa8, 0x6d, 0x84, 0x5d, 0xba, 0x40, 0x32,
235 	0x30, 0xef, 0x83, 0x13, 0xa6, 0x78, 0xcc, 0x81, 0x9e, 0xda, 0xca, 0xd3, 0x7e, 0x9d, 0x6f, 0xcd,
236 	0xb7, 0xb3, 0xd8, 0xcf, 0x3b, 0x00, 0x92, 0xb8, 0x86, 0xac, 0x49, 0x7c, 0xf1, 0xd5, 0xcb, 0x7d,
237 };
238 
239 const unsigned char kof99_address_0_7_xor[256] =
240 {
241 	0x74, 0xad, 0x5d, 0x1d, 0x9e, 0xc3, 0xfa, 0x4e, 0xf7, 0xdb, 0xca, 0xa2, 0x64, 0x36, 0x56, 0x0c,
242 	0x4f, 0xcf, 0x43, 0x66, 0x1e, 0x91, 0xe3, 0xa5, 0x58, 0xc2, 0xc1, 0xd4, 0xb9, 0xdd, 0x76, 0x16,
243 	0xce, 0x61, 0x75, 0x01, 0x2b, 0x22, 0x38, 0x55, 0x50, 0xef, 0x6c, 0x99, 0x05, 0xe9, 0xe8, 0xe0,
244 	0x2d, 0xa4, 0x4b, 0x4a, 0x42, 0xae, 0xba, 0x8c, 0x6f, 0x93, 0x14, 0xbd, 0x71, 0x21, 0xb0, 0x02,
245 	0x15, 0xc4, 0xe6, 0x60, 0xd7, 0x44, 0xfd, 0x85, 0x7e, 0x78, 0x8f, 0x00, 0x81, 0xf1, 0xa7, 0x3b,
246 	0xa0, 0x10, 0xf4, 0x9f, 0x39, 0x88, 0x35, 0x62, 0xcb, 0x19, 0x31, 0x11, 0x51, 0xfb, 0x2a, 0x20,
247 	0x45, 0xd3, 0x7d, 0x92, 0x1b, 0xf2, 0x09, 0x0d, 0x97, 0xa9, 0xb5, 0x3c, 0xee, 0x5c, 0xaf, 0x7b,
248 	0xd2, 0x3a, 0x49, 0x8e, 0xb6, 0xcd, 0xd9, 0xde, 0x8a, 0x29, 0x6e, 0xd8, 0x0b, 0xe1, 0x69, 0x87,
249 	0x1a, 0x96, 0x18, 0xcc, 0xdf, 0xe7, 0xc5, 0xc7, 0xf8, 0x52, 0xc9, 0xf0, 0xb7, 0xe5, 0x33, 0xda,
250 	0x67, 0x9d, 0xa3, 0x03, 0x0e, 0x72, 0x26, 0x79, 0xe2, 0xb8, 0xfc, 0xaa, 0xfe, 0xb4, 0x86, 0xc8,
251 	0xd1, 0xbc, 0x12, 0x08, 0x77, 0xeb, 0x40, 0x8d, 0x04, 0x25, 0x4d, 0x5a, 0x6a, 0x7a, 0x2e, 0x41,
252 	0x65, 0x1c, 0x13, 0x94, 0xb2, 0x63, 0x28, 0x59, 0x5e, 0x9a, 0x30, 0x07, 0xc6, 0xbf, 0x17, 0xf5,
253 	0x0f, 0x89, 0xf3, 0x1f, 0xea, 0x6d, 0xb3, 0xc0, 0x70, 0x47, 0xf9, 0x53, 0xf6, 0xd6, 0x54, 0xed,
254 	0x6b, 0x4c, 0xe4, 0x8b, 0x83, 0x24, 0x90, 0xb1, 0x7c, 0xbb, 0x73, 0xab, 0xd5, 0x2f, 0x5f, 0xec,
255 	0x9c, 0x2c, 0xa8, 0x34, 0x46, 0x37, 0x27, 0xa1, 0x0a, 0x06, 0x80, 0x68, 0x82, 0x32, 0x84, 0xff,
256 	0x48, 0xac, 0x7f, 0x3f, 0x95, 0xdc, 0x98, 0x9b, 0xbe, 0x23, 0x57, 0x3e, 0x5b, 0xd0, 0x3d, 0xa6,
257 };
258 
259 
260 
261 
262 
263 
264 const unsigned char kof2000_type0_t03[256] =
265 {
266 	0x10, 0x61, 0xf1, 0x78, 0x85, 0x52, 0x68, 0xe3, 0x12, 0x0d, 0xfa, 0xf0, 0xc9, 0x36, 0x5e, 0x3d,
267 	0xf9, 0xa6, 0x01, 0x2e, 0xc7, 0x84, 0xea, 0x2b, 0x6d, 0x14, 0x38, 0x4f, 0x55, 0x1c, 0x9d, 0xa7,
268 	0x7a, 0xc6, 0xf8, 0x9a, 0xe6, 0x42, 0xb5, 0xed, 0x7d, 0x3a, 0xb1, 0x05, 0x43, 0x4a, 0x22, 0xfd,
269 	0xac, 0xa4, 0x31, 0xc3, 0x32, 0x76, 0x95, 0x9e, 0x7e, 0x88, 0x8e, 0xa2, 0x97, 0x18, 0xbe, 0x2a,
270 	0xf5, 0xd6, 0xca, 0xcc, 0x72, 0x3b, 0x87, 0x6c, 0xde, 0x75, 0xd7, 0x21, 0xcb, 0x0b, 0xdd, 0xe7,
271 	0xe1, 0x65, 0xaa, 0xb9, 0x44, 0xfb, 0x66, 0x15, 0x1a, 0x3c, 0x98, 0xcf, 0x8a, 0xdf, 0x37, 0xa5,
272 	0x2f, 0x67, 0xd2, 0x83, 0xb6, 0x6b, 0xfc, 0xe0, 0xb4, 0x7c, 0x08, 0xdc, 0x93, 0x30, 0xab, 0xe4,
273 	0x19, 0xc2, 0x8b, 0xeb, 0xa0, 0x0a, 0xc8, 0x03, 0xc0, 0x4b, 0x64, 0x71, 0x86, 0x9c, 0x9b, 0x16,
274 	0x79, 0xff, 0x70, 0x09, 0x8c, 0xd0, 0xf6, 0x53, 0x07, 0x73, 0xd4, 0x89, 0xb3, 0x00, 0xe9, 0xfe,
275 	0xec, 0x8f, 0xbc, 0xb2, 0x1e, 0x5d, 0x11, 0x35, 0xa9, 0x06, 0x59, 0x9f, 0xc1, 0xd3, 0x7b, 0xf2,
276 	0xc5, 0x77, 0x4e, 0x39, 0x20, 0xd5, 0x6a, 0x82, 0xda, 0x45, 0xf3, 0x33, 0x81, 0x23, 0xba, 0xe2,
277 	0x1d, 0x5f, 0x5c, 0x51, 0x49, 0xae, 0x8d, 0xc4, 0xa8, 0xf7, 0x1f, 0x0f, 0x34, 0x28, 0xa1, 0xd9,
278 	0x27, 0xd8, 0x4c, 0x2c, 0xbf, 0x91, 0x3e, 0x69, 0x57, 0x41, 0x25, 0x0c, 0x5a, 0x90, 0x92, 0xb0,
279 	0x63, 0x6f, 0x40, 0xaf, 0x74, 0xb8, 0x2d, 0x80, 0xbb, 0x46, 0x94, 0xe5, 0x29, 0xee, 0xb7, 0x1b,
280 	0x96, 0xad, 0x13, 0x0e, 0x58, 0x99, 0x60, 0x4d, 0x17, 0x26, 0xce, 0xe8, 0xdb, 0xef, 0x24, 0xa3,
281 	0x6e, 0x7f, 0x54, 0x3f, 0x02, 0xd1, 0x5b, 0x50, 0x56, 0x48, 0xf4, 0xbd, 0x62, 0x47, 0x04, 0xcd,
282 };
283 
284 const unsigned char kof2000_type0_t12[256] =
285 {
286 	0xf4, 0x28, 0xb4, 0x8f, 0xfa, 0xeb, 0x8e, 0x54, 0x2b, 0x49, 0xd1, 0x76, 0x71, 0x47, 0x8b, 0x57,
287 	0x92, 0x85, 0x7c, 0xb8, 0x5c, 0x22, 0xf9, 0x26, 0xbc, 0x5b, 0x6d, 0x67, 0xae, 0x5f, 0x6f, 0xf5,
288 	0x9f, 0x48, 0x66, 0x40, 0x0d, 0x11, 0x4e, 0xb2, 0x6b, 0x35, 0x15, 0x0f, 0x18, 0x25, 0x1d, 0xba,
289 	0xd3, 0x69, 0x79, 0xec, 0xa8, 0x8c, 0xc9, 0x7f, 0x4b, 0xdb, 0x51, 0xaf, 0xca, 0xe2, 0xb3, 0x81,
290 	0x12, 0x5e, 0x7e, 0x38, 0xc8, 0x95, 0x01, 0xff, 0xfd, 0xfb, 0xf2, 0x74, 0x62, 0x14, 0xa5, 0x98,
291 	0xa6, 0xda, 0x80, 0x53, 0xe8, 0x56, 0xac, 0x1b, 0x52, 0xd0, 0xf1, 0x45, 0x42, 0xb6, 0x1a, 0x4a,
292 	0x3a, 0x99, 0xfc, 0xd2, 0x9c, 0xcf, 0x31, 0x2d, 0xdd, 0x86, 0x2f, 0x29, 0xe1, 0x03, 0x19, 0xa2,
293 	0x41, 0x33, 0x83, 0x90, 0xc1, 0xbf, 0x0b, 0x08, 0x3d, 0xd8, 0x8d, 0x6c, 0x39, 0xa0, 0xe3, 0x55,
294 	0x02, 0x50, 0x46, 0xe6, 0xc3, 0x82, 0x36, 0x13, 0x75, 0xab, 0x27, 0xd7, 0x1f, 0x0a, 0xd4, 0x89,
295 	0x59, 0x4f, 0xc0, 0x5d, 0xc6, 0xf7, 0x88, 0xbd, 0x3c, 0x00, 0xef, 0xcd, 0x05, 0x1c, 0xaa, 0x9b,
296 	0xed, 0x7a, 0x61, 0x17, 0x93, 0xfe, 0x23, 0xb9, 0xf3, 0x68, 0x78, 0xf6, 0x5a, 0x7b, 0xe0, 0xe4,
297 	0xa3, 0xee, 0x16, 0x72, 0xc7, 0x3b, 0x8a, 0x37, 0x2a, 0x70, 0xa9, 0x2c, 0x21, 0xf8, 0x24, 0x09,
298 	0xce, 0x20, 0x9e, 0x06, 0x87, 0xc5, 0x04, 0x64, 0x43, 0x7d, 0x4d, 0x10, 0xd6, 0xa4, 0x94, 0x4c,
299 	0x60, 0xde, 0xdf, 0x58, 0xb1, 0x44, 0x3f, 0xb0, 0xd9, 0xe5, 0xcb, 0xbb, 0xbe, 0xea, 0x07, 0x34,
300 	0x73, 0x6a, 0x77, 0xf0, 0x9d, 0x0c, 0x2e, 0x0e, 0x91, 0x9a, 0xcc, 0xc2, 0xb7, 0x63, 0x97, 0xd5,
301 	0xdc, 0xc4, 0x32, 0xe7, 0x84, 0x3e, 0x30, 0xa1, 0x1e, 0xb5, 0x6e, 0x65, 0xe9, 0xad, 0xa7, 0x96,
302 };
303 
304 const unsigned char kof2000_type1_t03[256] =
305 {
306 	0x9a, 0x2f, 0xcc, 0x4e, 0x40, 0x69, 0xac, 0xca, 0xa5, 0x7b, 0x0a, 0x61, 0x91, 0x0d, 0x55, 0x74,
307 	0xcd, 0x8b, 0x0b, 0x80, 0x09, 0x5e, 0x38, 0xc7, 0xda, 0xbf, 0xf5, 0x37, 0x23, 0x31, 0x33, 0xe9,
308 	0xae, 0x87, 0xe5, 0xfa, 0x6e, 0x5c, 0xad, 0xf4, 0x76, 0x62, 0x9f, 0x2e, 0x01, 0xe2, 0xf6, 0x47,
309 	0x8c, 0x7c, 0xaa, 0x98, 0xb5, 0x92, 0x51, 0xec, 0x5f, 0x07, 0x5d, 0x6f, 0x16, 0xa1, 0x1d, 0xa9,
310 	0x48, 0x45, 0xf0, 0x6a, 0x9c, 0x1e, 0x11, 0xa0, 0x06, 0x46, 0xd5, 0xf1, 0x73, 0xed, 0x94, 0xf7,
311 	0xc3, 0x57, 0x1b, 0xe0, 0x97, 0xb1, 0xa4, 0xa7, 0x24, 0xe7, 0x2b, 0x05, 0x5b, 0x34, 0x0c, 0xb8,
312 	0x0f, 0x9b, 0xc8, 0x4d, 0x5a, 0xa6, 0x86, 0x3e, 0x14, 0x29, 0x84, 0x58, 0x90, 0xdb, 0x2d, 0x54,
313 	0x9d, 0x82, 0xd4, 0x7d, 0xc6, 0x67, 0x41, 0x89, 0xc1, 0x13, 0xb0, 0x9e, 0x81, 0x6d, 0xa8, 0x59,
314 	0xbd, 0x39, 0x8e, 0xe6, 0x25, 0x8f, 0xd9, 0xa2, 0xe4, 0x53, 0xc5, 0x72, 0x7e, 0x36, 0x4a, 0x4f,
315 	0x52, 0xc2, 0x22, 0x2a, 0xce, 0x3c, 0x21, 0x2c, 0x00, 0xd7, 0x75, 0x8a, 0x27, 0xee, 0x43, 0xfe,
316 	0xcb, 0x6b, 0xb9, 0xa3, 0x78, 0xb7, 0x85, 0x02, 0x20, 0xd0, 0x83, 0xc4, 0x12, 0xf9, 0xfd, 0xd8,
317 	0x79, 0x64, 0x3a, 0x49, 0x03, 0xb4, 0xc0, 0xf2, 0xdf, 0x15, 0x93, 0x08, 0x35, 0xff, 0x70, 0xdd,
318 	0x28, 0x6c, 0x0e, 0x04, 0xde, 0x7a, 0x65, 0xd2, 0xab, 0x42, 0x95, 0xe1, 0x3f, 0x3b, 0x7f, 0x66,
319 	0xd1, 0x8d, 0xe3, 0xbb, 0x1c, 0xfc, 0x77, 0x1a, 0x88, 0x18, 0x19, 0x68, 0x1f, 0x56, 0xd6, 0xe8,
320 	0xb6, 0xbc, 0xd3, 0xea, 0x3d, 0x26, 0xb3, 0xc9, 0x44, 0xdc, 0xf3, 0x32, 0x30, 0xef, 0x96, 0x4c,
321 	0xaf, 0x17, 0xf8, 0xfb, 0x60, 0x50, 0xeb, 0x4b, 0x99, 0x63, 0xba, 0xb2, 0x71, 0xcf, 0x10, 0xbe,
322 };
323 
324 const unsigned char kof2000_type1_t12[256] =
325 {
326 	0xda, 0xa7, 0xd6, 0x6e, 0x2f, 0x5e, 0xf0, 0x3f, 0xa4, 0xce, 0xd3, 0xfd, 0x46, 0x2a, 0xac, 0xc9,
327 	0xbe, 0xeb, 0x9f, 0xd5, 0x3c, 0x61, 0x96, 0x11, 0xd0, 0x38, 0xca, 0x06, 0xed, 0x1b, 0x65, 0xe7,
328 	0x23, 0xdd, 0xd9, 0x05, 0xbf, 0x5b, 0x5d, 0xa5, 0x95, 0x00, 0xec, 0xf1, 0x01, 0xa9, 0xa6, 0xfc,
329 	0xbb, 0x54, 0xe3, 0x2e, 0x92, 0x58, 0x0a, 0x7b, 0xb6, 0xcc, 0xb1, 0x5f, 0x14, 0x35, 0x72, 0xff,
330 	0xe6, 0x52, 0xd7, 0x8c, 0xf3, 0x43, 0xaf, 0x9c, 0xc0, 0x4f, 0x0c, 0x42, 0x8e, 0xef, 0x80, 0xcd,
331 	0x1d, 0x7e, 0x88, 0x3b, 0x98, 0xa1, 0xad, 0xe4, 0x9d, 0x8d, 0x2b, 0x56, 0xb5, 0x50, 0xdf, 0x66,
332 	0x6d, 0xd4, 0x60, 0x09, 0xe1, 0xee, 0x4a, 0x47, 0xf9, 0xfe, 0x73, 0x07, 0x89, 0xa8, 0x39, 0xea,
333 	0x82, 0x9e, 0xcf, 0x26, 0xb2, 0x4e, 0xc3, 0x59, 0xf2, 0x3d, 0x9a, 0xb0, 0x69, 0xf7, 0xbc, 0x34,
334 	0xe5, 0x36, 0x22, 0xfb, 0x57, 0x71, 0x99, 0x6c, 0x83, 0x30, 0x55, 0xc2, 0xbd, 0xf4, 0x77, 0xe9,
335 	0x76, 0x97, 0xa0, 0xe0, 0xb9, 0x86, 0x6b, 0xa3, 0x84, 0x67, 0x1a, 0x70, 0x02, 0x5a, 0x41, 0x5c,
336 	0x25, 0x81, 0xaa, 0x28, 0x78, 0x4b, 0xc6, 0x64, 0x53, 0x16, 0x4d, 0x8b, 0x20, 0x93, 0xae, 0x0f,
337 	0x94, 0x2c, 0x3a, 0xc7, 0x62, 0xe8, 0xc4, 0xdb, 0x04, 0xc5, 0xfa, 0x29, 0x48, 0xd1, 0x08, 0x24,
338 	0x0d, 0xe2, 0xd8, 0x10, 0xb4, 0x91, 0x8a, 0x13, 0x0e, 0xdc, 0xd2, 0x79, 0xb8, 0xf8, 0xba, 0x2d,
339 	0xcb, 0xf5, 0x7d, 0x37, 0x51, 0x40, 0x31, 0xa2, 0x0b, 0x18, 0x63, 0x7f, 0xb3, 0xab, 0x9b, 0x87,
340 	0xf6, 0x90, 0xde, 0xc8, 0x27, 0x45, 0x7c, 0x1c, 0x85, 0x68, 0x33, 0x19, 0x03, 0x75, 0x15, 0x7a,
341 	0x1f, 0x49, 0x8f, 0x4c, 0xc1, 0x44, 0x17, 0x12, 0x6f, 0x32, 0xb7, 0x3e, 0x74, 0x1e, 0x21, 0x6a,
342 };
343 
344 
345 
346 const unsigned char kof2000_address_8_15_xor1[256] =
347 {
348 	0xfc, 0x9b, 0x1c, 0x35, 0x72, 0x53, 0xd6, 0x7d, 0x84, 0xa4, 0xc5, 0x93, 0x7b, 0xe7, 0x47, 0xd5,
349 	0x24, 0xa2, 0xfa, 0x19, 0x0c, 0xb1, 0x8c, 0xb9, 0x9d, 0xd8, 0x59, 0x4f, 0x3c, 0xb2, 0x78, 0x4a,
350 	0x2a, 0x96, 0x9a, 0xf1, 0x1f, 0x22, 0xa8, 0x5b, 0x67, 0xa3, 0x0f, 0x00, 0xfb, 0xdf, 0xeb, 0x0a,
351 	0x57, 0xb8, 0x25, 0xd7, 0xf0, 0x6b, 0x0b, 0x31, 0x95, 0x23, 0x2d, 0x5c, 0x27, 0xc7, 0xf4, 0x55,
352 	0x1a, 0xf7, 0x74, 0xbe, 0xd3, 0xac, 0x3d, 0xc1, 0x7f, 0xbd, 0x28, 0x01, 0x10, 0xe5, 0x09, 0x37,
353 	0x1e, 0x58, 0xaf, 0x17, 0xf2, 0x16, 0x30, 0x92, 0x36, 0x68, 0xe6, 0xd4, 0xea, 0xb7, 0x75, 0x54,
354 	0x77, 0x41, 0xb4, 0x8d, 0xe0, 0xf3, 0x51, 0x03, 0xa9, 0xe8, 0x66, 0xab, 0x29, 0xa5, 0xed, 0xcb,
355 	0xd1, 0xaa, 0xf5, 0xdb, 0x4c, 0x42, 0x97, 0x8a, 0xae, 0xc9, 0x6e, 0x04, 0x33, 0x85, 0xdd, 0x2b,
356 	0x6f, 0xef, 0x12, 0x21, 0x7a, 0xa1, 0x5a, 0x91, 0xc8, 0xcc, 0xc0, 0xa7, 0x60, 0x3e, 0x56, 0x2f,
357 	0xe4, 0x71, 0x99, 0xc2, 0xa0, 0x45, 0x80, 0x65, 0xbb, 0x87, 0x69, 0x81, 0x73, 0xca, 0xf6, 0x46,
358 	0x43, 0xda, 0x26, 0x7e, 0x8f, 0xe1, 0x8b, 0xfd, 0x50, 0x79, 0xba, 0xc6, 0x63, 0x4b, 0xb3, 0x8e,
359 	0x34, 0xe2, 0x48, 0x14, 0xcd, 0xe3, 0xc4, 0x05, 0x13, 0x40, 0x06, 0x6c, 0x88, 0xb0, 0xe9, 0x1b,
360 	0x4d, 0xf8, 0x76, 0x02, 0x44, 0x94, 0xcf, 0x32, 0xfe, 0xce, 0x3b, 0x5d, 0x2c, 0x89, 0x5f, 0xdc,
361 	0xd2, 0x9c, 0x6a, 0xec, 0x18, 0x6d, 0x0e, 0x86, 0xff, 0x5e, 0x9e, 0xee, 0x11, 0xd0, 0x49, 0x52,
362 	0x4e, 0x61, 0x90, 0x0d, 0xc3, 0x39, 0x15, 0x83, 0xb5, 0x62, 0x3f, 0x70, 0x7c, 0xad, 0x20, 0xbf,
363 	0x2e, 0x08, 0x1d, 0xf9, 0xb6, 0xa6, 0x64, 0x07, 0x82, 0x38, 0x98, 0x3a, 0x9f, 0xde, 0xbc, 0xd9,
364 };
365 
366 const unsigned char kof2000_address_8_15_xor2[256] =
367 {
368 	0x00, 0xbe, 0x06, 0x5a, 0xfa, 0x42, 0x15, 0xf2, 0x3f, 0x0a, 0x84, 0x93, 0x4e, 0x78, 0x3b, 0x89,
369 	0x32, 0x98, 0xa2, 0x87, 0x73, 0xdd, 0x26, 0xe5, 0x05, 0x71, 0x08, 0x6e, 0x9b, 0xe0, 0xdf, 0x9e,
370 	0xfc, 0x83, 0x81, 0xef, 0xb2, 0xc0, 0xc3, 0xbf, 0xa7, 0x6d, 0x1b, 0x95, 0xed, 0xb9, 0x3e, 0x13,
371 	0xb0, 0x47, 0x9c, 0x7a, 0x24, 0x41, 0x68, 0xd0, 0x36, 0x0b, 0xb5, 0xc2, 0x67, 0xf7, 0x54, 0x92,
372 	0x1e, 0x44, 0x86, 0x2b, 0x94, 0xcc, 0xba, 0x23, 0x0d, 0xca, 0x6b, 0x4c, 0x2a, 0x9a, 0x2d, 0x8b,
373 	0xe3, 0x52, 0x29, 0xf0, 0x21, 0xbd, 0xbb, 0x1f, 0xa3, 0xab, 0xf8, 0x46, 0xb7, 0x45, 0x82, 0x5e,
374 	0xdb, 0x07, 0x5d, 0xe9, 0x9d, 0x1a, 0x48, 0xce, 0x91, 0x12, 0xd4, 0xee, 0xa9, 0x39, 0xf1, 0x18,
375 	0x2c, 0x22, 0x8a, 0x7e, 0x34, 0x4a, 0x8c, 0xc1, 0x14, 0xf3, 0x20, 0x35, 0xd9, 0x96, 0x33, 0x77,
376 	0x9f, 0x76, 0x7c, 0x90, 0xc6, 0xd5, 0xa1, 0x5b, 0xac, 0x75, 0xc7, 0x0c, 0xb3, 0x17, 0xd6, 0x99,
377 	0x56, 0xa6, 0x3d, 0x1d, 0xb1, 0x2e, 0xd8, 0xbc, 0x2f, 0xde, 0x60, 0x55, 0x6c, 0x40, 0xcd, 0x43,
378 	0xff, 0xad, 0x38, 0x79, 0x51, 0xc8, 0x0e, 0x5f, 0xc4, 0x66, 0xcb, 0xa8, 0x7d, 0xa4, 0x3a, 0xea,
379 	0x27, 0x7b, 0x70, 0x8e, 0x5c, 0x19, 0x0f, 0x80, 0x6f, 0x8f, 0x10, 0xf9, 0x49, 0x85, 0x69, 0x7f,
380 	0xeb, 0x1c, 0x01, 0x65, 0x37, 0xa5, 0x28, 0xe4, 0x6a, 0x03, 0x04, 0xd1, 0x31, 0x11, 0x30, 0xfb,
381 	0x88, 0x97, 0xd3, 0xf6, 0xc5, 0x4d, 0xf5, 0x3c, 0xe8, 0x61, 0xdc, 0xd2, 0xb4, 0xb8, 0xa0, 0xae,
382 	0x16, 0x25, 0x02, 0x09, 0xfe, 0xcf, 0x53, 0x63, 0xaf, 0x59, 0xf4, 0xe1, 0xec, 0xd7, 0xe7, 0x50,
383 	0xe2, 0xc9, 0xaa, 0x4b, 0x8d, 0x4f, 0xe6, 0x64, 0xda, 0x74, 0xb6, 0x72, 0x57, 0x62, 0xfd, 0x58,
384 };
385 
386 const unsigned char kof2000_address_16_23_xor1[256] =
387 {
388 	0x45, 0x9f, 0x6e, 0x2f, 0x28, 0xbc, 0x5e, 0x6d, 0xda, 0xb5, 0x0d, 0xb8, 0xc0, 0x8e, 0xa2, 0x32,
389 	0xee, 0xcd, 0x8d, 0x48, 0x8c, 0x27, 0x14, 0xeb, 0x65, 0xd7, 0xf2, 0x93, 0x99, 0x90, 0x91, 0xfc,
390 	0x5f, 0xcb, 0xfa, 0x75, 0x3f, 0x26, 0xde, 0x72, 0x33, 0x39, 0xc7, 0x1f, 0x88, 0x79, 0x73, 0xab,
391 	0x4e, 0x36, 0x5d, 0x44, 0xd2, 0x41, 0xa0, 0x7e, 0xa7, 0x8b, 0xa6, 0xbf, 0x03, 0xd8, 0x86, 0xdc,
392 	0x2c, 0xaa, 0x70, 0x3d, 0x46, 0x07, 0x80, 0x58, 0x0b, 0x2b, 0xe2, 0xf0, 0xb1, 0xfe, 0x42, 0xf3,
393 	0xe9, 0xa3, 0x85, 0x78, 0xc3, 0xd0, 0x5a, 0xdb, 0x1a, 0xfb, 0x9d, 0x8a, 0xa5, 0x12, 0x0e, 0x54,
394 	0x8f, 0xc5, 0x6c, 0xae, 0x25, 0x5b, 0x4b, 0x17, 0x02, 0x9c, 0x4a, 0x24, 0x40, 0xe5, 0x9e, 0x22,
395 	0xc6, 0x49, 0x62, 0xb6, 0x6b, 0xbb, 0xa8, 0xcc, 0xe8, 0x81, 0x50, 0x47, 0xc8, 0xbe, 0x5c, 0xa4,
396 	0xd6, 0x94, 0x4f, 0x7b, 0x9a, 0xcf, 0xe4, 0x59, 0x7a, 0xa1, 0xea, 0x31, 0x37, 0x13, 0x2d, 0xaf,
397 	0x21, 0x69, 0x19, 0x1d, 0x6f, 0x16, 0x98, 0x1e, 0x08, 0xe3, 0xb2, 0x4d, 0x9b, 0x7f, 0xa9, 0x77,
398 	0xed, 0xbd, 0xd4, 0xd9, 0x34, 0xd3, 0xca, 0x09, 0x18, 0x60, 0xc9, 0x6a, 0x01, 0xf4, 0xf6, 0x64,
399 	0xb4, 0x3a, 0x15, 0xac, 0x89, 0x52, 0x68, 0x71, 0xe7, 0x82, 0xc1, 0x0c, 0x92, 0xf7, 0x30, 0xe6,
400 	0x1c, 0x3e, 0x0f, 0x0a, 0x67, 0x35, 0xba, 0x61, 0xdd, 0x29, 0xc2, 0xf8, 0x97, 0x95, 0xb7, 0x3b,
401 	0xe0, 0xce, 0xf9, 0xd5, 0x06, 0x76, 0xb3, 0x05, 0x4c, 0x04, 0x84, 0x3c, 0x87, 0x23, 0x63, 0x7c,
402 	0x53, 0x56, 0xe1, 0x7d, 0x96, 0x1b, 0xd1, 0xec, 0x2a, 0x66, 0xf1, 0x11, 0x10, 0xff, 0x43, 0x2e,
403 	0xdf, 0x83, 0x74, 0xf5, 0x38, 0x20, 0xfd, 0xad, 0xc4, 0xb9, 0x55, 0x51, 0xb0, 0xef, 0x00, 0x57,
404 };
405 
406 const unsigned char kof2000_address_16_23_xor2[256] =
407 {
408 	0x00, 0xb8, 0xf0, 0x34, 0xca, 0x21, 0x3c, 0xf9, 0x01, 0x8e, 0x75, 0x70, 0xec, 0x13, 0x27, 0x96,
409 	0xf4, 0x5b, 0x88, 0x1f, 0xeb, 0x4a, 0x7d, 0x9d, 0xbe, 0x02, 0x14, 0xaf, 0xa2, 0x06, 0xc6, 0xdb,
410 	0x35, 0x6b, 0x74, 0x45, 0x7b, 0x29, 0xd2, 0xfe, 0xb6, 0x15, 0xd0, 0x8a, 0xa9, 0x2d, 0x19, 0xf6,
411 	0x5e, 0x5a, 0x90, 0xe9, 0x11, 0x33, 0xc2, 0x47, 0x37, 0x4c, 0x4f, 0x59, 0xc3, 0x04, 0x57, 0x1d,
412 	0xf2, 0x63, 0x6d, 0x6e, 0x31, 0x95, 0xcb, 0x3e, 0x67, 0xb2, 0xe3, 0x98, 0xed, 0x8d, 0xe6, 0xfb,
413 	0xf8, 0xba, 0x5d, 0xd4, 0x2a, 0xf5, 0x3b, 0x82, 0x05, 0x16, 0x44, 0xef, 0x4d, 0xe7, 0x93, 0xda,
414 	0x9f, 0xbb, 0x61, 0xc9, 0x53, 0xbd, 0x76, 0x78, 0x52, 0x36, 0x0c, 0x66, 0xc1, 0x10, 0xdd, 0x7a,
415 	0x84, 0x69, 0xcd, 0xfd, 0x58, 0x0d, 0x6c, 0x89, 0x68, 0xad, 0x3a, 0xb0, 0x4b, 0x46, 0xc5, 0x03,
416 	0xb4, 0xf7, 0x30, 0x8c, 0x4e, 0x60, 0x73, 0xa1, 0x8b, 0xb1, 0x62, 0xcc, 0xd1, 0x08, 0xfc, 0x77,
417 	0x7e, 0xcf, 0x56, 0x51, 0x07, 0xa6, 0x80, 0x92, 0xdc, 0x0b, 0xa4, 0xc7, 0xe8, 0xe1, 0xb5, 0x71,
418 	0xea, 0xb3, 0x2f, 0x94, 0x18, 0xe2, 0x3d, 0x49, 0x65, 0xaa, 0xf1, 0x91, 0xc8, 0x99, 0x55, 0x79,
419 	0x86, 0xa7, 0x26, 0xa0, 0xac, 0x5f, 0xce, 0x6a, 0x5c, 0xf3, 0x87, 0x8f, 0x12, 0x1c, 0xd8, 0xe4,
420 	0x9b, 0x64, 0x2e, 0x1e, 0xd7, 0xc0, 0x17, 0xbc, 0xa3, 0xa8, 0x9a, 0x0e, 0x25, 0x40, 0x41, 0x50,
421 	0xb9, 0xbf, 0x28, 0xdf, 0x32, 0x54, 0x9e, 0x48, 0xd5, 0x2b, 0x42, 0xfa, 0x9c, 0x7f, 0xd3, 0x85,
422 	0x43, 0xde, 0x81, 0x0f, 0x24, 0xc4, 0x38, 0xae, 0x83, 0x1b, 0x6f, 0x7c, 0xe5, 0xff, 0x1a, 0xd9,
423 	0x3f, 0xb7, 0x22, 0x97, 0x09, 0xe0, 0xa5, 0x20, 0x23, 0x2c, 0x72, 0xd6, 0x39, 0xab, 0x0a, 0xee,
424 };
425 
426 const unsigned char kof2000_address_0_7_xor[256] =
427 {
428 	0x26, 0x48, 0x06, 0x9b, 0x21, 0xa9, 0x1b, 0x76, 0xc9, 0xf8, 0xb4, 0x67, 0xe4, 0xff, 0x99, 0xf7,
429 	0x15, 0x9e, 0x62, 0x00, 0x72, 0x4d, 0xa0, 0x4f, 0x02, 0xf1, 0xea, 0xef, 0x0b, 0xf3, 0xeb, 0xa6,
430 	0x93, 0x78, 0x6f, 0x7c, 0xda, 0xd4, 0x7b, 0x05, 0xe9, 0xc6, 0xd6, 0xdb, 0x50, 0xce, 0xd2, 0x01,
431 	0xb5, 0xe8, 0xe0, 0x2a, 0x08, 0x1a, 0xb8, 0xe3, 0xf9, 0xb1, 0xf4, 0x8b, 0x39, 0x2d, 0x85, 0x9c,
432 	0x55, 0x73, 0x63, 0x40, 0x38, 0x96, 0xdc, 0xa3, 0xa2, 0xa1, 0x25, 0x66, 0x6d, 0x56, 0x8e, 0x10,
433 	0x0f, 0x31, 0x1c, 0xf5, 0x28, 0x77, 0x0a, 0xd1, 0x75, 0x34, 0xa4, 0xfe, 0x7d, 0x07, 0x51, 0x79,
434 	0x41, 0x90, 0x22, 0x35, 0x12, 0xbb, 0xc4, 0xca, 0xb2, 0x1f, 0xcb, 0xc8, 0xac, 0xdd, 0xd0, 0x0d,
435 	0xfc, 0xc5, 0x9d, 0x14, 0xbc, 0x83, 0xd9, 0x58, 0xc2, 0x30, 0x9a, 0x6a, 0xc0, 0x0c, 0xad, 0xf6,
436 	0x5d, 0x74, 0x7f, 0x2f, 0xbd, 0x1d, 0x47, 0xd5, 0xe6, 0x89, 0xcf, 0xb7, 0xd3, 0x59, 0x36, 0x98,
437 	0xf0, 0xfb, 0x3c, 0xf2, 0x3f, 0xa7, 0x18, 0x82, 0x42, 0x5c, 0xab, 0xba, 0xde, 0x52, 0x09, 0x91,
438 	0xaa, 0x61, 0xec, 0xd7, 0x95, 0x23, 0xcd, 0x80, 0xa5, 0x68, 0x60, 0x27, 0x71, 0xe1, 0x2c, 0x2e,
439 	0x8d, 0x2b, 0x57, 0x65, 0xbf, 0xc1, 0x19, 0xc7, 0x49, 0x64, 0x88, 0x4a, 0xcc, 0x20, 0x4e, 0xd8,
440 	0x3b, 0x4c, 0x13, 0x5f, 0x9f, 0xbe, 0x5e, 0x6e, 0xfd, 0xe2, 0xfa, 0x54, 0x37, 0x0e, 0x16, 0x7a,
441 	0x6c, 0x33, 0xb3, 0x70, 0x84, 0x7e, 0xc3, 0x04, 0xb0, 0xae, 0xb9, 0x81, 0x03, 0x29, 0xdf, 0x46,
442 	0xe5, 0x69, 0xe7, 0x24, 0x92, 0x5a, 0x4b, 0x5b, 0x94, 0x11, 0x3a, 0x3d, 0x87, 0xed, 0x97, 0xb6,
443 	0x32, 0x3e, 0x45, 0xaf, 0x1e, 0x43, 0x44, 0x8c, 0x53, 0x86, 0x6b, 0xee, 0xa8, 0x8a, 0x8f, 0x17,
444 };
445 
446 static const UINT8 m1_address_8_15_xor[256] =
447 {
448         0x0a, 0x72, 0xb7, 0xaf, 0x67, 0xde, 0x1d, 0xb1, 0x78, 0xc4, 0x4f, 0xb5, 0x4b, 0x18, 0x76, 0xdd,
449         0x11, 0xe2, 0x36, 0xa1, 0x82, 0x03, 0x98, 0xa0, 0x10, 0x5f, 0x3f, 0xd6, 0x1f, 0x90, 0x6a, 0x0b,
450         0x70, 0xe0, 0x64, 0xcb, 0x9f, 0x38, 0x8b, 0x53, 0x04, 0xca, 0xf8, 0xd0, 0x07, 0x68, 0x56, 0x32,
451         0xae, 0x1c, 0x2e, 0x48, 0x63, 0x92, 0x9a, 0x9c, 0x44, 0x85, 0x41, 0x40, 0x09, 0xc0, 0xc8, 0xbf,
452         0xea, 0xbb, 0xf7, 0x2d, 0x99, 0x21, 0xf6, 0xba, 0x15, 0xce, 0xab, 0xb0, 0x2a, 0x60, 0xbc, 0xf1,
453         0xf0, 0x9e, 0xd5, 0x97, 0xd8, 0x4e, 0x14, 0x9d, 0x42, 0x4d, 0x2c, 0x5c, 0x2b, 0xa6, 0xe1, 0xa7,
454         0xef, 0x25, 0x33, 0x7a, 0xeb, 0xe7, 0x1b, 0x6d, 0x4c, 0x52, 0x26, 0x62, 0xb6, 0x35, 0xbe, 0x80,
455         0x01, 0xbd, 0xfd, 0x37, 0xf9, 0x47, 0x55, 0x71, 0xb4, 0xf2, 0xff, 0x27, 0xfa, 0x23, 0xc9, 0x83,
456         0x17, 0x39, 0x13, 0x0d, 0xc7, 0x86, 0x16, 0xec, 0x49, 0x6f, 0xfe, 0x34, 0x05, 0x8f, 0x00, 0xe6,
457         0xa4, 0xda, 0x7b, 0xc1, 0xf3, 0xf4, 0xd9, 0x75, 0x28, 0x66, 0x87, 0xa8, 0x45, 0x6c, 0x20, 0xe9,
458         0x77, 0x93, 0x7e, 0x3c, 0x1e, 0x74, 0xf5, 0x8c, 0x3e, 0x94, 0xd4, 0xc2, 0x5a, 0x06, 0x0e, 0xe8,
459         0x3d, 0xa9, 0xb2, 0xe3, 0xe4, 0x22, 0xcf, 0x24, 0x8e, 0x6b, 0x8a, 0x8d, 0x84, 0x4a, 0xd2, 0x91,
460         0x88, 0x79, 0x57, 0xa5, 0x0f, 0xcd, 0xb9, 0xac, 0x3b, 0xaa, 0xb3, 0xd1, 0xee, 0x31, 0x81, 0x7c,
461         0xd7, 0x89, 0xd3, 0x96, 0x43, 0xc5, 0xc6, 0xc3, 0x69, 0x7f, 0x46, 0xdf, 0x30, 0x5b, 0x6e, 0xe5,
462         0x08, 0x95, 0x9b, 0xfb, 0xb8, 0x58, 0x0c, 0x61, 0x50, 0x5d, 0x3a, 0xa2, 0x29, 0x12, 0xfc, 0x51,
463         0x7d, 0x1a, 0x02, 0x65, 0x54, 0x5e, 0x19, 0xcc, 0xdc, 0xdb, 0x73, 0xed, 0xad, 0x59, 0x2f, 0xa3,
464 };
465 
466 static const UINT8 m1_address_0_7_xor[256] =
467 {
468         0xf4, 0xbc, 0x02, 0xf7, 0x2c, 0x3d, 0xe8, 0xd9, 0x50, 0x62, 0xec, 0xbd, 0x53, 0x73, 0x79, 0x61,
469         0x00, 0x34, 0xcf, 0xa2, 0x63, 0x28, 0x90, 0xaf, 0x44, 0x3b, 0xc5, 0x8d, 0x3a, 0x46, 0x07, 0x70,
470         0x66, 0xbe, 0xd8, 0x8b, 0xe9, 0xa0, 0x4b, 0x98, 0xdc, 0xdf, 0xe2, 0x16, 0x74, 0xf1, 0x37, 0xf5,
471         0xb7, 0x21, 0x81, 0x01, 0x1c, 0x1b, 0x94, 0x36, 0x09, 0xa1, 0x4a, 0x91, 0x30, 0x92, 0x9b, 0x9a,
472         0x29, 0xb1, 0x38, 0x4d, 0x55, 0xf2, 0x56, 0x18, 0x24, 0x47, 0x9d, 0x3f, 0x80, 0x1f, 0x22, 0xa4,
473         0x11, 0x54, 0x84, 0x0d, 0x25, 0x48, 0xee, 0xc6, 0x59, 0x15, 0x03, 0x7a, 0xfd, 0x6c, 0xc3, 0x33,
474         0x5b, 0xc4, 0x7b, 0x5a, 0x05, 0x7f, 0xa6, 0x40, 0xa9, 0x5d, 0x41, 0x8a, 0x96, 0x52, 0xd3, 0xf0,
475         0xab, 0x72, 0x10, 0x88, 0x6f, 0x95, 0x7c, 0xa8, 0xcd, 0x9c, 0x5f, 0x32, 0xae, 0x85, 0x39, 0xac,
476         0xe5, 0xd7, 0xfb, 0xd4, 0x08, 0x23, 0x19, 0x65, 0x6b, 0xa7, 0x93, 0xbb, 0x2b, 0xbf, 0xb8, 0x35,
477         0xd0, 0x06, 0x26, 0x68, 0x3e, 0xdd, 0xb9, 0x69, 0x2a, 0xb2, 0xde, 0x87, 0x45, 0x58, 0xff, 0x3c,
478         0x9e, 0x7d, 0xda, 0xed, 0x49, 0x8c, 0x14, 0x8e, 0x75, 0x2f, 0xe0, 0x6e, 0x78, 0x6d, 0x20, 0xd2,
479         0xfa, 0x2d, 0x51, 0xcc, 0xc7, 0xe7, 0x1d, 0x27, 0x97, 0xfc, 0x31, 0xdb, 0xf8, 0x42, 0xe3, 0x99,
480         0x5e, 0x83, 0x0e, 0xb4, 0x2e, 0xf6, 0xc0, 0x0c, 0x4c, 0x57, 0xb6, 0x64, 0x0a, 0x17, 0xa3, 0xc1,
481         0x77, 0x12, 0xfe, 0xe6, 0x8f, 0x13, 0x71, 0xe4, 0xf9, 0xad, 0x9f, 0xce, 0xd5, 0x89, 0x7e, 0x0f,
482         0xc2, 0x86, 0xf3, 0x67, 0xba, 0x60, 0x43, 0xc9, 0x04, 0xb3, 0xb0, 0x1e, 0xb5, 0xc8, 0xeb, 0xa5,
483         0x76, 0xea, 0x5c, 0x82, 0x1a, 0x4f, 0xaa, 0xca, 0xe1, 0x0b, 0x4e, 0xcb, 0x6a, 0xef, 0xd1, 0xd6,
484 };
485 
486 
487 
488 
decrypt(unsigned char * r0,unsigned char * r1,unsigned char c0,unsigned char c1,const unsigned char * table0hi,const unsigned char * table0lo,const unsigned char * table1,int base,int invert)489 static void decrypt(unsigned char *r0, unsigned char *r1,
490 		    unsigned char c0,  unsigned char c1,
491 		    const unsigned char *table0hi,
492 		    const unsigned char *table0lo,
493 		    const unsigned char *table1,
494 		    int base,
495 		    int invert)
496 
497 {
498 	unsigned char tmp,xor0,xor1;
499 
500 	tmp = table1[(base & 0xff) ^ address_0_7_xor[(base >> 8) & 0xff]];
501 	xor0 = (table0hi[(base >> 8) & 0xff] & 0xfe) | (tmp & 0x01);
502 	xor1 = (tmp & 0xfe) | (table0lo[(base >> 8) & 0xff] & 0x01);
503 
504 	if (invert)
505 	{
506 		*r0 = c1 ^ xor0;
507 		*r1 = c0 ^ xor1;
508 	}
509 	else
510 	{
511 		*r0 = c0 ^ xor0;
512 		*r1 = c1 ^ xor1;
513 	}
514 }
515 
neogeo_gfx_decrypt(int extra_xor)516 static void neogeo_gfx_decrypt(int extra_xor)
517 {
518 	int rom_size;
519 	UINT8 *buf;
520 	UINT8 *rom;
521 	int rpos;
522 
523 	rom_size = memory_region_length(REGION_GFX3);
524 
525 	buf = malloc(rom_size);
526 
527 	if (!buf) return;
528 
529 	rom = memory_region(REGION_GFX3);
530 
531 	/* Data xor*/
532 	for (rpos = 0;rpos < rom_size/4;rpos++)
533 	{
534 		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);
535 		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);
536 	}
537 
538 	/* Address xor*/
539 	for (rpos = 0;rpos < rom_size/4;rpos++)
540 	{
541 		int baser;
542 
543 		baser = rpos;
544 
545 		baser ^= extra_xor;
546 
547 		baser ^= address_8_15_xor1[(baser >> 16) & 0xff] << 8;
548 		baser ^= address_8_15_xor2[baser & 0xff] << 8;
549 		baser ^= address_16_23_xor1[baser & 0xff] << 16;
550 		baser ^= address_16_23_xor2[(baser >> 8) & 0xff] << 16;
551 		baser ^= address_0_7_xor[(baser >> 8) & 0xff];
552 
553 		/* special handling for preisle2 */
554 		if (rom_size == 0x3000000)
555 		{
556 			if (rpos < 0x2000000/4)
557 				baser &= (0x2000000/4)-1;
558 			else
559 				baser = 0x2000000/4 + (baser & ((0x1000000/4)-1));
560 		}
561 		else	/* Clamp to the real rom size */
562 			baser &= (rom_size/4)-1;
563 
564 		rom[4*rpos+0] = buf[4*baser+0];
565 		rom[4*rpos+1] = buf[4*baser+1];
566 		rom[4*rpos+2] = buf[4*baser+2];
567 		rom[4*rpos+3] = buf[4*baser+3];
568 	}
569 
570 	free(buf);
571 
572 
573 	/* the S data comes from the end fo the C data */
574 	{
575 		int i;
576 		int tx_size = memory_region_length(REGION_GFX1);
577 		UINT8 *src = memory_region(REGION_GFX3)+rom_size-tx_size;
578 		UINT8 *dst = memory_region(REGION_GFX1);
579 
580 		for (i = 0;i < tx_size;i++)
581 			dst[i] = src[(i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4)];
582 	}
583 }
584 
neogeo_gfx_decrypt_for_mc50(int extra_xor)585 static void neogeo_gfx_decrypt_for_mc50(int extra_xor)
586 {
587 	int rom_size;
588 	UINT8 *buf;
589 	UINT8 *rom;
590 	int rpos;
591 
592 	rom_size = memory_region_length(REGION_GFX3);
593 	buf = malloc(rom_size);
594 
595 	if (!buf) return;
596 
597 	rom = memory_region(REGION_GFX3);
598 
599 	// Data xor
600 	for (rpos = 0;rpos < rom_size/4;rpos++)
601 	{
602 		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);
603 		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);
604 	}
605 
606 	// Address xor
607 	for (rpos = 0;rpos < rom_size/4;rpos++)
608 	{
609 		int baser;
610 
611 		baser = rpos;
612 
613 		baser ^= extra_xor;
614 
615 		baser ^= address_8_15_xor1[(baser >> 16) & 0xff] << 8;
616 		baser ^= address_8_15_xor2[baser & 0xff] << 8;
617 		baser ^= address_16_23_xor1[baser & 0xff] << 16;
618 		baser ^= address_16_23_xor2[(baser >> 8) & 0xff] << 16;
619 		baser ^= address_0_7_xor[(baser >> 8) & 0xff];
620 
621 
622 		if (rom_size == 0x3000000) /* special handling for preisle2 */
623 		{
624 			if (rpos < 0x2000000/4)
625 				baser &= (0x2000000/4)-1;
626 			else
627 				baser = 0x2000000/4 + (baser & ((0x1000000/4)-1));
628 		}
629 		else if (rom_size == 0x6000000)	/* special handling for kf2k3pcb */
630 		{
631 			if (rpos < 0x4000000/4)
632 				baser &= (0x4000000/4)-1;
633 			else
634 				baser = 0x4000000/4 + (baser & ((0x1000000/4)-1));
635 		}
636 		else /* Clamp to the real rom size */
637 			baser &= (rom_size/4)-1;
638 
639 		rom[4*rpos+0] = buf[4*baser+0];
640 		rom[4*rpos+1] = buf[4*baser+1];
641 		rom[4*rpos+2] = buf[4*baser+2];
642 		rom[4*rpos+3] = buf[4*baser+3];
643 	}
644 
645 	free(buf);
646 }
647 
648 /* The CMC50 hardware does a checksum of the first 64kb of the M1 rom,
649    ,and uses this checksum as the basis of the key with which to decrypt
650    the rom */
651 
generate_cs16(UINT8 * rom,int size)652 static UINT16 generate_cs16(UINT8 *rom, int size)
653 {
654     UINT16 cs16;
655     int i;
656     cs16 = 0x0000;
657     for (i=0;i<size;i++ )
658     {
659         cs16 += rom[i];
660     }
661     return cs16&0xFFFF;
662 }
663 
664 
m1_address_scramble(int address,UINT16 key)665 int m1_address_scramble(int address, UINT16 key)
666 {
667 	int block;
668 	int aux;
669 
670 	const int p1[8][16] = {
671 		{15,14,10,7,1,2,3,8,0,12,11,13,6,9,5,4},
672 		{7,1,8,11,15,9,2,3,5,13,4,14,10,0,6,12},
673 		{8,6,14,3,10,7,15,1,4,0,2,5,13,11,12,9},
674 		{2,8,15,9,3,4,11,7,13,6,0,10,1,12,14,5},
675 		{1,13,6,15,14,3,8,10,9,4,7,12,5,2,0,11},
676 		{11,15,3,4,7,0,9,2,6,14,12,1,8,5,10,13},
677 		{10,5,13,8,6,15,1,14,11,9,3,0,12,7,4,2},
678 		{9,3,7,0,2,12,4,11,14,10,5,8,15,13,1,6},
679 	};
680 
681 	block = (address>>16)&7;
682 	aux = address&0xffff;
683 
684         aux ^= BITSWAP16(key,12,0,2,4,8,15,7,13,10,1,3,6,11,9,14,5);
685 	aux = BITSWAP16(aux,
686 		p1[block][15],p1[block][14],p1[block][13],p1[block][12],
687 		p1[block][11],p1[block][10],p1[block][9],p1[block][8],
688 		p1[block][7],p1[block][6],p1[block][5],p1[block][4],
689 		p1[block][3],p1[block][2],p1[block][1],p1[block][0]);
690         aux ^= m1_address_0_7_xor[(aux>>8)&0xff];
691 	aux ^= m1_address_8_15_xor[aux&0xff]<<8;
692 	aux = BITSWAP16(aux, 7,15,14,6,5,13,12,4,11,3,10,2,9,1,8,0);
693 
694 	return (block<<16)|aux;
695 }
696 
neogeo_cmc50_m1_decrypt(void)697 void neogeo_cmc50_m1_decrypt( void )
698 {
699 	UINT8* rom = memory_region( audiocrypt );
700 	size_t rom_size = 0x80000;
701 	UINT8* rom2 = memory_region( REGION_CPU2 );
702 
703 	UINT8* buffer = malloc(rom_size);
704 
705 	UINT32 i;
706 
707 	UINT16 key=generate_cs16(rom,0x10000);
708 
709 	//printf("key %04x\n",key);
710 
711 	for (i=0; i<rom_size; i++)
712 	{
713 		buffer[i] = rom[m1_address_scramble(i,key)];
714 	}
715 
716 	memcpy(rom,buffer,rom_size);
717 
718 	memcpy(rom2,rom,0x10000);
719 	memcpy(rom2+0x10000,rom,0x80000);
720 
721 
722 
723 	free( buffer );
724 }
725 
726 /* CMC42 protection chip */
kof99_neogeo_gfx_decrypt(int extra_xor)727 void kof99_neogeo_gfx_decrypt(int extra_xor)
728 {
729 	type0_t03 =          kof99_type0_t03;
730 	type0_t12 =          kof99_type0_t12;
731 	type1_t03 =          kof99_type1_t03;
732 	type1_t12 =          kof99_type1_t12;
733 	address_8_15_xor1 =  kof99_address_8_15_xor1;
734 	address_8_15_xor2 =  kof99_address_8_15_xor2;
735 	address_16_23_xor1 = kof99_address_16_23_xor1;
736 	address_16_23_xor2 = kof99_address_16_23_xor2;
737 	address_0_7_xor =    kof99_address_0_7_xor;
738 	neogeo_gfx_decrypt(extra_xor);
739 }
740 
741 /* CMC50 protection chip */
kof2000_neogeo_gfx_decrypt(int extra_xor)742 void kof2000_neogeo_gfx_decrypt(int extra_xor)
743 {
744 	type0_t03 =          kof2000_type0_t03;
745 	type0_t12 =          kof2000_type0_t12;
746 	type1_t03 =          kof2000_type1_t03;
747 	type1_t12 =          kof2000_type1_t12;
748 	address_8_15_xor1 =  kof2000_address_8_15_xor1;
749 	address_8_15_xor2 =  kof2000_address_8_15_xor2;
750 	address_16_23_xor1 = kof2000_address_16_23_xor1;
751 	address_16_23_xor2 = kof2000_address_16_23_xor2;
752 	address_0_7_xor =    kof2000_address_0_7_xor;
753 	neogeo_gfx_decrypt(extra_xor);
754 
755 	/* here I should also decrypt the sound ROM */
756 }
757 
cmc50_neogeo_gfx_decrypt(int extra_xor)758 void cmc50_neogeo_gfx_decrypt(int extra_xor)
759 {
760 	type0_t03 =          kof2000_type0_t03;
761 	type0_t12 =          kof2000_type0_t12;
762 	type1_t03 =          kof2000_type1_t03;
763 	type1_t12 =          kof2000_type1_t12;
764 	address_8_15_xor1 =  kof2000_address_8_15_xor1;
765 	address_8_15_xor2 =  kof2000_address_8_15_xor2;
766 	address_16_23_xor1 = kof2000_address_16_23_xor1;
767 	address_16_23_xor2 = kof2000_address_16_23_xor2;
768 	address_0_7_xor =    kof2000_address_0_7_xor;
769 	neogeo_gfx_decrypt_for_mc50(extra_xor);
770 
771 	/* here I should also decrypt the sound ROM */
772 }
773 
neo_pcm2_snk_1999(int value)774 void neo_pcm2_snk_1999(int value)
775 {	/* thanks to Elsemi for the NEO-PCM2 info */
776 	UINT16 *rom = (UINT16 *)memory_region(REGION_SOUND1);
777 	int size = memory_region_length(REGION_SOUND1);
778 	int i, j;
779 
780 	if( rom != NULL )
781 	{	/* swap address lines on the whole ROMs */
782 		UINT16 *buffer = malloc((value / 2) * sizeof(UINT16));
783 		if (!buffer)
784 			return;
785 
786 		for( i = 0; i < size / 2; i += ( value / 2 ) )
787 		{
788 			memcpy( buffer, &rom[ i ], value );
789 			for( j = 0; j < (value / 2); j++ )
790 			{
791 				rom[ i + j ] = buffer[ j ^ (value/4) ];
792 			}
793 		}
794 		free(buffer);
795 	}
796 }
797 
neo_pcm2_swap(int value)798 void neo_pcm2_swap(int value)
799 {
800 	static const unsigned int addrs[7][2]={
801 		{0x000000,0xA5000},
802 		{0xFFCE20,0x01000},
803 		{0xFE2CF6,0x4E001},
804 		{0xFFAC28,0xC2000},
805 		{0xFEB2C0,0x0A000},
806 		{0xFF14EA,0xA7001},
807 		{0xFFB440,0x02000}};
808 	static const UINT8 xordata[7][8]={
809 		{0xF9,0xE0,0x5D,0xF3,0xEA,0x92,0xBE,0xEF},
810 		{0xC4,0x83,0xA8,0x5F,0x21,0x27,0x64,0xAF},
811 		{0xC3,0xFD,0x81,0xAC,0x6D,0xE7,0xBF,0x9E},
812 		{0xC3,0xFD,0x81,0xAC,0x6D,0xE7,0xBF,0x9E},
813 		{0xCB,0x29,0x7D,0x43,0xD2,0x3A,0xC2,0xB4},
814 		{0x4B,0xA4,0x63,0x46,0xF0,0x91,0xEA,0x62},
815 		{0x4B,0xA4,0x63,0x46,0xF0,0x91,0xEA,0x62}};
816 	UINT8 *src = memory_region(REGION_SOUND1);
817 	UINT8 *buf = malloc(0x1000000);
818 	int i, j, d;
819 
820 	memcpy(buf,src,0x1000000);
821 	for (i=0;i<0x1000000;i++)
822 	{
823 		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);
824 		j=j^addrs[value][1];
825 		d=((i+addrs[value][0])&0xffffff);
826 		src[j]=buf[d]^xordata[value][j&0x7];
827 	}
828 	free(buf);
829 }
830 
831 
832 
833 
834 
READ16_HANDLER(prot_9a37_r)835 static READ16_HANDLER( prot_9a37_r )
836 {
837 	return 0x9a37;
838 }
839 /* information about the sma random number generator provided by razoola */
840 /* this RNG is correct for KOF99, other games might be different */
841 
842 int neogeo_rng = 0x2345;	/* this is reset in MACHINE_INIT() */
843 
READ16_HANDLER(sma_random_r)844 static READ16_HANDLER( sma_random_r )
845 {
846 	int old = neogeo_rng;
847 
848 	int newbit = (
849 			(neogeo_rng >> 2) ^
850 			(neogeo_rng >> 3) ^
851 			(neogeo_rng >> 5) ^
852 			(neogeo_rng >> 6) ^
853 			(neogeo_rng >> 7) ^
854 			(neogeo_rng >>11) ^
855 			(neogeo_rng >>12) ^
856 			(neogeo_rng >>15)) & 1;
857 
858 	neogeo_rng = ((neogeo_rng << 1) | newbit) & 0xffff;
859 
860 	return old;
861 }
862 
kog_px_decrypt(void)863 void kog_px_decrypt( void )
864 {
865 	/* the protection chip does some *very* strange things to the rom */
866 	UINT8 *src = memory_region(REGION_CPU1);
867 	UINT8 *dst = malloc( 0x600000 );
868 	UINT16 *rom = (UINT16 *)memory_region(REGION_CPU1);
869 	int i;
870 	static const unsigned int sec[] = { 0x3, 0x8, 0x7, 0xC, 0x1, 0xA, 0x6, 0xD };
871 
872 	for (i = 0; i < 8; i++){
873 		memcpy (dst + i * 0x20000, src + sec[i] * 0x20000, 0x20000);
874 	}
875 
876 	memcpy (dst + 0x0007A6, src + 0x0407A6, 0x000006);
877 	memcpy (dst + 0x0007C6, src + 0x0407C6, 0x000006);
878 	memcpy (dst + 0x0007E6, src + 0x0407E6, 0x000006);
879 	memcpy (dst + 0x090000, src + 0x040000, 0x004000);
880 	memcpy (dst + 0x100000, src + 0x200000, 0x400000);
881 	memcpy (src, dst, 0x600000);
882 	free (dst);
883 
884 	for (i = 0x90000/2; i < 0x94000/2; i++){
885 		if (((rom[i]&0xFFBF) == 0x4EB9 || rom[i] == 0x43F9) && !rom[i + 1])
886 			rom[i + 1] = 0x0009;
887 
888 		if (rom[i] == 0x4EB8)
889 			rom[i] = 0x6100;
890 	}
891 
892 	rom[0x007A8/2] = 0x0009;
893 	rom[0x007C8/2] = 0x0009;
894 	rom[0x007E8/2] = 0x0009;
895 	rom[0x93408/2] = 0xF168;
896 	rom[0x9340C/2] = 0xFB7A;
897 	rom[0x924AC/2] = 0x0009;
898 	rom[0x9251C/2] = 0x0009;
899 	rom[0x93966/2] = 0xFFDA;
900 	rom[0x93974/2] = 0xFFCC;
901 	rom[0x93982/2] = 0xFFBE;
902 	rom[0x93990/2] = 0xFFB0;
903 	rom[0x9399E/2] = 0xFFA2;
904 	rom[0x939AC/2] = 0xFF94;
905 	rom[0x939BA/2] = 0xFF86;
906 	rom[0x939C8/2] = 0xFF78;
907 	rom[0x939D4/2] = 0xFA5C;
908 	rom[0x939E0/2] = 0xFA50;
909 	rom[0x939EC/2] = 0xFA44;
910 	rom[0x939F8/2] = 0xFA38;
911 	rom[0x93A04/2] = 0xFA2C;
912 	rom[0x93A10/2] = 0xFA20;
913 	rom[0x93A1C/2] = 0xFA14;
914 	rom[0x93A28/2] = 0xFA08;
915 	rom[0x93A34/2] = 0xF9FC;
916 	rom[0x93A40/2] = 0xF9F0;
917 	rom[0x93A4C/2] = 0xFD14;
918 	rom[0x93A58/2] = 0xFD08;
919 	rom[0x93A66/2] = 0xF9CA;
920 	rom[0x93A72/2] = 0xF9BE;
921 
922 }
923 
neogeo_bootleg_sx_decrypt(int value)924 void neogeo_bootleg_sx_decrypt( int value )
925 {
926 	int sx_size = memory_region_length( REGION_GFX1 );
927 	UINT8 *rom = memory_region( REGION_GFX1 );
928 	int i;
929 
930 	if (value == 1)
931 	{
932 		UINT8 *buf = malloc( sx_size );
933 		memcpy( buf, rom, sx_size );
934 
935 		for( i = 0; i < sx_size; i += 0x10 )
936 		{
937 			memcpy( &rom[ i ], &buf[ i + 8 ], 8 );
938 			memcpy( &rom[ i + 8 ], &buf[ i ], 8 );
939 		}
940 		free( buf );
941 	}
942 	else if (value == 2)
943 	{
944 		for( i = 0; i < sx_size; i++ )
945 			rom[ i ] = BITSWAP8( rom[ i ], 7, 6, 0, 4, 3, 2, 1, 5 );
946 	}
947 }
948 
neogeo_bootleg_cx_decrypt(void)949 void neogeo_bootleg_cx_decrypt( void )
950 {
951 	int i;
952 	int cx_size = memory_region_length( REGION_GFX3 );
953 	UINT8 *rom = memory_region( REGION_GFX3 );
954 	UINT8 *buf = malloc( cx_size );
955 
956 	memcpy( buf, rom, cx_size );
957 
958 	for( i = 0; i < cx_size / 0x40; i++ ){
959 		memcpy( &rom[ i * 0x40 ], &buf[ (i ^ 1) * 0x40 ], 0x40 );
960 	}
961 
962 	free( buf );
963 }
964 
cthd2003_neogeo_gfx_address_fix_do(int start,int end,int bit3shift,int bit2shift,int bit1shift,int bit0shift)965 static void cthd2003_neogeo_gfx_address_fix_do(int start, int end, int bit3shift, int bit2shift, int bit1shift, int bit0shift)
966 {
967 	int i,j;
968 	int tilesize=128;
969 
970 	UINT8* rom = (UINT8*)malloc(16*tilesize);	// 16 tiles buffer
971 	UINT8* realrom = memory_region(REGION_GFX3) + start*tilesize;
972 
973 	for (i = 0; i < (end-start)/16; i++) {
974 		for (j = 0; j < 16; j++) {
975 			int offset = (((j&1)>>0)<<bit0shift)
976 					+(((j&2)>>1)<<bit1shift)
977 					+(((j&4)>>2)<<bit2shift)
978 					+(((j&8)>>3)<<bit3shift);
979 
980 			memcpy(rom+j*tilesize, realrom+offset*tilesize, tilesize);
981 		}
982 		memcpy(realrom,rom,tilesize*16);
983 		realrom+=16*tilesize;
984 	}
985 	free(rom);
986 }
987 
cthd2003_neogeo_gfx_address_fix(int start,int end)988 static void cthd2003_neogeo_gfx_address_fix(int start, int end)
989 {
990 	cthd2003_neogeo_gfx_address_fix_do(start+512*0, end+512*0, 0,3,2,1);
991 	cthd2003_neogeo_gfx_address_fix_do(start+512*1, end+512*1, 1,0,3,2);
992 	cthd2003_neogeo_gfx_address_fix_do(start+512*2, end+512*2, 2,1,0,3);
993 	// skip 3 & 4
994 	cthd2003_neogeo_gfx_address_fix_do(start+512*5, end+512*5, 0,1,2,3);
995 	cthd2003_neogeo_gfx_address_fix_do(start+512*6, end+512*6, 0,1,2,3);
996 	cthd2003_neogeo_gfx_address_fix_do(start+512*7, end+512*7, 0,2,3,1);
997 }
998 
cthd2003_c(int pow)999 static void cthd2003_c(int pow)
1000 {
1001 	int i;
1002 
1003 	for (i=0; i<=192; i+=8)
1004 		cthd2003_neogeo_gfx_address_fix(i*512,i*512+512);
1005 
1006 	for (i=200; i<=392; i+=8)
1007 		cthd2003_neogeo_gfx_address_fix(i*512,i*512+512);
1008 
1009 	for (i=400; i<=592; i+=8)
1010 		cthd2003_neogeo_gfx_address_fix(i*512,i*512+512);
1011 
1012 	for (i=600; i<=792; i+=8)
1013 		cthd2003_neogeo_gfx_address_fix(i*512,i*512+512);
1014 
1015 	for (i=800; i<=992; i+=8)
1016 		cthd2003_neogeo_gfx_address_fix(i*512,i*512+512);
1017 
1018 	for (i=1000; i<=1016; i+=8)
1019 		cthd2003_neogeo_gfx_address_fix(i*512,i*512+512);
1020 }
1021 
decrypt_cthd2003(void)1022 void decrypt_cthd2003(void)
1023 {
1024 	UINT8 *romdata = memory_region(REGION_GFX1);
1025 	UINT8*tmp = (UINT8*)malloc(8*128*128);
1026 
1027 	memcpy(tmp+8*0*128, romdata+8*0*128, 8*32*128);
1028 	memcpy(tmp+8*32*128, romdata+8*64*128, 8*32*128);
1029 	memcpy(tmp+8*64*128, romdata+8*32*128, 8*32*128);
1030 	memcpy(tmp+8*96*128, romdata+8*96*128, 8*32*128);
1031 	memcpy(romdata, tmp, 8*128*128);
1032 
1033 	romdata = memory_region(REGION_CPU2)+0x10000;
1034  	memcpy(tmp+8*0*128, romdata+8*0*128, 8*32*128);
1035 	memcpy(tmp+8*32*128, romdata+8*64*128, 8*32*128);
1036  	memcpy(tmp+8*64*128, romdata+8*32*128, 8*32*128);
1037 	memcpy(tmp+8*96*128, romdata+8*96*128, 8*32*128);
1038 	memcpy(romdata, tmp, 8*128*128);
1039 
1040  	free(tmp);
1041 
1042 	memcpy(romdata-0x10000,romdata,0x10000);;
1043 
1044 	cthd2003_c(0);
1045 }
1046 
WRITE16_HANDLER(cthd2003_bankswitch_w)1047 static WRITE16_HANDLER ( cthd2003_bankswitch_w )
1048 {
1049 	int bankaddress;
1050 	static int cthd2003_banks[8] =
1051 	{
1052 		1,0,1,0,1,0,3,2,
1053 	};
1054 	if (offset == 0)
1055 	{
1056 		bankaddress = 0x100000 + cthd2003_banks[data&7]*0x100000;
1057 		neogeo_set_cpu1_second_bank(bankaddress);
1058 	}
1059 }
1060 
patch_cthd2003(void)1061 void patch_cthd2003( void )
1062 {
1063 	/* patches thanks to razoola */
1064 	int i;
1065 	UINT16 *mem16 = (UINT16 *)memory_region(REGION_CPU1);
1066 
1067 	/* special ROM banking handler */
1068     install_mem_write16_handler(0, 0x2ffff0, 0x2fffff, cthd2003_bankswitch_w);
1069 	// theres still a problem on the character select screen but it seems to be related to cpu core timing issues,
1070 	// overclocking the 68k prevents it.
1071 
1072 	// fix garbage on s1 layer over everything
1073 	mem16[0xf415a/2] = 0x4ef9;
1074 	mem16[0xf415c/2] = 0x000f;
1075 	mem16[0xf415e/2] = 0x4cf2;
1076 	// Fix corruption in attract mode before title screen
1077 	for (i=0x1ae290/2;i < 0x1ae8d0/2; i=i+1)
1078 	{
1079 		mem16[i] = 0x0000;
1080 	}
1081 
1082 	// Fix for title page
1083 	for (i=0x1f8ef0/2;i < 0x1fa1f0/2; i=i+2)
1084 	{
1085 		mem16[i] -= 0x7000;
1086 		mem16[i+1] -= 0x0010;
1087  	}
1088 
1089 	// Fix for green dots on title page
1090 	for (i=0xac500/2;i < 0xac520/2; i=i+1)
1091 	{
1092 		mem16[i] = 0xFFFF;
1093 	}
1094  	// Fix for blanks as screen change level end clear
1095 	mem16[0x991d0/2] = 0xdd03;
1096 	mem16[0x99306/2] = 0xdd03;
1097 	mem16[0x99354/2] = 0xdd03;
1098  	mem16[0x9943e/2] = 0xdd03;
1099 }
1100 
ct2k3sp_sx_decrypt(void)1101 static void ct2k3sp_sx_decrypt( void )
1102 {
1103 	int rom_size = memory_region_length( REGION_GFX1 );
1104 	UINT8 *rom = memory_region( REGION_GFX1 );
1105 	UINT8 *buf = malloc( rom_size );
1106 	int i;
1107 	int ofst;
1108 
1109 	memcpy( buf, rom, rom_size );
1110 
1111 	for( i = 0; i < rom_size; i++ ){
1112 		ofst = BITSWAP24( (i & 0x1ffff), 23, 22, 21, 20, 19, 18, 17,  3,
1113 									      0,  1,  4,  2, 13, 14, 16, 15,
1114 										  5,  6, 11, 10,  9,  8,  7, 12 );
1115 
1116 		ofst += (i >> 17) << 17;
1117 
1118 		rom[ i ] = buf[ ofst ];
1119 	}
1120 
1121 	memcpy( buf, rom, rom_size );
1122 
1123 	memcpy( &rom[ 0x08000 ], &buf[ 0x10000 ], 0x8000 );
1124 	memcpy( &rom[ 0x10000 ], &buf[ 0x08000 ], 0x8000 );
1125 	memcpy( &rom[ 0x28000 ], &buf[ 0x30000 ], 0x8000 );
1126 	memcpy( &rom[ 0x30000 ], &buf[ 0x28000 ], 0x8000 );
1127 
1128 	free( buf );
1129 }
1130 
1131 
decrypt_ct2k3sp(void)1132 void decrypt_ct2k3sp(void)
1133 {
1134 	UINT8 *romdata = memory_region(REGION_CPU2)+0x10000;
1135 	UINT8*tmp = (UINT8*)malloc(8*128*128);
1136 	memcpy(tmp+8*0*128, romdata+8*0*128, 8*32*128);
1137 	memcpy(tmp+8*32*128, romdata+8*64*128, 8*32*128);
1138 	memcpy(tmp+8*64*128, romdata+8*32*128, 8*32*128);
1139 	memcpy(tmp+8*96*128, romdata+8*96*128, 8*32*128);
1140 	memcpy(romdata, tmp, 8*128*128);
1141 
1142 	free(tmp);
1143 	memcpy(romdata-0x10000,romdata,0x10000);
1144 	ct2k3sp_sx_decrypt();
1145 	cthd2003_c(0);
1146 }
1147 
kof2002_decrypt_68k(void)1148 void kof2002_decrypt_68k(void)
1149 {
1150 	int i;
1151 	static const unsigned int sec[]={0x100000,0x280000,0x300000,0x180000,0x000000,0x380000,0x200000,0x080000};
1152 	UINT8 *src = memory_region(REGION_CPU1)+0x100000;
1153 	UINT8 *dst = malloc(0x400000);
1154 	if (dst)
1155 	{
1156 		memcpy( dst, src, 0x400000 );
1157 		for( i=0; i<8; ++i )
1158 		{
1159 			memcpy( src+i*0x80000, dst+sec[i], 0x80000 );
1160 		}
1161 	free(dst);
1162 	}
1163 }
1164 
kf2k2mp_decrypt(void)1165 void kf2k2mp_decrypt( void )
1166 {
1167 	int i,j;
1168 
1169 	unsigned char *src = memory_region(REGION_CPU1);
1170 	unsigned char *dst = (unsigned char*)malloc(0x80);
1171 
1172 	memcpy(src, src + 0x300000, 0x500000);
1173 
1174 	if (dst)
1175 	{
1176 		for (i = 0; i < 0x800000; i+=0x80)
1177 		{
1178 			for (j = 0; j < 0x80 / 2; j++)
1179 			{
1180 				int ofst = BITSWAP8( j, 6, 7, 2, 3, 4, 5, 0, 1 );
1181 				memcpy(dst + j * 2, src + i + ofst * 2, 2);
1182 			}
1183 			memcpy(src + i, dst, 0x80);
1184 		}
1185 	}
1186 	free(dst);
1187 }
1188 
kof2km2_px_decrypt(void)1189 void kof2km2_px_decrypt( void )
1190 {
1191 	unsigned char *src = memory_region(REGION_CPU1);
1192 	unsigned char *dst = (unsigned char*)malloc(0x600000);
1193 
1194 	memcpy (dst + 0x000000, src + 0x1C0000, 0x040000);
1195 	memcpy (dst + 0x040000, src + 0x140000, 0x080000);
1196 	memcpy (dst + 0x0C0000, src + 0x100000, 0x040000);
1197 	memcpy (dst + 0x100000, src + 0x200000, 0x400000);
1198 	memcpy (src + 0x000000, dst + 0x000000, 0x600000);
1199 	free (dst);
1200 }
1201 
decrypt_kof2k4se_68k(void)1202 void decrypt_kof2k4se_68k( void )
1203 {
1204 	UINT8 *src = memory_region(REGION_CPU1)+0x100000;
1205 	UINT8 *dst = malloc(0x400000);
1206 	int i;
1207 	unsigned int sec[] = {0x300000,0x200000,0x100000,0x000000};
1208 	if (dst)
1209 	{
1210 		memcpy(dst,src,0x400000);
1211 
1212 		for(i = 0; i < 4; ++i)
1213 		{
1214 		memcpy(src+i*0x100000,dst+sec[i],0x100000);
1215 		}
1216 			free(dst);
1217 	}
1218 }
1219 
1220 static UINT16 kof10thExtraRAMB[0x01000];
1221 
kof10thBankswitch(unsigned int nBank)1222 static void kof10thBankswitch(unsigned int nBank)
1223 {
1224 	nBank = 0x100000 + ((nBank & 7) << 20);
1225 	if (nBank >= 0x700000)
1226 		nBank = 0x100000;
1227 	neogeo_set_cpu1_second_bank(nBank);
1228 }
1229 
READ16_HANDLER(kof10th_RAMB_r)1230 READ16_HANDLER( kof10th_RAMB_r )
1231 {
1232 	return kof10thExtraRAMB[offset];
1233 }
1234 
WRITE16_HANDLER(kof10th_custom_w)1235 WRITE16_HANDLER( kof10th_custom_w )
1236 {
1237 	if (!kof10thExtraRAMB[0xFFE]) { // Write to RAM bank A
1238 		UINT16 *prom = (UINT16*)memory_region( REGION_CPU1 );
1239 		COMBINE_DATA(&prom[(0xE0000/2) + (offset & 0xFFFF)]);
1240 	} else {
1241 //      S data should be written here... ??  scrambled??
1242 //      UINT16 *prom = (UINT16*)memory_region( REGION_GFX1 );
1243 //      UINT8 datalow = BITSWAP8((data&0xff)^0xf3,7,6,0,4,3,2,1,5);
1244 //      UINT8 datahigh = BITSWAP8(((data>>8)&0xff)^0xf3,7,6,0,4,3,2,1,5);
1245 //      data = datalow | datahigh<<8;
1246 //      COMBINE_DATA(&prom[offset & 0xFFFF]);
1247 //      decodechar(Machine->gfx[0], (offset&0xffff)/16, (UINT8 *)prom, &kof10th_layout);
1248 
1249 	}
1250 }
1251 
WRITE16_HANDLER(kof10th_bankswitch_w)1252 static WRITE16_HANDLER( kof10th_bankswitch_w )
1253 {
1254 	if (offset >= 0x5F000) {
1255 		if (offset == 0x5FFF8) { // Standard bankswitch
1256 			kof10thBankswitch(data);
1257 		} else if (offset == 0x5FFFC && kof10thExtraRAMB[0xFFC] != data) {
1258 			UINT8 *src = memory_region( REGION_CPU1 );
1259 			memcpy (src + 0x400,  src + ((data & 1) ? 0x800400 : 0x700400), 0xdfbff);
1260 		}
1261 		COMBINE_DATA(&kof10thExtraRAMB[offset & 0xFFF]);
1262 	} else {
1263 		// Usually writes 0x8EF3 or 0x7DF3, sometimes writes 0x0003 to offset 0x25FFF0
1264 	}
1265 }
1266 
install_kof10th_protection(void)1267 void install_kof10th_protection ( void )
1268 {
1269 	install_mem_read16_handler(0, 0x2fe000, 0x2fffff, kof10th_RAMB_r);
1270 	install_mem_write16_handler(0, 0x200000, 0x23ffff, kof10th_custom_w);
1271 	install_mem_write16_handler(0, 0x240000, 0x2fffff, kof10th_bankswitch_w);
1272 }
1273 
decrypt_kof10th(void)1274 void decrypt_kof10th( void )
1275 {
1276 	int i, j;
1277 	UINT8 *dst = malloc(0x900000);
1278 	UINT8 *src = memory_region( REGION_CPU1 );
1279 	UINT8 *srm = memory_region( REGION_GFX1 );
1280 
1281 	if (dst) {
1282 		memcpy(dst + 0x000000, src + 0x600000, 0x100000); // Correct?
1283 		memcpy(dst + 0x100000, src + 0x000000, 0x800000);
1284 		for (i = 0; i < 0x900000; i++) {
1285 			j = (i&0xFFF000) + BITSWAP16(i&0xFFF,15,14,13,12,11,2,9,8,7,1,5,4,3,10,6,0);
1286 			src[j] = dst[i];
1287 		}
1288 		free(dst);
1289 	}
1290 
1291 	// Altera protection chip patches these over P ROM
1292 	((UINT16*)src)[0x0124/2] = 0x000d; // Enables XOR for RAM moves, forces SoftDIPs, and USA region
1293 	((UINT16*)src)[0x0126/2] = 0xf7a8;
1294 
1295 	((UINT16*)src)[0x8bf4/2] = 0x4ef9; // Run code to change "S" data
1296 	((UINT16*)src)[0x8bf6/2] = 0x000d;
1297 	((UINT16*)src)[0x8bf8/2] = 0xf980;
1298 
1299  	for (i = 0; i < 0x10000; i++) { // Get S data, should be done on the fly
1300 		srm[0x00000+(i^1)]=BITSWAP8(src[0x600000+i]^0xf3,7,6,0,4,3,2,1,5);
1301  		srm[0x10000+(i^1)]=BITSWAP8(src[0x6d0000+i]^0xf3,7,6,0,4,3,2,1,5);
1302 	}
1303  	for (i = 0; i < 0x04000; i++) {
1304 		srm[0x02000+(i^1)]=BITSWAP8(src[0x6c2000+i]^0xf3,7,6,0,4,3,2,1,5);
1305 		srm[0x12000+(i^1)]=BITSWAP8(src[0x612000+i]^0xf3,7,6,0,4,3,2,1,5);
1306 	}
1307 }
1308 
decrypt_kf10thep(void)1309 void decrypt_kf10thep(void)
1310 {
1311 	int i;
1312 	UINT16 *rom = (UINT16*)memory_region(REGION_CPU1);
1313 	UINT8  *src = memory_region(REGION_CPU1);
1314 	UINT16 *buf = (UINT16*)memory_region(REGION_USER4);
1315 	UINT8 *srom = (UINT8*)memory_region(REGION_GFX1);
1316 	UINT8 *sbuf = malloc(0x20000);
1317 
1318 	UINT8 *dst = (UINT8*)malloc(0x200000);
1319 
1320 	memcpy(dst,buf,0x200000);
1321 	memcpy(src+0x000000,dst+0x060000,0x20000);
1322 	memcpy(src+0x020000,dst+0x100000,0x20000);
1323 	memcpy(src+0x040000,dst+0x0e0000,0x20000);
1324 	memcpy(src+0x060000,dst+0x180000,0x20000);
1325 	memcpy(src+0x080000,dst+0x020000,0x20000);
1326 	memcpy(src+0x0a0000,dst+0x140000,0x20000);
1327 	memcpy(src+0x0c0000,dst+0x0c0000,0x20000);
1328 	memcpy(src+0x0e0000,dst+0x1a0000,0x20000);
1329 	memcpy(src+0x0002e0,dst+0x0402e0,0x6a); // copy banked code to a new memory region
1330 	memcpy(src+0x0f92bc,dst+0x0492bc,0xb9e); // copy banked code to a new memory region
1331 	for (i=0xf92bc/2;i < 0xf9e58/2 ;i++)
1332 	{
1333 		if (rom[i+0] == 0x4eb9 && rom[i+1] == 0x0000) rom[i+1] = 0x000F; // correct JSR in moved code
1334 		if (rom[i+0] == 0x4ef9 && rom[i+1] == 0x0000) rom[i+1] = 0x000F; // correct JMP in moved code
1335 	}
1336 	rom[0x00342/2] = 0x000f;
1337 	free(dst);
1338 
1339 	for (i=0;i<0x20000;i++)
1340 		sbuf[i]=srom[i^0x8];
1341 
1342 	memcpy(srom,sbuf,0x20000);
1343 	free(sbuf);
1344 }
1345 
kf2k5uni_px_decrypt(void)1346 static void kf2k5uni_px_decrypt( void )
1347 {
1348 	int i, j, ofst;
1349 	unsigned char *src = memory_region( REGION_CPU1 );
1350 	unsigned char *dst = (unsigned char*)malloc(0x80);
1351 
1352 	for (i = 0; i < 0x800000; i+=0x80)
1353 	{
1354 		for (j = 0; j < 0x80; j+=2)
1355 		{
1356 			ofst = BITSWAP8(j, 0, 3, 4, 5, 6, 1, 2, 7);
1357 			memcpy(dst + j, src + i + ofst, 2);
1358 		}
1359 		memcpy(src + i, dst, 0x80);
1360 	}
1361 	free(dst);
1362 
1363 	memcpy(src, src + 0x600000, 0x100000); // Seems to be the same as kof10th
1364 }
1365 
kf2k5uni_sx_decrypt(void)1366 static void kf2k5uni_sx_decrypt( void )
1367 {
1368 	int i;
1369 	UINT8 *srom = memory_region( REGION_GFX1 );
1370 
1371 	for (i = 0; i < 0x20000; i++)
1372 		srom[i] = BITSWAP8(srom[i], 4, 5, 6, 7, 0, 1, 2, 3);
1373 }
1374 
kf2k5uni_mx_decrypt(void)1375 static void kf2k5uni_mx_decrypt( void )
1376 {
1377 	int i;
1378 	UINT8 *mrom = memory_region( REGION_CPU2 );
1379 
1380 	for (i = 0; i < 0x30000; i++)
1381 		mrom[i] = BITSWAP8(mrom[i], 4, 5, 6, 7, 0, 1, 2, 3);
1382 }
1383 
decrypt_kf2k5uni(void)1384 void decrypt_kf2k5uni(void)
1385 {
1386 	kf2k5uni_px_decrypt();
1387 	kf2k5uni_sx_decrypt();
1388 	kf2k5uni_mx_decrypt();
1389 }
1390 
kof2003_decrypt_68k(void)1391 void kof2003_decrypt_68k( void )
1392 {
1393 	static const unsigned char 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 };
1394 	static const unsigned char 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 };
1395 	int i;
1396 	int ofst;
1397 	int rom_size = 0x900000;
1398 	UINT8 *rom = memory_region( REGION_CPU1 );
1399 	UINT8 *buf = malloc( rom_size );
1400 
1401 	for (i = 0; i < 0x100000; i++)
1402 	{
1403 		rom[ 0x800000 + i ] ^= rom[ 0x100002 | i ];
1404 	}
1405 	for( i = 0; i < 0x100000; i++)
1406 	{
1407 		rom[ i ] ^= xor1[ (i % 0x20) ];
1408 	}
1409 	for( i = 0x100000; i < 0x800000; i++)
1410 	{
1411 		rom[ i ] ^= xor2[ (i % 0x20) ];
1412 	}
1413 	for( i = 0x100000; i < 0x800000; i += 4)
1414 	{
1415 		UINT16 *rom16 = (UINT16*)&rom[i + 1];
1416 		*rom16 = BITSWAP16( *rom16, 15, 14, 13, 12, 5, 4, 7, 6, 9, 8, 11, 10, 3, 2, 1, 0 );
1417 	}
1418 	for( i = 0; i < 0x0100000 / 0x10000; i++ )
1419 	{
1420 		ofst = (i & 0xf0) + BITSWAP8((i & 0x0f), 7, 6, 5, 4, 0, 1, 2, 3);
1421 		memcpy( &buf[ i * 0x10000 ], &rom[ ofst * 0x10000 ], 0x10000 );
1422 	}
1423 	for( i = 0x100000; i < 0x900000; i += 0x100)
1424 	{
1425 		ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00800) + (BITSWAP8( ((i & 0x0ff000) >> 12), 4, 5, 6, 7, 1, 0, 3, 2 ) << 12);
1426 		memcpy( &buf[ i ], &rom[ ofst ], 0x100 );
1427 	}
1428 	memcpy (&rom[0x000000], &buf[0x000000], 0x100000);
1429 	memcpy (&rom[0x100000], &buf[0x800000], 0x100000);
1430 	memcpy (&rom[0x200000], &buf[0x100000], 0x700000);
1431 	free( buf );
1432 }
1433 
1434 static unsigned short CartRAM[0x1000];
1435 
pvc_w8(unsigned int offset,unsigned char data)1436 void pvc_w8(unsigned int offset, unsigned char data)
1437 {
1438 	*(((unsigned char*)CartRAM)+BYTE_XOR_LE(offset))=data;
1439 }
1440 
pvc_r8(unsigned int offset)1441 unsigned char pvc_r8(unsigned int offset)
1442 {
1443 	return *(((unsigned char*)CartRAM)+BYTE_XOR_LE(offset));
1444 }
1445 
pvc_prot1(void)1446 void pvc_prot1( void )
1447 {
1448 	unsigned char b1, b2;
1449 	b1 = pvc_r8(0x1fe1);
1450 	b2 = pvc_r8(0x1fe0);
1451 	pvc_w8(0x1fe2,(((b2>>0)&0xf)<<1)|((b1>>4)&1));
1452 	pvc_w8(0x1fe3,(((b2>>4)&0xf)<<1)|((b1>>5)&1));
1453 	pvc_w8(0x1fe4,(((b1>>0)&0xf)<<1)|((b1>>6)&1));
1454 	pvc_w8(0x1fe5, (b1>>7));
1455 }
1456 
1457 
pvc_prot2(void)1458 void pvc_prot2( void ) // on writes to e8/e9/ea/eb
1459 {
1460 	unsigned char b1, b2, b3, b4;
1461 	b1 = pvc_r8(0x1fe9);
1462 	b2 = pvc_r8(0x1fe8);
1463 	b3 = pvc_r8(0x1feb);
1464 	b4 = pvc_r8(0x1fea);
1465 	pvc_w8(0x1fec,(b2>>1)|((b1>>1)<<4));
1466 	pvc_w8(0x1fed,(b4>>1)|((b2&1)<<4)|((b1&1)<<5)|((b4&1)<<6)|((b3&1)<<7));
1467 }
1468 
pvc_write_bankswitch(void)1469 void pvc_write_bankswitch( void )
1470 {
1471 	UINT32 bankaddress;
1472 	bankaddress = ((CartRAM[0xff8]>>8)|(CartRAM[0xff9]<<8));
1473 	*(((unsigned char *)CartRAM) + BYTE_XOR_LE(0x1ff0)) = 0xA0;
1474 	*(((unsigned char *)CartRAM) + BYTE_XOR_LE(0x1ff1)) &= 0xFE;
1475 	*(((unsigned char *)CartRAM) + BYTE_XOR_LE(0x1ff3)) &= 0x7F;
1476 	neogeo_set_cpu1_second_bank(bankaddress+0x100000);
1477 }
1478 
READ16_HANDLER(pvc_prot_r)1479 static READ16_HANDLER( pvc_prot_r )
1480 {
1481 	return CartRAM[ offset ];
1482 }
1483 
WRITE16_HANDLER(pvc_prot_w)1484 static WRITE16_HANDLER( pvc_prot_w )
1485 {
1486 	COMBINE_DATA( &CartRAM[ offset ] );
1487 	if (offset == 0xFF0)pvc_prot1();
1488 	else if(offset >= 0xFF4 && offset <= 0xFF5)pvc_prot2();
1489 	else if(offset >= 0xFF8)pvc_write_bankswitch();
1490 }
1491 
install_pvc_protection(void)1492 void install_pvc_protection( void )
1493 {
1494 	install_mem_read16_handler(0, 0x2fe000, 0x2fffff, pvc_prot_r);
1495 	install_mem_write16_handler(0, 0x2fe000, 0x2fffff, pvc_prot_w);
1496 }
1497 
1498 static UINT16 kof2003_tbl[4096];
1499 
READ16_HANDLER(kof2003_r)1500 READ16_HANDLER( kof2003_r)
1501 {
1502 	return kof2003_tbl[offset];
1503 }
1504 
WRITE16_HANDLER(kof2003_w)1505 WRITE16_HANDLER( kof2003_w )
1506 {
1507 	data = COMBINE_DATA(&kof2003_tbl[offset]);
1508 	if (offset == 0x1ff0/2 || offset == 0x1ff2/2) {
1509 		UINT8* cr = (UINT8 *)kof2003_tbl;
1510 		UINT32 address = (cr[0x1ff3]<<16)|(cr[0x1ff2]<<8)|cr[0x1ff1];
1511 		UINT8 prt = cr[0x1ff2];
1512 		UINT8* mem = (UINT8 *)memory_region(REGION_CPU1);
1513 
1514 		cr[0x1ff0] =  0xa0;
1515 		cr[0x1ff1] &= 0xfe;
1516 		cr[0x1ff3] &= 0x7f;
1517 		neogeo_set_cpu1_second_bank(address+0x100000);
1518 
1519 		mem[0x58196] = prt;
1520 	}
1521 }
1522 
WRITE16_HANDLER(kof2003p_w)1523 WRITE16_HANDLER( kof2003p_w )
1524 {
1525 	data = COMBINE_DATA(&kof2003_tbl[offset]);
1526 	if (offset == 0x1ff0/2 || offset == 0x1ff2/2) {
1527 		UINT8* cr = (UINT8 *)kof2003_tbl;
1528 		UINT32 address = (cr[0x1ff3]<<16)|(cr[0x1ff2]<<8)|cr[0x1ff0];
1529 		UINT8 prt = cr[0x1ff2];
1530 		UINT8* mem = (UINT8 *)memory_region(REGION_CPU1);
1531 
1532 		cr[0x1ff0] &= 0xfe;
1533 		cr[0x1ff3] &= 0x7f;
1534 		neogeo_set_cpu1_second_bank(address+0x100000);
1535 
1536 		mem[0x58196] = prt;
1537 	}
1538 }
1539 
kf2k3bl_install_protection(void)1540 void kf2k3bl_install_protection(void)
1541 {
1542     install_mem_read16_handler( 0, 0x2fe000, 0x2fffff, kof2003_r );
1543     install_mem_write16_handler( 0, 0x2fe000, 0x2fffff, kof2003_w );
1544 }
1545 
kf2k3pl_px_decrypt(void)1546 void kf2k3pl_px_decrypt( void )
1547 {
1548 	UINT16*tmp = malloc(0x100000);
1549 	UINT16*rom = (UINT16*)memory_region( REGION_CPU1 );
1550 	int j;
1551 	int i;
1552 
1553 	for (i = 0;i < 0x700000/2;i+=0x100000/2)
1554 	{
1555 		memcpy(tmp,&rom[i],0x100000);
1556 		for (j = 0;j < 0x100000/2;j++)
1557 			rom[i+j] = tmp[BITSWAP24(j,23,22,21,20,19,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)];
1558 	}
1559 	free(tmp);
1560 
1561 	/* patched by Altera protection chip on PCB */
1562 	rom[0xf38ac/2] = 0x4e75;
1563 }
1564 
kf2k3pl_install_protection(void)1565 void kf2k3pl_install_protection(void)
1566 {
1567     install_mem_read16_handler( 0, 0x2fe000, 0x2fffff, kof2003_r );
1568     install_mem_write16_handler( 0, 0x2fe000, 0x2fffff,  kof2003p_w );
1569 }
1570 
kf2k3upl_px_decrypt(void)1571 void kf2k3upl_px_decrypt( void )
1572 {
1573 	{
1574 		UINT8 *src = memory_region(REGION_CPU1);
1575 		memmove(src+0x100000, src, 0x600000);
1576 		memmove(src, src+0x700000, 0x100000);
1577 	}
1578 
1579 	{
1580 
1581 		int ofst;
1582 		int i;
1583 		UINT8 *rom = memory_region( REGION_CPU1 ) + 0xfe000;
1584 		UINT8 *buf = memory_region( REGION_CPU1 ) + 0xd0610;
1585 
1586 		for( i = 0; i < 0x2000 / 2; i++ ){
1587 			ofst = (i & 0xff00) + BITSWAP8( (i & 0x00ff), 7, 6, 0, 4, 3, 2, 1, 5 );
1588 			memcpy( &rom[ i * 2 ], &buf[ ofst * 2 ], 2 );
1589 		}
1590 	}
1591 }
1592 
kf2k3upl_install_protection(void)1593 void kf2k3upl_install_protection(void)
1594 {
1595     install_mem_read16_handler( 0, 0x2fe000, 0x2fffff, kof2003_r );
1596     install_mem_write16_handler( 0, 0x2fe000, 0x2fffff, kof2003_w );
1597 }
1598 
1599 /* kof99, garou, garouo, mslug3 and kof2000 have and SMA chip which contains program code and decrypts the 68k roms */
kof99_decrypt_68k(void)1600 void kof99_decrypt_68k(void)
1601 {
1602 	UINT16 *rom;
1603 	int i,j;
1604 
1605 	rom = (UINT16 *)(memory_region(REGION_CPU1) + 0x100000);
1606 	/* swap data lines on the whole ROMs */
1607 	for (i = 0;i < 0x800000/2;i++)
1608 	{
1609 		rom[i] = BITSWAP16(rom[i],13,7,3,0,9,4,5,6,1,12,8,14,10,11,2,15);
1610 	}
1611 
1612 	/* swap address lines for the banked part */
1613 	for (i = 0;i < 0x600000/2;i+=0x800/2)
1614 	{
1615 		UINT16 buffer[0x800/2];
1616 		memcpy(buffer,&rom[i],0x800);
1617 		for (j = 0;j < 0x800/2;j++)
1618 		{
1619 			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)];
1620 		}
1621 	}
1622 
1623 	/* swap address lines & relocate fixed part */
1624 	rom = (UINT16 *)memory_region(REGION_CPU1);
1625 	for (i = 0;i < 0x0c0000/2;i++)
1626 	{
1627 		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)];
1628 	}
1629 }
1630 
WRITE16_HANDLER(kof99_bankswitch_w)1631 static WRITE16_HANDLER( kof99_bankswitch_w )
1632 {
1633 	int bankaddress;
1634 	static int bankoffset[64] =
1635 	{
1636 		0x000000, 0x100000, 0x200000, 0x300000,
1637 		0x3cc000, 0x4cc000, 0x3f2000, 0x4f2000,
1638 		0x407800, 0x507800, 0x40d000, 0x50d000,
1639 		0x417800, 0x517800, 0x420800, 0x520800,
1640 		0x424800, 0x524800, 0x429000, 0x529000,
1641 		0x42e800, 0x52e800, 0x431800, 0x531800,
1642 		0x54d000, 0x551000, 0x567000, 0x592800,
1643 		0x588800, 0x581800, 0x599800, 0x594800,
1644 		0x598000,	/* rest not used? */
1645 	};
1646 
1647 	/* unscramble bank number */
1648 	data =
1649 		(((data>>14)&1)<<0)+
1650 		(((data>> 6)&1)<<1)+
1651 		(((data>> 8)&1)<<2)+
1652 		(((data>>10)&1)<<3)+
1653 		(((data>>12)&1)<<4)+
1654 		(((data>> 5)&1)<<5);
1655 
1656 	bankaddress = 0x100000 + bankoffset[data];
1657 
1658 	neogeo_set_cpu1_second_bank(bankaddress);
1659 }
1660 
kof99_install_protection(void)1661 void kof99_install_protection(void)
1662 {
1663 	install_mem_write16_handler(0, 0x2ffff0, 0x2ffff1, kof99_bankswitch_w);
1664 	install_mem_read16_handler(0, 0x2fe446, 0x2fe447, prot_9a37_r);
1665 	install_mem_read16_handler(0, 0x2ffff8, 0x2ffff9, sma_random_r);
1666 	install_mem_read16_handler(0, 0x2ffffa, 0x2ffffb, sma_random_r);
1667 }
1668 
garou_decrypt_68k(void)1669 void garou_decrypt_68k(void)
1670 {
1671 	data16_t *rom;
1672 	int i,j;
1673 
1674 	/* thanks to Razoola and Mr K for the info */
1675 	rom = (data16_t *)(memory_region(REGION_CPU1) + 0x100000);
1676 	/* swap data lines on the whole ROMs */
1677 	for (i = 0;i < 0x800000/2;i++)
1678 	{
1679 		rom[i] = BITSWAP16(rom[i],13,12,14,10,8,2,3,1,5,9,11,4,15,0,6,7);
1680 	}
1681 
1682 	/* swap address lines & relocate fixed part */
1683 	rom = (data16_t *)memory_region(REGION_CPU1);
1684 	for (i = 0;i < 0x0c0000/2;i++)
1685 	{
1686 		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)];
1687 	}
1688 
1689 	/* swap address lines for the banked part */
1690 	rom = (data16_t *)(memory_region(REGION_CPU1) + 0x100000);
1691 	for (i = 0;i < 0x800000/2;i+=0x8000/2)
1692 	{
1693 		data16_t buffer[0x8000/2];
1694 		memcpy(buffer,&rom[i],0x8000);
1695 		for (j = 0;j < 0x8000/2;j++)
1696 		{
1697 			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)];
1698 		}
1699 	}
1700 }
1701 
WRITE16_HANDLER(garou_bankswitch_w)1702 static WRITE16_HANDLER( garou_bankswitch_w )
1703 {
1704 	/* thanks to Razoola and Mr K for the info */
1705 	int bankaddress;
1706 	static int bankoffset[64] =
1707 	{
1708 		0x000000, 0x100000, 0x200000, 0x300000, // 00
1709 		0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04
1710 		0x2f0000, 0x3f0000, 0x400000, 0x500000, // 08
1711 		0x420000, 0x520000, 0x440000, 0x540000, // 12
1712 		0x498000, 0x598000, 0x4a0000, 0x5a0000, // 16
1713 		0x4a8000, 0x5a8000, 0x4b0000, 0x5b0000, // 20
1714 		0x4b8000, 0x5b8000, 0x4c0000, 0x5c0000, // 24
1715 		0x4c8000, 0x5c8000, 0x4d0000, 0x5d0000, // 28
1716 		0x458000, 0x558000, 0x460000, 0x560000, // 32
1717 		0x468000, 0x568000, 0x470000, 0x570000, // 36
1718 		0x478000, 0x578000, 0x480000, 0x580000, // 40
1719 		0x488000, 0x588000, 0x490000, 0x590000, // 44
1720 		0x5d0000, 0x5d8000, 0x5e0000, 0x5e8000, // 48
1721 		0x5f0000, 0x5f8000, 0x600000, /* rest not used? */
1722 	};
1723 
1724 	/* unscramble bank number */
1725 	data =
1726 		(((data>> 5)&1)<<0)+
1727 		(((data>> 9)&1)<<1)+
1728 		(((data>> 7)&1)<<2)+
1729 		(((data>> 6)&1)<<3)+
1730 		(((data>>14)&1)<<4)+
1731 		(((data>>12)&1)<<5);
1732 
1733 	bankaddress = 0x100000 + bankoffset[data];
1734 
1735 	neogeo_set_cpu1_second_bank(bankaddress);
1736 }
1737 
garou_install_protection(void)1738 void garou_install_protection(void)
1739 {
1740 	install_mem_write16_handler(0, 0x2fffc0, 0x2fffc1, garou_bankswitch_w);
1741 	install_mem_read16_handler(0, 0x2fe446, 0x2fe447, prot_9a37_r);
1742 	install_mem_read16_handler(0, 0x2ffff8, 0x2ffff9, sma_random_r);
1743 	install_mem_read16_handler(0, 0x2ffffa, 0x2ffffb, sma_random_r);
1744 }
1745 
garouo_decrypt_68k(void)1746 void garouo_decrypt_68k(void)
1747 {
1748 	data16_t *rom;
1749 	int i,j;
1750 
1751 	/* thanks to Razoola and Mr K for the info */
1752 	rom = (data16_t *)(memory_region(REGION_CPU1) + 0x100000);
1753 	/* swap data lines on the whole ROMs */
1754 	for (i = 0;i < 0x800000/2;i++)
1755 	{
1756 		rom[i] = BITSWAP16(rom[i],14,5,1,11,7,4,10,15,3,12,8,13,0,2,9,6);
1757 	}
1758 
1759 	/* swap address lines & relocate fixed part */
1760 	rom = (data16_t *)memory_region(REGION_CPU1);
1761 	for (i = 0;i < 0x0c0000/2;i++)
1762 	{
1763 		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)];
1764 	}
1765 
1766 	/* swap address lines for the banked part */
1767 	rom = (data16_t *)(memory_region(REGION_CPU1) + 0x100000);
1768 	for (i = 0;i < 0x800000/2;i+=0x8000/2)
1769 	{
1770 		data16_t buffer[0x8000/2];
1771 		memcpy(buffer,&rom[i],0x8000);
1772 		for (j = 0;j < 0x8000/2;j++)
1773 		{
1774 			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)];
1775 		}
1776 	}
1777 }
1778 
WRITE16_HANDLER(garouo_bankswitch_w)1779 static WRITE16_HANDLER( garouo_bankswitch_w )
1780 {
1781 	/* thanks to Razoola and Mr K for the info */
1782 	int bankaddress;
1783 	static int bankoffset[64] =
1784 	{
1785 		0x000000, 0x100000, 0x200000, 0x300000, // 00
1786 		0x280000, 0x380000, 0x2d0000, 0x3d0000, // 04
1787 		0x2c8000, 0x3c8000, 0x400000, 0x500000, // 08
1788 		0x420000, 0x520000, 0x440000, 0x540000, // 12
1789 		0x598000, 0x698000, 0x5a0000, 0x6a0000, // 16
1790 		0x5a8000, 0x6a8000, 0x5b0000, 0x6b0000, // 20
1791 		0x5b8000, 0x6b8000, 0x5c0000, 0x6c0000, // 24
1792 		0x5c8000, 0x6c8000, 0x5d0000, 0x6d0000, // 28
1793 		0x458000, 0x558000, 0x460000, 0x560000, // 32
1794 		0x468000, 0x568000, 0x470000, 0x570000, // 36
1795 		0x478000, 0x578000, 0x480000, 0x580000, // 40
1796 		0x488000, 0x588000, 0x490000, 0x590000, // 44
1797 		0x5d8000, 0x6d8000, 0x5e0000, 0x6e0000, // 48
1798 		0x5e8000, 0x6e8000, 0x6e8000, 0x000000, // 52
1799 		0x000000, 0x000000, 0x000000, 0x000000, // 56
1800 		0x000000, 0x000000, 0x000000, 0x000000, // 60
1801 	};
1802 
1803 	/* unscramble bank number */
1804 	data =
1805 		(((data>> 4)&1)<<0)+
1806 		(((data>> 8)&1)<<1)+
1807 		(((data>>14)&1)<<2)+
1808 		(((data>> 2)&1)<<3)+
1809 		(((data>>11)&1)<<4)+
1810 		(((data>>13)&1)<<5);
1811 
1812 	bankaddress = 0x100000 + bankoffset[data];
1813 
1814 	neogeo_set_cpu1_second_bank(bankaddress);
1815 }
1816 
garouo_install_protection(void)1817 void garouo_install_protection(void)
1818 {
1819 	install_mem_write16_handler(0, 0x2fffc0, 0x2fffc1, garouo_bankswitch_w);
1820 	install_mem_read16_handler(0, 0x2fe446, 0x2fe447, prot_9a37_r);
1821 	install_mem_read16_handler(0, 0x2ffff8, 0x2ffff9, sma_random_r);
1822 	install_mem_read16_handler(0, 0x2ffffa, 0x2ffffb, sma_random_r);
1823 }
1824 
mslug3_decrypt_68k(void)1825 void mslug3_decrypt_68k(void)
1826 {
1827 	data16_t *rom;
1828 	int i,j;
1829 
1830 	/* thanks to Razoola and Mr K for the info */
1831 	rom = (data16_t *)(memory_region(REGION_CPU1) + 0x100000);
1832 	/* swap data lines on the whole ROMs */
1833 	for (i = 0;i < 0x800000/2;i++)
1834 	{
1835 		rom[i] = BITSWAP16(rom[i],4,11,14,3,1,13,0,7,2,8,12,15,10,9,5,6);
1836 	}
1837 
1838 	/* swap address lines & relocate fixed part */
1839 	rom = (data16_t *)memory_region(REGION_CPU1);
1840 	for (i = 0;i < 0x0c0000/2;i++)
1841 	{
1842 		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)];
1843 	}
1844 
1845 	/* swap address lines for the banked part */
1846 	rom = (data16_t *)(memory_region(REGION_CPU1) + 0x100000);
1847 	for (i = 0;i < 0x800000/2;i+=0x10000/2)
1848 	{
1849 		data16_t buffer[0x10000/2];
1850 		memcpy(buffer,&rom[i],0x10000);
1851 		for (j = 0;j < 0x10000/2;j++)
1852 		{
1853 			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)];
1854 		}
1855 	}
1856 }
1857 
WRITE16_HANDLER(mslug3_bankswitch_w)1858 static WRITE16_HANDLER( mslug3_bankswitch_w )
1859 {
1860 	/* thanks to Razoola and Mr K for the info */
1861 	int bankaddress;
1862 	static int bankoffset[64] =
1863 	{
1864 	  0x000000, 0x020000, 0x040000, 0x060000, // 00
1865 	  0x070000, 0x090000, 0x0b0000, 0x0d0000, // 04
1866 	  0x0e0000, 0x0f0000, 0x120000, 0x130000, // 08
1867 	  0x140000, 0x150000, 0x180000, 0x190000, // 12
1868 	  0x1a0000, 0x1b0000, 0x1e0000, 0x1f0000, // 16
1869 	  0x200000, 0x210000, 0x240000, 0x250000, // 20
1870 	  0x260000, 0x270000, 0x2a0000, 0x2b0000, // 24
1871 	  0x2c0000, 0x2d0000, 0x300000, 0x310000, // 28
1872 	  0x320000, 0x330000, 0x360000, 0x370000, // 32
1873 	  0x380000, 0x390000, 0x3c0000, 0x3d0000, // 36
1874 	  0x400000, 0x410000, 0x440000, 0x450000, // 40
1875 	  0x460000, 0x470000, 0x4a0000, 0x4b0000, // 44
1876 	  0x4c0000, /* rest not used? */
1877 	};
1878 
1879 	/* unscramble bank number */
1880 	data =
1881 		(((data>>14)&1)<<0)+
1882 		(((data>>12)&1)<<1)+
1883 		(((data>>15)&1)<<2)+
1884 		(((data>> 6)&1)<<3)+
1885 		(((data>> 3)&1)<<4)+
1886 		(((data>> 9)&1)<<5);
1887 
1888 	bankaddress = 0x100000 + bankoffset[data];
1889 
1890 	neogeo_set_cpu1_second_bank(bankaddress);
1891 }
1892 
mslug3_install_protection(void)1893 void mslug3_install_protection(void)
1894 {
1895 	install_mem_write16_handler(0, 0x2fffe4, 0x2fffe5, mslug3_bankswitch_w);
1896 	install_mem_read16_handler(0, 0x2fe446, 0x2fe447, prot_9a37_r);
1897 	install_mem_read16_handler(0, 0x2ffff8, 0x2ffff9, sma_random_r);
1898 	install_mem_read16_handler(0, 0x2ffffa, 0x2ffffb, sma_random_r);
1899 }
1900 
kof2000_decrypt_68k(void)1901 void kof2000_decrypt_68k(void)
1902 {
1903 	data16_t *rom;
1904 	int i,j;
1905 
1906 	/* thanks to Razoola and Mr K for the info */
1907 	rom = (data16_t *)(memory_region(REGION_CPU1) + 0x100000);
1908 	/* swap data lines on the whole ROMs */
1909 	for (i = 0;i < 0x800000/2;i++)
1910 	{
1911 		rom[i] = BITSWAP16(rom[i],12,8,11,3,15,14,7,0,10,13,6,5,9,2,1,4);
1912 	}
1913 
1914 	/* swap address lines for the banked part */
1915 	for (i = 0;i < 0x63a000/2;i+=0x800/2)
1916 	{
1917 		data16_t buffer[0x800/2];
1918 		memcpy(buffer,&rom[i],0x800);
1919 		for (j = 0;j < 0x800/2;j++)
1920 		{
1921 			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)];
1922 		}
1923 	}
1924 
1925 	/* swap address lines & relocate fixed part */
1926 	rom = (data16_t *)memory_region(REGION_CPU1);
1927 	for (i = 0;i < 0x0c0000/2;i++)
1928 	{
1929 		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)];
1930 	}
1931 }
1932 
WRITE16_HANDLER(kof2000_bankswitch_w)1933 static WRITE16_HANDLER( kof2000_bankswitch_w )
1934 {
1935 	/* thanks to Razoola and Mr K for the info */
1936 	int bankaddress;
1937 	static int bankoffset[64] =
1938 	{
1939 		0x000000, 0x100000, 0x200000, 0x300000, // 00
1940 		0x3f7800, 0x4f7800, 0x3ff800, 0x4ff800, // 04
1941 		0x407800, 0x507800, 0x40f800, 0x50f800, // 08
1942 		0x416800, 0x516800, 0x41d800, 0x51d800, // 12
1943 		0x424000, 0x524000, 0x523800, 0x623800, // 16
1944 		0x526000, 0x626000, 0x528000, 0x628000, // 20
1945 		0x52a000, 0x62a000, 0x52b800, 0x62b800, // 24
1946 		0x52d000, 0x62d000, 0x52e800, 0x62e800, // 28
1947 		0x618000, 0x619000, 0x61a000, 0x61a800, // 32
1948 	};
1949 
1950 	/* unscramble bank number */
1951 	data =
1952 		(((data>>15)&1)<<0)+
1953 		(((data>>14)&1)<<1)+
1954 		(((data>> 7)&1)<<2)+
1955 		(((data>> 3)&1)<<3)+
1956 		(((data>>10)&1)<<4)+
1957 		(((data>> 5)&1)<<5);
1958 
1959 	bankaddress = 0x100000 + bankoffset[data];
1960 
1961 	neogeo_set_cpu1_second_bank(bankaddress);
1962 }
1963 
kof2000_install_protection(void)1964 void kof2000_install_protection(void)
1965 {
1966 	install_mem_write16_handler(0, 0x2fffec, 0x2fffed, kof2000_bankswitch_w);
1967 	install_mem_read16_handler(0, 0x2fe446, 0x2fe447, prot_9a37_r);
1968 	install_mem_read16_handler(0, 0x2ffff8, 0x2ffff9, sma_random_r);
1969 	install_mem_read16_handler(0, 0x2ffffa, 0x2ffffb, sma_random_r);
1970 }
1971 
1972 /* Kof98 uses an early encryption, quite different from the others */
kof98_decrypt_68k(void)1973 void kof98_decrypt_68k(void)
1974 {
1975 	UINT8 *src = memory_region(REGION_CPU1);
1976 	UINT8 *dst = malloc(0x200000);
1977 	int i, j, k;
1978 	static const unsigned int sec[]={0x000000,0x100000,0x000004,0x100004,0x10000a,0x00000a,0x10000e,0x00000e};
1979 	static const unsigned int pos[]={0x000,0x004,0x00a,0x00e};
1980 
1981 	memcpy( dst, src, 0x200000);
1982 	for( i=0x800; i<0x100000; i+=0x200 )
1983 	{
1984 		for( j=0; j<0x100; j+=0x10 )
1985 		{
1986 			for( k=0; k<16; k+=2)
1987 			{
1988 				memcpy( &src[i+j+k],       &dst[ i+j+sec[k/2]+0x100 ], 2 );
1989 				memcpy( &src[i+j+k+0x100], &dst[ i+j+sec[k/2] ],       2 );
1990 			}
1991 			if( i >= 0x080000 && i < 0x0c0000)
1992 			{
1993 				for( k=0; k<4; k++ )
1994 				{
1995 					memcpy( &src[i+j+pos[k]],       &dst[i+j+pos[k]],       2 );
1996 					memcpy( &src[i+j+pos[k]+0x100], &dst[i+j+pos[k]+0x100], 2 );
1997 				}
1998 			}
1999 			else if( i >= 0x0c0000 )
2000 			{
2001 				for( k=0; k<4; k++ )
2002 				{
2003 					memcpy( &src[i+j+pos[k]],       &dst[i+j+pos[k]+0x100], 2 );
2004 					memcpy( &src[i+j+pos[k]+0x100], &dst[i+j+pos[k]],       2 );
2005 				}
2006 			}
2007 		}
2008 		memcpy( &src[i+0x000000], &dst[i+0x000000], 2 );
2009 		memcpy( &src[i+0x000002], &dst[i+0x100000], 2 );
2010 		memcpy( &src[i+0x000100], &dst[i+0x000100], 2 );
2011 		memcpy( &src[i+0x000102], &dst[i+0x100100], 2 );
2012 	}
2013 	memcpy( &src[0x100000], &src[0x200000], 0x400000 );
2014 
2015 	free(dst);
2016 }
2017 
WRITE16_HANDLER(kof98_prot_w)2018 WRITE16_HANDLER ( kof98_prot_w )
2019 {
2020 	/* info from razoola */
2021 	UINT16* mem16 = (UINT16*)memory_region(REGION_CPU1);
2022 
2023 	switch (data)
2024 	{
2025 		case 0x0090:
2026 		logerror ("%06x kof98 - protection 0x0090 old %04x %04x\n",activecpu_get_pc(), mem16[0x100/2], mem16[0x102/2]);
2027 		mem16[0x100/2] = 0x00c2; mem16[0x102/2] = 0x00fd;
2028 		break;
2029 
2030 		case 0x00f0:
2031 		logerror ("%06x kof98 - protection 0x00f0 old %04x %04x\n",activecpu_get_pc(), mem16[0x100/2], mem16[0x102/2]);
2032 		mem16[0x100/2] = 0x4e45; mem16[0x102/2] = 0x4f2d;
2033 		break;
2034 
2035 		default: // 00aa is written, but not needed?
2036 		logerror ("%06x kof98 - unknown protection write %04x\n",activecpu_get_pc(), data);
2037 		break;
2038 	}
2039 }
2040 
install_kof98_protection(void)2041 void install_kof98_protection(void)
2042 {
2043 	/* when 0x20aaaa contains 0x0090 (word) then 0x100 (normally the neogeo header) should return 0x00c200fd
2044    worked out using real hw */
2045 
2046 		install_mem_write16_handler(0, 0x20aaaa, 0x20aaab, kof98_prot_w);
2047 }
2048 
matrim_decrypt_68k(void)2049 void matrim_decrypt_68k(void)
2050 {
2051 	int i;
2052 	unsigned int sec[]={0x100000,0x280000,0x300000,0x180000,0x000000,0x380000,0x200000,0x080000};
2053 	UINT8 *src = memory_region(REGION_CPU1)+0x100000;
2054 	UINT8 *dst = malloc(0x400000);
2055 	if (dst)
2056 	{
2057 		memcpy( dst, src, 0x400000);
2058 		for( i=0; i<8; ++i )
2059 		{
2060 			memcpy( src+i*0x80000, dst+sec[i], 0x80000 );
2061 		}
2062 	free(dst);
2063 	}
2064 }
2065 
svcboot_px_decrypt(void)2066 void svcboot_px_decrypt( void )
2067 {
2068 	static const unsigned char sec[] = {
2069 		0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00
2070 	};
2071 	int i;
2072 	int size = memory_region_length( REGION_CPU1 );
2073 	UINT8 *src = memory_region( REGION_CPU1 );
2074 	UINT8 *dst = malloc( size );
2075 	int ofst;
2076 	for( i = 0; i < size / 0x100000; i++ ){
2077 		memcpy( &dst[ i * 0x100000 ], &src[ sec[ i ] * 0x100000 ], 0x100000 );
2078 	}
2079 	for( i = 0; i < size / 2; i++ ){
2080 		ofst = BITSWAP8( (i & 0x0000ff), 7, 6, 1, 0, 3, 2, 5, 4 );
2081 		ofst += (i & 0xffff00);
2082 		memcpy( &src[ i * 2 ], &dst[ ofst * 2 ], 0x02 );
2083 	}
2084 	free( dst );
2085 }
2086 
svcboot_cx_decrypt(void)2087 void svcboot_cx_decrypt( void )
2088 {
2089 	static const unsigned char idx_tbl[ 0x10 ] = {
2090 		0, 1, 0, 1, 2, 3, 2, 3, 3, 4, 3, 4, 4, 5, 4, 5,
2091 	};
2092 	static const unsigned char bitswap4_tbl[ 6 ][ 4 ] = {
2093 		{ 3, 0, 1, 2 },
2094 		{ 2, 3, 0, 1 },
2095 		{ 1, 2, 3, 0 },
2096 		{ 0, 1, 2, 3 },
2097 		{ 3, 2, 1, 0 },
2098 		{ 3, 0, 2, 1 },
2099 	};
2100 	int i;
2101 	int size = memory_region_length( REGION_GFX3 );
2102 	UINT8 *src = memory_region( REGION_GFX3 );
2103 	UINT8 *dst = malloc( size );
2104 	int ofst;
2105 	memcpy( dst, src, size );
2106 	for( i = 0; i < size / 0x80; i++ ){
2107 		int idx = idx_tbl[ (i & 0xf00) >> 8 ];
2108 		int bit0 = bitswap4_tbl[ idx ][ 0 ];
2109 		int bit1 = bitswap4_tbl[ idx ][ 1 ];
2110 		int bit2 = bitswap4_tbl[ idx ][ 2 ];
2111 		int bit3 = bitswap4_tbl[ idx ][ 3 ];
2112 		ofst = BITSWAP8( (i & 0x0000ff), 7, 6, 5, 4, bit3, bit2, bit1, bit0 );
2113 		ofst += (i & 0xfffff00);
2114 		memcpy( &src[ i * 0x80 ], &dst[ ofst * 0x80 ], 0x80 );
2115 	}
2116 	free( dst );
2117 }
2118 
samsho5_decrypt_68k(void)2119 void samsho5_decrypt_68k(void)
2120 {
2121 	int i;
2122 	static const unsigned int sec[]={0x000000,0x080000,0x700000,0x680000,0x500000,0x180000,0x200000,0x480000,0x300000,0x780000,0x600000,0x280000,0x100000,0x580000,0x400000,0x380000};
2123 	UINT8 *src = memory_region(REGION_CPU1);
2124 	UINT8 *dst = malloc(0x800000);
2125 
2126 		memcpy( dst, src, 0x800000 );
2127 		for( i=0; i<16; ++i )
2128 		{
2129 			memcpy( src+i*0x80000, dst+sec[i], 0x80000 );
2130 		}
2131 	free(dst);
2132 }
2133 
samsh5sp_decrypt_68k(void)2134 void samsh5sp_decrypt_68k(void)
2135 {
2136 		/* Descrambling Px by Vorador from speksnk Coneverted to Mame code by James */
2137 	UINT8 *src = memory_region(REGION_CPU1);
2138 	UINT8 *dst = malloc(0x800000);
2139 	int i;
2140 	unsigned int sec[]={0x0,0x1,0xA,0x9,0xC,0xB,0xE,0x5,0x2,0xD,0x8,0xF,0x4,0x7,0x6,0x3};
2141 	if (dst)
2142 	{
2143   memcpy(dst,src,0x800000);
2144 
2145   for(i=0;i<0x10;i++)
2146   {
2147   	memcpy(src+i*0x80000,dst+sec[i]*0x80000,0x80000);
2148   }
2149   free(dst);
2150 	}
2151 }
2152 
mslug5_decrypt_68k(void)2153 void mslug5_decrypt_68k(void)
2154 {
2155 	static const unsigned char 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 };
2156 	static const unsigned char 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 };
2157 	int i;
2158 	int ofst;
2159 	int rom_size = 0x800000;
2160 	UINT8 *rom = memory_region( REGION_CPU1 );
2161 	UINT8 *buf = malloc( rom_size );
2162 
2163 	for( i = 0; i < 0x100000; i++ )
2164 	{
2165 		rom[ i ] ^= xor1[ (BYTE_XOR_LE(i) % 0x20) ];
2166 	}
2167 	for( i = 0x100000; i < 0x800000; i++ )
2168 	{
2169 		rom[ i ] ^= xor2[ (BYTE_XOR_LE(i) % 0x20) ];
2170 	}
2171 
2172 	for( i = 0x100000; i < 0x0800000; i += 4 )
2173 	{
2174 		UINT16 rom16;
2175 		rom16 = rom[BYTE_XOR_LE(i+1)] | rom[BYTE_XOR_LE(i+2)]<<8;
2176 		rom16 = BITSWAP16( rom16, 15, 14, 13, 12, 10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1, 0 );
2177 		rom[BYTE_XOR_LE(i+1)] = rom16&0xff;
2178 		rom[BYTE_XOR_LE(i+2)] = rom16>>8;
2179 	}
2180 	memcpy( buf, rom, rom_size );
2181 	for( i = 0; i < 0x0100000 / 0x10000; i++ )
2182 	{
2183 		ofst = (i & 0xf0) + BITSWAP8( (i & 0x0f), 7, 6, 5, 4, 1, 0, 3, 2 );
2184 		memcpy( &rom[ i * 0x10000 ], &buf[ ofst * 0x10000 ], 0x10000 );
2185 	}
2186 	for( i = 0x100000; i < 0x800000; i += 0x100 )
2187 	{
2188 		ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00700) + (BITSWAP8( ((i & 0x0ff000) >> 12), 5, 4, 7, 6, 1, 0, 3, 2 ) << 12);
2189 		memcpy( &rom[ i ], &buf[ ofst ], 0x100 );
2190 	}
2191 	memcpy( buf, rom, rom_size );
2192 	memcpy( &rom[ 0x100000 ], &buf[ 0x700000 ], 0x100000 );
2193 	memcpy( &rom[ 0x200000 ], &buf[ 0x100000 ], 0x600000 );
2194 	free( buf );
2195 }
2196 
2197 /* kof2003d Init Start */
kof2003_px_decrypt(void)2198 void kof2003_px_decrypt( void )
2199 {
2200 	const unsigned char xor2[ 0x20 ] = {
2201 		0xb4, 0x0f, 0x40, 0x6c, 0x38, 0x07, 0xd0, 0x3f, 0x53, 0x08, 0x80, 0xaa, 0xbe, 0x07, 0xc0, 0xfa,
2202 		0xd0, 0x08, 0x10, 0xd2, 0xf1, 0x03, 0x70, 0x7e, 0x87, 0x0B, 0x40, 0xf6, 0x2a, 0x0a, 0xe0, 0xf9
2203 	};
2204 
2205 	int i;
2206 	int ofst;
2207 	UINT8 *rom, *buf;
2208 
2209 	rom = memory_region( REGION_CPU1 );
2210 
2211 	for( i = 0x100000; i < 0x800000; i++ ){
2212 		rom[ i ] ^= xor2[ (i % 0x20) ];
2213 	}
2214 
2215 	for( i = 0x100000; i < 0x800000; i += 4 ){
2216 		UINT16 *rom16 = (UINT16*)&rom[ i + 1 ];
2217 		*rom16 = BITSWAP16( *rom16, 15, 14, 13, 12, 4, 5, 6, 7, 8, 9, 10, 11, 3, 2, 1, 0 );
2218 	}
2219 
2220 	buf = malloc( 0x800000 );
2221 	memcpy( buf, rom, 0x800000 );
2222 
2223 	for( i = 0; i < 0x0100000 / 0x10000; i++ ){
2224 		ofst = (i & 0xf0) + BITSWAP8( (i & 0x0f), 7, 6, 5, 4, 1, 0, 3, 2 );
2225 		memcpy( &rom[ i * 0x10000 ], &buf[ ofst * 0x10000 ], 0x10000 );
2226 	}
2227 
2228 	for( i = 0x100000; i < 0x800000; i += 0x100 ){
2229 		ofst = (i & 0xf000ff) +
2230 			   ((i & 0x000f00) ^ 0x00300) +
2231 			   (BITSWAP8( ((i & 0x0ff000) >> 12), 4, 5, 6, 7, 1, 0, 3, 2 ) << 12);
2232 
2233 		memcpy( &rom[ i ], &buf[ ofst ], 0x100 );
2234 	}
2235 
2236 	free( buf );
2237 
2238 	buf = malloc(0x900000);
2239 	memcpy( buf, rom, 0x900000 );
2240 
2241 	memcpy( &rom[0x100000], &buf[0x800000], 0x100000 );
2242 	memcpy( &rom[0x200000], &buf[0x100000], 0x700000 );
2243 
2244 	free(buf);
2245 }
2246 
kof2003_sx_decrypt(void)2247 void kof2003_sx_decrypt( void )
2248 {
2249 	int i;
2250 	int tx_size = memory_region_length( REGION_GFX1 );
2251 	int rom_size = memory_region_length( REGION_GFX3 );
2252 	UINT8 *src;
2253 	UINT8 *dst;
2254 
2255 	src = memory_region( REGION_GFX3 ) + rom_size - 0x1000000 - 0x80000;
2256 	dst = memory_region( REGION_GFX1 );
2257 
2258 	for( i = 0; i < tx_size / 2; i++ ){
2259 		dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
2260 	}
2261 
2262 	src = memory_region( REGION_GFX3 ) + rom_size - 0x80000;
2263 	dst = memory_region( REGION_GFX1 ) + 0x80000;
2264 
2265 	for( i = 0; i < tx_size / 2; i++ ){
2266 		dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
2267 	}
2268 
2269 	dst = memory_region( REGION_GFX1 );
2270 	for( i = 0; i < tx_size; i++ ){
2271 		dst[ i ] = BITSWAP8( dst[ i ] ^ 0xd2, 4, 0, 7, 2, 5, 1, 6, 3 );
2272 	}
2273 }
2274 
kf2k3pcb_decrypt_68k(void)2275 void kf2k3pcb_decrypt_68k( void )
2276 {
2277 	static const unsigned char 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 };
2278 	int i;
2279 	int ofst;
2280 	int rom_size = 0x900000;
2281 	UINT8 *rom = memory_region( REGION_CPU1 );
2282 	UINT8 *buf = malloc( rom_size );
2283 
2284 	for (i = 0; i < 0x100000; i++)
2285 	{
2286 		rom[ 0x800000 + i ] ^= rom[ 0x100002 | i ];
2287 	}
2288 	for( i = 0x100000; i < 0x800000; i++ )
2289 	{
2290 		rom[ i ] ^= xor2[ (i % 0x20) ];
2291 	}
2292 	for( i = 0x100000; i < 0x800000; i += 4 )
2293 	{
2294 		UINT16 *rom16 = (UINT16*)&rom[ i + 1 ];
2295 		*rom16 = BITSWAP16( *rom16, 15, 14, 13, 12, 4, 5, 6, 7, 8, 9, 10, 11, 3, 2, 1, 0 );
2296 	}
2297 	for( i = 0; i < 0x0100000 / 0x10000; i++ )
2298 	{
2299 		ofst = (i & 0xf0) + BITSWAP8( (i & 0x0f), 7, 6, 5, 4, 1, 0, 3, 2 );
2300 		memcpy( &buf[ i * 0x10000 ], &rom[ ofst * 0x10000 ], 0x10000 );
2301 	}
2302 	for( i = 0x100000; i < 0x900000; i += 0x100 )
2303 	{
2304 		ofst = (i & 0xf000ff) + ((i & 0x000f00) ^ 0x00300) + (BITSWAP8( ((i & 0x0ff000) >> 12), 4, 5, 6, 7, 1, 0, 3, 2 ) << 12);
2305 		memcpy( &buf[ i ], &rom[ ofst ], 0x100 );
2306 	}
2307 	memcpy (&rom[0x000000], &buf[0x000000], 0x100000);
2308 	memcpy (&rom[0x100000], &buf[0x800000], 0x100000);
2309 	memcpy (&rom[0x200000], &buf[0x100000], 0x700000);
2310 	free( buf );
2311 }
2312 
kf2k3pcb_gfx_decrypt(void)2313 void kf2k3pcb_gfx_decrypt( void )
2314 {
2315 	static const unsigned char xor[ 4 ] = { 0x34, 0x21, 0xc4, 0xe9 };
2316 	int i;
2317 	int ofst;
2318 	int rom_size = memory_region_length( REGION_GFX3 );
2319 	UINT8 *rom = memory_region( REGION_GFX3 );
2320 	UINT8 *buf = malloc( rom_size );
2321 
2322 	for ( i = 0; i < rom_size; i++ )
2323 	{
2324 		rom[ i ] ^= xor[ (i % 4) ];
2325 	}
2326 	for ( i = 0; i < rom_size; i+=4 )
2327 	{
2328 		UINT32 *rom32 = (UINT32*)&rom[ i ];
2329 		*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 );
2330 	}
2331 	memcpy( buf, rom, rom_size );
2332 	for ( i = 0; i < rom_size; i+=4 )
2333 	{
2334 		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 );
2335 		ofst ^= 0x000000;
2336 		ofst += (i & 0xff800000);;
2337 		memcpy( &rom[ ofst ], &buf[ i ], 0x04 );
2338 	}
2339 	free( buf );
2340 }
2341 
kf2k3pcb_decrypt_s1data(void)2342 void kf2k3pcb_decrypt_s1data( void )
2343 {
2344 	UINT8 *src;
2345 	UINT8 *dst;
2346 	int i;
2347 	int tx_size = memory_region_length( REGION_GFX1 );
2348 	int srom_size = memory_region_length( REGION_GFX3 );
2349 
2350 	src = memory_region( REGION_GFX3 ) + srom_size - 0x1000000 - 0x80000; // Decrypt S
2351 	dst = memory_region( REGION_GFX1 );
2352 
2353 	for( i = 0; i < tx_size / 2; i++ )
2354 	{
2355 		dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
2356 	}
2357 
2358 	src = memory_region( REGION_GFX3 ) + srom_size - 0x80000;
2359 	dst = memory_region( REGION_GFX1 ) + 0x80000;
2360 
2361 	for( i = 0; i < tx_size / 2; i++ )
2362 	{
2363 		dst[ i ] = src[ (i & ~0x1f) + ((i & 7) << 2) + ((~i & 8) >> 2) + ((i & 0x10) >> 4) ];
2364 	}
2365 
2366 	dst = memory_region( REGION_GFX1 );
2367 
2368 	for( i = 0; i < tx_size; i++ )
2369 	{
2370 		dst[ i ] = BITSWAP8( dst[ i ] ^ 0xd2, 4, 0, 7, 2, 5, 1, 6, 3 );
2371 	}
2372 }
2373 
kof2003biosdecode(void)2374 void kof2003biosdecode(void)
2375 {
2376 	static const UINT8 address[0x80]={
2377 		0xb9,0xb8,0x36,0x37,0x3d,0x3c,0xb2,0xb3,
2378 		0xb9,0xb8,0x36,0x37,0x3d,0x3c,0xb2,0xb3,
2379 		0x65,0xea,0x6f,0xe0,0xe1,0x6e,0xeb,0x64,
2380 		0x65,0xea,0x6f,0xe0,0xe1,0x6e,0xeb,0x64,
2381 		0x45,0xca,0x47,0xc8,0xc9,0x46,0xcb,0x44,
2382 		0x45,0xca,0x47,0xc8,0xc9,0x46,0xcb,0x44,
2383 		0x9a,0x15,0x98,0x17,0x1e,0x91,0x1c,0x93,
2384 		0x9a,0x15,0x98,0x17,0x1e,0x91,0x1c,0x93,
2385 		0x7e,0xf1,0x7c,0xf3,0xf0,0x7f,0xf2,0x7d,
2386 		0x7e,0xf1,0x7c,0xf3,0xf0,0x7f,0xf2,0x7d,
2387 		0x27,0xa8,0x25,0xaa,0xa3,0x2c,0xa1,0x2e,
2388 		0x27,0xa8,0x25,0xaa,0xa3,0x2c,0xa1,0x2e,
2389 		0x04,0x8b,0x06,0x89,0x80,0x0f,0x82,0x0d,
2390 		0x04,0x8b,0x06,0x89,0x80,0x0f,0x82,0x0d,
2391 		0xd3,0xd2,0x5c,0x5d,0x57,0x56,0xd8,0xd9,
2392 		0xd3,0xd2,0x5c,0x5d,0x57,0x56,0xd8,0xd9,
2393 	};
2394 	UINT16*src= (UINT16*)memory_region( REGION_USER1 );
2395 	UINT16*buf= (UINT16*)malloc(0x80000);
2396 	int	a,addr;
2397 
2398 		for (a=0;a<0x80000/2;a++)
2399 		{
2400 			//data xor
2401 			if (src[a] & 0x0004)	src[a] ^= 0x0001;
2402 			if (src[a] & 0x0010)	src[a] ^= 0x0002;
2403 			if (src[a] & 0x0020)	src[a] ^= 0x0008;
2404 			//address xor
2405 			addr  = a & ~0xff;
2406 			addr |= address[a & 0x7f];
2407 			if ( a & 0x00008)	addr ^= 0x0008;
2408 			if ( a & 0x00080)	addr ^= 0x0080;
2409 			if ( a & 0x00200)	addr ^= 0x0100;
2410 			if (~a & 0x02000)	addr ^= 0x0400;
2411 			if (~a & 0x10000)	addr ^= 0x1000;
2412 			if ( a & 0x02000)	addr ^= 0x8000;
2413 			buf[addr]=src[a];
2414 		}
2415 		memcpy(src,buf,0x80000);
2416 		free(buf);
2417 }
2418 
svcchaos_px_decrypt(void)2419 void svcchaos_px_decrypt( void )
2420 {
2421 	const unsigned char xor1[ 0x20 ] = {
2422 		0x3b, 0x6a, 0xf7, 0xb7, 0xe8, 0xa9, 0x20, 0x99, 0x9f, 0x39, 0x34, 0x0c, 0xc3, 0x9a, 0xa5, 0xc8,
2423 		0xb8, 0x18, 0xce, 0x56, 0x94, 0x44, 0xe3, 0x7a, 0xf7, 0xdd, 0x42, 0xf0, 0x18, 0x60, 0x92, 0x9f,
2424 	};
2425 
2426 	const unsigned char xor2[ 0x20 ] = {
2427 		0x69, 0x0b, 0x60, 0xd6, 0x4f, 0x01, 0x40, 0x1a, 0x9f, 0x0b, 0xf0, 0x75, 0x58, 0x0e, 0x60, 0xb4,
2428 		0x14, 0x04, 0x20, 0xe4, 0xb9, 0x0d, 0x10, 0x89, 0xeb, 0x07, 0x30, 0x90, 0x50, 0x0e, 0x20, 0x26,
2429 	};
2430 
2431 	int i;
2432 	int ofst;
2433 	UINT8 *rom, *buf;
2434 
2435 	rom = memory_region( REGION_CPU1 );
2436 
2437 	for( i = 0; i < 0x100000; i++ ){
2438 		rom[ i ] ^= xor1[ (i % 0x20) ];
2439 	}
2440 
2441 	for( i = 0x100000; i < 0x800000; i++ ){
2442 		rom[ i ] ^= xor2[ (i % 0x20) ];
2443 	}
2444 
2445 	for( i = 0x100000; i < 0x800000; i += 4 ){
2446 		UINT16 *rom16 = (UINT16*)&rom[ i + 1 ];
2447 		*rom16 = BITSWAP16( *rom16, 15, 14, 13, 12, 10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1, 0 );
2448 	}
2449 
2450 	buf = malloc( 0x800000 );
2451 	memcpy( buf, rom, 0x800000 );
2452 
2453 	for( i = 0; i < 0x0100000 / 0x10000; i++ ){
2454 		ofst = (i & 0xf0) + BITSWAP8( (i & 0x0f), 7, 6, 5, 4, 2, 3, 0, 1 );
2455 		memcpy( &rom[ i * 0x10000 ], &buf[ ofst * 0x10000 ], 0x10000 );
2456 	}
2457 
2458 	for( i = 0x100000; i < 0x800000; i += 0x100 ){
2459 		ofst = (i & 0xf000ff) +
2460 			   ((i & 0x000f00) ^ 0x00a00) +
2461 			   (BITSWAP8( ((i & 0x0ff000) >> 12), 4, 5, 6, 7, 1, 0, 3, 2 ) << 12);
2462 
2463 		memcpy( &rom[ i ], &buf[ ofst ], 0x100 );
2464 	}
2465 
2466 	free( buf );
2467 
2468 	buf = malloc( 0x800000 );
2469 	memcpy( buf, rom, 0x800000 );
2470 	memcpy( &rom[ 0x100000 ], &buf[ 0x700000 ], 0x100000 );
2471 	memcpy( &rom[ 0x200000 ], &buf[ 0x100000 ], 0x600000 );
2472 	free( buf );
2473 }
2474 
svcchaos_vx_decrypt(void)2475 void svcchaos_vx_decrypt( void )
2476 {
2477 	const unsigned char xor[ 0x08 ] = {
2478 		0xc3, 0xfd, 0x81, 0xac, 0x6d, 0xe7, 0xbf, 0x9e
2479 	};
2480 
2481 	int ofst;
2482 
2483 	int rom_size = memory_region_length( REGION_SOUND1 );
2484 	UINT8 *rom = memory_region( REGION_SOUND1 );
2485 	UINT8 *buf = malloc( rom_size );
2486 	int i;
2487 
2488 	memcpy( buf, rom, rom_size );
2489 
2490 	for( i=0;i<rom_size;i++ ){
2491 		ofst = (i & 0xfefffe) |
2492 			   ((i & 0x010000) >> 16) |
2493 			   ((i & 0x000001) << 16);
2494 
2495 		ofst ^= 0xc2000;
2496 
2497 		rom[ ofst ] = buf[ ((i + 0xffac28) & 0xffffff) ] ^ xor[ (ofst & 0x07) ];
2498 	}
2499 
2500 	free( buf );
2501 }
2502 
2503 /* svcchaos has an additional scramble on top of the standard CMC scrambling */
2504 
svcpcb_gfx_decrypt(void)2505 void svcpcb_gfx_decrypt( void )
2506 {
2507 	static const unsigned char xor[ 4 ] = { 0x34, 0x21, 0xc4, 0xe9 };
2508 	int i;
2509 	int ofst;
2510 	int rom_size = memory_region_length( REGION_GFX3 );
2511 	UINT8 *rom = memory_region( REGION_GFX3 );
2512 	UINT8 *buf = malloc( rom_size );
2513 
2514 	for( i = 0; i < rom_size; i++ )
2515 	{
2516 		rom[ i ] ^= xor[ (i % 4) ];
2517 	}
2518 	for( i = 0; i < rom_size; i += 4 )
2519 	{
2520 		UINT32 *rom32 = (UINT32*)&rom[ i ];
2521 		*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 );
2522 	}
2523 	memcpy( buf, rom, rom_size );
2524 	for( i = 0; i < rom_size / 4; i++ )
2525 	{
2526 		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 );
2527 		ofst ^= 0x0c8923;
2528 		ofst += (i & 0xffe00000);
2529 		memcpy( &rom[ i * 4 ], &buf[ ofst * 4 ], 0x04 );
2530 	}
2531 	free( buf );
2532 }
2533 
2534 /* and a further swap on the s1 data */
svcpcb_s1data_decrypt(void)2535 void svcpcb_s1data_decrypt( void )
2536 {
2537 	int i;
2538 	UINT8 *s1 = memory_region( REGION_GFX1 );
2539 	size_t s1_size = memory_region_length( REGION_GFX1 );
2540 
2541 	for( i = 0; i < s1_size; i++ ) // Decrypt S
2542 	{
2543 		s1[ i ] = BITSWAP8( s1[ i ] ^ 0xd2, 4, 0, 7, 2, 5, 1, 6, 3 );
2544 	}
2545 }
2546 
svcplus_px_decrypt(void)2547 void svcplus_px_decrypt( void )
2548 {
2549 	static const int sec[] = {
2550 		0x00, 0x03, 0x02, 0x05, 0x04, 0x01
2551 	};
2552 	int size = memory_region_length( REGION_CPU1 );
2553 	UINT8 *src = memory_region( REGION_CPU1 );
2554 	UINT8 *dst = malloc( size );
2555 	int i;
2556 	int ofst;
2557 	memcpy( dst, src, size );
2558 	for( i = 0; i < size / 2; i++ ){
2559 		ofst = BITSWAP24( (i & 0xfffff), 0x17, 0x16, 0x15, 0x14, 0x13, 0x00, 0x01, 0x02,
2560 										 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
2561 										 0x07, 0x06, 0x05, 0x04, 0x03, 0x10, 0x11, 0x12 );
2562 		ofst ^= 0x0f0007;
2563 		ofst += (i & 0xff00000);
2564 		memcpy( &src[ i * 0x02 ], &dst[ ofst * 0x02 ], 0x02 );
2565 	}
2566 	memcpy( dst, src, size );
2567 	for( i = 0; i < 6; i++ ){
2568 		memcpy( &src[ i * 0x100000 ], &dst[ sec[ i ] * 0x100000 ], 0x100000 );
2569 	}
2570 	free( dst );
2571 }
2572 
svcplus_px_hack(void)2573 void svcplus_px_hack( void )
2574 {
2575 	/* patched by the protection chip? */
2576 	UINT8 *src = memory_region( REGION_CPU1 );
2577 	src[ 0x0f8010 ] = 0x40;
2578 	src[ 0x0f8011 ] = 0x04;
2579 	src[ 0x0f8012 ] = 0x00;
2580 	src[ 0x0f8013 ] = 0x10;
2581 	src[ 0x0f8014 ] = 0x40;
2582 	src[ 0x0f8015 ] = 0x46;
2583 	src[ 0x0f8016 ] = 0xc1;
2584 	src[ 0x0f802c ] = 0x16;
2585 }
2586 
svcplusa_px_decrypt(void)2587 void svcplusa_px_decrypt( void )
2588 {
2589 	int i;
2590 	static const int sec[] = {
2591 		0x01, 0x02, 0x03, 0x04, 0x05, 0x00
2592 	};
2593 	int size = memory_region_length( REGION_CPU1 );
2594 	UINT8 *src = memory_region( REGION_CPU1 );
2595 	UINT8 *dst = malloc( size );
2596 	memcpy( dst, src, size );
2597 	for( i = 0; i < 6; i++ ){
2598 		memcpy( &src[ i * 0x100000 ], &dst[ sec[ i ] * 0x100000 ], 0x100000 );
2599 	}
2600 	free( dst );
2601 }
2602 
svcsplus_px_decrypt(void)2603 void svcsplus_px_decrypt( void )
2604 {
2605 	static const int sec[] = {
2606 		0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00
2607 	};
2608 	int size = memory_region_length( REGION_CPU1 );
2609 	UINT8 *src = memory_region( REGION_CPU1 );
2610 	UINT8 *dst = malloc( size );
2611 	int i;
2612 	int ofst;
2613 	memcpy( dst, src, size );
2614 	for( i = 0; i < size / 2; i++ ){
2615 		ofst = BITSWAP16( (i & 0x007fff), 0x0f, 0x00, 0x08, 0x09, 0x0b, 0x0a, 0x0c, 0x0d,
2616 										  0x04, 0x03, 0x01, 0x07, 0x06, 0x02, 0x05, 0x0e );
2617 
2618 		ofst += (i & 0x078000);
2619 		ofst += sec[ (i & 0xf80000) >> 19 ] << 19;
2620 		memcpy( &src[ i * 2 ], &dst[ ofst * 2 ], 0x02 );
2621 	}
2622 	free( dst );
2623 }
2624 
svcsplus_px_hack(void)2625 void svcsplus_px_hack( void )
2626 {
2627 	/* patched by the protection chip? */
2628 	UINT16 *mem16 = (UINT16 *)memory_region(REGION_CPU1);
2629 	mem16[0x9e90/2] = 0x000f;
2630 	mem16[0x9e92/2] = 0xc9c0;
2631 	mem16[0xa10c/2] = 0x4eb9;
2632 	mem16[0xa10e/2] = 0x000e;
2633 	mem16[0xa110/2] = 0x9750;
2634 }
2635 
2636 
2637