1 /* level9.c Treaty of Babel module for Level 9 files
\r
2 * 2006 By L. Ross Raszewski
\r
4 * Note that this module will handle both bare Level 9 A-Code and
\r
5 * Spectrum .SNA snapshots. It will not handle compressed .Z80 images.
\r
7 * The Level 9 identification algorithm is based in part on the algorithm
\r
8 * used by Paul David Doherty's l9cut program.
\r
10 * This file depends on treaty_builder.h
\r
12 * This file is public domain, but note that any changes to this file
\r
13 * may render it noncompliant with the Treaty of Babel
\r
16 #define FORMAT level9
\r
17 #define HOME_PAGE "http://www.if-legends.org/~l9memorial/html/home.html"
\r
18 #define FORMAT_EXT ".l9,.sna"
\r
22 #include "treaty_builder.h"
\r
34 static struct l9rec l9_registry[] = {
\r
35 { 0x3a31, 0xe5, "LEVEL9-001-1" },
\r
36 { 0x8333, 0xb7, "LEVEL9-001-1" },
\r
37 { 0x7c6f, 0x0f, "LEVEL9-001-1" },
\r
38 { 0x72fa, 0x8b, "LEVEL9-001-1" },
\r
39 { 0x38dd, 0x31, "LEVEL9-001-A" },
\r
40 { 0x39c0, 0x44, "LEVEL9-001-B" },
\r
41 { 0x3a12, 0x8f, "LEVEL9-001-C" },
\r
42 { 0x37f1, 0x77, "LEVEL9-001-2" },
\r
43 { 0x844d, 0x50, "LEVEL9-001-2" },
\r
44 { 0x738e, 0x5b, "LEVEL9-001-2" },
\r
45 { 0x3900, 0x1c, "LEVEL9-001-3" },
\r
46 { 0x8251, 0x5f, "LEVEL9-001-3" },
\r
47 { 0x7375, 0xe5, "LEVEL9-001-3" },
\r
48 { 0x3910, 0xac, "LEVEL9-001-4" },
\r
49 { 0x7a78, 0x5e, "LEVEL9-001-4" },
\r
50 { 0x78d5, 0xe3, "LEVEL9-001-4" },
\r
51 { 0x3ad6, 0xa7, "LEVEL9-001-5" },
\r
52 { 0x38a5, 0x0f, "LEVEL9-001-6" },
\r
53 { 0x361e, 0x7e, "LEVEL9-001-7" },
\r
54 { 0x3934, 0x75, "LEVEL9-001-8" },
\r
55 { 0x3511, 0xcc, "LEVEL9-001-9" },
\r
56 { 0x593a, 0xaf, "LEVEL9-002-1" },
\r
57 { 0x7931, 0xb9, "LEVEL9-002-1" },
\r
58 { 0x6841, 0x4a, "LEVEL9-002-1" },
\r
59 { 0x57e6, 0x8a, "LEVEL9-002-2" },
\r
60 { 0x7cdf, 0xa5, "LEVEL9-002-2" },
\r
61 { 0x6bc0, 0x62, "LEVEL9-002-2" },
\r
62 { 0x5819, 0xcd, "LEVEL9-002-3" },
\r
63 { 0x7a0c, 0x97, "LEVEL9-002-3" },
\r
64 { 0x692c, 0x21, "LEVEL9-002-3" },
\r
65 { 0x579b, 0xad, "LEVEL9-002-4" },
\r
66 { 0x7883, 0xe2, "LEVEL9-002-4" },
\r
67 { 0x670a, 0x94, "LEVEL9-002-4" },
\r
68 { 0x5323, 0xb7, "LEVEL9-003" },
\r
69 { 0x6e60, 0x83, "LEVEL9-003" },
\r
70 { 0x5b58, 0x50, "LEVEL9-003" },
\r
71 { 0x63b6, 0x2e, "LEVEL9-003" },
\r
72 { 0x6968, 0x32, "LEVEL9-003" },
\r
73 { 0x5b50, 0x66, "LEVEL9-003" },
\r
74 { 0x6970, 0xd6, "LEVEL9-003" },
\r
75 { 0x5ace, 0x11, "LEVEL9-003" },
\r
76 { 0x6e5c, 0xf6, "LEVEL9-003" },
\r
77 { 0x1929, 0x00, "LEVEL9-004-DEMO" },
\r
78 { 0x40e0, 0x02, "LEVEL9-004-DEMO" },
\r
79 { 0x3ebb, 0x00, "LEVEL9-004-en" },
\r
80 { 0x3e4f, 0x00, "LEVEL9-004-en" },
\r
81 { 0x3e8f, 0x00, "LEVEL9-004-en" },
\r
82 { 0x0fd8, 0x00, "LEVEL9-004-en" },
\r
83 { 0x14a3, 0x00, "LEVEL9-004-en" },
\r
84 { 0x110f, 0x00, "LEVEL9-004-fr" },
\r
85 { 0x4872, 0x00, "LEVEL9-004-de" },
\r
86 { 0x4846, 0x00, "LEVEL9-004-de" },
\r
87 { 0x11f5, 0x00, "LEVEL9-004-de" },
\r
88 { 0x11f5, 0x00, "LEVEL9-004-de" },
\r
89 { 0x76f4, 0x5e, "LEVEL9-005" },
\r
90 { 0x5b16, 0x3b, "LEVEL9-005" },
\r
91 { 0x6c8e, 0xb6, "LEVEL9-005" },
\r
92 { 0x6f4d, 0xcb, "LEVEL9-005" },
\r
93 { 0x6f6a, 0xa5, "LEVEL9-005" },
\r
94 { 0x5e31, 0x7c, "LEVEL9-005" },
\r
95 { 0x6f70, 0x40, "LEVEL9-005" },
\r
96 { 0x6f6e, 0x78, "LEVEL9-005" },
\r
97 { 0x5a8e, 0xf2, "LEVEL9-005" },
\r
98 { 0x76f4, 0x5a, "LEVEL9-005" },
\r
99 { 0x630e, 0x8d, "LEVEL9-006" },
\r
100 { 0x630e, 0xbe, "LEVEL9-006" },
\r
101 { 0x6f0c, 0x95, "LEVEL9-006" },
\r
102 { 0x593a, 0x80, "LEVEL9-006" },
\r
103 { 0x6bd2, 0x65, "LEVEL9-006" },
\r
104 { 0x6dc0, 0x63, "LEVEL9-006" },
\r
105 { 0x58a6, 0x24, "LEVEL9-006" },
\r
106 { 0x6de8, 0x4c, "LEVEL9-006" },
\r
107 { 0x58a3, 0x38, "LEVEL9-006" },
\r
108 { 0x63be, 0xd6, "LEVEL9-007" },
\r
109 { 0x378c, 0x8d, "LEVEL9-007" },
\r
110 { 0x63be, 0x0a, "LEVEL9-007" },
\r
111 { 0x34b3, 0x20, "LEVEL9-008" },
\r
112 { 0x34b3, 0xc7, "LEVEL9-008" },
\r
113 { 0x34b3, 0x53, "LEVEL9-008" },
\r
114 { 0xb1a9, 0x80, "LEVEL9-009-1" },
\r
115 { 0x908e, 0x0d, "LEVEL9-009-1" },
\r
116 { 0xad41, 0xa8, "LEVEL9-009-1" },
\r
117 { 0xb1aa, 0xad, "LEVEL9-009-1" },
\r
118 { 0x8aab, 0xc0, "LEVEL9-009-1" },
\r
119 { 0xb0ec, 0xc2, "LEVEL9-009-1" },
\r
120 { 0xb19e, 0x92, "LEVEL9-009-1" },
\r
121 { 0x5ff0, 0xf8, "LEVEL9-009-1" },
\r
122 { 0x52aa, 0xdf, "LEVEL9-009-1" },
\r
123 { 0xab9d, 0x31, "LEVEL9-009-2" },
\r
124 { 0x8f6f, 0x0a, "LEVEL9-009-2" },
\r
125 { 0xa735, 0xf7, "LEVEL9-009-2" },
\r
126 { 0xab8b, 0xbf, "LEVEL9-009-2" },
\r
127 { 0x8ac8, 0x9a, "LEVEL9-009-2" },
\r
128 { 0xaf82, 0x83, "LEVEL9-009-2" },
\r
129 { 0x6024, 0x01, "LEVEL9-009-2" },
\r
130 { 0x6ffa, 0xdb, "LEVEL9-009-2" },
\r
131 { 0xae28, 0x87, "LEVEL9-009-3" },
\r
132 { 0x9060, 0xbb, "LEVEL9-009-3" },
\r
133 { 0xa9c0, 0x9e, "LEVEL9-009-3" },
\r
134 { 0xae16, 0x81, "LEVEL9-009-3" },
\r
135 { 0x8a93, 0x4f, "LEVEL9-009-3" },
\r
136 { 0xb3e6, 0xab, "LEVEL9-009-3" },
\r
137 { 0x6036, 0x3d, "LEVEL9-009-3" },
\r
138 { 0x723a, 0x69, "LEVEL9-009-3" },
\r
139 { 0xd188, 0x13, "LEVEL9-010-1" },
\r
140 { 0x9089, 0xce, "LEVEL9-010-1" },
\r
141 { 0xb770, 0x03, "LEVEL9-010-1" },
\r
142 { 0xd19b, 0xad, "LEVEL9-010-1" },
\r
143 { 0x8ab7, 0x68, "LEVEL9-010-1" },
\r
144 { 0xd183, 0x83, "LEVEL9-010-1" },
\r
145 { 0x5a38, 0xf7, "LEVEL9-010-1" },
\r
146 { 0x76a0, 0x3a, "LEVEL9-010-1" },
\r
147 { 0xc594, 0x03, "LEVEL9-010-2" },
\r
148 { 0x908d, 0x80, "LEVEL9-010-2" },
\r
149 { 0xb741, 0xb6, "LEVEL9-010-2" },
\r
150 { 0xc5a5, 0xfe, "LEVEL9-010-2" },
\r
151 { 0x8b1e, 0x84, "LEVEL9-010-2" },
\r
152 { 0xc58f, 0x65, "LEVEL9-010-2" },
\r
153 { 0x531a, 0xed, "LEVEL9-010-2" },
\r
154 { 0x7674, 0x0b, "LEVEL9-010-2" },
\r
155 { 0xd79f, 0xb5, "LEVEL9-010-3" },
\r
156 { 0x909e, 0x9f, "LEVEL9-010-3" },
\r
157 { 0xb791, 0xa1, "LEVEL9-010-3" },
\r
158 { 0xd7ae, 0x9e, "LEVEL9-010-3" },
\r
159 { 0x8b1c, 0xa8, "LEVEL9-010-3" },
\r
160 { 0xd79a, 0x57, "LEVEL9-010-3" },
\r
161 { 0x57e4, 0x19, "LEVEL9-010-3" },
\r
162 { 0x765e, 0xba, "LEVEL9-010-3" },
\r
163 { 0xbb93, 0x36, "LEVEL9-011-1" },
\r
164 { 0x898a, 0x43, "LEVEL9-011-1" },
\r
165 { 0x8970, 0x6b, "LEVEL9-011-1" },
\r
166 { 0xbb6e, 0xa6, "LEVEL9-011-1" },
\r
167 { 0x86d0, 0xb7, "LEVEL9-011-1" },
\r
168 { 0xbb6e, 0xad, "LEVEL9-011-1" },
\r
169 { 0x46ec, 0x64, "LEVEL9-011-1" },
\r
170 { 0x74e0, 0x92, "LEVEL9-011-1" },
\r
171 { 0xc58e, 0x4a, "LEVEL9-011-2" },
\r
172 { 0x8b9f, 0x61, "LEVEL9-011-2" },
\r
173 { 0x8b90, 0x4e, "LEVEL9-011-2" },
\r
174 { 0xc58e, 0x43, "LEVEL9-011-2" },
\r
175 { 0x8885, 0x22, "LEVEL9-011-2" },
\r
176 { 0x6140, 0x18, "LEVEL9-011-2" },
\r
177 { 0x6dbc, 0x97, "LEVEL9-011-2" },
\r
178 { 0xcb9a, 0x0f, "LEVEL9-011-3" },
\r
179 { 0x8af9, 0x61, "LEVEL9-011-3" },
\r
180 { 0x8aea, 0x4e, "LEVEL9-011-3" },
\r
181 { 0xcb9a, 0x08, "LEVEL9-011-3" },
\r
182 { 0x87e5, 0x0e, "LEVEL9-011-3" },
\r
183 { 0x640e, 0xc1, "LEVEL9-011-3" },
\r
184 { 0x7402, 0x07, "LEVEL9-011-3" },
\r
185 { 0xbba4, 0x94, "LEVEL9-012-1" },
\r
186 { 0xc0cf, 0x4e, "LEVEL9-012-1" },
\r
187 { 0x8afc, 0x07, "LEVEL9-012-1" },
\r
188 { 0x8feb, 0xba, "LEVEL9-012-1" },
\r
189 { 0xb4c9, 0x94, "LEVEL9-012-1" },
\r
190 { 0xc0bd, 0x57, "LEVEL9-012-1" },
\r
191 { 0x8ade, 0xf2, "LEVEL9-012-1" },
\r
192 { 0x4fd2, 0x9d, "LEVEL9-012-1" },
\r
193 { 0x5c7a, 0x44, "LEVEL9-012-1" },
\r
194 { 0x768c, 0xe8, "LEVEL9-012-1" },
\r
195 { 0xd0c0, 0x56, "LEVEL9-012-2" },
\r
196 { 0xd5e9, 0x6a, "LEVEL9-012-2" },
\r
197 { 0x8aec, 0x13, "LEVEL9-012-2" },
\r
198 { 0x8f6b, 0xfa, "LEVEL9-012-2" },
\r
199 { 0xb729, 0x51, "LEVEL9-012-2" },
\r
200 { 0xd5d7, 0x99, "LEVEL9-012-2" },
\r
201 { 0x8b0e, 0xfb, "LEVEL9-012-2" },
\r
202 { 0x4dac, 0xa8, "LEVEL9-012-2" },
\r
203 { 0x53a2, 0x1e, "LEVEL9-012-2" },
\r
204 { 0x76b0, 0x1d, "LEVEL9-012-2" },
\r
205 { 0xb6ac, 0xc6, "LEVEL9-012-3" },
\r
206 { 0xbb8f, 0x1a, "LEVEL9-012-3" },
\r
207 { 0x8aba, 0x0d, "LEVEL9-012-3" },
\r
208 { 0x8f71, 0x2f, "LEVEL9-012-3" },
\r
209 { 0xb702, 0xe4, "LEVEL9-012-3" },
\r
210 { 0xbb7d, 0x17, "LEVEL9-012-3" },
\r
211 { 0x8ab3, 0xc1, "LEVEL9-012-3" },
\r
212 { 0x4f96, 0x22, "LEVEL9-012-3" },
\r
213 { 0x5914, 0x22, "LEVEL9-012-3" },
\r
214 { 0x765e, 0x4f, "LEVEL9-012-3" },
\r
215 { 0x5eb9, 0x30, "LEVEL9-013" },
\r
216 { 0x5eb9, 0x5d, "LEVEL9-013" },
\r
217 { 0x5eb9, 0x6e, "LEVEL9-013" },
\r
218 { 0xb257, 0xf8, "LEVEL9-013" },
\r
219 { 0xb576, 0x2a, "LEVEL9-013" },
\r
220 { 0x8d78, 0x3a, "LEVEL9-013" },
\r
221 { 0x9070, 0x43, "LEVEL9-013" },
\r
222 { 0xb38c, 0x37, "LEVEL9-013" },
\r
223 { 0xb563, 0x6a, "LEVEL9-013" },
\r
224 { 0xb57c, 0x44, "LEVEL9-013" },
\r
225 { 0xb260, 0xe5, "LEVEL9-013" },
\r
226 { 0x8950, 0xa1, "LEVEL9-013" },
\r
227 { 0xb579, 0x89, "LEVEL9-013" },
\r
228 { 0x579e, 0x97, "LEVEL9-013" },
\r
229 { 0x69fe, 0x56, "LEVEL9-013" },
\r
230 { 0x6f1e, 0xda, "LEVEL9-013" },
\r
231 { 0x5671, 0xbc, "LEVEL9-014" },
\r
232 { 0x6fc6, 0x14, "LEVEL9-014" },
\r
233 { 0x5aa4, 0xc1, "LEVEL9-014" },
\r
234 { 0x7410, 0x5e, "LEVEL9-014" },
\r
235 { 0x5aa4, 0xc1, "LEVEL9-014" },
\r
236 { 0x5aa4, 0xc1, "LEVEL9-014" },
\r
237 { 0xb797, 0x1f, "LEVEL9-014" },
\r
238 { 0xbaca, 0x3a, "LEVEL9-014" },
\r
239 { 0x8c46, 0xf0, "LEVEL9-014" },
\r
240 { 0x8f51, 0xb2, "LEVEL9-014" },
\r
241 { 0xb451, 0xa8, "LEVEL9-014" },
\r
242 { 0xbab2, 0x87, "LEVEL9-014" },
\r
243 { 0xbac7, 0x7f, "LEVEL9-014" },
\r
244 { 0xb7a0, 0x7e, "LEVEL9-014" },
\r
245 { 0x8a60, 0x2a, "LEVEL9-014" },
\r
246 { 0xbac4, 0x80, "LEVEL9-014" },
\r
247 { 0x579a, 0x2a, "LEVEL9-014" },
\r
248 { 0x5a50, 0xa9, "LEVEL9-014" },
\r
249 { 0x6108, 0xdd, "LEVEL9-014" },
\r
250 { 0x506c, 0xf0, "LEVEL9-015" },
\r
251 { 0x505d, 0x32, "LEVEL9-015" },
\r
252 { 0xa398, 0x82, "LEVEL9-015" },
\r
253 { 0xa692, 0xd1, "LEVEL9-015" },
\r
254 { 0x8d56, 0xd3, "LEVEL9-015" },
\r
255 { 0x903f, 0x6b, "LEVEL9-015" },
\r
256 { 0xa4e2, 0xa6, "LEVEL9-015" },
\r
257 { 0xa67c, 0xb8, "LEVEL9-015" },
\r
258 { 0xa69e, 0x6c, "LEVEL9-015" },
\r
259 { 0xa3a4, 0xdf, "LEVEL9-015" },
\r
260 { 0x8813, 0x11, "LEVEL9-015" },
\r
261 { 0xa698, 0x41, "LEVEL9-015" },
\r
262 { 0x5500, 0x50, "LEVEL9-015" },
\r
263 { 0x6888, 0x8d, "LEVEL9-015" },
\r
264 { 0x6da0, 0xb8, "LEVEL9-015" },
\r
265 { 0x6064, 0xbd, "LEVEL9-016" },
\r
266 { 0x6064, 0x01, "LEVEL9-016" },
\r
267 { 0x6047, 0x6c, "LEVEL9-016" },
\r
268 { 0x6064, 0xda, "LEVEL9-016" },
\r
269 { 0x6064, 0x95, "LEVEL9-016" },
\r
270 { 0x60c4, 0x28, "LEVEL9-016" },
\r
271 { 0x5cb7, 0xfe, "LEVEL9-016" },
\r
272 { 0x5ca1, 0x33, "LEVEL9-016" },
\r
273 { 0x5cb7, 0x64, "LEVEL9-016" },
\r
274 { 0x7d16, 0xe6, "LEVEL9-016" },
\r
275 { 0x639c, 0x8b, "LEVEL9-016" },
\r
276 { 0x60f7, 0x68, "LEVEL9-016" },
\r
277 { 0x772f, 0xca, "LEVEL9-016" },
\r
278 { 0x7cff, 0xf8, "LEVEL9-016" },
\r
279 { 0x7cf8, 0x24, "LEVEL9-016" },
\r
280 { 0x7d14, 0xe8, "LEVEL9-016" },
\r
281 { 0x7c55, 0x18, "LEVEL9-016" },
\r
282 { 0x5f43, 0xca, "LEVEL9-016" },
\r
283 { 0xc132, 0x14, "LEVEL9-017-1" },
\r
284 { 0xbeab, 0x2d, "LEVEL9-017-1" },
\r
285 { 0x9058, 0xcf, "LEVEL9-017-1" },
\r
286 { 0xbe94, 0xcc, "LEVEL9-017-1" },
\r
287 { 0x8a21, 0xf4, "LEVEL9-017-1" },
\r
288 { 0x55ce, 0xa1, "LEVEL9-017-1" },
\r
289 { 0x5cbc, 0xa5, "LEVEL9-017-1" },
\r
290 { 0x762e, 0x82, "LEVEL9-017-1" },
\r
291 { 0x99bd, 0x65, "LEVEL9-017-2" },
\r
292 { 0x8f43, 0xc9, "LEVEL9-017-2" },
\r
293 { 0x8a12, 0xe3, "LEVEL9-017-2" },
\r
294 { 0x54a6, 0xa9, "LEVEL9-017-2" },
\r
295 { 0x5932, 0x4e, "LEVEL9-017-2" },
\r
296 { 0x5bd6, 0x35, "LEVEL9-017-2" },
\r
297 { 0xbcb6, 0x7a, "LEVEL9-017-3 (Amiga/PC/ST)" },
\r
298 { 0x90ac, 0x68, "LEVEL9-017-3" },
\r
299 { 0x8a16, 0xcc, "LEVEL9-017-3" },
\r
300 { 0x51bc, 0xe3, "LEVEL9-017-3" },
\r
301 { 0x5860, 0x95, "LEVEL9-017-3" },
\r
302 { 0x6fa8, 0xa4, "LEVEL9-017-3" },
\r
303 { 0x5fab, 0x5c, "LEVEL9-018" },
\r
304 { 0x5fab, 0x2f, "LEVEL9-018" },
\r
305 { 0x7b31, 0x6e, "LEVEL9-018" },
\r
306 { 0x67a3, 0x9d, "LEVEL9-018" },
\r
307 { 0x6bf8, 0x3f, "LEVEL9-018" },
\r
308 { 0x7363, 0x65, "LEVEL9-018" },
\r
309 { 0x7b2f, 0x70, "LEVEL9-018" },
\r
310 { 0x7b2f, 0x70, "LEVEL9-018" },
\r
311 { 0x6541, 0x02, "LEVEL9-018" },
\r
312 { 0x5834, 0x42, "LEVEL9-019-1" },
\r
313 { 0x765d, 0xcd, "LEVEL9-019-1" },
\r
314 { 0x6ce5, 0x58, "LEVEL9-019-1" },
\r
315 { 0x56dd, 0x51, "LEVEL9-019-2" },
\r
316 { 0x6e58, 0x07, "LEVEL9-019-2" },
\r
317 { 0x68da, 0xc1, "LEVEL9-019-2" },
\r
318 { 0x5801, 0x53, "LEVEL9-019-3" },
\r
319 { 0x7e98, 0x6a, "LEVEL9-019-3" },
\r
320 { 0x6c67, 0x9a, "LEVEL9-019-3" },
\r
321 { 0x54a4, 0x01, "LEVEL9-019-4" },
\r
322 { 0x81e2, 0xd5, "LEVEL9-019-4" },
\r
323 { 0x6d91, 0xb9, "LEVEL9-019-4" },
\r
324 { 0x5828, 0xbd, "LEVEL9-020" },
\r
325 { 0x6d84, 0xf9, "LEVEL9-020" },
\r
326 { 0x6d84, 0xc8, "LEVEL9-020" },
\r
327 { 0x6030, 0x47, "LEVEL9-020" },
\r
328 { 0x772b, 0xcd, "LEVEL9-020" },
\r
329 { 0x546c, 0xb7, "LEVEL9-020" },
\r
330 { 0x7cd9, 0x0c, "LEVEL9-020" },
\r
331 { 0x60dd, 0xf2, "LEVEL9-020" },
\r
332 { 0x6161, 0xf3, "LEVEL9-020" },
\r
333 { 0x788d, 0x72, "LEVEL9-020" },
\r
334 { 0x7cd7, 0x0e, "LEVEL9-020" },
\r
335 { 0x5ebb, 0xf1, "LEVEL9-020" },
\r
342 static int32 read_l9_int(unsigned char *sf)
\r
344 return ((int32) sf[1]) << 8 | sf[0];
\r
347 static int v2_recognition (unsigned char *sf, int32 extent, int32 *l, unsigned char *c)
\r
350 for (i=0;i<extent-20;i++)
\r
351 if ((read_l9_int(sf+i+4) == 0x0020) &&
\r
352 (read_l9_int(sf+i+0x0a) == 0x8000) &&
\r
353 (read_l9_int(sf+i+0x14) == read_l9_int(sf+i+0x16)))
\r
355 *l=read_l9_int(sf+i+0x1c);
\r
356 if (*l && *l+i <=extent)
\r
366 static int v1_recognition(unsigned char *sf, int32 extent, char **ifid)
\r
369 unsigned char a = 0xff, b = 0xff;
\r
371 for (i=0;i<extent-20;i++)
\r
372 if (memcmp(sf+i,"ATTAC",5)==0 && sf[i+5]==0xcb)
\r
377 for (;i<(extent-20);i++)
\r
378 if (memcmp(sf+i,"BUNC",4)==0 && sf[i+4]==0xc8)
\r
383 if (a == 0xff && b == 0xff)
\r
385 if (a == 0x14 && b == 0xff) *ifid="LEVEL9-006";
\r
386 else if (a == 0x15 && b == 0x5d) *ifid="LEVEL9-013";
\r
387 else if (a == 0x1a && b == 0x24) *ifid="LEVEL9-005";
\r
388 else if (a == 0x20 && b == 0x3b) *ifid="LEVEL9-003";
\r
392 static int v3_recognition_phase (int phase,unsigned char *sf, int32 extent, int32 *l, unsigned char *c)
\r
394 int32 end, i, j, ll;
\r
396 for (i=0;i<extent-20;i++)
\r
399 *l = read_l9_int(sf+i);
\r
403 if (end <= (extent - 2) &&
\r
406 (((sf[end-1] == 0) &&
\r
407 (sf[end-2] == 0)) ||
\r
408 ((sf[end+1] == 0) &&
\r
409 (sf[end+2] == 0))))
\r
410 && (*l>0x4000) && (*l<=0xdb00)))
\r
411 if ((*l!=0) && (sf[i+0x0d] == 0))
\r
412 for (j=i;j<i+16;j+=2)
\r
413 if (((read_l9_int(sf+j)+read_l9_int(sf+j+2))==read_l9_int(sf+j+4))
\r
414 && ((read_l9_int(sf+j)+read_l9_int(sf+j+2))))
\r
419 if ((extent>0x0fd0) && (end <= (extent - 2)) &&
\r
420 (((read_l9_int(sf+i+2) + read_l9_int(sf+i+4))==read_l9_int(sf+i+6))
\r
421 && (read_l9_int(sf+i+2) != 0) && (read_l9_int(sf+i+4)) != 0) &&
\r
422 (((read_l9_int(sf+i+6) + read_l9_int(sf+i+8)) == read_l9_int(sf+i+10))
\r
423 && ((sf[i + 18] == 0x2a) || (sf[i + 18] == 0x2c))
\r
424 && (sf[i + 19] == 0) && (sf[i + 20] == 0) && (sf[i + 21] == 0)))
\r
430 if (phase==3) ll=1;
\r
434 for (j=i;j<=end;j++)
\r
436 if (!checksum) ll=1;
\r
442 if (ll) return *l < 0x8500 ? 3:4;
\r
445 static char *get_l9_ifid(int32 length, unsigned char chk)
\r
448 for(i=0;l9_registry[i].length;i++)
\r
449 if (length==l9_registry[i].length && chk==l9_registry[i].chk) return l9_registry[i].ifid;
\r
452 static int get_l9_version(unsigned char *sf, int32 extent, char **ifid)
\r
457 if (v2_recognition(sf,extent, &l, &c)) { *ifid=get_l9_ifid(l,c); return 2; }
\r
459 i=v3_recognition_phase(1,sf,extent, &l, &c);
\r
460 if (i) { *ifid=get_l9_ifid(l,c); return i; }
\r
461 if (v1_recognition(sf,extent, ifid)) return 1;
\r
463 i=v3_recognition_phase(2,sf,extent, &l, &c);
\r
464 if (i) { *ifid=get_l9_ifid(l,c); return i; }
\r
465 i=v3_recognition_phase(3,sf,extent, &l, &c);
\r
470 static int32 claim_story_file(void *story, int32 extent)
\r
473 if (get_l9_version((unsigned char *) story,extent, &ifid))
\r
474 if (ifid) return VALID_STORY_FILE_RV;
\r
475 else return NO_REPLY_RV;
\r
476 return INVALID_STORY_FILE_RV;
\r
481 static int32 get_story_file_IFID(void *story_file, int32 extent, char *output, int32 output_extent)
\r
484 int i=get_l9_version((unsigned char *)story_file, extent, &ifid);
\r
485 if (!i) return INVALID_STORY_FILE_RV;
\r
488 ASSERT_OUTPUT_SIZE((signed) strlen(ifid)+1);
\r
489 strcpy(output,ifid);
\r
492 ASSERT_OUTPUT_SIZE(10);
\r
493 sprintf(output,"LEVEL9-%d-",i);
\r
494 return INCOMPLETE_REPLY_RV;
\r