1 #include <ctype.h>
2
3 #include "driver.h"
4 #include "sound/samples.h"
5 #include "info.h"
6 #include "datafile.h"
7
8 /* Output format indentation */
9
10 /* Indentation */
11 #define INDENT "\t"
12
13 /* Possible output format */
14 #define OUTPUT_FORMAT_UNFORMATTED 0
15 #define OUTPUT_FORMAT_ONE_LEVEL 1
16 #define OUTPUT_FORMAT_TWO_LEVEL 2
17
18 /* Output format */
19 #define OUTPUT_FORMAT OUTPUT_FORMAT_ONE_LEVEL
20
21 /* Output format configuration
22 L list
23 1,2 levels
24 B,S,E Begin, Separator, End
25 */
26
27 #if OUTPUT_FORMAT == OUTPUT_FORMAT_UNFORMATTED
28 #define L1B "("
29 #define L1P " "
30 #define L1N ""
31 #define L1E ")"
32 #define L2B "("
33 #define L2P " "
34 #define L2N ""
35 #define L2E ")"
36 #elif OUTPUT_FORMAT == OUTPUT_FORMAT_ONE_LEVEL
37 #define L1B " (\n"
38 #define L1P INDENT
39 #define L1N "\n"
40 #define L1E ")\n\n"
41 #define L2B " ("
42 #define L2P " "
43 #define L2N ""
44 #define L2E " )"
45 #elif OUTPUT_FORMAT == OUTPUT_FORMAT_TWO_LEVEL
46 #define L1B " (\n"
47 #define L1P INDENT
48 #define L1N "\n"
49 #define L1E ")\n\n"
50 #define L2B " (\n"
51 #define L2P INDENT INDENT
52 #define L2N "\n"
53 #define L2E INDENT ")"
54 #else
55 #error Wrong OUTPUT_FORMAT
56 #endif
57
58 /* Print a string in C format */
print_c_string(FILE * out,const char * s)59 static void print_c_string(FILE* out, const char* s) {
60 fprintf(out, "\"");
61 if (s) {
62 while (*s) {
63 switch (*s) {
64 case '\a' : fprintf(out, "\\a"); break;
65 case '\b' : fprintf(out, "\\b"); break;
66 case '\f' : fprintf(out, "\\f"); break;
67 case '\n' : fprintf(out, "\\n"); break;
68 case '\r' : fprintf(out, "\\r"); break;
69 case '\t' : fprintf(out, "\\t"); break;
70 case '\v' : fprintf(out, "\\v"); break;
71 case '\\' : fprintf(out, "\\\\"); break;
72 case '\"' : fprintf(out, "\\\""); break;
73 default:
74 if (*s>=' ' && *s<='~')
75 fprintf(out, "%c", *s);
76 else
77 fprintf(out, "\\x%02x", (unsigned)(unsigned char)*s);
78 }
79 ++s;
80 }
81 }
82 fprintf(out, "\"");
83 }
84
85 /* Print a string in statement format (remove space, parentesis, ") */
print_statement_string(FILE * out,const char * s)86 static void print_statement_string(FILE* out, const char* s) {
87 if (s) {
88 while (*s) {
89 if (isspace(*s)) {
90 fprintf(out, "_");
91 } else {
92 switch (*s) {
93 case '(' :
94 case ')' :
95 case '"' :
96 fprintf(out, "_");
97 break;
98 default:
99 fprintf(out, "%c", *s);
100 }
101 }
102 ++s;
103 }
104 } else {
105 fprintf(out, "null");
106 }
107 }
108
print_game_switch(FILE * out,const struct GameDriver * game)109 static void print_game_switch(FILE* out, const struct GameDriver* game) {
110 const struct InputPortTiny* input = game->input_ports;
111
112 while ((input->type & ~IPF_MASK) != IPT_END) {
113 if ((input->type & ~IPF_MASK)==IPT_DIPSWITCH_NAME) {
114 int def = input->default_value;
115 const char* def_name = 0;
116
117 fprintf(out, L1P "dipswitch" L2B);
118
119 fprintf(out, L2P "name " );
120 print_c_string(out,input->name);
121 fprintf(out, "%s", L2N);
122 ++input;
123
124 while ((input->type & ~IPF_MASK)==IPT_DIPSWITCH_SETTING) {
125 if (def == input->default_value)
126 def_name = input->name;
127 fprintf(out, L2P "entry " );
128 print_c_string(out,input->name);
129 fprintf(out, "%s", L2N);
130 ++input;
131 }
132
133 if (def_name) {
134 fprintf(out, L2P "default ");
135 print_c_string(out,def_name);
136 fprintf(out, "%s", L2N);
137 }
138
139 fprintf(out, L2E L1N);
140 }
141 else
142 ++input;
143 }
144 }
145
print_game_input(FILE * out,const struct GameDriver * game)146 static void print_game_input(FILE* out, const struct GameDriver* game) {
147 const struct InputPortTiny* input = game->input_ports;
148 int nplayer = 0;
149 const char* control = 0;
150 int nbutton = 0;
151 int ncoin = 0;
152 const char* service = 0;
153 const char* tilt = 0;
154
155 while ((input->type & ~IPF_MASK) != IPT_END) {
156 switch (input->type & IPF_PLAYERMASK) {
157 case IPF_PLAYER1:
158 if (nplayer<1) nplayer = 1;
159 break;
160 case IPF_PLAYER2:
161 if (nplayer<2) nplayer = 2;
162 break;
163 case IPF_PLAYER3:
164 if (nplayer<3) nplayer = 3;
165 break;
166 case IPF_PLAYER4:
167 if (nplayer<4) nplayer = 4;
168 break;
169 }
170 switch (input->type & ~IPF_MASK) {
171 case IPT_JOYSTICK_UP:
172 case IPT_JOYSTICK_DOWN:
173 case IPT_JOYSTICK_LEFT:
174 case IPT_JOYSTICK_RIGHT:
175 if (input->type & IPF_2WAY)
176 control = "joy2way";
177 else if (input->type & IPF_4WAY)
178 control = "joy4way";
179 else
180 control = "joy8way";
181 break;
182 case IPT_JOYSTICKRIGHT_UP:
183 case IPT_JOYSTICKRIGHT_DOWN:
184 case IPT_JOYSTICKRIGHT_LEFT:
185 case IPT_JOYSTICKRIGHT_RIGHT:
186 case IPT_JOYSTICKLEFT_UP:
187 case IPT_JOYSTICKLEFT_DOWN:
188 case IPT_JOYSTICKLEFT_LEFT:
189 case IPT_JOYSTICKLEFT_RIGHT:
190 if (input->type & IPF_2WAY)
191 control = "doublejoy2way";
192 else if (input->type & IPF_4WAY)
193 control = "doublejoy4way";
194 else
195 control = "doublejoy8way";
196 break;
197 case IPT_BUTTON1:
198 if (nbutton<1) nbutton = 1;
199 break;
200 case IPT_BUTTON2:
201 if (nbutton<2) nbutton = 2;
202 break;
203 case IPT_BUTTON3:
204 if (nbutton<3) nbutton = 3;
205 break;
206 case IPT_BUTTON4:
207 if (nbutton<4) nbutton = 4;
208 break;
209 case IPT_BUTTON5:
210 if (nbutton<5) nbutton = 5;
211 break;
212 case IPT_BUTTON6:
213 if (nbutton<6) nbutton = 6;
214 break;
215 case IPT_BUTTON7:
216 if (nbutton<7) nbutton = 7;
217 break;
218 case IPT_BUTTON8:
219 if (nbutton<8) nbutton = 8;
220 break;
221 case IPT_PADDLE:
222 control = "paddle";
223 break;
224 case IPT_DIAL:
225 control = "dial";
226 break;
227 case IPT_TRACKBALL_X:
228 case IPT_TRACKBALL_Y:
229 control = "trackball";
230 break;
231 case IPT_AD_STICK_X:
232 case IPT_AD_STICK_Y:
233 control = "stick";
234 break;
235 case IPT_COIN1:
236 if (ncoin < 1) ncoin = 1;
237 break;
238 case IPT_COIN2:
239 if (ncoin < 2) ncoin = 2;
240 break;
241 case IPT_COIN3:
242 if (ncoin < 3) ncoin = 3;
243 break;
244 case IPT_COIN4:
245 if (ncoin < 4) ncoin = 4;
246 break;
247 case IPT_SERVICE :
248 service = "yes";
249 break;
250 case IPT_TILT :
251 tilt = "yes";
252 break;
253 }
254 ++input;
255 }
256
257 fprintf(out, L1P "input" L2B);
258 fprintf(out, L2P "players %d" L2N, nplayer );
259 if (control)
260 fprintf(out, L2P "control %s" L2N, control );
261 if (nbutton)
262 fprintf(out, L2P "buttons %d" L2N, nbutton );
263 if (ncoin)
264 fprintf(out, L2P "coins %d" L2N, ncoin );
265 if (service)
266 fprintf(out, L2P "service %s" L2N, service );
267 if (tilt)
268 fprintf(out, L2P "tilt %s" L2N, tilt );
269 fprintf(out, L2E L1N);
270 }
271
print_game_rom(FILE * out,const struct GameDriver * game)272 static void print_game_rom(FILE* out, const struct GameDriver* game) {
273 const struct RomModule *rom = game->rom, *p_rom = NULL;
274 extern struct GameDriver driver_0;
275
276 if (!rom) return;
277
278 if (game->clone_of && game->clone_of != &driver_0) {
279 fprintf(out, L1P "romof %s" L1N, game->clone_of->name);
280 }
281
282 while (rom->name || rom->offset || rom->length) {
283 int region = rom->crc;
284 rom++;
285
286 while (rom->length) {
287 char name[100];
288 int offset, length, crc, in_parent;
289
290 sprintf(name,rom->name,game->name);
291 offset = rom->offset;
292 crc = rom->crc;
293
294 in_parent = 0;
295 length = 0;
296 do {
297 if (rom->name == (char *)-1)
298 length = 0; /* restart */
299 length += rom->length & ~ROMFLAG_MASK;
300 rom++;
301 } while (rom->length && (rom->name == 0 || rom->name == (char *)-1));
302
303 if(game->clone_of && crc)
304 {
305 p_rom = game->clone_of->rom;
306 if (p_rom)
307 while( !in_parent && (p_rom->name || p_rom->offset || p_rom->length) )
308 {
309 p_rom++;
310 while(!in_parent && p_rom->length) {
311 do {
312 if (p_rom->crc == crc)
313 in_parent = 1;
314 else
315 p_rom++;
316 } while (!in_parent && p_rom->length && (p_rom->name == 0 || p_rom->name == (char *)-1));
317 }
318 }
319 }
320
321 fprintf(out, L1P "rom" L2B);
322 if (*name)
323 fprintf(out, L2P "name %s" L2N, name);
324 if(in_parent && p_rom && p_rom->name)
325 fprintf(out, L2P "merge %s" L2N, p_rom->name);
326 fprintf(out, L2P "size %d" L2N, length);
327 fprintf(out, L2P "crc %08x" L2N, crc);
328 switch (region & ~REGIONFLAG_MASK)
329 {
330 case REGION_CPU1: fprintf(out, L2P "region cpu1" L2N); break;
331 case REGION_CPU2: fprintf(out, L2P "region cpu2" L2N); break;
332 case REGION_CPU3: fprintf(out, L2P "region cpu3" L2N); break;
333 case REGION_CPU4: fprintf(out, L2P "region cpu4" L2N); break;
334 case REGION_CPU5: fprintf(out, L2P "region cpu5" L2N); break;
335 case REGION_CPU6: fprintf(out, L2P "region cpu6" L2N); break;
336 case REGION_CPU7: fprintf(out, L2P "region cpu7" L2N); break;
337 case REGION_CPU8: fprintf(out, L2P "region cpu8" L2N); break;
338 case REGION_GFX1: fprintf(out, L2P "region gfx1" L2N); break;
339 case REGION_GFX2: fprintf(out, L2P "region gfx2" L2N); break;
340 case REGION_GFX3: fprintf(out, L2P "region gfx3" L2N); break;
341 case REGION_GFX4: fprintf(out, L2P "region gfx4" L2N); break;
342 case REGION_GFX5: fprintf(out, L2P "region gfx5" L2N); break;
343 case REGION_GFX6: fprintf(out, L2P "region gfx6" L2N); break;
344 case REGION_GFX7: fprintf(out, L2P "region gfx7" L2N); break;
345 case REGION_GFX8: fprintf(out, L2P "region gfx8" L2N); break;
346 case REGION_PROMS: fprintf(out, L2P "region proms" L2N); break;
347 case REGION_SOUND1: fprintf(out, L2P "region sound1" L2N); break;
348 case REGION_SOUND2: fprintf(out, L2P "region sound2" L2N); break;
349 case REGION_SOUND3: fprintf(out, L2P "region sound3" L2N); break;
350 case REGION_SOUND4: fprintf(out, L2P "region sound4" L2N); break;
351 case REGION_SOUND5: fprintf(out, L2P "region sound5" L2N); break;
352 case REGION_SOUND6: fprintf(out, L2P "region sound6" L2N); break;
353 case REGION_SOUND7: fprintf(out, L2P "region sound7" L2N); break;
354 case REGION_SOUND8: fprintf(out, L2P "region sound8" L2N); break;
355 case REGION_USER1: fprintf(out, L2P "region user1" L2N); break;
356 case REGION_USER2: fprintf(out, L2P "region user2" L2N); break;
357 case REGION_USER3: fprintf(out, L2P "region user3" L2N); break;
358 case REGION_USER4: fprintf(out, L2P "region user4" L2N); break;
359 case REGION_USER5: fprintf(out, L2P "region user5" L2N); break;
360 case REGION_USER6: fprintf(out, L2P "region user6" L2N); break;
361 case REGION_USER7: fprintf(out, L2P "region user7" L2N); break;
362 case REGION_USER8: fprintf(out, L2P "region user8" L2N); break;
363 default: fprintf(out, L2P "region 0x%x" L2N, region & ~REGIONFLAG_MASK);
364 }
365 switch (region & REGIONFLAG_MASK)
366 {
367 case 0:
368 break;
369 case REGIONFLAG_SOUNDONLY:
370 fprintf(out, L2P "flags soundonly" L2N);
371 break;
372 case REGIONFLAG_DISPOSE:
373 fprintf(out, L2P "flags dispose" L2N);
374 break;
375 default:
376 fprintf(out, L2P "flags 0x%x" L2N, region & REGIONFLAG_MASK);
377 }
378 fprintf(out, L2P "offs %x", offset);
379 fprintf(out, L2E L1N);
380 }
381 }
382 }
383
print_game_sample(FILE * out,const struct GameDriver * game)384 static void print_game_sample(FILE* out, const struct GameDriver* game) {
385 #if (HAS_SAMPLES)
386 int i;
387 for( i = 0; game->drv->sound[i].sound_type && i < MAX_SOUND; i++ )
388 {
389 const char **samplenames = NULL;
390 if( game->drv->sound[i].sound_type != SOUND_SAMPLES )
391 continue;
392 samplenames = ((struct Samplesinterface *)game->drv->sound[i].sound_interface)->samplenames;
393 if (samplenames != 0 && samplenames[0] != 0) {
394 int k = 0;
395 if (samplenames[k][0]=='*') {
396 /* output sampleof only if different from game name */
397 if (strcmp(samplenames[k] + 1, game->name)!=0) {
398 fprintf(out, L1P "sampleof %s" L1N, samplenames[k] + 1);
399 }
400 ++k;
401 }
402 while (samplenames[k] != 0) {
403 /* Check if is not empty */
404 if (*samplenames[k]) {
405 /* Check if sample is duplicate */
406 int l = 0;
407 while (l<k && strcmp(samplenames[k],samplenames[l])!=0)
408 ++l;
409 if (l==k) {
410 fprintf(out, L1P "sample %s" L1N, samplenames[k]);
411 }
412 }
413 ++k;
414 }
415 }
416 }
417 #endif
418 }
419
420
print_game_micro(FILE * out,const struct GameDriver * game)421 static void print_game_micro(FILE* out, const struct GameDriver* game)
422 {
423 const struct MachineDriver* driver = game->drv;
424 const struct MachineCPU* cpu = driver->cpu;
425 const struct MachineSound* sound = driver->sound;
426 int j;
427
428 for(j=0;j<MAX_CPU;++j)
429 {
430 if (cpu[j].cpu_type!=0)
431 {
432 fprintf(out, L1P "chip" L2B);
433 if (cpu[j].cpu_type & CPU_AUDIO_CPU)
434 fprintf(out, L2P "type cpu flags audio" L2N);
435 else
436 fprintf(out, L2P "type cpu" L2N);
437
438 fprintf(out, L2P "name ");
439 print_statement_string(out, cputype_name(cpu[j].cpu_type));
440 fprintf(out, "%s", L2N);
441
442 fprintf(out, L2P "clock %d" L2N, cpu[j].cpu_clock);
443 fprintf(out, L2E L1N);
444 }
445 }
446
447 for(j=0;j<MAX_SOUND;++j) if (sound[j].sound_type)
448 {
449 if (sound[j].sound_type)
450 {
451 int num = sound_num(&sound[j]);
452 int l;
453
454 if (num == 0) num = 1;
455
456 for(l=0;l<num;++l)
457 {
458 fprintf(out, L1P "chip" L2B);
459 fprintf(out, L2P "type audio" L2N);
460 fprintf(out, L2P "name ");
461 print_statement_string(out, sound_name(&sound[j]));
462 fprintf(out, "%s", L2N);
463 if (sound_clock(&sound[j]))
464 fprintf(out, L2P "clock %d" L2N, sound_clock(&sound[j]));
465 fprintf(out, L2E L1N);
466 }
467 }
468 }
469 }
470
print_game_video(FILE * out,const struct GameDriver * game)471 static void print_game_video(FILE* out, const struct GameDriver* game)
472 {
473 const struct MachineDriver* driver = game->drv;
474
475 int dx;
476 int dy;
477 int showxy;
478 int orientation;
479
480 fprintf(out, L1P "video" L2B);
481 if (driver->video_attributes & VIDEO_TYPE_VECTOR)
482 {
483 fprintf(out, L2P "screen vector" L2N);
484 showxy = 0;
485 }
486 else
487 {
488 fprintf(out, L2P "screen raster" L2N);
489 showxy = 1;
490 }
491
492 if (game->flags & ORIENTATION_SWAP_XY)
493 {
494 dx = driver->default_visible_area.max_y - driver->default_visible_area.min_y + 1;
495 dy = driver->default_visible_area.max_x - driver->default_visible_area.min_x + 1;
496 orientation = 1;
497 }
498 else
499 {
500 dx = driver->default_visible_area.max_x - driver->default_visible_area.min_x + 1;
501 dy = driver->default_visible_area.max_y - driver->default_visible_area.min_y + 1;
502 orientation = 0;
503 }
504
505
506 fprintf(out, L2P "orientation %s" L2N, orientation ? "vertical" : "horizontal" );
507 if (showxy)
508 {
509 fprintf(out, L2P "x %d" L2N, dx);
510 fprintf(out, L2P "y %d" L2N, dy);
511 }
512
513 fprintf(out, L2P "colors %d" L2N, driver->total_colors);
514 fprintf(out, L2P "freq %f" L2N, driver->frames_per_second);
515 fprintf(out, L2E L1N);
516 }
517
print_game_sound(FILE * out,const struct GameDriver * game)518 static void print_game_sound(FILE* out, const struct GameDriver* game) {
519 const struct MachineDriver* driver = game->drv;
520 const struct MachineCPU* cpu = driver->cpu;
521 const struct MachineSound* sound = driver->sound;
522
523 /* check if the game have sound emulation */
524 int has_sound = 0;
525 int i;
526
527 i = 0;
528 while (i < MAX_SOUND && !has_sound)
529 {
530 if (sound[i].sound_type)
531 has_sound = 1;
532 ++i;
533 }
534 i = 0;
535 while (i < MAX_CPU && !has_sound)
536 {
537 if ((cpu[i].cpu_type & CPU_AUDIO_CPU)!=0)
538 has_sound = 1;
539 ++i;
540 }
541
542 fprintf(out, L1P "sound" L2B);
543
544 /* sound channel */
545 if (has_sound) {
546 if (driver->sound_attributes & SOUND_SUPPORTS_STEREO)
547 fprintf(out, L2P "channels 2" L2N);
548 else
549 fprintf(out, L2P "channels 1" L2N);
550 } else
551 fprintf(out, L2P "channels 0" L2N);
552
553 fprintf(out, L2E L1N);
554 }
555
556 #define HISTORY_BUFFER_MAX 16384
557
print_game_history(FILE * out,const struct GameDriver * game)558 static void print_game_history(FILE* out, const struct GameDriver* game) {
559 char buffer[HISTORY_BUFFER_MAX];
560
561 if (load_driver_history(game,buffer,HISTORY_BUFFER_MAX)==0) {
562 fprintf(out, L1P "history ");
563 print_c_string(out, buffer);
564 fprintf(out, "%s", L1N);
565 }
566 }
567
print_game_driver(FILE * out,const struct GameDriver * game)568 static void print_game_driver(FILE* out, const struct GameDriver* game) {
569 fprintf(out, L1P "driver" L2B);
570 if (game->flags & GAME_NOT_WORKING)
571 fprintf(out, L2P "status preliminary" L2N);
572 else
573 fprintf(out, L2P "status good" L2N);
574
575 if (game->flags & GAME_WRONG_COLORS)
576 fprintf(out, L2P "color preliminary" L2N);
577 else if (game->flags & GAME_IMPERFECT_COLORS)
578 fprintf(out, L2P "color imperfect" L2N);
579 else
580 fprintf(out, L2P "color good" L2N);
581
582 if (game->flags & GAME_NO_SOUND)
583 fprintf(out, L2P "sound preliminary" L2N);
584 else if (game->flags & GAME_IMPERFECT_SOUND)
585 fprintf(out, L2P "sound imperfect" L2N);
586 else
587 fprintf(out, L2P "sound good" L2N);
588
589 if (game->flags & GAME_REQUIRES_16BIT)
590 fprintf(out, L2P "colordeep 16" L2N);
591 else
592 fprintf(out, L2P "colordeep 8" L2N);
593
594 fprintf(out, L2E L1N);
595 }
596
597 /* Print the MAME info record for a game */
print_game_info(FILE * out,const struct GameDriver * game)598 static void print_game_info(FILE* out, const struct GameDriver* game) {
599
600 #ifndef MESS
601 fprintf(out, "game" L1B );
602 #else
603 fprintf(out, "machine" L1B );
604 #endif
605
606 fprintf(out, L1P "name %s" L1N, game->name );
607
608 if (game->description) {
609 fprintf(out, L1P "description ");
610 print_c_string(out, game->description );
611 fprintf(out, "%s", L1N);
612 }
613
614 /* print the year only if is a number */
615 if (game->year && strspn(game->year,"0123456789")==strlen(game->year)) {
616 fprintf(out, L1P "year %s" L1N, game->year );
617 }
618
619 if (game->manufacturer) {
620 fprintf(out, L1P "manufacturer ");
621 print_c_string(out, game->manufacturer );
622 fprintf(out, "%s", L1N);
623 }
624
625 print_game_history(out,game);
626
627 if (game->clone_of && !(game->clone_of->flags & NOT_A_DRIVER)) {
628 fprintf(out, L1P "cloneof %s" L1N, game->clone_of->name);
629 }
630
631 print_game_rom(out,game);
632 print_game_sample(out,game);
633 print_game_micro(out,game);
634 print_game_video(out,game);
635 print_game_sound(out,game);
636 print_game_input(out,game);
637 print_game_switch(out,game);
638 print_game_driver(out,game);
639
640 fprintf(out, L1E);
641 }
642
643 /* Print all the MAME info database */
print_mame_info(FILE * out,const struct GameDriver * games[])644 void print_mame_info(FILE* out, const struct GameDriver* games[]) {
645 int j;
646
647 for(j=0;games[j];++j)
648 print_game_info( out, games[j] );
649
650 #ifndef MESS
651 /* addictional fixed record */
652 fprintf(out, "resource" L1B);
653 fprintf(out, L1P "name neogeo" L1N);
654 fprintf(out, L1P "description \"Neo Geo BIOS\"" L1N);
655 fprintf(out, L1P "rom" L2B);
656 fprintf(out, L2P "name neo-geo.rom" L2N);
657 fprintf(out, L2P "size 131072" L2N);
658 fprintf(out, L2P "crc 9036d879" L2N);
659 fprintf(out, L2E L1N);
660 fprintf(out, L1P "rom" L2B);
661 fprintf(out, L2P "name ng-sm1.rom" L2N);
662 fprintf(out, L2P "size 131072" L2N);
663 fprintf(out, L2P "crc 97cf998b" L2N);
664 fprintf(out, L2E L1N);
665 fprintf(out, L1P "rom" L2B);
666 fprintf(out, L2P "name ng-sfix.rom" L2N);
667 fprintf(out, L2P "size 131072" L2N);
668 fprintf(out, L2P "crc 354029fc" L2N);
669 fprintf(out, L2E L1N);
670 fprintf(out, L1E);
671 #endif
672 }
673