1 /*********************************************************************
2 common.c
3 Generic functions, mostly ROM and graphics related.
4 *********************************************************************/
5
6 #include "driver.h"
7 #include "png.h"
8 #include "harddisk.h"
9 #include "artwork.h"
10 #include "bootstrap.h"
11 #include <stdarg.h>
12 #include <ctype.h>
13 #include <string/stdstring.h>
14 #include "libretro-deps/libFLAC/include/FLAC/all.h"
15 #include "log.h"
16 //#define LOG_LOAD
17
18
19 char *chd_error_text[] =
20 {
21 "CHDERR_NONE",
22 "CHDERR_NO_INTERFACE",
23 "CHDERR_OUT_OF_MEMORY",
24 "CHDERR_INVALID_FILE",
25 "CHDERR_INVALID_PARAMETER",
26 "CHDERR_INVALID_DATA",
27 "CHDERR_FILE_NOT_FOUND",
28 "CHDERR_REQUIRES_PARENT",
29 "CHDERR_FILE_NOT_WRITEABLE",
30 "CHDERR_READ_ERROR",
31 "CHDERR_WRITE_ERROR",
32 "CHDERR_CODEC_ERROR",
33 "CHDERR_INVALID_PARENT",
34 "CHDERR_HUNK_OUT_OF_RANGE",
35 "CHDERR_DECOMPRESSION_ERROR",
36 "CHDERR_COMPRESSION_ERROR",
37 "CHDERR_CANT_CREATE_FILE",
38 "CHDERR_CANT_VERIFY",
39 "CHDERR_NOT_SUPPORTED",
40 "CHDERR_METADATA_NOT_FOUND",
41 "CHDERR_INVALID_METADATA_SIZE",
42 "CHDERR_UNSUPPORTED_VERSION"
43 };
44 /***************************************************************************
45 Constants
46 ***************************************************************************/
47
48 // VERY IMPORTANT: osd_alloc_bitmap must allocate also a "safety area" 16 pixels wide all
49 // around the bitmap. This is required because, for performance reasons, some graphic
50 // routines don't clip at boundaries of the bitmap.
51 #define BITMAP_SAFETY 16
52
53 #define MAX_MALLOCS 4096
54
55 /***************************************************************************
56 Type definitions
57 ***************************************************************************/
58
59 struct malloc_info
60 {
61 int tag;
62 void *ptr;
63 };
64
65
66 /***************************************************************************
67 FLAC stuff
68 ***************************************************************************/
69 typedef struct _flac_reader
70 {
71 UINT8* rawdata;
72 INT16* write_data;
73 int position;
74 int length;
75 int decoded_size;
76 int sample_rate;
77 int channels;
78 int bits_per_sample;
79 int total_samples;
80 int write_position;
81 }flac_reader;
82
83
my_error_callback(const FLAC__StreamDecoder * decoder,FLAC__StreamDecoderErrorStatus status,void * client_data)84 void my_error_callback(const FLAC__StreamDecoder * decoder, FLAC__StreamDecoderErrorStatus status, void * client_data)
85 {
86 printf("FLAC callback error\n");
87 }
88
my_metadata_callback(const FLAC__StreamDecoder * decoder,const FLAC__StreamMetadata * metadata,void * client_data)89 void my_metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
90 {
91
92 flac_reader *flacrd = (flac_reader*)client_data;
93
94 if (metadata->type==0)
95 {
96 const FLAC__StreamMetadata_StreamInfo *streaminfo = &(metadata->data.stream_info);
97
98 flacrd->sample_rate = streaminfo->sample_rate;
99 flacrd->channels = streaminfo->channels;
100 flacrd->bits_per_sample = streaminfo->bits_per_sample;
101 flacrd->total_samples = streaminfo->total_samples;
102 }
103 }
104
105
106
107
my_read_callback(const FLAC__StreamDecoder * decoder,FLAC__byte buffer[],size_t * bytes,void * client_data)108 FLAC__StreamDecoderReadStatus my_read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
109 {
110 flac_reader *flacrd = (flac_reader*)client_data;
111
112 if(*bytes > 0)
113 {
114 if (*bytes <= flacrd->length)
115 {
116 memcpy(buffer, flacrd->rawdata+flacrd->position, *bytes);
117 flacrd->position+=*bytes;
118 flacrd->length-=*bytes;
119 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
120 }
121 else
122 {
123 memcpy(buffer, flacrd->rawdata+flacrd->position, flacrd->length);
124 flacrd->position+= flacrd->length;
125 flacrd->length = 0;
126
127 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
128 }
129 }
130 else
131 {
132 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
133 }
134
135 if ( flacrd->length==0)
136 {
137 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
138 }
139
140 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
141
142 }
143
my_write_callback(const FLAC__StreamDecoder * decoder,const FLAC__Frame * frame,const FLAC__int32 * const buffer[],void * client_data)144 FLAC__StreamDecoderWriteStatus my_write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
145 {
146 int i;
147 flac_reader *flacrd = (flac_reader*)client_data;
148
149 flacrd->decoded_size += frame->header.blocksize;
150
151 for ( i=0;i<frame->header.blocksize;i++)
152 {
153 flacrd->write_data[i+flacrd->write_position] = buffer[0][i];
154 }
155
156 flacrd->write_position += frame->header.blocksize;
157
158 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
159 }
160
161 /***************************************************************************
162 Global variables
163 ***************************************************************************/
164
165 /* These globals are only kept on a machine basis - LBO 042898 */
166 unsigned int dispensed_tickets;
167 unsigned int coins[COIN_COUNTERS];
168 unsigned int lastcoin[COIN_COUNTERS];
169 unsigned int coinlockedout[COIN_COUNTERS];
170
171 int snapno;
172
173 /* malloc tracking */
174 static struct malloc_info malloc_list[MAX_MALLOCS];
175 static int malloc_list_index = 0;
176
177 /* resource tracking */
178 int resource_tracking_tag = 0;
179
180 /* generic NVRAM */
181 size_t generic_nvram_size;
182 data8_t *generic_nvram;
183
184 /* disks */
185 static struct chd_file *disk_handle[4];
186
187 /* system BIOS */
188 static int system_bios;
189
190
191 /***************************************************************************
192 Functions
193 ***************************************************************************/
194
showdisclaimer(void)195 void showdisclaimer(void) /* MAURY_BEGIN: dichiarazione */
196 {
197 printf("MAME is an emulator: it reproduces, more or less faithfully, the behaviour of\n"
198 "several arcade machines. But hardware is useless without software, so an image\n"
199 "of the ROMs which run on that hardware is required. Such ROMs, like any other\n"
200 "commercial software, are copyrighted material and it is therefore illegal to\n"
201 "use them if you don't own the original arcade machine. Needless to say, ROMs\n"
202 "are not distributed together with MAME. Distribution of MAME together with ROM\n"
203 "images is a violation of copyright law and should be promptly reported to the\n"
204 "authors so that appropriate legal action can be taken.\n\n");
205 } /* MAURY_END: dichiarazione */
206
207
208
209 /***************************************************************************
210 Sample handling code
211 This function is different from readroms() because it doesn't fail if
212 it doesn't find a file: it will load as many samples as it can find.
213 ***************************************************************************/
214
215 #ifdef MSB_FIRST
216 #define intelLong(x) (((x << 24) | (((unsigned long) x) >> 24) | (( x & 0x0000ff00) << 8) | (( x & 0x00ff0000) >> 8)))
217 #else
218 #define intelLong(x) (x)
219 #endif
220
221 /*-------------------------------------------------
222 read_wav_sample - read a WAV file as a sample
223 -------------------------------------------------*/
read_wav_sample(mame_file * f,const char * gamename,const char * filename,int filetype,int b_data)224 static struct GameSample *read_wav_sample(mame_file *f, const char *gamename, const char *filename, int filetype, int b_data)
225 {
226 unsigned long offset = 0;
227 UINT32 length, rate, filesize, temp32;
228 UINT16 bits, temp16;
229 char buf[32];
230 struct GameSample *result;
231 int f_type = 0;
232
233 /* read the core header and make sure it's a proper file */
234 offset += mame_fread(f, buf, 4);
235
236 if (offset < 4)
237 return NULL;
238
239 if (memcmp(&buf[0], "RIFF", 4) == 0)
240 f_type = 1; // WAV
241 else if (memcmp(&buf[0], "fLaC", 4) == 0)
242 f_type = 2; // FLAC
243 else
244 return NULL; // No idea what file this is.
245
246 // Load WAV file.
247 if(f_type == 1) {
248 /* get the total size */
249 offset += mame_fread(f, &filesize, 4);
250 if (offset < 8)
251 return NULL;
252 filesize = intelLong(filesize);
253
254 /* read the RIFF file type and make sure it's a WAVE file */
255 offset += mame_fread(f, buf, 4);
256 if (offset < 12)
257 return NULL;
258 if (memcmp(&buf[0], "WAVE", 4) != 0)
259 return NULL;
260
261 /* seek until we find a format tag */
262 while (1)
263 {
264 offset += mame_fread(f, buf, 4);
265 offset += mame_fread(f, &length, 4);
266 length = intelLong(length);
267 if (memcmp(&buf[0], "fmt ", 4) == 0)
268 break;
269
270 /* seek to the next block */
271 mame_fseek(f, length, SEEK_CUR);
272 offset += length;
273 if (offset >= filesize)
274 return NULL;
275 }
276
277 /* read the format -- make sure it is PCM */
278 offset += mame_fread_lsbfirst(f, &temp16, 2);
279 if (temp16 != 1)
280 return NULL;
281
282 /* number of channels -- only mono is supported */
283 offset += mame_fread_lsbfirst(f, &temp16, 2);
284 if (temp16 != 1)
285 return NULL;
286
287 /* sample rate */
288 offset += mame_fread(f, &rate, 4);
289 rate = intelLong(rate);
290
291 /* bytes/second and block alignment are ignored */
292 offset += mame_fread(f, buf, 6);
293
294 /* bits/sample */
295 offset += mame_fread_lsbfirst(f, &bits, 2);
296 if (bits != 8 && bits != 16)
297 return NULL;
298
299 /* seek past any extra data */
300 mame_fseek(f, length - 16, SEEK_CUR);
301 offset += length - 16;
302
303 /* seek until we find a data tag */
304 while (1)
305 {
306 offset += mame_fread(f, buf, 4);
307 offset += mame_fread(f, &length, 4);
308 length = intelLong(length);
309 if (memcmp(&buf[0], "data", 4) == 0)
310 break;
311
312 /* seek to the next block */
313 mame_fseek(f, length, SEEK_CUR);
314 offset += length;
315 if (offset >= filesize)
316 return NULL;
317 }
318
319 // For small samples, lets force them to pre load into memory.
320 if(length <= GAME_SAMPLE_LARGE)
321 b_data = 1;
322
323 /* allocate the game sample */
324 if(b_data == 1)
325 result = auto_malloc(sizeof(struct GameSample) + length);
326 else
327 result = malloc(sizeof(struct GameSample));
328
329 if (result == NULL)
330 return NULL;
331
332 /* fill in the sample data */
333 strcpy(result->gamename, gamename);
334 strcpy(result->filename, filename);
335 result->filetype = filetype;
336
337 result->length = length;
338 result->smpfreq = rate;
339 result->resolution = bits;
340
341 if(b_data == 1) {
342 // read the data in
343 if (bits == 8)
344 {
345 mame_fread(f, result->data, length);
346
347 // convert 8-bit data to signed samples
348 for (temp32 = 0; temp32 < length; temp32++)
349 result->data[temp32] ^= 0x80;
350 }
351 else
352 {
353 // 16-bit data is fine as-is
354 mame_fread_lsbfirst(f, result->data, length);
355 }
356
357 result->b_decoded = 1;
358 }
359 else
360 result->b_decoded = 0;
361
362 return result;
363 }
364 else if(f_type == 2) { // Load FLAC file.
365 int f_length;
366 flac_reader flac_file;
367 FLAC__StreamDecoder *decoder;
368
369 mame_fseek(f, 0, SEEK_END);
370 f_length = mame_ftell(f);
371 mame_fseek(f, 0, 0);
372
373 // For small samples, lets force them to pre load into memory.
374 if (f_length <= GAME_SAMPLE_LARGE)
375 b_data = 1;
376
377 flac_file.length = f_length;
378 flac_file.position = 0;
379 flac_file.decoded_size = 0;
380
381 // Allocate space for the data.
382 flac_file.rawdata = malloc(f_length);
383
384 // Read the sample data in.
385 mame_fread(f, flac_file.rawdata, f_length);
386 decoder = FLAC__stream_decoder_new();
387
388 if (!decoder) {
389 free(flac_file.rawdata);
390 return NULL;
391 }
392
393 if(FLAC__stream_decoder_init_stream(decoder, my_read_callback,
394 NULL, //my_seek_callback, // or NULL
395 NULL, //my_tell_callback, // or NULL
396 NULL, //my_length_callback, // or NULL
397 NULL, //my_eof_callback, // or NULL
398 my_write_callback,
399 my_metadata_callback, //my_metadata_callback, // or NULL
400 my_error_callback,
401 (void*)&flac_file) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
402 return NULL;
403
404 if (FLAC__stream_decoder_process_until_end_of_metadata(decoder) != FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM) {
405 free(flac_file.rawdata);
406 FLAC__stream_decoder_delete(decoder);
407 return NULL;
408 }
409
410 // only Mono supported
411 if (flac_file.channels != 1) {
412 free(flac_file.rawdata);
413 FLAC__stream_decoder_delete(decoder);
414 return NULL;
415 }
416
417 // only support 16 bit.
418 if (flac_file.bits_per_sample != 16) {
419 free(flac_file.rawdata);
420 FLAC__stream_decoder_delete(decoder);
421 return NULL;
422 }
423
424 if (b_data == 1)
425 result = auto_malloc(sizeof(struct GameSample) + (flac_file.total_samples * (flac_file.bits_per_sample / 8)));
426 else
427 result = malloc(sizeof(struct GameSample));
428
429 strcpy(result->gamename, gamename);
430 strcpy(result->filename, filename);
431 result->filetype = filetype;
432
433 result->smpfreq = flac_file.sample_rate;
434 result->length = flac_file.total_samples * (flac_file.bits_per_sample / 8);
435 result->resolution = flac_file.bits_per_sample;
436 flac_file.write_position = 0;
437
438 if (b_data == 1) {
439 flac_file.write_data = result->data;
440
441 if (FLAC__stream_decoder_process_until_end_of_stream (decoder) != FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM) {
442 free(flac_file.rawdata);
443 FLAC__stream_decoder_delete(decoder);
444 return NULL;
445 }
446
447 result->b_decoded = 1;
448 }
449 else
450 result->b_decoded = 0;
451
452 if (FLAC__stream_decoder_finish (decoder) != true) {
453 free(flac_file.rawdata);
454 FLAC__stream_decoder_delete(decoder);
455 return NULL;
456 }
457
458 FLAC__stream_decoder_delete(decoder);
459
460 free(flac_file.rawdata);
461
462 return result;
463 }
464 else
465 return NULL;
466 }
467
468 /* Handles freeing previous played sample from memory. Helps with the low memory devices which load large sample files. */
469
readsample(struct GameSample * SampleInfo,int channel,struct GameSamples * SamplesData,int load)470 void readsample(struct GameSample *SampleInfo, int channel, struct GameSamples *SamplesData, int load)
471 {
472 mame_file *f;
473 struct GameSample *SampleFile;
474
475 // Try opening the file.
476 f = mame_fopen(SampleInfo->gamename,SampleInfo->filename,SampleInfo->filetype,0);
477
478 if (f != 0) {
479 char gamename[512];
480 char filename[512];
481 int filetype = SampleInfo->filetype;
482
483 strcpy(gamename, SampleInfo->gamename);
484 strcpy(filename, SampleInfo->filename);
485
486 // Free up some memory.
487 free(SamplesData->sample[channel]);
488
489 // Reload or load a sample into memory.
490 SamplesData->sample[channel] = read_wav_sample(f, gamename, filename, filetype, load);
491
492 mame_fclose(f);
493 }
494 }
495
496 /*-------------------------------------------------
497 readsamples() load all samples
498 -------------------------------------------------*/
499
readsamples(const char ** samplenames,const char * basename)500 struct GameSamples *readsamples(const char **samplenames,const char *basename)
501 /* V.V - avoids samples duplication */
502 /* if first samplename is *dir, looks for samples into "basename" first, then "dir" */
503 {
504 int i;
505 struct GameSamples *samples;
506 int skipfirst = 0;
507 bool missing_sample = false;
508
509 /* if the user doesn't want to use samples, bail */
510 if( (!options.use_samples) && (options.content_flags[CONTENT_ALT_SOUND]) ) return 0;
511
512 if (samplenames == 0 || samplenames[0] == 0) return 0;
513
514 if (samplenames[0][0] == '*')
515 skipfirst = 1;
516
517 i = 0;
518 while (samplenames[i+skipfirst] != 0) i++;
519
520 if (!i) return 0;
521
522 if ((samples = auto_malloc(sizeof(struct GameSamples) + (i-1)*sizeof(struct GameSample))) == 0)
523 return 0;
524
525 samples->total = i;
526 for (i = 0;i < samples->total;i++)
527 samples->sample[i] = 0;
528
529 for (i = 0;i < samples->total;i++)
530 {
531 mame_file *f;
532 int f_type = 0;
533 int f_skip = 0;
534
535 if (samplenames[i+skipfirst][0])
536 {
537 // Try opening FLAC samples first.
538 if ((f = mame_fopen(basename,samplenames[i+skipfirst],FILETYPE_SAMPLE_FLAC,0)) == 0)
539 {
540 if (skipfirst) {
541 f = mame_fopen(samplenames[0]+1,samplenames[i+skipfirst],FILETYPE_SAMPLE_FLAC,0);
542 f_skip = 1;
543 }
544
545 // Fall back to WAV if it exists.
546 if (!f)
547 {
548 f_type = 1;
549 f_skip = 0;
550
551 if ((f = mame_fopen(basename,samplenames[i+skipfirst],FILETYPE_SAMPLE,0)) == 0)
552 if (skipfirst) {
553 f = mame_fopen(samplenames[0]+1,samplenames[i+skipfirst],FILETYPE_SAMPLE,0);
554 f_skip = 1;
555 }
556 }
557 }
558
559 // Get sample info. Small sample files will pre load into memory at this point.
560 if (f != 0)
561 {
562 // Open FLAC.
563 if(f_type == 0) {
564 if (f_skip == 1)
565 samples->sample[i] = read_wav_sample(f, samplenames[0]+1, samplenames[i+skipfirst], FILETYPE_SAMPLE_FLAC, 0);
566 else
567 samples->sample[i] = read_wav_sample(f, basename, samplenames[i+skipfirst], FILETYPE_SAMPLE_FLAC, 0);
568 }
569 else { // Open WAV.
570 if (f_skip == 1)
571 samples->sample[i] = read_wav_sample(f, samplenames[0]+1, samplenames[i+skipfirst], FILETYPE_SAMPLE, 0);
572 else
573 samples->sample[i] = read_wav_sample(f, basename, samplenames[i+skipfirst], FILETYPE_SAMPLE, 0);
574 }
575
576 mame_fclose(f);
577 }
578 else if (samples->sample[i] == NULL)
579 {
580 log_cb(RETRO_LOG_WARN, LOGPRE "Missing audio sample: %s\n", samplenames[i+skipfirst]);
581 missing_sample = true;
582 log_cb(RETRO_LOG_WARN, LOGPRE "Warning: audio sample(s) not found.\n");
583 frontend_message_cb("Warning: audio sample(s) not found.", 180);
584 }
585 }
586 }
587
588 return samples;
589 }
590
591
592
593 /***************************************************************************
594
595 Memory region code
596
597 ***************************************************************************/
598
599 /*-------------------------------------------------
600 memory_region - returns pointer to a memory
601 region
602 -------------------------------------------------*/
603
memory_region(int num)604 unsigned char *memory_region(int num)
605 {
606 int i;
607
608 if (num < MAX_MEMORY_REGIONS)
609 return Machine->memory_region[num].base;
610 else
611 {
612 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
613 {
614 if (Machine->memory_region[i].type == num)
615 return Machine->memory_region[i].base;
616 }
617 }
618
619 return 0;
620 }
621
622
623 /*-------------------------------------------------
624 memory_region_length - returns length of a
625 memory region
626 -------------------------------------------------*/
627
memory_region_length(int num)628 size_t memory_region_length(int num)
629 {
630 int i;
631
632 if (num < MAX_MEMORY_REGIONS)
633 return Machine->memory_region[num].length;
634 else
635 {
636 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
637 {
638 if (Machine->memory_region[i].type == num)
639 return Machine->memory_region[i].length;
640 }
641 }
642
643 return 0;
644 }
645
646
647 /*-------------------------------------------------
648 new_memory_region - allocates memory for a
649 region
650 -------------------------------------------------*/
651
new_memory_region(int num,size_t length,UINT32 flags)652 int new_memory_region(int num, size_t length, UINT32 flags)
653 {
654 int i;
655
656 if (num < MAX_MEMORY_REGIONS)
657 {
658 Machine->memory_region[num].length = length;
659 Machine->memory_region[num].base = malloc(length);
660 return (Machine->memory_region[num].base == NULL) ? 1 : 0;
661 }
662 else
663 {
664 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
665 {
666 if (Machine->memory_region[i].base == NULL)
667 {
668 Machine->memory_region[i].length = length;
669 Machine->memory_region[i].type = num;
670 Machine->memory_region[i].flags = flags;
671 Machine->memory_region[i].base = malloc(length);
672 return (Machine->memory_region[i].base == NULL) ? 1 : 0;
673 }
674 }
675 }
676 return 1;
677 }
678
679
680 /*-------------------------------------------------
681 free_memory_region - releases memory for a
682 region
683 -------------------------------------------------*/
684
free_memory_region(int num)685 void free_memory_region(int num)
686 {
687 int i;
688
689 if (num < MAX_MEMORY_REGIONS)
690 {
691 free(Machine->memory_region[num].base);
692 memset(&Machine->memory_region[num], 0, sizeof(Machine->memory_region[num]));
693 }
694 else
695 {
696 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
697 {
698 if (Machine->memory_region[i].type == num)
699 {
700 free(Machine->memory_region[i].base);
701 memset(&Machine->memory_region[i], 0, sizeof(Machine->memory_region[i]));
702 return;
703 }
704 }
705 }
706 }
707
708
709
710 /***************************************************************************
711
712 Coin counter code
713
714 ***************************************************************************/
715
716 /*-------------------------------------------------
717 coin_counter_w - sets input for coin counter
718 -------------------------------------------------*/
719
coin_counter_w(int num,int on)720 void coin_counter_w(int num,int on)
721 {
722 if (num >= COIN_COUNTERS) return;
723 /* Count it only if the data has changed from 0 to non-zero */
724 if (on && (lastcoin[num] == 0))
725 {
726 coins[num]++;
727 }
728 lastcoin[num] = on;
729 }
730
731
732 /*-------------------------------------------------
733 coin_lockout_w - locks out one coin input
734 -------------------------------------------------*/
735
coin_lockout_w(int num,int on)736 void coin_lockout_w(int num,int on)
737 {
738 if (num >= COIN_COUNTERS) return;
739
740 coinlockedout[num] = on;
741 }
742
743
744 /*-------------------------------------------------
745 coin_lockout_global_w - locks out all the coin
746 inputs
747 -------------------------------------------------*/
748
coin_lockout_global_w(int on)749 void coin_lockout_global_w(int on)
750 {
751 int i;
752
753 for (i = 0; i < COIN_COUNTERS; i++)
754 {
755 coin_lockout_w(i,on);
756 }
757 }
758
759
760
761 /***************************************************************************
762
763 Generic NVRAM code
764
765 ***************************************************************************/
766
767 /*-------------------------------------------------
768 nvram_handler_generic_0fill - generic NVRAM
769 with a 0 fill
770 -------------------------------------------------*/
771
nvram_handler_generic_0fill(mame_file * file,int read_or_write)772 void nvram_handler_generic_0fill(mame_file *file, int read_or_write)
773 {
774 if (read_or_write)
775 mame_fwrite(file, generic_nvram, generic_nvram_size);
776 else if (file)
777 mame_fread(file, generic_nvram, generic_nvram_size);
778 else
779 memset(generic_nvram, 0, generic_nvram_size);
780 }
781
782
783 /*-------------------------------------------------
784 nvram_handler_generic_1fill - generic NVRAM
785 with a 1 fill
786 -------------------------------------------------*/
787
nvram_handler_generic_1fill(mame_file * file,int read_or_write)788 void nvram_handler_generic_1fill(mame_file *file, int read_or_write)
789 {
790 if (read_or_write)
791 mame_fwrite(file, generic_nvram, generic_nvram_size);
792 else if (file)
793 mame_fread(file, generic_nvram, generic_nvram_size);
794 else
795 memset(generic_nvram, 0xff, generic_nvram_size);
796 }
797
798
799
800 /***************************************************************************
801
802 Bitmap allocation/freeing code
803
804 ***************************************************************************/
805
806 /*-------------------------------------------------
807 bitmap_alloc_core
808 -------------------------------------------------*/
809
bitmap_alloc_core(int width,int height,int depth,int use_auto)810 struct mame_bitmap *bitmap_alloc_core(int width,int height,int depth,int use_auto)
811 {
812 struct mame_bitmap *bitmap;
813
814 /* obsolete kludge: pass in negative depth to prevent orientation swapping */
815 if (depth < 0)
816 depth = -depth;
817
818 /* verify it's a depth we can handle */
819 if (depth != 8 && depth != 15 && depth != 16 && depth != 32)
820 {
821 log_cb(RETRO_LOG_ERROR, LOGPRE "osd_alloc_bitmap() unknown depth %d\n",depth);
822 return NULL;
823 }
824
825 /* allocate memory for the bitmap struct */
826 bitmap = use_auto ? auto_malloc(sizeof(struct mame_bitmap)) : malloc(sizeof(struct mame_bitmap));
827 if (bitmap != NULL)
828 {
829 int i, rowlen, rdwidth, bitmapsize, linearraysize, pixelsize;
830 unsigned char *bm;
831
832 /* initialize the basic parameters */
833 bitmap->depth = depth;
834 bitmap->width = width;
835 bitmap->height = height;
836
837 /* determine pixel size in bytes */
838 pixelsize = 1;
839 if (depth == 15 || depth == 16)
840 pixelsize = 2;
841 else if (depth == 32)
842 pixelsize = 4;
843
844 /* round the width to a multiple of 8 */
845 rdwidth = (width + 7) & ~7;
846 rowlen = rdwidth + 2 * BITMAP_SAFETY;
847 bitmap->rowpixels = rowlen;
848
849 /* now convert from pixels to bytes */
850 rowlen *= pixelsize;
851 bitmap->rowbytes = rowlen;
852
853 /* determine total memory for bitmap and line arrays */
854 bitmapsize = (height + 2 * BITMAP_SAFETY) * rowlen;
855 linearraysize = (height + 2 * BITMAP_SAFETY) * sizeof(unsigned char *);
856
857 /* align to 16 bytes */
858 linearraysize = (linearraysize + 15) & ~15;
859
860 /* allocate the bitmap data plus an array of line pointers */
861 bitmap->line = use_auto ? auto_malloc(linearraysize + bitmapsize) : malloc(linearraysize + bitmapsize);
862 if (bitmap->line == NULL)
863 {
864 if (!use_auto) free(bitmap);
865 return NULL;
866 }
867
868 /* clear ALL bitmap, including safety area, to avoid garbage on right */
869 bm = (unsigned char *)bitmap->line + linearraysize;
870 memset(bm, 0, (height + 2 * BITMAP_SAFETY) * rowlen);
871
872 /* initialize the line pointers */
873 for (i = 0; i < height + 2 * BITMAP_SAFETY; i++)
874 bitmap->line[i] = &bm[i * rowlen + BITMAP_SAFETY * pixelsize];
875
876 /* adjust for the safety rows */
877 bitmap->line += BITMAP_SAFETY;
878 bitmap->base = bitmap->line[0];
879
880 /* set the pixel functions */
881 set_pixel_functions(bitmap);
882 }
883
884 /* return the result */
885 return bitmap;
886 }
887
888
889 /*-------------------------------------------------
890 bitmap_alloc - allocate a bitmap at the
891 current screen depth
892 -------------------------------------------------*/
893
bitmap_alloc(int width,int height)894 struct mame_bitmap *bitmap_alloc(int width,int height)
895 {
896 return bitmap_alloc_core(width,height,Machine->scrbitmap->depth,0);
897 }
898
899
900 /*-------------------------------------------------
901 bitmap_alloc_depth - allocate a bitmap for a
902 specific depth
903 -------------------------------------------------*/
904
bitmap_alloc_depth(int width,int height,int depth)905 struct mame_bitmap *bitmap_alloc_depth(int width,int height,int depth)
906 {
907 return bitmap_alloc_core(width,height,depth,0);
908 }
909
910
911 /*-------------------------------------------------
912 bitmap_free - free a bitmap
913 -------------------------------------------------*/
914
bitmap_free(struct mame_bitmap * bitmap)915 void bitmap_free(struct mame_bitmap *bitmap)
916 {
917 /* skip if NULL */
918 if (!bitmap)
919 return;
920
921 /* unadjust for the safety rows */
922 bitmap->line -= BITMAP_SAFETY;
923
924 /* free the memory */
925 free(bitmap->line);
926 free(bitmap);
927 }
928
929
930
931 /***************************************************************************
932
933 Resource tracking code
934
935 ***************************************************************************/
936
937 /*-------------------------------------------------
938 auto_malloc - allocate auto-freeing memory
939 -------------------------------------------------*/
940
auto_malloc(size_t size)941 void *auto_malloc(size_t size)
942 {
943 void *result = malloc(size);
944 if (result)
945 {
946 struct malloc_info *info;
947
948 /* make sure we have space */
949 if (malloc_list_index >= MAX_MALLOCS)
950 {
951 log_cb(RETRO_LOG_ERROR, LOGPRE "Out of malloc tracking slots!\n");
952 return result;
953 }
954
955 /* fill in the current entry */
956 info = &malloc_list[malloc_list_index++];
957 info->tag = get_resource_tag();
958 info->ptr = result;
959 }
960 return result;
961 }
962
963
964
965 /*-------------------------------------------------
966 auto_strdup - allocate auto-freeing string
967 -------------------------------------------------*/
968
auto_strdup(const char * str)969 char *auto_strdup(const char *str)
970 {
971 char *new_str = auto_malloc(strlen(str) + 1);
972 if (!new_str)
973 return NULL;
974 strcpy(new_str, str);
975 return new_str;
976 }
977
978
979
980 /*-------------------------------------------------
981 end_resource_tracking - stop tracking
982 resources
983 -------------------------------------------------*/
984
auto_free(void)985 void auto_free(void)
986 {
987 int tag = get_resource_tag();
988
989 /* start at the end and free everything on the current tag */
990 while (malloc_list_index > 0 && malloc_list[malloc_list_index - 1].tag >= tag)
991 {
992 struct malloc_info *info = &malloc_list[--malloc_list_index];
993 free(info->ptr);
994 }
995 }
996
997
998 /*-------------------------------------------------
999 bitmap_alloc - allocate a bitmap at the
1000 current screen depth
1001 -------------------------------------------------*/
1002
auto_bitmap_alloc(int width,int height)1003 struct mame_bitmap *auto_bitmap_alloc(int width,int height)
1004 {
1005 return bitmap_alloc_core(width,height,Machine->scrbitmap->depth,1);
1006 }
1007
1008
1009 /*-------------------------------------------------
1010 bitmap_alloc_depth - allocate a bitmap for a
1011 specific depth
1012 -------------------------------------------------*/
1013
auto_bitmap_alloc_depth(int width,int height,int depth)1014 struct mame_bitmap *auto_bitmap_alloc_depth(int width,int height,int depth)
1015 {
1016 return bitmap_alloc_core(width,height,depth,1);
1017 }
1018
1019
1020 /*-------------------------------------------------
1021 begin_resource_tracking - start tracking
1022 resources
1023 -------------------------------------------------*/
1024
begin_resource_tracking(void)1025 void begin_resource_tracking(void)
1026 {
1027 /* increment the tag counter */
1028 resource_tracking_tag++;
1029 }
1030
1031
1032 /*-------------------------------------------------
1033 end_resource_tracking - stop tracking
1034 resources
1035 -------------------------------------------------*/
1036
end_resource_tracking(void)1037 void end_resource_tracking(void)
1038 {
1039 /* call everyone who tracks resources to let them know */
1040 auto_free();
1041 timer_free();
1042
1043 /* decrement the tag counter */
1044 resource_tracking_tag--;
1045 }
1046
1047 /***************************************************************************
1048
1049 Hard disk handling
1050
1051 ***************************************************************************/
1052
get_disk_handle(int diskindex)1053 struct chd_file *get_disk_handle(int diskindex)
1054 {
1055 return disk_handle[diskindex];
1056 }
1057
1058
1059
1060 /***************************************************************************
1061
1062 ROM loading code
1063
1064 ***************************************************************************/
1065
1066 /*-------------------------------------------------
1067 rom_first_region - return pointer to first ROM
1068 region
1069 -------------------------------------------------*/
1070
rom_first_region(const struct GameDriver * drv)1071 const struct RomModule *rom_first_region(const struct GameDriver *drv)
1072 {
1073 return drv->rom;
1074 }
1075
1076
1077 /*-------------------------------------------------
1078 rom_next_region - return pointer to next ROM
1079 region
1080 -------------------------------------------------*/
1081
rom_next_region(const struct RomModule * romp)1082 const struct RomModule *rom_next_region(const struct RomModule *romp)
1083 {
1084 romp++;
1085 while (!ROMENTRY_ISREGIONEND(romp))
1086 romp++;
1087 return ROMENTRY_ISEND(romp) ? NULL : romp;
1088 }
1089
1090
1091 /*-------------------------------------------------
1092 rom_first_file - return pointer to first ROM
1093 file
1094 -------------------------------------------------*/
1095
rom_first_file(const struct RomModule * romp)1096 const struct RomModule *rom_first_file(const struct RomModule *romp)
1097 {
1098 romp++;
1099 while (!ROMENTRY_ISFILE(romp) && !ROMENTRY_ISREGIONEND(romp))
1100 romp++;
1101 return ROMENTRY_ISREGIONEND(romp) ? NULL : romp;
1102 }
1103
1104
1105 /*-------------------------------------------------
1106 rom_next_file - return pointer to next ROM
1107 file
1108 -------------------------------------------------*/
1109
rom_next_file(const struct RomModule * romp)1110 const struct RomModule *rom_next_file(const struct RomModule *romp)
1111 {
1112 romp++;
1113 while (!ROMENTRY_ISFILE(romp) && !ROMENTRY_ISREGIONEND(romp))
1114 romp++;
1115 return ROMENTRY_ISREGIONEND(romp) ? NULL : romp;
1116 }
1117
1118
1119 /*-------------------------------------------------
1120 rom_first_chunk - return pointer to first ROM
1121 chunk
1122 -------------------------------------------------*/
1123
rom_first_chunk(const struct RomModule * romp)1124 const struct RomModule *rom_first_chunk(const struct RomModule *romp)
1125 {
1126 return (ROMENTRY_ISFILE(romp)) ? romp : NULL;
1127 }
1128
1129
1130 /*-------------------------------------------------
1131 rom_next_chunk - return pointer to next ROM
1132 chunk
1133 -------------------------------------------------*/
1134
rom_next_chunk(const struct RomModule * romp)1135 const struct RomModule *rom_next_chunk(const struct RomModule *romp)
1136 {
1137 romp++;
1138 return (ROMENTRY_ISCONTINUE(romp)) ? romp : NULL;
1139 }
1140
1141
1142 /*-------------------------------------------------
1143 debugload - log data to a file
1144 -------------------------------------------------*/
1145
1146
1147
1148 /*-------------------------------------------------
1149 determine_bios_rom - determine system_bios
1150 from SystemBios structure and options.bios
1151 -------------------------------------------------*/
1152
determine_bios_rom(const struct SystemBios * bios)1153 int determine_bios_rom(const struct SystemBios *bios)
1154 {
1155 const struct SystemBios *firstbios = bios;
1156
1157 /* set to default */
1158 int bios_no = 0;
1159
1160 /* Not system_bios_0 and options.bios is set */
1161 if(bios && (options.bios != NULL))
1162 {
1163
1164 /* Allow '-bios n' to still be used */
1165 /* no actually in mame2003 we don't use the old numerical bios index
1166 we use the core option & option.bios string */
1167 /*
1168 while(!BIOSENTRY_ISEND(bios))
1169 {
1170 char bios_number[3];
1171
1172 if(!strcmp(bios_number, options.bios))
1173 bios_no = bios->value;
1174
1175 bios++;
1176 }
1177
1178 bios = firstbios;
1179 */
1180
1181 /* Test for bios short names */
1182 while(!BIOSENTRY_ISEND(bios))
1183 {
1184 if(strcmp(bios->_name, options.bios) == 0)
1185 {
1186 log_cb(RETRO_LOG_INFO, LOGPRE "Using BIOS: %s\n", options.bios);
1187 bios_no = bios->value;
1188 break;
1189 }
1190 bios++;
1191 }
1192 if(string_is_empty(options.bios))
1193 log_cb(RETRO_LOG_INFO, LOGPRE "No matching BIOS found. Using default system BIOS.");
1194
1195 }
1196
1197 return bios_no;
1198 }
1199
1200
1201 /*-------------------------------------------------
1202 count_roms - counts the total number of ROMs
1203 that will need to be loaded
1204 -------------------------------------------------*/
1205
count_roms(const struct RomModule * romp)1206 static int count_roms(const struct RomModule *romp)
1207 {
1208 const struct RomModule *region, *rom;
1209 int count = 0;
1210
1211 /* determine the correct biosset to load based on options.bios string */
1212 int this_bios = determine_bios_rom(Machine->gamedrv->bios);
1213
1214 /* loop over regions, then over files */
1215 for (region = romp; region; region = rom_next_region(region))
1216 for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
1217 if (!ROM_GETBIOSFLAGS(romp) || (ROM_GETBIOSFLAGS(romp) == (this_bios+1))) /* alternate bios sets */
1218 count++;
1219
1220 /* return the total count */
1221 return count;
1222 }
1223
1224
1225 /*-------------------------------------------------
1226 fill_random - fills an area of memory with
1227 random data
1228 -------------------------------------------------*/
1229
fill_random(UINT8 * base,UINT32 length)1230 static void fill_random(UINT8 *base, UINT32 length)
1231 {
1232 while (length--)
1233 *base++ = rand();
1234 }
1235
1236
1237 /*-------------------------------------------------
1238 handle_missing_file - handles error generation
1239 for missing files
1240 -------------------------------------------------*/
1241
handle_missing_file(struct rom_load_data * romdata,const struct RomModule * romp)1242 static void handle_missing_file(struct rom_load_data *romdata, const struct RomModule *romp)
1243 {
1244 /* optional files are okay */
1245 if (ROM_ISOPTIONAL(romp))
1246 {
1247 log_cb(RETRO_LOG_ERROR, LOGPRE "OPTIONAL %-12s NOT FOUND\n", ROM_GETNAME(romp));
1248 romdata->warnings++;
1249 }
1250
1251 /* no good dumps are okay */
1252 else if (ROM_NOGOODDUMP(romp))
1253 {
1254 log_cb(RETRO_LOG_INFO, LOGPRE "%-12s NOT FOUND (NO GOOD DUMP KNOWN)\n", ROM_GETNAME(romp));
1255 romdata->warnings++;
1256 }
1257
1258 /* anything else is bad */
1259 else
1260 {
1261 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s NOT FOUND\n", ROM_GETNAME(romp));
1262 romdata->errors++;
1263 }
1264 }
1265
1266 /*-------------------------------------------------
1267 dump_wrong_and_correct_checksums - dump an
1268 error message containing the wrong and the
1269 correct checksums for a given ROM
1270 -------------------------------------------------*/
1271
dump_wrong_and_correct_checksums(struct rom_load_data * romdata,const char * hash,const char * acthash)1272 static void dump_wrong_and_correct_checksums(struct rom_load_data* romdata, const char* hash, const char* acthash)
1273 {
1274 unsigned i;
1275 char chksum[256];
1276 unsigned found_functions;
1277 unsigned wrong_functions;
1278
1279 found_functions = hash_data_used_functions(hash) & hash_data_used_functions(acthash);
1280
1281 hash_data_print(hash, found_functions, chksum);
1282 log_cb(RETRO_LOG_ERROR, LOGPRE " EXPECTED: %s\n", chksum);
1283
1284 /* We dump informations only of the functions for which MAME provided
1285 a correct checksum. Other functions we might have calculated are
1286 useless here */
1287 hash_data_print(acthash, found_functions, chksum);
1288 log_cb(RETRO_LOG_ERROR, LOGPRE " FOUND: %s\n", chksum);
1289
1290 /* For debugging purposes, we check if the checksums available in the
1291 driver are correctly specified or not. This can be done by checking
1292 the return value of one of the extract functions. Maybe we want to
1293 activate this only in debug buils, but many developers only use
1294 release builds, so I keep it as is for now. */
1295 wrong_functions = 0;
1296 for (i=0;i<HASH_NUM_FUNCTIONS;i++)
1297 if (hash_data_extract_printable_checksum(hash, 1<<i, chksum) == 2)
1298 wrong_functions |= 1<<i;
1299
1300 if (wrong_functions)
1301 {
1302 for (i=0;i<HASH_NUM_FUNCTIONS;i++)
1303 if (wrong_functions & (1<<i))
1304 {
1305 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)],
1306 "\tInvalid %s checksum treated as 0 (check leading zeros)\n",
1307 hash_function_name(1<<i));
1308
1309 romdata->warnings++;
1310 }
1311 }
1312 }
1313
1314
1315 /*-------------------------------------------------
1316 verify_length_and_hash - verify the length
1317 and hash signatures of a file
1318 -------------------------------------------------*/
1319
verify_length_and_hash(struct rom_load_data * romdata,const char * name,UINT32 explength,const char * hash)1320 static void verify_length_and_hash(struct rom_load_data *romdata, const char *name, UINT32 explength, const char* hash)
1321 {
1322 UINT32 actlength;
1323 const char* acthash;
1324
1325 /* we've already complained if there is no file */
1326 if (!romdata->file)
1327 return;
1328
1329 /* get the length and CRC from the file */
1330 actlength = mame_fsize(romdata->file);
1331 acthash = mame_fhash(romdata->file);
1332
1333 /* verify length */
1334 if (explength != actlength)
1335 {
1336 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s WRONG LENGTH (expected: %08x found: %08x)\n", name, explength, actlength);
1337 romdata->warnings++;
1338 }
1339
1340 /* If there is no good dump known, write it */
1341 if (hash_data_has_info(hash, HASH_INFO_NO_DUMP))
1342 {
1343 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s NO GOOD DUMP KNOWN\n", name);
1344 romdata->warnings++;
1345 }
1346 /* verify checksums */
1347 else if (!hash_data_is_equal(hash, acthash, 0))
1348 {
1349 /* otherwise, it's just bad */
1350 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s WRONG CHECKSUMS:\n", name);
1351
1352 dump_wrong_and_correct_checksums(romdata, hash, acthash);
1353
1354 romdata->warnings++;
1355 }
1356 /* If it matches, but it is actually a bad dump, write it */
1357 else if (hash_data_has_info(hash, HASH_INFO_BAD_DUMP))
1358 {
1359 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s ROM NEEDS REDUMP\n",name);
1360 romdata->warnings++;
1361 }
1362 }
1363
1364
1365 /*-------------------------------------------------
1366 display_rom_load_results - display the final
1367 results of ROM loading
1368 -------------------------------------------------*/
1369
display_rom_load_results(struct rom_load_data * romdata)1370 static int display_rom_load_results(struct rom_load_data *romdata)
1371 {
1372 int region;
1373 const char *missing_files = "Required files are missing, the game cannot be run.\n";
1374 const char *rom_warnings = "Warnings flagged during ROM loading.\n";
1375
1376 /* display either an error message or a warning message */
1377 if (romdata->errors)
1378 {
1379 extern int bailing;
1380 frontend_message_cb(missing_files, 300);
1381 bailing = 1;
1382 strcat(romdata->errorbuf, missing_files);
1383 log_cb(RETRO_LOG_ERROR, LOGPRE "%s", romdata->errorbuf);
1384 }
1385 else if (romdata->warnings)
1386 {
1387 frontend_message_cb(rom_warnings, 180);
1388 strcat(romdata->errorbuf, rom_warnings);
1389 log_cb(RETRO_LOG_WARN, LOGPRE "%s", romdata->errorbuf);
1390 }
1391 else
1392 {
1393 log_cb(RETRO_LOG_INFO, LOGPRE "Succesfully loaded ROMs.\n");
1394 }
1395
1396 /* clean up any regions */
1397 if (romdata->errors)
1398 for (region = 0; region < MAX_MEMORY_REGIONS; region++)
1399 free_memory_region(region);
1400
1401 /* return true if we had any errors */
1402 return (romdata->errors != 0);
1403 }
1404
1405
1406 /*-------------------------------------------------
1407 region_post_process - post-process a region,
1408 byte swapping and inverting data as necessary
1409 -------------------------------------------------*/
1410
region_post_process(struct rom_load_data * romdata,const struct RomModule * regiondata)1411 static void region_post_process(struct rom_load_data *romdata, const struct RomModule *regiondata)
1412 {
1413 int type = ROMREGION_GETTYPE(regiondata);
1414 int datawidth = ROMREGION_GETWIDTH(regiondata) / 8;
1415 int littleendian = ROMREGION_ISLITTLEENDIAN(regiondata);
1416 UINT8 *base;
1417 int i, j;
1418
1419 log_cb(RETRO_LOG_DEBUG, LOGPRE "+ datawidth=%d little=%d\n", datawidth, littleendian);
1420
1421 /* if this is a CPU region, override with the CPU width and endianness */
1422 if (type >= REGION_CPU1 && type < REGION_CPU1 + MAX_CPU)
1423 {
1424 int cputype = Machine->drv->cpu[type - REGION_CPU1].cpu_type;
1425 if (cputype != 0)
1426 {
1427 datawidth = cputype_databus_width(cputype) / 8;
1428 littleendian = (cputype_endianess(cputype) == CPU_IS_LE);
1429 log_cb(RETRO_LOG_DEBUG, LOGPRE "+ CPU region #%d: datawidth=%d little=%d\n", type - REGION_CPU1, datawidth, littleendian);
1430 }
1431 }
1432
1433 /* if the region is inverted, do that now */
1434 if (ROMREGION_ISINVERTED(regiondata))
1435 {
1436 log_cb(RETRO_LOG_DEBUG, LOGPRE "+ Inverting region\n");
1437 for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i++)
1438 *base++ ^= 0xff;
1439 }
1440
1441 /* swap the endianness if we need to */
1442 #ifdef MSB_FIRST
1443 if (datawidth > 1 && littleendian)
1444 #else
1445 if (datawidth > 1 && !littleendian)
1446 #endif
1447 {
1448 log_cb(RETRO_LOG_DEBUG, LOGPRE "+ Byte swapping region\n");
1449 for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i += datawidth)
1450 {
1451 UINT8 temp[8];
1452 memcpy(temp, base, datawidth);
1453 for (j = datawidth - 1; j >= 0; j--)
1454 *base++ = temp[j];
1455 }
1456 }
1457 }
1458
1459
1460 /*-------------------------------------------------
1461 open_rom_file - open a ROM file, searching
1462 up the parent and loading by checksum
1463 -------------------------------------------------*/
1464
open_rom_file(struct rom_load_data * romdata,const struct RomModule * romp)1465 static int open_rom_file(struct rom_load_data *romdata, const struct RomModule *romp)
1466 {
1467 const struct GameDriver *drv;
1468
1469 ++romdata->romsloaded;
1470
1471 /* Attempt reading up the chain through the parents. It automatically also
1472 attempts any kind of load by checksum supported by the archives. */
1473 romdata->file = NULL;
1474 for (drv = Machine->gamedrv; !romdata->file && drv; drv = drv->clone_of)
1475 {
1476 if (drv->name && *drv->name)
1477 romdata->file = mame_fopen_rom(drv->name, ROM_GETNAME(romp), ROM_GETHASHDATA(romp));
1478 }
1479
1480 /* return the result */
1481 return (romdata->file != NULL);
1482 }
1483
1484 /*-------------------------------------------------
1485 rom_fread - cheesy fread that fills with
1486 random data for a NULL file
1487 -------------------------------------------------*/
1488
rom_fread(struct rom_load_data * romdata,UINT8 * buffer,int length)1489 static int rom_fread(struct rom_load_data *romdata, UINT8 *buffer, int length)
1490 {
1491 /* files just pass through */
1492 if (romdata->file)
1493 return mame_fread(romdata->file, buffer, length);
1494
1495 /* otherwise, fill with randomness */
1496 else
1497 fill_random(buffer, length);
1498
1499 return length;
1500 }
1501
1502
1503 /*-------------------------------------------------
1504 read_rom_data - read ROM data for a single
1505 entry
1506 -------------------------------------------------*/
1507
read_rom_data(struct rom_load_data * romdata,const struct RomModule * romp)1508 static int read_rom_data(struct rom_load_data *romdata, const struct RomModule *romp)
1509 {
1510 int datashift = ROM_GETBITSHIFT(romp);
1511 int datamask = ((1 << ROM_GETBITWIDTH(romp)) - 1) << datashift;
1512 int numbytes = ROM_GETLENGTH(romp);
1513 int groupsize = ROM_GETGROUPSIZE(romp);
1514 int skip = ROM_GETSKIPCOUNT(romp);
1515 int reversed = ROM_ISREVERSED(romp);
1516 int numgroups = (numbytes + groupsize - 1) / groupsize;
1517 UINT8 *base = romdata->regionbase + ROM_GETOFFSET(romp);
1518 int i;
1519
1520 log_cb(RETRO_LOG_DEBUG, LOGPRE "Loading ROM data: offs=%X len=%X mask=%02X group=%d skip=%d reverse=%d\n", ROM_GETOFFSET(romp), numbytes, datamask, groupsize, skip, reversed);
1521
1522 /* make sure the length was an even multiple of the group size */
1523 if (numbytes % groupsize != 0)
1524 {
1525 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: %s length not an even multiple of group size\n", ROM_GETNAME(romp));
1526 return -1;
1527 }
1528
1529 /* make sure we only fill within the region space */
1530 if (ROM_GETOFFSET(romp) + numgroups * groupsize + (numgroups - 1) * skip > romdata->regionlength)
1531 {
1532 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: %s out of memory region space\n", ROM_GETNAME(romp));
1533 return -1;
1534 }
1535
1536 /* make sure the length was valid */
1537 if (numbytes == 0)
1538 {
1539 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: %s has an invalid length\n", ROM_GETNAME(romp));
1540 return -1;
1541 }
1542
1543 /* special case for simple loads */
1544 if (datamask == 0xff && (groupsize == 1 || !reversed) && skip == 0)
1545 return rom_fread(romdata, base, numbytes);
1546
1547 /* chunky reads for complex loads */
1548 skip += groupsize;
1549 while (numbytes)
1550 {
1551 int evengroupcount = (sizeof(romdata->tempbuf) / groupsize) * groupsize;
1552 int bytesleft = (numbytes > evengroupcount) ? evengroupcount : numbytes;
1553 UINT8 *bufptr = romdata->tempbuf;
1554
1555 /* read as much as we can */
1556 log_cb(RETRO_LOG_DEBUG, LOGPRE " Reading %X bytes into buffer\n", bytesleft);
1557 if (rom_fread(romdata, romdata->tempbuf, bytesleft) != bytesleft)
1558 return 0;
1559 numbytes -= bytesleft;
1560
1561 log_cb(RETRO_LOG_DEBUG, LOGPRE " Copying to %08X\n", (int)base);
1562
1563 /* unmasked cases */
1564 if (datamask == 0xff)
1565 {
1566 /* non-grouped data */
1567 if (groupsize == 1)
1568 for (i = 0; i < bytesleft; i++, base += skip)
1569 *base = *bufptr++;
1570
1571 /* grouped data -- non-reversed case */
1572 else if (!reversed)
1573 while (bytesleft)
1574 {
1575 for (i = 0; i < groupsize && bytesleft; i++, bytesleft--)
1576 base[i] = *bufptr++;
1577 base += skip;
1578 }
1579
1580 /* grouped data -- reversed case */
1581 else
1582 while (bytesleft)
1583 {
1584 for (i = groupsize - 1; i >= 0 && bytesleft; i--, bytesleft--)
1585 base[i] = *bufptr++;
1586 base += skip;
1587 }
1588 }
1589
1590 /* masked cases */
1591 else
1592 {
1593 /* non-grouped data */
1594 if (groupsize == 1)
1595 for (i = 0; i < bytesleft; i++, base += skip)
1596 *base = (*base & ~datamask) | ((*bufptr++ << datashift) & datamask);
1597
1598 /* grouped data -- non-reversed case */
1599 else if (!reversed)
1600 while (bytesleft)
1601 {
1602 for (i = 0; i < groupsize && bytesleft; i++, bytesleft--)
1603 base[i] = (base[i] & ~datamask) | ((*bufptr++ << datashift) & datamask);
1604 base += skip;
1605 }
1606
1607 /* grouped data -- reversed case */
1608 else
1609 while (bytesleft)
1610 {
1611 for (i = groupsize - 1; i >= 0 && bytesleft; i--, bytesleft--)
1612 base[i] = (base[i] & ~datamask) | ((*bufptr++ << datashift) & datamask);
1613 base += skip;
1614 }
1615 }
1616 }
1617 log_cb(RETRO_LOG_INFO, LOGPRE "read_rom_data: All done\n");
1618 return ROM_GETLENGTH(romp);
1619 }
1620
1621
1622 /*-------------------------------------------------
1623 fill_rom_data - fill a region of ROM space
1624 -------------------------------------------------*/
1625
fill_rom_data(struct rom_load_data * romdata,const struct RomModule * romp)1626 static int fill_rom_data(struct rom_load_data *romdata, const struct RomModule *romp)
1627 {
1628 UINT32 numbytes = ROM_GETLENGTH(romp);
1629 UINT8 *base = romdata->regionbase + ROM_GETOFFSET(romp);
1630
1631 /* make sure we fill within the region space */
1632 if (ROM_GETOFFSET(romp) + numbytes > romdata->regionlength)
1633 {
1634 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: FILL out of memory region space\n");
1635 return 0;
1636 }
1637
1638 /* make sure the length was valid */
1639 if (numbytes == 0)
1640 {
1641 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: FILL has an invalid length\n");
1642 return 0;
1643 }
1644
1645 /* fill the data (filling value is stored in place of the hashdata) */
1646 memset(base, (UINT32)ROM_GETHASHDATA(romp) & 0xff, numbytes);
1647 return 1;
1648 }
1649
1650
1651 /*-------------------------------------------------
1652 copy_rom_data - copy a region of ROM space
1653 -------------------------------------------------*/
1654
copy_rom_data(struct rom_load_data * romdata,const struct RomModule * romp)1655 static int copy_rom_data(struct rom_load_data *romdata, const struct RomModule *romp)
1656 {
1657 UINT8 *base = romdata->regionbase + ROM_GETOFFSET(romp);
1658 int srcregion = ROM_GETFLAGS(romp) >> 24;
1659 UINT32 numbytes = ROM_GETLENGTH(romp);
1660 UINT32 srcoffs = (UINT32)ROM_GETHASHDATA(romp); /* srcoffset in place of hashdata */
1661 UINT8 *srcbase;
1662
1663 /* make sure we copy within the region space */
1664 if (ROM_GETOFFSET(romp) + numbytes > romdata->regionlength)
1665 {
1666 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: COPY out of target memory region space\n");
1667 return 0;
1668 }
1669
1670 /* make sure the length was valid */
1671 if (numbytes == 0)
1672 {
1673 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: COPY has an invalid length\n");
1674 return 0;
1675 }
1676
1677 /* make sure the source was valid */
1678 srcbase = memory_region(srcregion);
1679 if (!srcbase)
1680 {
1681 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: COPY from an invalid region\n");
1682 return 0;
1683 }
1684
1685 /* make sure we find within the region space */
1686 if (srcoffs + numbytes > memory_region_length(srcregion))
1687 {
1688 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: COPY out of source memory region space\n");
1689 return 0;
1690 }
1691
1692 /* fill the data */
1693 memcpy(base, srcbase + srcoffs, numbytes);
1694 return 1;
1695 }
1696
1697
1698 /*-------------------------------------------------
1699 process_rom_entries - process all ROM entries
1700 for a region
1701 -------------------------------------------------*/
1702
process_rom_entries(struct rom_load_data * romdata,const struct RomModule * romp)1703 static int process_rom_entries(struct rom_load_data *romdata, const struct RomModule *romp)
1704 {
1705 UINT32 lastflags = 0;
1706
1707 /* loop until we hit the end of this region */
1708 while (!ROMENTRY_ISREGIONEND(romp))
1709 {
1710 /* if this is a continue entry, it's invalid */
1711 if (ROMENTRY_ISCONTINUE(romp))
1712 {
1713 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: ROM_CONTINUE not preceded by ROM_LOAD\n");
1714 goto fatalerror;
1715 }
1716
1717 /* if this is a reload entry, it's invalid */
1718 if (ROMENTRY_ISRELOAD(romp))
1719 {
1720 log_cb(RETRO_LOG_ERROR, LOGPRE "Error in RomModule definition: ROM_RELOAD not preceded by ROM_LOAD\n");
1721 goto fatalerror;
1722 }
1723
1724 /* handle fills */
1725 if (ROMENTRY_ISFILL(romp))
1726 {
1727 if (!fill_rom_data(romdata, romp++))
1728 goto fatalerror;
1729 }
1730
1731 /* handle copies */
1732 else if (ROMENTRY_ISCOPY(romp))
1733 {
1734 if (!copy_rom_data(romdata, romp++))
1735 goto fatalerror;
1736 }
1737
1738 /* handle files */
1739 else if (ROMENTRY_ISFILE(romp))
1740 {
1741 if (!ROM_GETBIOSFLAGS(romp) || (ROM_GETBIOSFLAGS(romp) == (system_bios+1))) /* alternate bios sets */
1742 {
1743 const struct RomModule *baserom = romp;
1744 int explength = 0;
1745
1746 /* open the file */
1747 log_cb(RETRO_LOG_INFO, LOGPRE "Opening ROM file: %s\n", ROM_GETNAME(romp));
1748 if (!open_rom_file(romdata, romp))
1749 handle_missing_file(romdata, romp);
1750
1751 /* loop until we run out of reloads */
1752 do
1753 {
1754 /* loop until we run out of continues */
1755 do
1756 {
1757 struct RomModule modified_romp = *romp++;
1758 int readresult;
1759
1760 /* handle flag inheritance */
1761 if (!ROM_INHERITSFLAGS(&modified_romp))
1762 lastflags = modified_romp._flags;
1763 else
1764 modified_romp._flags = (modified_romp._flags & ~ROM_INHERITEDFLAGS) | lastflags;
1765
1766 explength += ROM_GETLENGTH(&modified_romp);
1767
1768 /* attempt to read using the modified entry */
1769 readresult = read_rom_data(romdata, &modified_romp);
1770 if (readresult == -1)
1771 goto fatalerror;
1772 }
1773 while (ROMENTRY_ISCONTINUE(romp));
1774
1775 /* if this was the first use of this file, verify the length and CRC */
1776 if (baserom)
1777 {
1778 log_cb(RETRO_LOG_DEBUG, LOGPRE "Verifying length (%X) and checksums\n", explength);
1779 verify_length_and_hash(romdata, ROM_GETNAME(baserom), explength, ROM_GETHASHDATA(baserom));
1780 log_cb(RETRO_LOG_DEBUG, LOGPRE "Length and checksum verify finished\n");
1781 }
1782
1783 /* reseek to the start and clear the baserom so we don't reverify */
1784 if (romdata->file)
1785 mame_fseek(romdata->file, 0, SEEK_SET);
1786 baserom = NULL;
1787 explength = 0;
1788 }
1789 while (ROMENTRY_ISRELOAD(romp));
1790
1791 /* close the file */
1792 if (romdata->file)
1793 {
1794 log_cb(RETRO_LOG_DEBUG, LOGPRE "Closing ROM file\n");
1795 mame_fclose(romdata->file);
1796 romdata->file = NULL;
1797 }
1798 }
1799 else
1800 {
1801 romp++; /* skip over file */
1802 }
1803 }
1804 }
1805 return 1;
1806
1807 /* error case */
1808 fatalerror:
1809 if (romdata->file)
1810 mame_fclose(romdata->file);
1811 romdata->file = NULL;
1812 return 0;
1813 }
1814
1815
1816
1817 /*-------------------------------------------------
1818 process_disk_entries - process all disk entries
1819 for a region
1820 -------------------------------------------------*/
1821
process_disk_entries(struct rom_load_data * romdata,const struct RomModule * romp)1822 static int process_disk_entries(struct rom_load_data *romdata, const struct RomModule *romp)
1823 {
1824 /* loop until we hit the end of this region */
1825 while (!ROMENTRY_ISREGIONEND(romp))
1826 {
1827 /* handle files */
1828 if (ROMENTRY_ISFILE(romp))
1829 {
1830 struct chd_file *source, *diff = NULL;
1831 struct chd_header header;
1832 char filename[1024], *c;
1833 char acthash[HASH_BUF_SIZE];
1834 int err;
1835
1836 /* make the filename of the source */
1837 strcpy(filename, ROM_GETNAME(romp));
1838 c = strrchr(filename, '.');
1839 if (c)
1840 strcpy(c, ".chd");
1841 else
1842 strcat(filename, ".chd");
1843
1844 /* first open the source drive */
1845 log_cb(RETRO_LOG_INFO, LOGPRE "Opening disk image: %s\n", filename);
1846 source = chd_open(filename, 0, NULL);
1847 if (!source)
1848 {
1849 if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
1850 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s UNSUPPORTED CHD VERSION\n", filename);
1851 else
1852 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s NOT FOUND\n", filename);
1853 romdata->errors++;
1854 romp++;
1855 continue;
1856 }
1857
1858 /* get the header and extract the MD5/SHA1 */
1859 header = *chd_get_header(source);
1860 hash_data_clear(acthash);
1861 hash_data_insert_binary_checksum(acthash, HASH_MD5, header.md5);
1862 hash_data_insert_binary_checksum(acthash, HASH_SHA1, header.sha1);
1863
1864 /* verify the MD5 */
1865 if (!hash_data_is_equal(ROM_GETHASHDATA(romp), acthash, 0))
1866 {
1867 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s WRONG CHECKSUMS:\n", filename);
1868 dump_wrong_and_correct_checksums(romdata, ROM_GETHASHDATA(romp), acthash);
1869 romdata->warnings++;
1870 }
1871
1872 /* if not read-only, make the diff file */
1873 if (!DISK_ISREADONLY(romp))
1874 {
1875 /* make the filename of the diff */
1876 strcpy(filename, ROM_GETNAME(romp));
1877 c = strrchr(filename, '.');
1878 if (c)
1879 strcpy(c, ".dif");
1880 else
1881 strcat(filename, ".dif");
1882
1883 /* try to open the diff */
1884 log_cb(RETRO_LOG_INFO, LOGPRE "Opening differencing image: %s\n", filename);
1885 diff = chd_open(filename, 1, source);
1886 if (!diff)
1887 {
1888 /* didn't work; try creating it instead */
1889 log_cb(RETRO_LOG_INFO, LOGPRE "Creating differencing image: %s\n", filename);
1890 err = chd_create(filename, 0, 0, CHDCOMPRESSION_NONE, source);
1891 if (err != CHDERR_NONE)
1892 {
1893 if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
1894 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s UNSUPPORTED CHD VERSION\n", filename);
1895 else
1896 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s: CAN'T CREATE DIFF FILE Error code %s\n", filename, chd_error_text[err]);
1897 romdata->errors++;
1898 romp++;
1899 continue;
1900 }
1901
1902 /* open the newly-created diff file */
1903 log_cb(RETRO_LOG_INFO, LOGPRE "Opening new differencing image: %s\n", filename);
1904 diff = chd_open(filename, 1, source);
1905 if (!diff)
1906 {
1907 if (chd_get_last_error() == CHDERR_UNSUPPORTED_VERSION)
1908 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s UNSUPPORTED CHD VERSION\n", filename);
1909 else
1910 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s: CAN'T OPEN DIFF FILE Error code %s\n", filename, chd_error_text[err]);
1911 romdata->errors++;
1912 romp++;
1913 continue;
1914 }
1915 }
1916 }
1917
1918 /* we're okay, set the handle */
1919 log_cb(RETRO_LOG_DEBUG, LOGPRE "Assigning to handle %d\n", DISK_GETINDEX(romp));
1920 disk_handle[DISK_GETINDEX(romp)] = DISK_ISREADONLY(romp) ? source : diff;
1921 romp++;
1922 }
1923 }
1924 return 1;
1925 }
1926
1927
1928 /*-------------------------------------------------
1929 rom_load - new, more flexible ROM
1930 loading system
1931 -------------------------------------------------*/
1932
rom_load(const struct RomModule * romp)1933 int rom_load(const struct RomModule *romp)
1934 {
1935 const struct RomModule *regionlist[REGION_MAX];
1936 const struct RomModule *region;
1937 static struct rom_load_data romdata;
1938 int regnum;
1939
1940 /* reset the region list */
1941 for (regnum = 0;regnum < REGION_MAX;regnum++)
1942 regionlist[regnum] = NULL;
1943
1944 /* reset the romdata struct */
1945 memset(&romdata, 0, sizeof(romdata));
1946 romdata.romstotal = count_roms(romp);
1947
1948 /* reset the disk list */
1949 memset(disk_handle, 0, sizeof(disk_handle));
1950
1951 /* determine the correct biosset to load based on options.bios string */
1952 system_bios = determine_bios_rom(Machine->gamedrv->bios);
1953
1954 /* loop until we hit the end */
1955 for (region = romp, regnum = 0; region; region = rom_next_region(region), regnum++)
1956 {
1957 int regiontype = ROMREGION_GETTYPE(region);
1958
1959 log_cb(RETRO_LOG_DEBUG, LOGPRE "Processing region %02X (length=%X)\n", regiontype, ROMREGION_GETLENGTH(region));
1960
1961 /* the first entry must be a region */
1962 if (!ROMENTRY_ISREGION(region))
1963 {
1964 log_cb(RETRO_LOG_ERROR, LOGPRE "Error: missing ROM_REGION header\n");
1965 return 1;
1966 }
1967
1968 /* if sound is disabled and it's a sound-only region, skip it */
1969 if (Machine->sample_rate == 0 && ROMREGION_ISSOUNDONLY(region))
1970 continue;
1971
1972 /* allocate memory for the region */
1973 if (new_memory_region(regiontype, ROMREGION_GETLENGTH(region), ROMREGION_GETFLAGS(region)))
1974 {
1975 log_cb(RETRO_LOG_ERROR, LOGPRE "Error: unable to allocate memory for region %d\n", regiontype);
1976 return 1;
1977 }
1978
1979 /* remember the base and length */
1980 romdata.regionlength = memory_region_length(regiontype);
1981 romdata.regionbase = memory_region(regiontype);
1982 log_cb(RETRO_LOG_DEBUG, LOGPRE "Allocated %X bytes @ %08X\n", romdata.regionlength, (int)romdata.regionbase);
1983
1984 /* clear the region if it's requested */
1985 if (ROMREGION_ISERASE(region))
1986 memset(romdata.regionbase, ROMREGION_GETERASEVAL(region), romdata.regionlength);
1987
1988 /* or if it's sufficiently small (<= 4MB) */
1989 else if (romdata.regionlength <= 0x400000)
1990 memset(romdata.regionbase, 0, romdata.regionlength);
1991
1992 #ifdef MAME_DEBUG
1993 /* if we're debugging, fill region with random data to catch errors */
1994 else
1995 fill_random(romdata.regionbase, romdata.regionlength);
1996 #endif
1997
1998 /* now process the entries in the region */
1999 if (ROMREGION_ISROMDATA(region))
2000 {
2001 if (!process_rom_entries(&romdata, region + 1))
2002 return 1;
2003 }
2004 else if (ROMREGION_ISDISKDATA(region))
2005 {
2006 if (!process_disk_entries(&romdata, region + 1))
2007 return 1;
2008 }
2009
2010 /* add this region to the list */
2011 if (regiontype < REGION_MAX)
2012 regionlist[regiontype] = region;
2013 }
2014
2015 /* post-process the regions */
2016 for (regnum = 0; regnum < REGION_MAX; regnum++)
2017 if (regionlist[regnum])
2018 {
2019 log_cb(RETRO_LOG_DEBUG, LOGPRE "Post-processing region %02X\n", regnum);
2020 romdata.regionlength = memory_region_length(regnum);
2021 romdata.regionbase = memory_region(regnum);
2022 region_post_process(&romdata, regionlist[regnum]);
2023 }
2024
2025 /* display the results and exit */
2026 return display_rom_load_results(&romdata);
2027 }
2028
2029
2030 /*-------------------------------------------------
2031 printromlist - print list of ROMs
2032 -------------------------------------------------*/
2033
printromlist(const struct RomModule * romp,const char * basename)2034 void printromlist(const struct RomModule *romp,const char *basename)
2035 {
2036 const struct RomModule *region, *rom, *chunk;
2037 char buf[512];
2038
2039 if (!romp) return;
2040
2041 printf("This is the list of the ROMs required for driver \"%s\".\n"
2042 "Name Size Checksum\n",basename);
2043
2044 for (region = romp; region; region = rom_next_region(region))
2045 {
2046 for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
2047 {
2048 const char *name = ROM_GETNAME(rom);
2049 const char* hash = ROM_GETHASHDATA(rom);
2050 int length = -1; /* default is for disks! */
2051
2052 if (ROMREGION_ISROMDATA(region))
2053 {
2054 length = 0;
2055 for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk))
2056 length += ROM_GETLENGTH(chunk);
2057 }
2058
2059 log_cb(RETRO_LOG_ERROR, LOGPRE "%-12s ", name);
2060 if (length >= 0)
2061 log_cb(RETRO_LOG_ERROR, LOGPRE "%7d",length);
2062 else
2063 log_cb(RETRO_LOG_ERROR, LOGPRE " ");
2064
2065 if (!hash_data_has_info(hash, HASH_INFO_NO_DUMP))
2066 {
2067 if (hash_data_has_info(hash, HASH_INFO_BAD_DUMP))
2068 log_cb(RETRO_LOG_ERROR, LOGPRE " BAD DUMP");
2069
2070 hash_data_print(hash, 0, buf);
2071 log_cb(RETRO_LOG_ERROR, LOGPRE " %s", buf);
2072 }
2073 else
2074 log_cb(RETRO_LOG_ERROR, LOGPRE " NO GOOD DUMP KNOWN");
2075
2076 log_cb(RETRO_LOG_ERROR, LOGPRE "\n");
2077 }
2078 }
2079 }
2080