Develop and Download Open Source Software

Browse CVS Repository

Contents of /mame32jp/mame32jp/src/common.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.7 - (show annotations) (download) (as text)
Tue May 14 07:14:34 2002 UTC (21 years, 10 months ago) by zero
Branch: MAIN
CVS Tags: ver0_60_3, ver0_60_4, ver0_60_5, HEAD
Changes since 1.6: +2 -1 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /*********************************************************************
2
3 common.c
4
5 Generic functions, mostly ROM and graphics related.
6
7 *********************************************************************/
8
9 #include "driver.h"
10 #include "png.h"
11 #include <stdarg.h>
12
13
14 //#define LOG_LOAD
15
16
17
18 /***************************************************************************
19
20 Constants
21
22 ***************************************************************************/
23
24 // VERY IMPORTANT: osd_alloc_bitmap must allocate also a "safety area" 16 pixels wide all
25 // around the bitmap. This is required because, for performance reasons, some graphic
26 // routines don't clip at boundaries of the bitmap.
27 #define BITMAP_SAFETY 16
28
29 #define MAX_MALLOCS 1024
30
31
32
33 /***************************************************************************
34
35 Type definitions
36
37 ***************************************************************************/
38
39 struct rom_load_data
40 {
41 int warnings; /* warning count during processing */
42 int errors; /* error count during processing */
43
44 int romsloaded; /* current ROMs loaded count */
45 int romstotal; /* total number of ROMs to read */
46
47 void * file; /* current file */
48
49 UINT8 * regionbase; /* base of current region */
50 UINT32 regionlength; /* length of current region */
51
52 char errorbuf[4096]; /* accumulated errors */
53 UINT8 tempbuf[65536]; /* temporary buffer */
54 };
55
56
57 struct malloc_info
58 {
59 int tag;
60 void *ptr;
61 };
62
63
64
65 /***************************************************************************
66
67 Global variables
68
69 ***************************************************************************/
70
71 /* These globals are only kept on a machine basis - LBO 042898 */
72 unsigned int dispensed_tickets;
73 unsigned int coins[COIN_COUNTERS];
74 unsigned int lastcoin[COIN_COUNTERS];
75 unsigned int coinlockedout[COIN_COUNTERS];
76
77 int snapno;
78
79 /* malloc tracking */
80 static struct malloc_info malloc_list[MAX_MALLOCS];
81 static int malloc_list_index = 0;
82
83 /* resource tracking */
84 int resource_tracking_tag = 0;
85
86 /* generic NVRAM */
87 size_t generic_nvram_size;
88 data8_t *generic_nvram;
89
90
91
92 /***************************************************************************
93
94 Prototypes
95
96 ***************************************************************************/
97
98 static int rom_load_new(const struct RomModule *romp);
99
100
101
102 /***************************************************************************
103
104 Functions
105
106 ***************************************************************************/
107
108 #if (defined(MAME32JP) && defined(BUILD_CONSOLE)) || !defined(MAME32JP)
109 void showdisclaimer(void) /* MAURY_BEGIN: dichiarazione */
110 {
111 printf("MAME is an emulator: it reproduces, more or less faithfully, the behaviour of\n"
112 "several arcade machines. But hardware is useless without software, so an image\n"
113 "of the ROMs which run on that hardware is required. Such ROMs, like any other\n"
114 "commercial software, are copyrighted material and it is therefore illegal to\n"
115 "use them if you don't own the original arcade machine. Needless to say, ROMs\n"
116 "are not distributed together with MAME. Distribution of MAME together with ROM\n"
117 "images is a violation of copyright law and should be promptly reported to the\n"
118 "authors so that appropriate legal action can be taken.\n\n");
119 } /* MAURY_END: dichiarazione */
120 #endif
121
122
123 /***************************************************************************
124
125 Sample handling code
126
127 This function is different from readroms() because it doesn't fail if
128 it doesn't find a file: it will load as many samples as it can find.
129
130 ***************************************************************************/
131
132 #ifdef LSB_FIRST
133 #define intelLong(x) (x)
134 #else
135 #define intelLong(x) (((x << 24) | (((unsigned long) x) >> 24) | (( x & 0x0000ff00) << 8) | (( x & 0x00ff0000) >> 8)))
136 #endif
137
138 /*-------------------------------------------------
139 read_wav_sample - read a WAV file as a sample
140 -------------------------------------------------*/
141
142 static struct GameSample *read_wav_sample(void *f)
143 {
144 unsigned long offset = 0;
145 UINT32 length, rate, filesize, temp32;
146 UINT16 bits, temp16;
147 char buf[32];
148 struct GameSample *result;
149
150 /* read the core header and make sure it's a WAVE file */
151 offset += osd_fread(f, buf, 4);
152 if (offset < 4)
153 return NULL;
154 if (memcmp(&buf[0], "RIFF", 4) != 0)
155 return NULL;
156
157 /* get the total size */
158 offset += osd_fread(f, &filesize, 4);
159 if (offset < 8)
160 return NULL;
161 filesize = intelLong(filesize);
162
163 /* read the RIFF file type and make sure it's a WAVE file */
164 offset += osd_fread(f, buf, 4);
165 if (offset < 12)
166 return NULL;
167 if (memcmp(&buf[0], "WAVE", 4) != 0)
168 return NULL;
169
170 /* seek until we find a format tag */
171 while (1)
172 {
173 offset += osd_fread(f, buf, 4);
174 offset += osd_fread(f, &length, 4);
175 length = intelLong(length);
176 if (memcmp(&buf[0], "fmt ", 4) == 0)
177 break;
178
179 /* seek to the next block */
180 osd_fseek(f, length, SEEK_CUR);
181 offset += length;
182 if (offset >= filesize)
183 return NULL;
184 }
185
186 /* read the format -- make sure it is PCM */
187 offset += osd_fread_lsbfirst(f, &temp16, 2);
188 if (temp16 != 1)
189 return NULL;
190
191 /* number of channels -- only mono is supported */
192 offset += osd_fread_lsbfirst(f, &temp16, 2);
193 if (temp16 != 1)
194 return NULL;
195
196 /* sample rate */
197 offset += osd_fread(f, &rate, 4);
198 rate = intelLong(rate);
199
200 /* bytes/second and block alignment are ignored */
201 offset += osd_fread(f, buf, 6);
202
203 /* bits/sample */
204 offset += osd_fread_lsbfirst(f, &bits, 2);
205 if (bits != 8 && bits != 16)
206 return NULL;
207
208 /* seek past any extra data */
209 osd_fseek(f, length - 16, SEEK_CUR);
210 offset += length - 16;
211
212 /* seek until we find a data tag */
213 while (1)
214 {
215 offset += osd_fread(f, buf, 4);
216 offset += osd_fread(f, &length, 4);
217 length = intelLong(length);
218 if (memcmp(&buf[0], "data", 4) == 0)
219 break;
220
221 /* seek to the next block */
222 osd_fseek(f, length, SEEK_CUR);
223 offset += length;
224 if (offset >= filesize)
225 return NULL;
226 }
227
228 /* allocate the game sample */
229 result = auto_malloc(sizeof(struct GameSample) + length);
230 if (result == NULL)
231 return NULL;
232
233 /* fill in the sample data */
234 result->length = length;
235 result->smpfreq = rate;
236 result->resolution = bits;
237
238 /* read the data in */
239 if (bits == 8)
240 {
241 osd_fread(f, result->data, length);
242
243 /* convert 8-bit data to signed samples */
244 for (temp32 = 0; temp32 < length; temp32++)
245 result->data[temp32] ^= 0x80;
246 }
247 else
248 {
249 /* 16-bit data is fine as-is */
250 osd_fread_lsbfirst(f, result->data, length);
251 }
252
253 return result;
254 }
255
256
257 /*-------------------------------------------------
258 readsamples - load all samples
259 -------------------------------------------------*/
260
261 struct GameSamples *readsamples(const char **samplenames,const char *basename)
262 /* V.V - avoids samples duplication */
263 /* if first samplename is *dir, looks for samples into "basename" first, then "dir" */
264 {
265 int i;
266 struct GameSamples *samples;
267 int skipfirst = 0;
268
269 /* if the user doesn't want to use samples, bail */
270 if (!options.use_samples) return 0;
271
272 if (samplenames == 0 || samplenames[0] == 0) return 0;
273
274 if (samplenames[0][0] == '*')
275 skipfirst = 1;
276
277 i = 0;
278 while (samplenames[i+skipfirst] != 0) i++;
279
280 if (!i) return 0;
281
282 if ((samples = auto_malloc(sizeof(struct GameSamples) + (i-1)*sizeof(struct GameSample))) == 0)
283 return 0;
284
285 samples->total = i;
286 for (i = 0;i < samples->total;i++)
287 samples->sample[i] = 0;
288
289 for (i = 0;i < samples->total;i++)
290 {
291 void *f;
292
293 if (samplenames[i+skipfirst][0])
294 {
295 if ((f = osd_fopen(basename,samplenames[i+skipfirst],OSD_FILETYPE_SAMPLE,0)) == 0)
296 if (skipfirst)
297 f = osd_fopen(samplenames[0]+1,samplenames[i+skipfirst],OSD_FILETYPE_SAMPLE,0);
298 if (f != 0)
299 {
300 samples->sample[i] = read_wav_sample(f);
301 osd_fclose(f);
302 }
303 }
304 }
305
306 return samples;
307 }
308
309
310
311 /***************************************************************************
312
313 Memory region code
314
315 ***************************************************************************/
316
317 /*-------------------------------------------------
318 memory_region - returns pointer to a memory
319 region
320 -------------------------------------------------*/
321
322 unsigned char *memory_region(int num)
323 {
324 int i;
325
326 if (num < MAX_MEMORY_REGIONS)
327 return Machine->memory_region[num].base;
328 else
329 {
330 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
331 {
332 if (Machine->memory_region[i].type == num)
333 return Machine->memory_region[i].base;
334 }
335 }
336
337 return 0;
338 }
339
340
341 /*-------------------------------------------------
342 memory_region_length - returns length of a
343 memory region
344 -------------------------------------------------*/
345
346 size_t memory_region_length(int num)
347 {
348 int i;
349
350 if (num < MAX_MEMORY_REGIONS)
351 return Machine->memory_region[num].length;
352 else
353 {
354 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
355 {
356 if (Machine->memory_region[i].type == num)
357 return Machine->memory_region[i].length;
358 }
359 }
360
361 return 0;
362 }
363
364
365 /*-------------------------------------------------
366 new_memory_region - allocates memory for a
367 region
368 -------------------------------------------------*/
369
370 int new_memory_region(int num, size_t length, UINT32 flags)
371 {
372 int i;
373
374 if (num < MAX_MEMORY_REGIONS)
375 {
376 Machine->memory_region[num].length = length;
377 Machine->memory_region[num].base = malloc(length);
378 return (Machine->memory_region[num].base == NULL) ? 1 : 0;
379 }
380 else
381 {
382 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
383 {
384 if (Machine->memory_region[i].base == NULL)
385 {
386 Machine->memory_region[i].length = length;
387 Machine->memory_region[i].type = num;
388 Machine->memory_region[i].flags = flags;
389 Machine->memory_region[i].base = malloc(length);
390 return (Machine->memory_region[i].base == NULL) ? 1 : 0;
391 }
392 }
393 }
394 return 1;
395 }
396
397
398 /*-------------------------------------------------
399 free_memory_region - releases memory for a
400 region
401 -------------------------------------------------*/
402
403 void free_memory_region(int num)
404 {
405 int i;
406
407 if (num < MAX_MEMORY_REGIONS)
408 {
409 free(Machine->memory_region[num].base);
410 memset(&Machine->memory_region[num], 0, sizeof(Machine->memory_region[num]));
411 }
412 else
413 {
414 for (i = 0;i < MAX_MEMORY_REGIONS;i++)
415 {
416 if (Machine->memory_region[i].type == num)
417 {
418 free(Machine->memory_region[i].base);
419 memset(&Machine->memory_region[i], 0, sizeof(Machine->memory_region[i]));
420 return;
421 }
422 }
423 }
424 }
425
426
427
428 /***************************************************************************
429
430 Coin counter code
431
432 ***************************************************************************/
433
434 /*-------------------------------------------------
435 coin_counter_w - sets input for coin counter
436 -------------------------------------------------*/
437
438 void coin_counter_w(int num,int on)
439 {
440 if (num >= COIN_COUNTERS) return;
441 /* Count it only if the data has changed from 0 to non-zero */
442 if (on && (lastcoin[num] == 0))
443 {
444 coins[num]++;
445 }
446 lastcoin[num] = on;
447 }
448
449
450 /*-------------------------------------------------
451 coin_lockout_w - locks out one coin input
452 -------------------------------------------------*/
453
454 void coin_lockout_w(int num,int on)
455 {
456 if (num >= COIN_COUNTERS) return;
457
458 coinlockedout[num] = on;
459 }
460
461
462 /*-------------------------------------------------
463 coin_lockout_global_w - locks out all the coin
464 inputs
465 -------------------------------------------------*/
466
467 void coin_lockout_global_w(int on)
468 {
469 int i;
470
471 for (i = 0; i < COIN_COUNTERS; i++)
472 {
473 coin_lockout_w(i,on);
474 }
475 }
476
477
478
479 /***************************************************************************
480
481 Generic NVRAM code
482
483 ***************************************************************************/
484
485 /*-------------------------------------------------
486 nvram_handler_generic_0fill - generic NVRAM
487 with a 0 fill
488 -------------------------------------------------*/
489
490 void nvram_handler_generic_0fill(void *file, int read_or_write)
491 {
492 if (read_or_write)
493 osd_fwrite(file, generic_nvram, generic_nvram_size);
494 else if (file)
495 osd_fread(file, generic_nvram, generic_nvram_size);
496 else
497 memset(generic_nvram, 0, generic_nvram_size);
498 }
499
500
501 /*-------------------------------------------------
502 nvram_handler_generic_1fill - generic NVRAM
503 with a 1 fill
504 -------------------------------------------------*/
505
506 void nvram_handler_generic_1fill(void *file, int read_or_write)
507 {
508 if (read_or_write)
509 osd_fwrite(file, generic_nvram, generic_nvram_size);
510 else if (file)
511 osd_fread(file, generic_nvram, generic_nvram_size);
512 else
513 memset(generic_nvram, 0xff, generic_nvram_size);
514 }
515
516
517
518 /*-------------------------------------------------
519 set_visible_area - adjusts the visible portion
520 of the bitmap area dynamically
521 -------------------------------------------------*/
522
523 void set_visible_area(int min_x,int max_x,int min_y,int max_y)
524 {
525 Machine->visible_area.min_x = min_x;
526 Machine->visible_area.max_x = max_x;
527 Machine->visible_area.min_y = min_y;
528 Machine->visible_area.max_y = max_y;
529
530 /* vector games always use the whole bitmap */
531 if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
532 {
533 min_x = 0;
534 max_x = Machine->scrbitmap->width - 1;
535 min_y = 0;
536 max_y = Machine->scrbitmap->height - 1;
537 }
538 else
539 {
540 int temp;
541
542 if (Machine->orientation & ORIENTATION_SWAP_XY)
543 {
544 temp = min_x; min_x = min_y; min_y = temp;
545 temp = max_x; max_x = max_y; max_y = temp;
546 }
547 if (Machine->orientation & ORIENTATION_FLIP_X)
548 {
549 temp = Machine->scrbitmap->width - min_x - 1;
550 min_x = Machine->scrbitmap->width - max_x - 1;
551 max_x = temp;
552 }
553 if (Machine->orientation & ORIENTATION_FLIP_Y)
554 {
555 temp = Machine->scrbitmap->height - min_y - 1;
556 min_y = Machine->scrbitmap->height - max_y - 1;
557 max_y = temp;
558 }
559 }
560
561 osd_set_visible_area(min_x,max_x,min_y,max_y);
562
563 Machine->absolute_visible_area.min_x = min_x;
564 Machine->absolute_visible_area.max_x = max_x;
565 Machine->absolute_visible_area.min_y = min_y;
566 Machine->absolute_visible_area.max_y = max_y;
567 }
568
569
570
571 /***************************************************************************
572
573 Bitmap allocation/freeing code
574
575 ***************************************************************************/
576
577 /*-------------------------------------------------
578 bitmap_alloc_core
579 -------------------------------------------------*/
580
581 struct mame_bitmap *bitmap_alloc_core(int width,int height,int depth,int use_auto)
582 {
583 struct mame_bitmap *bitmap;
584
585 /* cheesy kludge: pass in negative depth to prevent orientation swapping */
586 if (depth < 0)
587 {
588 depth = -depth;
589 }
590
591 /* adjust for orientation */
592 else if (Machine->orientation & ORIENTATION_SWAP_XY)
593 {
594 int temp = width; width = height; height = temp;
595 }
596
597 /* verify it's a depth we can handle */
598 if (depth != 8 && depth != 15 && depth != 16 && depth != 32)
599 {
600 logerror("osd_alloc_bitmap() unknown depth %d\n",depth);
601 return NULL;
602 }
603
604 /* allocate memory for the bitmap struct */
605 bitmap = use_auto ? auto_malloc(sizeof(struct mame_bitmap)) : malloc(sizeof(struct mame_bitmap));
606 if (bitmap != NULL)
607 {
608 int i, rowlen, rdwidth, bitmapsize, linearraysize, pixelsize;
609 unsigned char *bm;
610
611 /* initialize the basic parameters */
612 bitmap->depth = depth;
613 bitmap->width = width;
614 bitmap->height = height;
615
616 /* determine pixel size in bytes */
617 pixelsize = 1;
618 if (depth == 15 || depth == 16)
619 pixelsize = 2;
620 else if (depth == 32)
621 pixelsize = 4;
622
623 /* round the width to a multiple of 8 */
624 rdwidth = (width + 7) & ~7;
625 rowlen = rdwidth + 2 * BITMAP_SAFETY;
626 bitmap->rowpixels = rowlen;
627
628 /* now convert from pixels to bytes */
629 rowlen *= pixelsize;
630 bitmap->rowbytes = rowlen;
631
632 /* determine total memory for bitmap and line arrays */
633 bitmapsize = (height + 2 * BITMAP_SAFETY) * rowlen;
634 linearraysize = (height + 2 * BITMAP_SAFETY) * sizeof(unsigned char *);
635
636 /* allocate the bitmap data plus an array of line pointers */
637 bitmap->line = use_auto ? auto_malloc(linearraysize + bitmapsize) : malloc(linearraysize + bitmapsize);
638 if (bitmap->line == NULL)
639 {
640 if (!use_auto) free(bitmap);
641 return NULL;
642 }
643
644 /* clear ALL bitmap, including safety area, to avoid garbage on right */
645 bm = (unsigned char *)bitmap->line + linearraysize;
646 memset(bm, 0, (height + 2 * BITMAP_SAFETY) * rowlen);
647
648 /* initialize the line pointers */
649 for (i = 0; i < height + 2 * BITMAP_SAFETY; i++)
650 bitmap->line[i] = &bm[i * rowlen + BITMAP_SAFETY * pixelsize];
651
652 /* adjust for the safety rows */
653 bitmap->line += BITMAP_SAFETY;
654 bitmap->base = bitmap->line[0];
655
656 /* set the pixel functions */
657 set_pixel_functions(bitmap);
658 }
659
660 /* return the result */
661 return bitmap;
662 }
663
664
665 /*-------------------------------------------------
666 bitmap_alloc - allocate a bitmap at the
667 current screen depth
668 -------------------------------------------------*/
669
670 struct mame_bitmap *bitmap_alloc(int width,int height)
671 {
672 return bitmap_alloc_core(width,height,Machine->scrbitmap->depth,0);
673 }
674
675
676 /*-------------------------------------------------
677 bitmap_alloc_depth - allocate a bitmap for a
678 specific depth
679 -------------------------------------------------*/
680
681 struct mame_bitmap *bitmap_alloc_depth(int width,int height,int depth)
682 {
683 return bitmap_alloc_core(width,height,depth,0);
684 }
685
686
687 /*-------------------------------------------------
688 bitmap_free - free a bitmap
689 -------------------------------------------------*/
690
691 void bitmap_free(struct mame_bitmap *bitmap)
692 {
693 /* skip if NULL */
694 if (!bitmap)
695 return;
696
697 /* unadjust for the safety rows */
698 bitmap->line -= BITMAP_SAFETY;
699
700 /* free the memory */
701 free(bitmap->line);
702 free(bitmap);
703 }
704
705
706
707 /***************************************************************************
708
709 Resource tracking code
710
711 ***************************************************************************/
712
713 /*-------------------------------------------------
714 auto_malloc - allocate auto-freeing memory
715 -------------------------------------------------*/
716
717 void *auto_malloc(size_t size)
718 {
719 void *result = malloc(size);
720 if (result)
721 {
722 struct malloc_info *info;
723
724 /* make sure we have space */
725 if (malloc_list_index >= MAX_MALLOCS)
726 {
727 fprintf(stderr, "Out of malloc tracking slots!\n");
728 return result;
729 }
730
731 /* fill in the current entry */
732 info = &malloc_list[malloc_list_index++];
733 info->tag = get_resource_tag();
734 info->ptr = result;
735 }
736 return result;
737 }
738
739
740 /*-------------------------------------------------
741 end_resource_tracking - stop tracking
742 resources
743 -------------------------------------------------*/
744
745 void auto_free(void)
746 {
747 int tag = get_resource_tag();
748
749 /* start at the end and free everything on the current tag */
750 while (malloc_list_index > 0 && malloc_list[malloc_list_index - 1].tag >= tag)
751 {
752 struct malloc_info *info = &malloc_list[--malloc_list_index];
753 free(info->ptr);
754 }
755 }
756
757
758 /*-------------------------------------------------
759 bitmap_alloc - allocate a bitmap at the
760 current screen depth
761 -------------------------------------------------*/
762
763 struct mame_bitmap *auto_bitmap_alloc(int width,int height)
764 {
765 return bitmap_alloc_core(width,height,Machine->scrbitmap->depth,1);
766 }
767
768
769 /*-------------------------------------------------
770 bitmap_alloc_depth - allocate a bitmap for a
771 specific depth
772 -------------------------------------------------*/
773
774 struct mame_bitmap *auto_bitmap_alloc_depth(int width,int height,int depth)
775 {
776 return bitmap_alloc_core(width,height,depth,1);
777 }
778
779
780 /*-------------------------------------------------
781 begin_resource_tracking - start tracking
782 resources
783 -------------------------------------------------*/
784
785 void begin_resource_tracking(void)
786 {
787 /* increment the tag counter */
788 resource_tracking_tag++;
789 }
790
791
792 /*-------------------------------------------------
793 end_resource_tracking - stop tracking
794 resources
795 -------------------------------------------------*/
796
797 void end_resource_tracking(void)
798 {
799 /* call everyone who tracks resources to let them know */
800 auto_free();
801 timer_free();
802
803 /* decrement the tag counter */
804 resource_tracking_tag--;
805 }
806
807
808
809 /***************************************************************************
810
811 Screen snapshot code
812
813 ***************************************************************************/
814
815 /*-------------------------------------------------
816 save_screen_snapshot_as - save a snapshot to
817 the given filename
818 -------------------------------------------------*/
819
820 void save_screen_snapshot_as(void *fp,struct mame_bitmap *bitmap)
821 {
822 if (Machine->drv->video_attributes & VIDEO_TYPE_VECTOR)
823 png_write_bitmap(fp,bitmap);
824 else
825 {
826 struct mame_bitmap *copy;
827 int sizex, sizey, scalex, scaley;
828
829 sizex = Machine->visible_area.max_x - Machine->visible_area.min_x + 1;
830 sizey = Machine->visible_area.max_y - Machine->visible_area.min_y + 1;
831
832 scalex = (Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_2_1) ? 2 : 1;
833 scaley = (Machine->drv->video_attributes & VIDEO_PIXEL_ASPECT_RATIO_1_2) ? 2 : 1;
834
835 copy = bitmap_alloc_depth(sizex * scalex,sizey * scaley,bitmap->depth);
836
837 if (copy)
838 {
839 int x,y,sx,sy;
840
841 sx = Machine->absolute_visible_area.min_x;
842 sy = Machine->absolute_visible_area.min_y;
843 if (Machine->orientation & ORIENTATION_SWAP_XY)
844 {
845 int t;
846
847 t = scalex; scalex = scaley; scaley = t;
848 }
849
850 switch (bitmap->depth)
851 {
852 case 8:
853 for (y = 0;y < copy->height;y++)
854 {
855 for (x = 0;x < copy->width;x++)
856 {
857 ((UINT8 *)copy->line[y])[x] = ((UINT8 *)bitmap->line[sy+(y/scaley)])[sx +(x/scalex)];
858 }
859 }
860 break;
861 case 15:
862 case 16:
863 for (y = 0;y < copy->height;y++)
864 {
865 for (x = 0;x < copy->width;x++)
866 {
867 ((UINT16 *)copy->line[y])[x] = ((UINT16 *)bitmap->line[sy+(y/scaley)])[sx +(x/scalex)];
868 }
869 }
870 break;
871 case 32:
872 for (y = 0;y < copy->height;y++)
873 {
874 for (x = 0;x < copy->width;x++)
875 {
876 ((UINT32 *)copy->line[y])[x] = ((UINT32 *)bitmap->line[sy+(y/scaley)])[sx +(x/scalex)];
877 }
878 }
879 break;
880 default:
881 logerror("Unknown color depth\n");
882 break;
883 }
884 png_write_bitmap(fp,copy);
885 bitmap_free(copy);
886 }
887 }
888 }
889
890
891
892 /*-------------------------------------------------
893 save_screen_snapshot - save a screen snapshot
894 -------------------------------------------------*/
895
896 void save_screen_snapshot(struct mame_bitmap *bitmap)
897 {
898 char name[20];
899 void *fp;
900
901 /* avoid overwriting existing files */
902 /* first of all try with "gamename.png" */
903 sprintf(name,"%.8s", Machine->gamedrv->name);
904 if (osd_faccess(name,OSD_FILETYPE_SCREENSHOT))
905 {
906 do
907 {
908 /* otherwise use "nameNNNN.png" */
909 sprintf(name,"%.4s%04d",Machine->gamedrv->name,snapno++);
910 } while (osd_faccess(name, OSD_FILETYPE_SCREENSHOT));
911 }
912
913 if ((fp = osd_fopen(Machine->gamedrv->name, name, OSD_FILETYPE_SCREENSHOT, 1)) != NULL)
914 {
915 save_screen_snapshot_as(fp,bitmap);
916 osd_fclose(fp);
917 }
918 }
919
920
921
922 /***************************************************************************
923
924 ROM loading code
925
926 ***************************************************************************/
927
928 /*-------------------------------------------------
929 rom_first_region - return pointer to first ROM
930 region
931 -------------------------------------------------*/
932
933 const struct RomModule *rom_first_region(const struct GameDriver *drv)
934 {
935 return drv->rom;
936 }
937
938
939 /*-------------------------------------------------
940 rom_next_region - return pointer to next ROM
941 region
942 -------------------------------------------------*/
943
944 const struct RomModule *rom_next_region(const struct RomModule *romp)
945 {
946 romp++;
947 while (!ROMENTRY_ISREGIONEND(romp))
948 romp++;
949 return ROMENTRY_ISEND(romp) ? NULL : romp;
950 }
951
952
953 /*-------------------------------------------------
954 rom_first_file - return pointer to first ROM
955 file
956 -------------------------------------------------*/
957
958 const struct RomModule *rom_first_file(const struct RomModule *romp)
959 {
960 romp++;
961 while (!ROMENTRY_ISFILE(romp) && !ROMENTRY_ISREGIONEND(romp))
962 romp++;
963 return ROMENTRY_ISREGIONEND(romp) ? NULL : romp;
964 }
965
966
967 /*-------------------------------------------------
968 rom_next_file - return pointer to next ROM
969 file
970 -------------------------------------------------*/
971
972 const struct RomModule *rom_next_file(const struct RomModule *romp)
973 {
974 romp++;
975 while (!ROMENTRY_ISFILE(romp) && !ROMENTRY_ISREGIONEND(romp))
976 romp++;
977 return ROMENTRY_ISREGIONEND(romp) ? NULL : romp;
978 }
979
980
981 /*-------------------------------------------------
982 rom_first_chunk - return pointer to first ROM
983 chunk
984 -------------------------------------------------*/
985
986 const struct RomModule *rom_first_chunk(const struct RomModule *romp)
987 {
988 return (ROMENTRY_ISFILE(romp)) ? romp : NULL;
989 }
990
991
992 /*-------------------------------------------------
993 rom_next_chunk - return pointer to next ROM
994 chunk
995 -------------------------------------------------*/
996
997 const struct RomModule *rom_next_chunk(const struct RomModule *romp)
998 {
999 romp++;
1000 return (ROMENTRY_ISCONTINUE(romp)) ? romp : NULL;
1001 }
1002
1003
1004
1005 /*-------------------------------------------------
1006 debugload - log data to a file
1007 -------------------------------------------------*/
1008
1009 void CLIB_DECL debugload(const char *string, ...)
1010 {
1011 #ifdef LOG_LOAD
1012 static int opened;
1013 va_list arg;
1014 FILE *f;
1015
1016 f = fopen("romload.log", opened++ ? "a" : "w");
1017 if (f)
1018 {
1019 va_start(arg, string);
1020 vfprintf(f, string, arg);
1021 va_end(arg);
1022 fclose(f);
1023 }
1024 #endif
1025 }
1026
1027
1028 /*-------------------------------------------------
1029 count_roms - counts the total number of ROMs
1030 that will need to be loaded
1031 -------------------------------------------------*/
1032
1033 static int count_roms(const struct RomModule *romp)
1034 {
1035 const struct RomModule *region, *rom;
1036 int count = 0;
1037
1038 /* loop over regions, then over files */
1039 for (region = romp; region; region = rom_next_region(region))
1040 for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
1041 count++;
1042
1043 /* return the total count */
1044 return count;
1045 }
1046
1047
1048 /*-------------------------------------------------
1049 fill_random - fills an area of memory with
1050 random data
1051 -------------------------------------------------*/
1052
1053 static void fill_random(UINT8 *base, UINT32 length)
1054 {
1055 while (length--)
1056 *base++ = rand();
1057 }
1058
1059
1060 /*-------------------------------------------------
1061 handle_missing_file - handles error generation
1062 for missing files
1063 -------------------------------------------------*/
1064
1065 static void handle_missing_file(struct rom_load_data *romdata, const struct RomModule *romp)
1066 {
1067 /* optional files are okay */
1068 if (ROM_ISOPTIONAL(romp))
1069 {
1070 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "OPTIONAL %-12s NOT FOUND\n", ROM_GETNAME(romp));
1071 romdata->warnings++;
1072 }
1073
1074 /* no good dumps are okay */
1075 else if (ROM_NOGOODDUMP(romp))
1076 {
1077 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s NOT FOUND (NO GOOD DUMP KNOWN)\n", ROM_GETNAME(romp));
1078 romdata->warnings++;
1079 }
1080
1081 /* anything else is bad */
1082 else
1083 {
1084 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s NOT FOUND\n", ROM_GETNAME(romp));
1085 romdata->errors++;
1086 }
1087 }
1088
1089
1090 /*-------------------------------------------------
1091 verify_length_and_crc - verify the length
1092 and CRC of a file
1093 -------------------------------------------------*/
1094
1095 static void verify_length_and_crc(struct rom_load_data *romdata, const char *name, UINT32 explength, UINT32 expcrc)
1096 {
1097 UINT32 actlength, actcrc;
1098
1099 /* we've already complained if there is no file */
1100 if (!romdata->file)
1101 return;
1102
1103 /* get the length and CRC from the file */
1104 actlength = osd_fsize(romdata->file);
1105 actcrc = osd_fcrc(romdata->file);
1106
1107 /* verify length */
1108 if (explength != actlength)
1109 {
1110 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s WRONG LENGTH (expected: %08x found: %08x)\n", name, explength, actlength);
1111 romdata->warnings++;
1112 }
1113
1114 /* verify CRC */
1115 if (expcrc != actcrc)
1116 {
1117 /* expected CRC == 0 means no good dump known */
1118 if (expcrc == 0)
1119 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s NO GOOD DUMP KNOWN\n", name);
1120
1121 /* inverted CRC means needs redump */
1122 else if (expcrc == BADCRC(actcrc))
1123 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s ROM NEEDS REDUMP\n",name);
1124
1125 /* otherwise, it's just bad */
1126 else
1127 sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%-12s WRONG CRC (expected: %08x found: %08x)\n", name, expcrc, actcrc);
1128 romdata->warnings++;
1129 }
1130 }
1131
1132
1133 /*-------------------------------------------------
1134 display_rom_load_results - display the final
1135 results of ROM loading
1136 -------------------------------------------------*/
1137
1138 static int display_rom_load_results(struct rom_load_data *romdata)
1139 {
1140 int region;
1141
1142 /* final status display */
1143 osd_display_loading_rom_message(NULL, romdata->romsloaded, romdata->romstotal);
1144
1145 /* only display if we have warnings or errors */
1146 if (romdata->warnings || romdata->errors)
1147 {
1148 extern int bailing;
1149
1150 /* display either an error message or a warning message */
1151 if (romdata->errors)
1152 {
1153 strcat(romdata->errorbuf, "ERROR: required files are missing, the game cannot be run.\n");
1154 bailing = 1;
1155 }
1156 else
1157 strcat(romdata->errorbuf, "WARNING: the game might not run correctly.\n");
1158
1159 /* display the result */
1160 printf("%s", romdata->errorbuf);
1161
1162 /* if we're not getting out of here, wait for a keypress */
1163 if (!options.gui_host && !bailing)
1164 {
1165 int k;
1166
1167 /* loop until we get one */
1168 printf ("Press any key to continue\n");
1169 do
1170 {
1171 k = code_read_async();
1172 }
1173 while (k == CODE_NONE || k == KEYCODE_LCONTROL);
1174
1175 /* bail on a control + C */
1176 if (keyboard_pressed(KEYCODE_LCONTROL) && keyboard_pressed(KEYCODE_C))
1177 return 1;
1178 }
1179 }
1180
1181 /* clean up any regions */
1182 if (romdata->errors)
1183 for (region = 0; region < MAX_MEMORY_REGIONS; region++)
1184 free_memory_region(region);
1185
1186 /* return true if we had any errors */
1187 return (romdata->errors != 0);
1188 }
1189
1190
1191 /*-------------------------------------------------
1192 region_post_process - post-process a region,
1193 byte swapping and inverting data as necessary
1194 -------------------------------------------------*/
1195
1196 static void region_post_process(struct rom_load_data *romdata, const struct RomModule *regiondata)
1197 {
1198 int type = ROMREGION_GETTYPE(regiondata);
1199 int datawidth = ROMREGION_GETWIDTH(regiondata) / 8;
1200 int littleendian = ROMREGION_ISLITTLEENDIAN(regiondata);
1201 UINT8 *base;
1202 int i, j;
1203
1204 debugload("+ datawidth=%d little=%d\n", datawidth, littleendian);
1205
1206 /* if this is a CPU region, override with the CPU width and endianness */
1207 if (type >= REGION_CPU1 && type < REGION_CPU1 + MAX_CPU)
1208 {
1209 int cputype = Machine->drv->cpu[type - REGION_CPU1].cpu_type & ~CPU_FLAGS_MASK;
1210 if (cputype != 0)
1211 {
1212 datawidth = cputype_databus_width(cputype) / 8;
1213 littleendian = (cputype_endianess(cputype) == CPU_IS_LE);
1214 debugload("+ CPU region #%d: datawidth=%d little=%d\n", type - REGION_CPU1, datawidth, littleendian);
1215 }
1216 }
1217
1218 /* if the region is inverted, do that now */
1219 if (ROMREGION_ISINVERTED(regiondata))
1220 {
1221 debugload("+ Inverting region\n");
1222 for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i++)
1223 *base++ ^= 0xff;
1224 }
1225
1226 /* swap the endianness if we need to */
1227 #ifdef LSB_FIRST
1228 if (datawidth > 1 && !littleendian)
1229 #else
1230 if (datawidth > 1 && littleendian)
1231 #endif
1232 {
1233 debugload("+ Byte swapping region\n");
1234 for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i += datawidth)
1235 {
1236 UINT8 temp[8];
1237 memcpy(temp, base, datawidth);
1238 for (j = datawidth - 1; j >= 0; j--)
1239 *base++ = temp[j];
1240 }
1241 }
1242 }
1243
1244
1245 /*-------------------------------------------------
1246 open_rom_file - open a ROM file, searching
1247 up the parent and loading via CRC
1248 -------------------------------------------------*/
1249
1250 static int open_rom_file(struct rom_load_data *romdata, const struct RomModule *romp)
1251 {
1252 const struct GameDriver *drv;
1253 char crc[9];
1254
1255 /* update status display */
1256 if (osd_display_loading_rom_message(ROM_GETNAME(romp), ++romdata->romsloaded, romdata->romstotal) != 0)
1257 return 0;
1258
1259 /* first attempt reading up the chain through the parents */
1260 romdata->file = NULL;
1261 for (drv = Machine->gamedrv; !romdata->file && drv; drv = drv->clone_of)
1262 if (drv->name && *drv->name)
1263 romdata->file = osd_fopen(drv->name, ROM_GETNAME(romp), OSD_FILETYPE_ROM, 0);
1264
1265 /* if that failed, attempt to open via CRC */
1266 sprintf(crc, "%08x", ROM_GETCRC(romp));
1267 for (drv = Machine->gamedrv; !romdata->file && drv; drv = drv->clone_of)
1268 if (drv->name && *drv->name)
1269 romdata->file = osd_fopen(drv->name, crc, OSD_FILETYPE_ROM, 0);
1270
1271 /* return the result */
1272 return (romdata->file != NULL);
1273 }
1274
1275
1276 /*-------------------------------------------------
1277 rom_fread - cheesy fread that fills with
1278 random data for a NULL file
1279 -------------------------------------------------*/
1280
1281 static int rom_fread(struct rom_load_data *romdata, UINT8 *buffer, int length)
1282 {
1283 /* files just pass through */
1284 if (romdata->file)
1285 return osd_fread(romdata->file, buffer, length);
1286
1287 /* otherwise, fill with randomness */
1288 else
1289 fill_random(buffer, length);
1290
1291 return length;
1292 }
1293
1294
1295 /*-------------------------------------------------
1296 read_rom_data - read ROM data for a single
1297 entry
1298 -------------------------------------------------*/
1299
1300 static int read_rom_data(struct rom_load_data *romdata, const struct RomModule *romp)
1301 {
1302 int datashift = ROM_GETBITSHIFT(romp);
1303 int datamask = ((1 << ROM_GETBITWIDTH(romp)) - 1) << datashift;
1304 int numbytes = ROM_GETLENGTH(romp);
1305 int groupsize = ROM_GETGROUPSIZE(romp);
1306 int skip = ROM_GETSKIPCOUNT(romp);
1307 int reversed = ROM_ISREVERSED(romp);
1308 int numgroups = (numbytes + groupsize - 1) / groupsize;
1309 UINT8 *base = romdata->regionbase + ROM_GETOFFSET(romp);
1310 int i;
1311
1312 debugload("Loading ROM data: offs=%X len=%X mask=%02X group=%d skip=%d reverse=%d\n", ROM_GETOFFSET(romp), numbytes, datamask, groupsize, skip, reversed);
1313
1314 /* make sure the length was an even multiple of the group size */
1315 if (numbytes % groupsize != 0)
1316 {
1317 printf("Error in RomModule definition: %s length not an even multiple of group size\n", ROM_GETNAME(romp));
1318 return -1;
1319 }
1320
1321 /* make sure we only fill within the region space */
1322 if (ROM_GETOFFSET(romp) + numgroups * groupsize + (numgroups - 1) * skip > romdata->regionlength)
1323 {
1324 printf("Error in RomModule definition: %s out of memory region space\n", ROM_GETNAME(romp));
1325 return -1;
1326 }
1327
1328 /* make sure the length was valid */
1329 if (numbytes == 0)
1330 {
1331 printf("Error in RomModule definition: %s has an invalid length\n", ROM_GETNAME(romp));
1332 return -1;
1333 }
1334
1335 /* special case for simple loads */
1336 if (datamask == 0xff && (groupsize == 1 || !reversed) && skip == 0)
1337 return rom_fread(romdata, base, numbytes);
1338
1339 /* chunky reads for complex loads */
1340 skip += groupsize;
1341 while (numbytes)
1342 {
1343 int evengroupcount = (sizeof(romdata->tempbuf) / groupsize) * groupsize;
1344 int bytesleft = (numbytes > evengroupcount) ? evengroupcount : numbytes;
1345 UINT8 *bufptr = romdata->tempbuf;
1346
1347 /* read as much as we can */
1348 debugload(" Reading %X bytes into buffer\n", bytesleft);
1349 if (rom_fread(romdata, romdata->tempbuf, bytesleft) != bytesleft)
1350 return 0;
1351 numbytes -= bytesleft;
1352
1353 debugload(" Copying to %08X\n", (int)base);
1354
1355 /* unmasked cases */
1356 if (datamask == 0xff)
1357 {
1358 /* non-grouped data */
1359 if (groupsize == 1)
1360 for (i = 0; i < bytesleft; i++, base += skip)
1361 *base = *bufptr++;
1362
1363 /* grouped data -- non-reversed case */
1364 else if (!reversed)
1365 while (bytesleft)
1366 {
1367 for (i = 0; i < groupsize && bytesleft; i++, bytesleft--)
1368 base[i] = *bufptr++;
1369 base += skip;
1370 }
1371
1372 /* grouped data -- reversed case */
1373 else
1374 while (bytesleft)
1375 {
1376 for (i = groupsize - 1; i >= 0 && bytesleft; i--, bytesleft--)
1377 base[i] = *bufptr++;
1378 base += skip;
1379 }
1380 }
1381
1382 /* masked cases */
1383 else
1384 {
1385 /* non-grouped data */
1386 if (groupsize == 1)
1387 for (i = 0; i < bytesleft; i++, base += skip)
1388 *base = (*base & ~datamask) | ((*bufptr++ << datashift) & datamask);
1389
1390 /* grouped data -- non-reversed case */
1391 else if (!reversed)
1392 while (bytesleft)
1393 {
1394 for (i = 0; i < groupsize && bytesleft; i++, bytesleft--)
1395 base[i] = (base[i] & ~datamask) | ((*bufptr++ << datashift) & datamask);
1396 base += skip;
1397 }
1398
1399 /* grouped data -- reversed case */
1400 else
1401 while (bytesleft)
1402 {
1403 for (i = groupsize - 1; i >= 0 && bytesleft; i--, bytesleft--)
1404 base[i] = (base[i] & ~datamask) | ((*bufptr++ << datashift) & datamask);
1405 base += skip;
1406 }
1407 }
1408 }
1409 debugload(" All done\n");
1410 return ROM_GETLENGTH(romp);
1411 }
1412
1413
1414 /*-------------------------------------------------
1415 fill_rom_data - fill a region of ROM space
1416 -------------------------------------------------*/
1417
1418 static int fill_rom_data(struct rom_load_data *romdata, const struct RomModule *romp)
1419 {
1420 UINT32 numbytes = ROM_GETLENGTH(romp);
1421 UINT8 *base = romdata->regionbase + ROM_GETOFFSET(romp);
1422
1423 /* make sure we fill within the region space */
1424 if (ROM_GETOFFSET(romp) + numbytes > romdata->regionlength)
1425 {
1426 printf("Error in RomModule definition: FILL out of memory region space\n");
1427 return 0;
1428 }
1429
1430 /* make sure the length was valid */
1431 if (numbytes == 0)
1432 {
1433 printf("Error in RomModule definition: FILL has an invalid length\n");
1434 return 0;
1435 }
1436
1437 /* fill the data */
1438 memset(base, ROM_GETCRC(romp) & 0xff, numbytes);
1439 return 1;
1440 }
1441
1442
1443 /*-------------------------------------------------
1444 copy_rom_data - copy a region of ROM space
1445 -------------------------------------------------*/
1446
1447 static int copy_rom_data(struct rom_load_data *romdata, const struct RomModule *romp)
1448 {
1449 UINT8 *base = romdata->regionbase + ROM_GETOFFSET(romp);
1450 int srcregion = ROM_GETFLAGS(romp) >> 24;
1451 UINT32 numbytes = ROM_GETLENGTH(romp);
1452 UINT32 srcoffs = ROM_GETCRC(romp);
1453 UINT8 *srcbase;
1454
1455 /* make sure we copy within the region space */
1456 if (ROM_GETOFFSET(romp) + numbytes > romdata->regionlength)
1457 {
1458 printf("Error in RomModule definition: COPY out of target memory region space\n");
1459 return 0;
1460 }
1461
1462 /* make sure the length was valid */
1463 if (numbytes == 0)
1464 {
1465 printf("Error in RomModule definition: COPY has an invalid length\n");
1466 return 0;
1467 }
1468
1469 /* make sure the source was valid */
1470 srcbase = memory_region(srcregion);
1471 if (!srcbase)
1472 {
1473 printf("Error in RomModule definition: COPY from an invalid region\n");
1474 return 0;
1475 }
1476
1477 /* make sure we find within the region space */
1478 if (srcoffs + numbytes > memory_region_length(srcregion))
1479 {
1480 printf("Error in RomModule definition: COPY out of source memory region space\n");
1481 return 0;
1482 }
1483
1484 /* fill the data */
1485 memcpy(base, srcbase + srcoffs, numbytes);
1486 return 1;
1487 }
1488
1489
1490 /*-------------------------------------------------
1491 process_rom_entries - process all ROM entries
1492 for a region
1493 -------------------------------------------------*/
1494
1495 static int process_rom_entries(struct rom_load_data *romdata, const struct RomModule *romp)
1496 {
1497 UINT32 lastflags = 0;
1498
1499 /* loop until we hit the end of this region */
1500 while (!ROMENTRY_ISREGIONEND(romp))
1501 {
1502 /* if this is a continue entry, it's invalid */
1503 if (ROMENTRY_ISCONTINUE(romp))
1504 {
1505 printf("Error in RomModule definition: ROM_CONTINUE not preceded by ROM_LOAD\n");
1506 goto fatalerror;
1507 }
1508
1509 /* if this is a reload entry, it's invalid */
1510 if (ROMENTRY_ISRELOAD(romp))
1511 {
1512 printf("Error in RomModule definition: ROM_RELOAD not preceded by ROM_LOAD\n");
1513 goto fatalerror;
1514 }
1515
1516 /* handle fills */
1517 if (ROMENTRY_ISFILL(romp))
1518 {
1519 if (!fill_rom_data(romdata, romp++))
1520 goto fatalerror;
1521 }
1522
1523 /* handle copies */
1524 else if (ROMENTRY_ISCOPY(romp))
1525 {
1526 if (!copy_rom_data(romdata, romp++))
1527 goto fatalerror;
1528 }
1529
1530 /* handle files */
1531 else if (ROMENTRY_ISFILE(romp))
1532 {
1533 const struct RomModule *baserom = romp;
1534 int explength = 0;
1535
1536 /* open the file */
1537 debugload("Opening ROM file: %s\n", ROM_GETNAME(romp));
1538 if (!open_rom_file(romdata, romp))
1539 handle_missing_file(romdata, romp);
1540
1541 /* loop until we run out of reloads */
1542 do
1543 {
1544 /* loop until we run out of continues */
1545 do
1546 {
1547 struct RomModule modified_romp = *romp++;
1548 int readresult;
1549
1550 /* handle flag inheritance */
1551 if (!ROM_INHERITSFLAGS(&modified_romp))
1552 lastflags = modified_romp._flags;
1553 else
1554 modified_romp._flags = (modified_romp._flags & ~ROM_INHERITEDFLAGS) | lastflags;
1555
1556 explength += ROM_GETLENGTH(&modified_romp);
1557
1558 /* attempt to read using the modified entry */
1559 readresult = read_rom_data(romdata, &modified_romp);
1560 if (readresult == -1)
1561 goto fatalerror;
1562 }
1563 while (ROMENTRY_ISCONTINUE(romp));
1564
1565 /* if this was the first use of this file, verify the length and CRC */
1566 if (baserom)
1567 {
1568 debugload("Verifying length (%X) and CRC (%08X)\n", explength, ROM_GETCRC(baserom));
1569 verify_length_and_crc(romdata, ROM_GETNAME(baserom), explength, ROM_GETCRC(baserom));
1570 debugload("Verify succeeded\n");
1571 }
1572
1573 /* reseek to the start and clear the baserom so we don't reverify */
1574 if (romdata->file)
1575 osd_fseek(romdata->file, 0, SEEK_SET);
1576 baserom = NULL;
1577 explength = 0;
1578 }
1579 while (ROMENTRY_ISRELOAD(romp));
1580
1581 /* close the file */
1582 if (romdata->file)
1583 {
1584 debugload("Closing ROM file\n");
1585 osd_fclose(romdata->file);
1586 romdata->file = NULL;
1587 }
1588 }
1589 }
1590 return 1;
1591
1592 /* error case */
1593 fatalerror:
1594 if (romdata->file)
1595 osd_fclose(romdata->file);
1596 romdata->file = NULL;
1597 return 0;
1598 }
1599
1600
1601 /*-------------------------------------------------
1602 readroms - load all the ROMs for this machine
1603 -------------------------------------------------*/
1604
1605 int readroms(void)
1606 {
1607 return rom_load_new(Machine->gamedrv->rom);
1608 }
1609
1610
1611 /*-------------------------------------------------
1612 rom_load_new - new, more flexible ROM
1613 loading system
1614 -------------------------------------------------*/
1615
1616 int rom_load_new(const struct RomModule *romp)
1617 {
1618 const struct RomModule *regionlist[REGION_MAX];
1619 const struct RomModule *region;
1620 static struct rom_load_data romdata;
1621 int regnum;
1622
1623 /* reset the region list */
1624 for (regnum = 0;regnum < REGION_MAX;regnum++)
1625 regionlist[regnum] = NULL;
1626
1627 /* reset the romdata struct */
1628 memset(&romdata, 0, sizeof(romdata));
1629 romdata.romstotal = count_roms(romp);
1630
1631 /* loop until we hit the end */
1632 for (region = romp, regnum = 0; region; region = rom_next_region(region), regnum++)
1633 {
1634 int regiontype = ROMREGION_GETTYPE(region);
1635
1636 debugload("Processing region %02X (length=%X)\n", regiontype, ROMREGION_GETLENGTH(region));
1637
1638 /* the first entry must be a region */
1639 if (!ROMENTRY_ISREGION(region))
1640 {
1641 printf("Error: missing ROM_REGION header\n");
1642 return 1;
1643 }
1644
1645 /* if sound is disabled and it's a sound-only region, skip it */
1646 if (Machine->sample_rate == 0 && ROMREGION_ISSOUNDONLY(region))
1647 continue;
1648
1649 /* allocate memory for the region */
1650 if (new_memory_region(regiontype, ROMREGION_GETLENGTH(region), ROMREGION_GETFLAGS(region)))
1651 {
1652 printf("Error: unable to allocate memory for region %d\n", regiontype);
1653 return 1;
1654 }
1655
1656 /* remember the base and length */
1657 romdata.regionlength = memory_region_length(regiontype);
1658 romdata.regionbase = memory_region(regiontype);
1659 debugload("Allocated %X bytes @ %08X\n", romdata.regionlength, (int)romdata.regionbase);
1660
1661 /* clear the region if it's requested */
1662 if (ROMREGION_ISERASE(region))
1663 memset(romdata.regionbase, ROMREGION_GETERASEVAL(region), romdata.regionlength);
1664
1665 /* or if it's sufficiently small (<= 4MB) */
1666 else if (romdata.regionlength <= 0x400000)
1667 memset(romdata.regionbase, 0, romdata.regionlength);
1668
1669 #ifdef MAME_DEBUG
1670 /* if we're debugging, fill region with random data to catch errors */
1671 else
1672 fill_random(romdata.regionbase, romdata.regionlength);
1673 #endif
1674
1675 /* now process the entries in the region */
1676 if (!process_rom_entries(&romdata, region + 1))
1677 return 1;
1678
1679 /* add this region to the list */
1680 if (regiontype < REGION_MAX)
1681 regionlist[regiontype] = region;
1682 }
1683
1684 /* post-process the regions */
1685 for (regnum = 0; regnum < REGION_MAX; regnum++)
1686 if (regionlist[regnum])
1687 {
1688 debugload("Post-processing region %02X\n", regnum);
1689 romdata.regionlength = memory_region_length(regnum);
1690 romdata.regionbase = memory_region(regnum);
1691 region_post_process(&romdata, regionlist[regnum]);
1692 }
1693
1694 /* display the results and exit */
1695 return display_rom_load_results(&romdata);
1696 }
1697
1698
1699 /*-------------------------------------------------
1700 printromlist - print list of ROMs
1701 -------------------------------------------------*/
1702
1703 void printromlist(const struct RomModule *romp,const char *basename)
1704 {
1705 const struct RomModule *region, *rom, *chunk;
1706
1707 if (!romp) return;
1708
1709 #ifdef MESS
1710 if (!strcmp(basename,"nes")) return;
1711 #endif
1712
1713 #ifdef JAPANESE
1714 printf("�h���C�o \"%s\" ���v������ROM�����������B\n"
1715 "�t�@�C���� �T�C�Y �`�F�b�N�T��\n",basename);
1716 #else
1717 printf("This is the list of the ROMs required for driver \"%s\".\n"
1718 "Name Size Checksum\n",basename);
1719 #endif
1720
1721 for (region = romp; region; region = rom_next_region(region))
1722 {
1723 for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
1724 {
1725 const char *name = ROM_GETNAME(rom);
1726 int expchecksum = ROM_GETCRC(rom);
1727 int length = 0;
1728
1729 for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk))
1730 length += ROM_GETLENGTH(chunk);
1731
1732 #ifdef JAPANESE
1733 if (expchecksum)
1734 printf("%-12s %7d �o�C�g %08x\n",name,length,expchecksum);
1735 else
1736 printf("%-12s %7d �o�C�g ������ROM��CRC���s������\n",name,length);
1737 #else
1738 if (expchecksum)
1739 printf("%-12s %7d bytes %08x\n",name,length,expchecksum);
1740 else
1741 printf("%-12s %7d bytes NO GOOD DUMP KNOWN\n",name,length);
1742 #endif
1743 }
1744 }
1745 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26