Added concept of rom sources to the rom loader. Updated auditing,

CLI utilities, validity checks, and ROM loading to use these new
functions so that device-specific ROMs are handled properly.
This commit is contained in:
Aaron Giles 2008-09-06 22:17:37 +00:00
parent 7097684ac8
commit c0b1419a96
6 changed files with 323 additions and 207 deletions

View File

@ -22,7 +22,7 @@
FUNCTION PROTOTYPES
***************************************************************************/
static int audit_one_rom(core_options *options, const rom_entry *rom, const game_driver *gamedrv, UINT32 validation, audit_record *record);
static int audit_one_rom(core_options *options, const rom_entry *rom, const char *regiontag, const game_driver *gamedrv, UINT32 validation, audit_record *record);
static int audit_one_disk(core_options *options, const rom_entry *rom, const game_driver *gamedrv, UINT32 validation, audit_record *record);
static int rom_used_by_parent(const game_driver *gamedrv, const rom_entry *romentry, const game_driver **parent);
@ -56,7 +56,9 @@ INLINE void set_status(audit_record *record, UINT8 status, UINT8 substatus)
int audit_images(core_options *options, const game_driver *gamedrv, UINT32 validation, audit_record **audit)
{
machine_config *config = machine_config_alloc(gamedrv->machine_config);
const rom_entry *region, *rom;
const rom_source *source;
audit_record *record;
int foundany = FALSE;
int allshared = TRUE;
@ -64,14 +66,18 @@ int audit_images(core_options *options, const game_driver *gamedrv, UINT32 valid
/* determine the number of records we will generate */
records = 0;
for (region = rom_first_region(gamedrv); region != NULL; region = rom_next_region(region))
for (source = rom_first_source(gamedrv, config); source != NULL; source = rom_next_source(gamedrv, config, source))
{
int source_is_gamedrv = rom_source_is_gamedrv(gamedrv, source);
for (region = rom_first_region(gamedrv, source); region != NULL; region = rom_next_region(region))
for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
if (ROMREGION_ISROMDATA(region) || ROMREGION_ISDISKDATA(region))
{
if (allshared && !rom_used_by_parent(gamedrv, rom, NULL))
if (source_is_gamedrv && allshared && !rom_used_by_parent(gamedrv, rom, NULL))
allshared = FALSE;
records++;
}
}
if (records > 0)
{
@ -80,8 +86,13 @@ int audit_images(core_options *options, const game_driver *gamedrv, UINT32 valid
memset(*audit, 0, sizeof(**audit) * records);
record = *audit;
/* iterate over regions and ROMs */
for (region = rom_first_region(gamedrv); region; region = rom_next_region(region))
/* iterate over ROM sources and regions */
for (source = rom_first_source(gamedrv, config); source != NULL; source = rom_next_source(gamedrv, config, source))
{
int source_is_gamedrv = rom_source_is_gamedrv(gamedrv, source);
for (region = rom_first_region(gamedrv, source); region != NULL; region = rom_next_region(region))
{
const char *regiontag = ROMREGION_ISLOADBYNAME(region) ? ROM_GETNAME(region) : NULL;
for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
{
int shared = rom_used_by_parent(gamedrv, rom, NULL);
@ -89,26 +100,31 @@ int audit_images(core_options *options, const game_driver *gamedrv, UINT32 valid
/* audit a file */
if (ROMREGION_ISROMDATA(region))
{
if (audit_one_rom(options, rom, gamedrv, validation, record++) && (!shared || allshared))
if (audit_one_rom(options, rom, regiontag, gamedrv, validation, record++) && source_is_gamedrv && (!shared || allshared))
foundany = TRUE;
}
/* audit a disk */
else if (ROMREGION_ISDISKDATA(region))
{
if (audit_one_disk(options, rom, gamedrv, validation, record++) && (!shared || allshared))
if (audit_one_disk(options, rom, gamedrv, validation, record++) && source_is_gamedrv && (!shared || allshared))
foundany = TRUE;
}
}
}
/* if we found nothing, we don't have the set at all */
if (!foundany)
if (rom_source_is_gamedrv(gamedrv, source) && !foundany)
{
free(*audit);
*audit = NULL;
records = 0;
break;
}
}
}
machine_config_free(config);
return records;
}
@ -310,7 +326,7 @@ int audit_summary(const game_driver *gamedrv, int count, const audit_record *rec
audit_one_rom - validate a single ROM entry
-------------------------------------------------*/
static int audit_one_rom(core_options *options, const rom_entry *rom, const game_driver *gamedrv, UINT32 validation, audit_record *record)
static int audit_one_rom(core_options *options, const rom_entry *rom, const char *regiontag, const game_driver *gamedrv, UINT32 validation, audit_record *record)
{
const game_driver *drv;
const rom_entry *chunk;
@ -322,6 +338,7 @@ static int audit_one_rom(core_options *options, const rom_entry *rom, const game
record->type = AUDIT_FILE_ROM;
record->name = ROM_GETNAME(rom);
record->exphash = ROM_GETHASHDATA(rom);
record->length = 0;
/* compute the expected length by summing the chunks */
for (chunk = rom_first_chunk(rom); chunk; chunk = rom_next_chunk(chunk))
@ -357,8 +374,32 @@ static int audit_one_rom(core_options *options, const rom_entry *rom, const game
}
}
/* if not found, check the region as a backup */
if (record->length == 0 && regiontag != NULL)
{
file_error filerr;
mame_file *file;
astring *fname;
/* open the file if we can */
fname = astring_assemble_3(astring_alloc(), regiontag, PATH_SEPARATOR, ROM_GETNAME(rom));
if (has_crc)
filerr = mame_fopen_crc_options(options, SEARCHPATH_ROM, astring_c(fname), crc, OPEN_FLAG_READ, &file);
else
filerr = mame_fopen_options(options, SEARCHPATH_ROM, astring_c(fname), OPEN_FLAG_READ, &file);
astring_free(fname);
/* if we got it, extract the hash and length */
if (filerr == FILERR_NONE)
{
hash_data_copy(record->hash, mame_fhash(file, validation));
record->length = (UINT32)mame_fsize(file);
mame_fclose(file);
}
}
/* if we failed to find the file, set the appropriate status */
if (drv == NULL)
if (record->length == 0)
{
const game_driver *parent;
@ -496,7 +537,7 @@ static int rom_used_by_parent(const game_driver *gamedrv, const rom_entry *romen
const rom_entry *rom;
/* see if the parent has the same ROM or not */
for (region = rom_first_region(drv); region; region = rom_next_region(region))
for (region = rom_first_region(drv, NULL); region; region = rom_next_region(region))
for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
if (hash_data_is_equal(ROM_GETHASHDATA(rom), hash, 0))
{

View File

@ -446,10 +446,13 @@ int cli_info_listcrc(core_options *options, const char *gamename)
for (drvindex = 0; drivers[drvindex]; drvindex++)
if (mame_strwildcmp(gamename, drivers[drvindex]->name) == 0)
{
machine_config *config = machine_config_alloc(drivers[drvindex]->machine_config);
const rom_entry *region, *rom;
const rom_source *source;
/* iterate over regions, and then ROMs within the region */
for (region = rom_first_region(drivers[drvindex]); region; region = rom_next_region(region))
/* iterate over sources, regions, and then ROMs within the region */
for (source = rom_first_source(drivers[drvindex], config); source != NULL; source = rom_next_source(drivers[drvindex], config, source))
for (region = rom_first_region(drivers[drvindex], source); region; region = rom_next_region(region))
for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
{
char hashbuf[HASH_BUF_SIZE];
@ -460,6 +463,7 @@ int cli_info_listcrc(core_options *options, const char *gamename)
}
count++;
machine_config_free(config);
}
/* return an error if none found */
@ -962,10 +966,13 @@ static void match_roms(const char *hash, int length, int *found)
/* iterate over drivers */
for (drvindex = 0; drivers[drvindex]; drvindex++)
{
machine_config *config = machine_config_alloc(drivers[drvindex]->machine_config);
const rom_entry *region, *rom;
const rom_source *source;
/* iterate over regions and files within the region */
for (region = rom_first_region(drivers[drvindex]); region; region = rom_next_region(region))
/* iterate over sources, regions and files within the region */
for (source = rom_first_source(drivers[drvindex], config); source != NULL; source = rom_next_source(drivers[drvindex], config, source))
for (region = rom_first_region(drivers[drvindex], source); region; region = rom_next_region(region))
for (rom = rom_first_file(region); rom; rom = rom_next_file(rom))
if (hash_data_is_equal(hash, ROM_GETHASHDATA(rom), 0))
{
@ -977,5 +984,7 @@ static void match_roms(const char *hash, int length, int *found)
mame_printf_info("= %s%-20s %s\n", baddump ? "(BAD) " : "", ROM_GETNAME(rom), drivers[drvindex]->description);
(*found)++;
}
machine_config_free(config);
}
}

View File

@ -357,22 +357,20 @@ static void print_game_bios(FILE *out, const game_driver *game)
the XML output
-------------------------------------------------*/
static void print_game_rom(FILE *out, const game_driver *game)
static void print_game_rom(FILE *out, const game_driver *game, const machine_config *config)
{
const game_driver *clone_of = driver_get_clone(game);
int rom_type;
/* if no roms, just exit early */
if (game->rom == NULL)
return;
/* iterate over 3 different ROM "types": BIOS, ROMs, DISKs */
for (rom_type = 0; rom_type < 3; rom_type++)
{
const rom_source *source;
const rom_entry *region;
/* iterate first through regions */
for (region = rom_first_region(game); region != NULL; region = rom_next_region(region))
/* iterate over ROM sources: first the game, then any devices */
for (source = rom_first_source(game, config); source != NULL; source = rom_next_source(game, config, source))
for (region = rom_first_region(game, source); region != NULL; region = rom_next_region(region))
{
int is_disk = ROMREGION_ISDISKDATA(region);
const rom_entry *rom;
@ -407,7 +405,7 @@ static void print_game_rom(FILE *out, const game_driver *game)
const rom_entry *pregion, *prom;
/* scan the clone_of ROM for a matching ROM entry */
for (pregion = rom_first_region(clone_of); pregion != NULL; pregion = rom_next_region(pregion))
for (pregion = rom_first_region(clone_of, NULL); pregion != NULL; pregion = rom_next_region(pregion))
for (prom = rom_first_file(pregion); prom != NULL; prom = rom_next_file(prom))
if (hash_data_is_equal(ROM_GETHASHDATA(rom), ROM_GETHASHDATA(prom), 0))
{
@ -843,7 +841,7 @@ static void print_game_info(FILE *out, const game_driver *game)
/* now print various additional information */
print_game_bios(out, game);
print_game_rom(out, game);
print_game_rom(out, game, config);
print_game_sample(out, game, config);
print_game_chips(out, game, config);
print_game_display(out, game, config);

View File

@ -99,14 +99,84 @@ void set_disk_handle(const char *region, mame_file *file, chd_file *chdfile)
ROM LOADING
***************************************************************************/
/*-------------------------------------------------
rom_source_is_gamedrv - return TRUE if the
given rom_source refers to the game driver
itself
-------------------------------------------------*/
int rom_source_is_gamedrv(const game_driver *drv, const rom_source *source)
{
return ((const game_driver *)source == drv);
}
/*-------------------------------------------------
rom_first_source - return pointer to first ROM
source
-------------------------------------------------*/
const rom_source *rom_first_source(const game_driver *drv, const machine_config *config)
{
const device_config *device;
/* if the driver has a ROM pointer, that's what we want */
if (drv->rom != NULL)
return (rom_source *)drv;
/* otherwise, look through devices */
if (config != NULL)
for (device = config->devicelist; device != NULL; device = device->next)
{
const rom_entry *devromp = device_get_info_ptr(device, DEVINFO_PTR_ROM_REGION);
if (devromp != NULL)
return (rom_source *)device;
}
return NULL;
}
/*-------------------------------------------------
rom_next_source - return pointer to next ROM
source
-------------------------------------------------*/
const rom_source *rom_next_source(const game_driver *drv, const machine_config *config, const rom_source *previous)
{
const device_config *device;
/* if the previous was the driver, we want the first device */
if (rom_source_is_gamedrv(drv, previous))
device = (config != NULL) ? config->devicelist : NULL;
else
device = ((const device_config *)previous)->next;
/* look for further devices with ROM definitions */
for ( ; device != NULL; device = device->next)
{
const rom_entry *devromp = device_get_info_ptr(device, DEVINFO_PTR_ROM_REGION);
if (devromp != NULL)
return (rom_source *)device;
}
return NULL;
}
/*-------------------------------------------------
rom_first_region - return pointer to first ROM
region
-------------------------------------------------*/
const rom_entry *rom_first_region(const game_driver *drv)
const rom_entry *rom_first_region(const game_driver *drv, const rom_source *source)
{
return (drv->rom != NULL && !ROMENTRY_ISEND(drv->rom)) ? drv->rom : NULL;
const rom_entry *romp;
if (source == NULL || rom_source_is_gamedrv(drv, source))
romp = drv->rom;
else
romp = device_get_info_ptr((const device_config *)source, DEVINFO_PTR_ROM_REGION);
return (romp != NULL && !ROMENTRY_ISEND(romp)) ? romp : NULL;
}
@ -868,6 +938,7 @@ chd_error open_disk_image_options(core_options *options, const game_driver *game
{
const game_driver *drv, *searchdrv;
const rom_entry *region, *rom;
const rom_source *source;
file_error filerr;
chd_error err;
@ -901,7 +972,8 @@ chd_error open_disk_image_options(core_options *options, const game_driver *game
/* otherwise, look at our parents for a CHD with an identical checksum */
/* and try to open that */
for (drv = gamedrv; drv != NULL; drv = driver_get_clone(drv))
for (region = rom_first_region(drv); region != NULL; region = rom_next_region(region))
for (source = rom_first_source(drv, NULL); source != NULL; source = rom_next_source(drv, NULL, source))
for (region = rom_first_region(drv, source); region != NULL; region = rom_next_region(region))
if (ROMREGION_ISDISKDATA(region))
for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))

View File

@ -126,6 +126,9 @@ enum
TYPE DEFINITIONS
***************************************************************************/
typedef struct _rom_source rom_source;
typedef struct _rom_entry rom_entry;
struct _rom_entry
{
@ -290,12 +293,14 @@ void set_disk_handle(const char *region, mame_file *file, chd_file *chd);
/* ROM processing */
void rom_init(running_machine *machine, const rom_entry *romp);
int rom_load_warnings(void);
const rom_entry *rom_first_region(const game_driver *drv);
int rom_source_is_gamedrv(const game_driver *drv, const rom_source *source);
const rom_source *rom_first_source(const game_driver *drv, const machine_config *config);
const rom_source *rom_next_source(const game_driver *drv, const machine_config *config, const rom_source *previous);
const rom_entry *rom_first_region(const game_driver *drv, const rom_source *romp);
const rom_entry *rom_next_region(const rom_entry *romp);
const rom_entry *rom_first_file(const rom_entry *romp);
const rom_entry *rom_next_file(const rom_entry *romp);
const rom_entry *rom_first_chunk(const rom_entry *romp);
const rom_entry *rom_next_chunk(const rom_entry *romp);
#endif /* __ROMLOAD_H__ */

View File

@ -504,23 +504,23 @@ static int validate_driver(int drivnum, const machine_config *config)
static int validate_roms(int drivnum, const machine_config *config, region_info *rgninfo)
{
const game_driver *driver = drivers[drivnum];
const device_config *device = NULL;
const rom_entry *romp;
const char *last_name = "???";
int error = FALSE;
int items_since_region = 1;
int bios_flags = 0, last_bios = 0;
const char *last_name = "???";
region_entry *currgn = NULL;
int items_since_region = 1;
const rom_source *source;
int error = FALSE;
/* reset region info */
memset(rgninfo, 0, sizeof(*rgninfo));
/* iterate, starting with the driver's ROMs and continuing with device ROMs */
romp = driver->rom;
while (romp != NULL)
for (source = rom_first_source(driver, config); source != NULL; source = rom_next_source(driver, config, source))
{
const rom_entry *romp;
/* scan the ROM entries */
for ( ; !ROMENTRY_ISEND(romp); romp++)
for (romp = rom_first_region(driver, source); !ROMENTRY_ISEND(romp); romp++)
{
/* if this is a region, make sure it's valid, and record the length */
if (ROMENTRY_ISREGION(romp))
@ -644,15 +644,6 @@ static int validate_roms(int drivnum, const machine_config *config, region_info
/* final check for empty regions */
if (items_since_region == 0)
mame_printf_warning("%s: %s has empty ROM region (warning)\n", driver->source_file, driver->name);
/* look for more devices with regions */
romp = NULL;
for (device = (device == NULL) ? config->devicelist : device->next; device != NULL; device = device->next)
{
romp = device_get_info_ptr(device, DEVINFO_PTR_ROM_REGION);
if (romp != NULL)
break;
}
}
return error;