static int display_rom_load_results(struct rom_load_data *romdata) { int region; /* final status display */ osd_display_loading_rom_message(NULL, romdata); /* only display if we have warnings or errors */ if (romdata->warnings || romdata->errors) { extern int bailing; /* display either an error message or a warning message */ if (romdata->errors) { strcat(romdata->errorbuf, "ERROR: required files are missing, the game cannot be run.\n"); bailing = 1; } else strcat(romdata->errorbuf, "WARNING: the game might not run correctly.\n"); /* display the result */ printf("%s", romdata->errorbuf); /* if we're not getting out of here, wait for a keypress */ if (!options.gui_host && !bailing) { #if 0 int k; /* loop until we get one */ printf ("Press any key to continue\n"); do { k = code_read_async(); } while (k == CODE_NONE || k == KEYCODE_LCONTROL); #endif /* bail on a control + C */ if (keyboard_pressed(KEYCODE_LCONTROL) && keyboard_pressed(KEYCODE_C)) return 1; } } /* clean up any regions */ if (romdata->errors) for (region = 0; region < MAX_MEMORY_REGIONS; region++) free_memory_region(region); /* return true if we had any errors */ return (romdata->errors != 0); }
static int open_rom_file(struct rom_load_data *romdata, const struct RomModule *romp) { const struct GameDriver *drv; ++romdata->romsloaded; /* update status display */ if (osd_display_loading_rom_message(ROM_GETNAME(romp), romdata)) return 0; /* Attempt reading up the chain through the parents. It automatically also attempts any kind of load by checksum supported by the archives. */ romdata->file = NULL; for (drv = Machine->gamedrv; !romdata->file && drv; drv = drv->clone_of) if (drv->name && *drv->name) romdata->file = mame_fopen_rom(drv->name, ROM_GETNAME(romp), ROM_GETHASHDATA(romp)); /* return the result */ return (romdata->file != NULL); }
int readroms(void) { int region; const struct RomModule *romp; int warning = 0; int fatalerror = 0; int total_roms,current_rom; char buf[4096] = ""; total_roms = current_rom = 0; romp = Machine->gamedrv->rom; if (!romp) return 0; while (romp->name || romp->offset || romp->length) { if (romp->name && romp->name != (char *)-1) total_roms++; romp++; } romp = Machine->gamedrv->rom; for (region = 0;region < MAX_MEMORY_REGIONS;region++) Machine->memory_region[region] = 0; region = 0; while (romp->name || romp->offset || romp->length) { unsigned int region_size; const char *name; /* Mish: An 'optional' rom region, only loaded if sound emulation is turned on */ if (Machine->sample_rate==0 && (romp->crc & REGIONFLAG_SOUNDONLY)) { logerror("readroms(): Ignoring rom region %d\n",region); Machine->memory_region_type[region] = romp->crc; region++; romp++; while (romp->name || romp->length) romp++; continue; } if (romp->name || romp->length) { printf("Error in RomModule definition: expecting ROM_REGION\n"); goto getout; } region_size = romp->offset; if ((Machine->memory_region[region] = (unsigned char *) malloc(region_size)) == 0) { printf("readroms(): Unable to allocate %d bytes of RAM\n",region_size); goto getout; } Machine->memory_region_length[region] = region_size; Machine->memory_region_type[region] = romp->crc; /* some games (i.e. Pleiades) want the memory clear on startup */ if (region_size <= 0x400000) /* don't clear large regions which will be filled anyway */ memset(Machine->memory_region[region],0,region_size); romp++; while (romp->length) { void *f; int expchecksum = romp->crc; int explength = 0; if (romp->name == 0) { printf("Error in RomModule definition: ROM_CONTINUE not preceded by ROM_LOAD\n"); goto getout; } else if (romp->name == (char *)-1) { printf("Error in RomModule definition: ROM_RELOAD not preceded by ROM_LOAD\n"); goto getout; } name = romp->name; /* update status display */ if (osd_display_loading_rom_message(name,++current_rom,total_roms) != 0) goto getout; { const struct GameDriver *drv; drv = Machine->gamedrv; do { f = osd_fopen(drv->name,name,OSD_FILETYPE_ROM,0); drv = drv->clone_of; } while (f == 0 && drv); if (f == 0) { /* NS981003: support for "load by CRC" */ char crc[9]; sprintf(crc,"%08x",romp->crc); drv = Machine->gamedrv; do { f = osd_fopen(drv->name,crc,OSD_FILETYPE_ROM,0); drv = drv->clone_of; } while (f == 0 && drv); } } if (f) { do { unsigned char *c; unsigned int i; int length = romp->length & ~ROMFLAG_MASK; if (romp->name == (char *)-1) osd_fseek(f,0,SEEK_SET); /* ROM_RELOAD */ else explength += length; if (romp->offset + length > region_size || (!(romp->length & ROMFLAG_NIBBLE) && (romp->length & ROMFLAG_ALTERNATE) && (romp->offset&~1) + 2*length > region_size)) { printf("Error in RomModule definition: %s out of memory region space\n",name); osd_fclose(f); goto getout; } if (romp->length & ROMFLAG_NIBBLE) { unsigned char *temp; temp = (unsigned char *) malloc(length); if (!temp) { printf("Out of memory reading ROM %s\n",name); osd_fclose(f); goto getout; } if (osd_fread(f,temp,length) != length) { printf("Unable to read ROM %s\n",name); } /* ROM_LOAD_NIB_LOW and ROM_LOAD_NIB_HIGH */ c = Machine->memory_region[region] + romp->offset; if (romp->length & ROMFLAG_ALTERNATE) { /* Load into the high nibble */ for (i = 0;i < length;i ++) { c[i] = (c[i] & 0x0f) | ((temp[i] & 0x0f) << 4); } } else { /* Load into the low nibble */ for (i = 0;i < length;i ++) { c[i] = (c[i] & 0xf0) | (temp[i] & 0x0f); } } free(temp); } else if (romp->length & ROMFLAG_ALTERNATE) { /* ROM_LOAD_EVEN and ROM_LOAD_ODD */ /* copy the ROM data */ #ifdef LSB_FIRST c = Machine->memory_region[region] + (romp->offset ^ 1); #else c = Machine->memory_region[region] + romp->offset; #endif if (osd_fread_scatter(f,c,length,2) != length) { printf("Unable to read ROM %s\n",name); } } else if (romp->length & ROMFLAG_QUAD) { static int which_quad=0; /* This is multi session friendly, as we only care about the modulus */ unsigned char *temp; int base=0; temp = (unsigned char *) malloc(length); /* Need to load rom to temporary space */ osd_fread(f,temp,length); /* Copy quad to region */ c = Machine->memory_region[region] + romp->offset; #ifdef LSB_FIRST switch (which_quad%4) { case 0: base=1; break; case 1: base=0; break; case 2: base=3; break; case 3: base=2; break; } #else switch (which_quad%4) { case 0: base=0; break; case 1: base=1; break; case 2: base=2; break; case 3: base=3; break; } #endif for (i=base; i< length*4; i += 4) c[i]=temp[i/4]; which_quad++; free(temp); } else { int wide = romp->length & ROMFLAG_WIDE; #ifdef LSB_FIRST int swap = (romp->length & ROMFLAG_SWAP) ^ ROMFLAG_SWAP; #else int swap = romp->length & ROMFLAG_SWAP; #endif osd_fread(f,Machine->memory_region[region] + romp->offset,length); /* apply swappage */ c = Machine->memory_region[region] + romp->offset; if (wide && swap) { for (i = 0; i < length; i += 2) { int temp = c[i]; c[i] = c[i+1]; c[i+1] = temp; } } } romp++; } while (romp->length && (romp->name == 0 || romp->name == (char *)-1)); if (explength != osd_fsize (f)) { sprintf (&buf[strlen(buf)], "%-12s WRONG LENGTH (expected: %08x found: %08x)\n", name,explength,osd_fsize(f)); warning = 1; } if (expchecksum != osd_fcrc (f)) { warning = 1; if (expchecksum == 0) sprintf(&buf[strlen(buf)],"%-12s NO GOOD DUMP KNOWN\n",name); else if (expchecksum == BADCRC(osd_fcrc(f))) sprintf(&buf[strlen(buf)],"%-12s ROM NEEDS REDUMP\n",name); else sprintf(&buf[strlen(buf)], "%-12s WRONG CRC (expected: %08x found: %08x)\n", name,expchecksum,osd_fcrc(f)); } osd_fclose(f); } else if (romp->length & ROMFLAG_OPTIONAL) { sprintf (&buf[strlen(buf)], "OPTIONAL %-12s NOT FOUND\n",name); romp ++; } else { /* allow for a NO GOOD DUMP KNOWN rom to be missing */ if (expchecksum == 0) { sprintf (&buf[strlen(buf)], "%-12s NOT FOUND (NO GOOD DUMP KNOWN)\n",name); warning = 1; } else { sprintf (&buf[strlen(buf)], "%-12s NOT FOUND\n",name); fatalerror = 1; } do { if (fatalerror == 0) { int i; /* fill space with random data */ if (romp->length & ROMFLAG_ALTERNATE) { unsigned char *c; /* ROM_LOAD_EVEN and ROM_LOAD_ODD */ #ifdef LSB_FIRST c = Machine->memory_region[region] + (romp->offset ^ 1); #else c = Machine->memory_region[region] + romp->offset; #endif for (i = 0;i < (romp->length & ~ROMFLAG_MASK);i++) c[2*i] = rand(); } else { for (i = 0;i < (romp->length & ~ROMFLAG_MASK);i++) Machine->memory_region[region][romp->offset + i] = rand(); } } romp++; } while (romp->length && (romp->name == 0 || romp->name == (char *)-1)); } } region++; } /* final status display */ osd_display_loading_rom_message(0,current_rom,total_roms); if (warning || fatalerror) { extern int bailing; if (fatalerror) { strcat (buf, "ERROR: required files are missing, the game cannot be run.\n"); bailing = 1; } else strcat (buf, "WARNING: the game might not run correctly.\n"); printf ("%s", buf); if (!options.gui_host && !bailing) { printf ("Press any key to continue\n"); keyboard_read_sync(); if (keyboard_pressed(KEYCODE_LCONTROL) && keyboard_pressed(KEYCODE_C)) return 1; } } if (fatalerror) return 1; else return 0; getout: /* final status display */ osd_display_loading_rom_message(0,current_rom,total_roms); for (region = 0;region < MAX_MEMORY_REGIONS;region++) { free(Machine->memory_region[region]); Machine->memory_region[region] = 0; } return 1; }