static void region_post_process(struct rom_load_data *romdata, const struct RomModule *regiondata) { int type = ROMREGION_GETTYPE(regiondata); int datawidth = ROMREGION_GETWIDTH(regiondata) / 8; int littleendian = ROMREGION_ISLITTLEENDIAN(regiondata); UINT8 *base; int i, j; debugload("+ datawidth=%d little=%d\n", datawidth, littleendian); /* if this is a CPU region, override with the CPU width and endianness */ if (type >= REGION_CPU1 && type < REGION_CPU1 + MAX_CPU) { int cputype = Machine->drv->cpu[type - REGION_CPU1].cpu_type; if (cputype != 0) { datawidth = cputype_databus_width(cputype) / 8; littleendian = (cputype_endianess(cputype) == CPU_IS_LE); debugload("+ CPU region #%d: datawidth=%d little=%d\n", type - REGION_CPU1, datawidth, littleendian); } } /* if the region is inverted, do that now */ if (ROMREGION_ISINVERTED(regiondata)) { debugload("+ Inverting region\n"); for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i++) *base++ ^= 0xff; } /* swap the endianness if we need to */ #ifdef MSB_FIRST if (datawidth > 1 && littleendian) #else if (datawidth > 1 && !littleendian) #endif { debugload("+ Byte swapping region\n"); for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i += datawidth) { UINT8 temp[8]; memcpy(temp, base, datawidth); for (j = datawidth - 1; j >= 0; j--) *base++ = temp[j]; } } }
int rom_load(const struct RomModule *romp) { const struct RomModule *regionlist[REGION_MAX]; const struct RomModule *region; static struct rom_load_data romdata; int regnum; /* reset the region list */ for (regnum = 0;regnum < REGION_MAX;regnum++) regionlist[regnum] = NULL; /* reset the romdata struct */ memset(&romdata, 0, sizeof(romdata)); romdata.romstotal = count_roms(romp); /* reset the disk list */ memset(disk_handle, 0, sizeof(disk_handle)); /* determine the correct biosset to load based on options.bios string */ system_bios = determine_bios_rom(Machine->gamedrv->bios); /* loop until we hit the end */ for (region = romp, regnum = 0; region; region = rom_next_region(region), regnum++) { int regiontype = ROMREGION_GETTYPE(region); debugload("Processing region %02X (length=%X)\n", regiontype, ROMREGION_GETLENGTH(region)); /* the first entry must be a region */ if (!ROMENTRY_ISREGION(region)) { printf("Error: missing ROM_REGION header\n"); return 1; } /* if sound is disabled and it's a sound-only region, skip it */ if (Machine->sample_rate == 0 && ROMREGION_ISSOUNDONLY(region)) continue; /* allocate memory for the region */ if (new_memory_region(regiontype, ROMREGION_GETLENGTH(region), ROMREGION_GETFLAGS(region))) { printf("Error: unable to allocate memory for region %d\n", regiontype); return 1; } /* remember the base and length */ romdata.regionlength = memory_region_length(regiontype); romdata.regionbase = memory_region(regiontype); debugload("Allocated %X bytes @ %08X\n", romdata.regionlength, (int)romdata.regionbase); /* clear the region if it's requested */ if (ROMREGION_ISERASE(region)) memset(romdata.regionbase, ROMREGION_GETERASEVAL(region), romdata.regionlength); /* or if it's sufficiently small (<= 4MB) */ else if (romdata.regionlength <= 0x400000) memset(romdata.regionbase, 0, romdata.regionlength); #ifdef MAME_DEBUG /* if we're debugging, fill region with random data to catch errors */ else fill_random(romdata.regionbase, romdata.regionlength); #endif /* now process the entries in the region */ if (ROMREGION_ISROMDATA(region)) { if (!process_rom_entries(&romdata, region + 1)) return 1; } else if (ROMREGION_ISDISKDATA(region)) { if (!process_disk_entries(&romdata, region + 1)) return 1; } /* add this region to the list */ if (regiontype < REGION_MAX) regionlist[regiontype] = region; } /* post-process the regions */ for (regnum = 0; regnum < REGION_MAX; regnum++) if (regionlist[regnum]) { debugload("Post-processing region %02X\n", regnum); romdata.regionlength = memory_region_length(regnum); romdata.regionbase = memory_region(regnum); region_post_process(&romdata, regionlist[regnum]); } /* display the results and exit */ return display_rom_load_results(&romdata); }
static void print_game_rom(FILE* out, const game_driver* game) { const rom_entry *region, *rom, *chunk; const rom_entry *pregion, *prom, *fprom=NULL; const game_driver *clone_of; if (!game->rom) return; clone_of = driver_get_clone(game); for (region = rom_first_region(game); region; region = rom_next_region(region)) for (rom = rom_first_file(region); rom; rom = rom_next_file(rom)) { int offset, length, in_parent, is_disk, is_bios, found_bios, i; char name[100], bios_name[100]; strcpy(name,ROM_GETNAME(rom)); offset = ROM_GETOFFSET(rom); is_disk = ROMREGION_ISDISKDATA(region); is_bios = ROM_GETBIOSFLAGS(rom); in_parent = 0; length = 0; for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk)) length += ROM_GETLENGTH(chunk); if (!ROM_NOGOODDUMP(rom) && clone_of) { fprom=NULL; for (pregion = rom_first_region(clone_of); pregion; pregion = rom_next_region(pregion)) for (prom = rom_first_file(pregion); prom; prom = rom_next_file(prom)) if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0)) { if (!fprom || !strcmp(ROM_GETNAME(prom), name)) fprom=prom; in_parent = 1; } } found_bios = 0; if(!is_disk && is_bios && game->bios) { const bios_entry *thisbios = game->bios; /* Match against bios short names */ while(!found_bios && !BIOSENTRY_ISEND(thisbios) ) { if((is_bios-1) == thisbios->value) /* Note '-1' */ { strcpy(bios_name,thisbios->_name); found_bios = 1; } thisbios++; } } if (!is_disk) fprintf(out, "\t\t<rom"); else fprintf(out, "\t\t<disk"); if (*name) fprintf(out, " name=\"%s\"", normalize_string(name)); if (in_parent) fprintf(out, " merge=\"%s\"", normalize_string(ROM_GETNAME(fprom))); if (!is_disk && found_bios) fprintf(out, " bios=\"%s\"", normalize_string(bios_name)); if (!is_disk) fprintf(out, " size=\"%d\"", length); /* dump checksum information only if there is a known dump */ if (!hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) { for (i=0;i<HASH_NUM_FUNCTIONS;i++) { int func = 1<<i; const char* func_name = hash_function_name(func); char checksum[1000]; if (hash_data_extract_printable_checksum(ROM_GETHASHDATA(rom), func, checksum)) { fprintf(out, " %s=\"%s\"", func_name, checksum); } } } switch (ROMREGION_GETTYPE(region)) { case REGION_CPU1: fprintf(out, " region=\"cpu1\""); break; case REGION_CPU2: fprintf(out, " region=\"cpu2\""); break; case REGION_CPU3: fprintf(out, " region=\"cpu3\""); break; case REGION_CPU4: fprintf(out, " region=\"cpu4\""); break; case REGION_CPU5: fprintf(out, " region=\"cpu5\""); break; case REGION_CPU6: fprintf(out, " region=\"cpu6\""); break; case REGION_CPU7: fprintf(out, " region=\"cpu7\""); break; case REGION_CPU8: fprintf(out, " region=\"cpu8\""); break; case REGION_GFX1: fprintf(out, " region=\"gfx1\""); break; case REGION_GFX2: fprintf(out, " region=\"gfx2\""); break; case REGION_GFX3: fprintf(out, " region=\"gfx3\""); break; case REGION_GFX4: fprintf(out, " region=\"gfx4\""); break; case REGION_GFX5: fprintf(out, " region=\"gfx5\""); break; case REGION_GFX6: fprintf(out, " region=\"gfx6\""); break; case REGION_GFX7: fprintf(out, " region=\"gfx7\""); break; case REGION_GFX8: fprintf(out, " region=\"gfx8\""); break; case REGION_PROMS: fprintf(out, " region=\"proms\""); break; case REGION_SOUND1: fprintf(out, " region=\"sound1\""); break; case REGION_SOUND2: fprintf(out, " region=\"sound2\""); break; case REGION_SOUND3: fprintf(out, " region=\"sound3\""); break; case REGION_SOUND4: fprintf(out, " region=\"sound4\""); break; case REGION_SOUND5: fprintf(out, " region=\"sound5\""); break; case REGION_SOUND6: fprintf(out, " region=\"sound6\""); break; case REGION_SOUND7: fprintf(out, " region=\"sound7\""); break; case REGION_SOUND8: fprintf(out, " region=\"sound8\""); break; case REGION_USER1: fprintf(out, " region=\"user1\""); break; case REGION_USER2: fprintf(out, " region=\"user2\""); break; case REGION_USER3: fprintf(out, " region=\"user3\""); break; case REGION_USER4: fprintf(out, " region=\"user4\""); break; case REGION_USER5: fprintf(out, " region=\"user5\""); break; case REGION_USER6: fprintf(out, " region=\"user6\""); break; case REGION_USER7: fprintf(out, " region=\"user7\""); break; case REGION_USER8: fprintf(out, " region=\"user8\""); break; case REGION_DISKS: fprintf(out, " region=\"disks\""); break; default: fprintf(out, " region=\"0x%x\"", ROMREGION_GETTYPE(region)); } if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_NO_DUMP)) fprintf(out, " status=\"nodump\""); if (hash_data_has_info(ROM_GETHASHDATA(rom), HASH_INFO_BAD_DUMP)) fprintf(out, " status=\"baddump\""); if (!is_disk) { if (ROMREGION_GETFLAGS(region) & ROMREGION_DISPOSE) fprintf(out, " dispose=\"yes\""); fprintf(out, " offset=\"%x\"", offset); fprintf(out, "/>\n"); } else { fprintf(out, " index=\"%x\"", DISK_GETINDEX(rom)); fprintf(out, "/>\n"); } } }
void rom_init(running_machine *machine, const rom_entry *romp) { const rom_entry *regionlist[REGION_MAX]; const rom_entry *region; static rom_load_data romdata; int regnum; /* if no roms, bail */ if (romp == NULL) return; /* make sure we get called back on the way out */ add_exit_callback(machine, rom_exit); /* reset the region list */ memset((void *)regionlist, 0, sizeof(regionlist)); /* reset the romdata struct */ memset(&romdata, 0, sizeof(romdata)); romdata.romstotal = count_roms(romp); /* reset the disk list */ memset(disk_handle, 0, sizeof(disk_handle)); /* determine the correct biosset to load based on options.bios string */ system_bios = determine_bios_rom(Machine->gamedrv->bios); /* loop until we hit the end */ for (region = romp, regnum = 0; region; region = rom_next_region(region), regnum++) { int regiontype = ROMREGION_GETTYPE(region); debugload("Processing region %02X (length=%X)\n", regiontype, ROMREGION_GETLENGTH(region)); /* the first entry must be a region */ assert(ROMENTRY_ISREGION(region)); /* remember the base and length */ romdata.regionbase = new_memory_region(machine, regiontype, ROMREGION_GETLENGTH(region), ROMREGION_GETFLAGS(region)); romdata.regionlength = ROMREGION_GETLENGTH(region); debugload("Allocated %X bytes @ %08X\n", romdata.regionlength, (int)romdata.regionbase); /* clear the region if it's requested */ if (ROMREGION_ISERASE(region)) memset(romdata.regionbase, ROMREGION_GETERASEVAL(region), romdata.regionlength); /* or if it's sufficiently small (<= 4MB) */ else if (romdata.regionlength <= 0x400000) memset(romdata.regionbase, 0, romdata.regionlength); #ifdef MAME_DEBUG /* if we're debugging, fill region with random data to catch errors */ else fill_random(romdata.regionbase, romdata.regionlength); #endif /* now process the entries in the region */ if (ROMREGION_ISROMDATA(region)) process_rom_entries(&romdata, region + 1); else if (ROMREGION_ISDISKDATA(region)) process_disk_entries(&romdata, region + 1); /* add this region to the list */ if (regiontype < REGION_MAX) regionlist[regiontype] = region; } /* post-process the regions */ for (regnum = 0; regnum < REGION_MAX; regnum++) if (regionlist[regnum]) { debugload("Post-processing region %02X\n", regnum); romdata.regionlength = memory_region_length(regnum); romdata.regionbase = memory_region(regnum); region_post_process(&romdata, regionlist[regnum]); } /* display the results and exit */ total_rom_load_warnings = romdata.warnings; display_rom_load_results(&romdata); }
static int load_cartridge(const rom_entry *romrgn, const rom_entry *roment, mame_file *file) { UINT32 region, flags; offs_t offset, length, read_length, pos = 0, len; UINT8 *ptr; UINT8 clear_val; int type, datawidth, littleendian, i, j; region = ROMREGION_GETTYPE(romrgn); offset = ROM_GETOFFSET(roment); length = ROM_GETLENGTH(roment); flags = ROM_GETFLAGS(roment); ptr = ((UINT8 *) memory_region(region)) + offset; if (file) { /* must this be full size */ if (flags & ROM_FULLSIZE) { if (mame_fsize(file) != length) return INIT_FAIL; } /* read the ROM */ pos = read_length = mame_fread(file, ptr, length); /* do we need to mirror the ROM? */ if (flags & ROM_MIRROR) { while(pos < length) { len = MIN(read_length, length - pos); memcpy(ptr + pos, ptr, len); pos += len; } } /* postprocess this region */ type = ROMREGION_GETTYPE(romrgn); littleendian = ROMREGION_ISLITTLEENDIAN(romrgn); datawidth = ROMREGION_GETWIDTH(romrgn) / 8; /* if the region is inverted, do that now */ if (type >= REGION_CPU1 && type < REGION_CPU1 + MAX_CPU) { int cputype = Machine->drv->cpu[type - REGION_CPU1].cpu_type; if (cputype != 0) { datawidth = cputype_databus_width(cputype, ADDRESS_SPACE_PROGRAM) / 8; littleendian = (cputype_endianness(cputype) == CPU_IS_LE); } } /* swap the endianness if we need to */ #ifdef LSB_FIRST if (datawidth > 1 && !littleendian) #else if (datawidth > 1 && littleendian) #endif { for (i = 0; i < length; i += datawidth) { UINT8 temp[8]; memcpy(temp, &ptr[i], datawidth); for (j = datawidth - 1; j >= 0; j--) ptr[i + j] = temp[datawidth - 1 - j]; } } } /* clear out anything that remains */ if (!(flags & ROM_NOCLEAR)) { clear_val = (flags & ROM_FILL_FF) ? 0xFF : 0x00; memset(ptr + pos, clear_val, length - pos); } return INIT_PASS; }