39
39
friend class simple_list<open_chd>;
42
open_chd(const char *region, emu_file &file, chd_file &chdfile, emu_file *difffile = NULL, chd_file *diffchd = NULL)
42
open_chd(const char *region)
48
m_difffile(difffile) { }
52
if (m_diffchd != NULL) chd_close(m_diffchd);
53
global_free(m_difffile);
55
global_free(m_origfile);
58
46
open_chd *next() const { return m_next; }
59
47
const char *region() const { return m_region; }
60
chd_file *chd() const { return (m_diffchd != NULL) ? m_diffchd : m_origchd; }
48
chd_file &chd() { return m_diffchd.opened() ? m_diffchd : m_origchd; }
49
chd_file &orig_chd() { return m_origchd; }
50
chd_file &diff_chd() { return m_diffchd; }
63
53
open_chd * m_next; /* pointer to next in the list */
64
54
astring m_region; /* disk region we came from */
65
chd_file * m_origchd; /* handle to the original CHD */
66
emu_file * m_origfile; /* file handle to the original CHD file */
67
chd_file * m_diffchd; /* handle to the diff CHD */
68
emu_file * m_difffile; /* file handle to the diff CHD file */
55
chd_file m_origchd; /* handle to the original CHD */
56
chd_file m_diffchd; /* handle to the diff CHD */
106
92
HELPERS (also used by devimage.c)
107
93
***************************************************************************/
109
file_error common_process_file(emu_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file **image_file)
95
file_error common_process_file(emu_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file &image_file)
111
*image_file = global_alloc(emu_file(options.media_path(), OPEN_FLAG_READ));
112
97
file_error filerr;
114
99
if (location != NULL && strcmp(location, "") != 0)
115
filerr = (*image_file)->open(location, PATH_SEPARATOR, ROM_GETNAME(romp), ext);
100
filerr = image_file.open(location, PATH_SEPARATOR, ROM_GETNAME(romp), ext);
117
filerr = (*image_file)->open(ROM_GETNAME(romp), ext);
102
filerr = image_file.open(ROM_GETNAME(romp), ext);
119
if (filerr != FILERR_NONE)
121
global_free(*image_file);
166
146
file associated with the given region
167
147
-------------------------------------------------*/
169
void set_disk_handle(running_machine &machine, const char *region, emu_file &file, chd_file &chdfile)
149
int set_disk_handle(running_machine &machine, const char *region, const char *fullpath)
171
machine.romload_data->chd_list.append(*global_alloc(open_chd(region, file, chdfile)));
151
open_chd *chd = global_alloc(open_chd(region));
152
chd_error err = chd->orig_chd().open(fullpath);
153
if (err == CHDERR_NONE)
154
machine.romload_data->chd_list.append(*chd);
178
164
***************************************************************************/
180
166
/*-------------------------------------------------
181
rom_first_source - return pointer to first ROM
183
-------------------------------------------------*/
185
const rom_source *rom_first_source(const machine_config &config)
187
/* look through devices */
188
device_iterator iter(config.root_device());
189
for (const device_t *device = iter.first(); device != NULL; device = iter.next())
190
if (device->rom_region() != NULL)
197
/*-------------------------------------------------
198
rom_next_source - return pointer to next ROM
200
-------------------------------------------------*/
202
const rom_source *rom_next_source(const rom_source &previous)
204
/* look for further devices with ROM definitions */
205
// fixme: this is awful
206
device_iterator iter(previous.mconfig().root_device());
207
const device_t *device;
208
for (device = iter.first(); device != NULL; device = iter.next())
209
if (device == &previous)
212
for (device = iter.next(); device != NULL; device = iter.next())
213
if (device->rom_region() != NULL)
220
/*-------------------------------------------------
221
167
rom_first_region - return pointer to first ROM
223
169
-------------------------------------------------*/
225
const rom_entry *rom_first_region(const rom_source &source)
171
const rom_entry *rom_first_region(const device_t &device)
227
const rom_entry *romp = source.rom_region();
173
const rom_entry *romp = device.rom_region();
228
174
return (romp != NULL && !ROMENTRY_ISEND(romp)) ? romp : NULL;
277
223
-------------------------------------------------*/
279
astring &rom_region_name(astring &result, const game_driver *drv, const rom_source *source, const rom_entry *romp)
225
astring &rom_region_name(astring &result, const device_t &device, const rom_entry *romp)
281
return source->subtag(result, ROM_GETNAME(romp));
227
return device.subtag(result, ROM_GETNAME(romp));
344
290
int default_no = 1;
345
291
int bios_count = 0;
347
romdata->system_bios = 0;
349
for (const rom_source *source = rom_first_source(romdata->machine().config()); source != NULL; source = rom_next_source(*source))
294
device_t &rootdevice = romdata->machine().config().root_device();
295
rootdevice.set_system_bios(0);
296
/* first determine the default BIOS name */
297
for (rom = rootdevice.rom_region(); !ROMENTRY_ISEND(rom); rom++)
298
if (ROMENTRY_ISDEFAULT_BIOS(rom))
299
defaultname = ROM_GETNAME(rom);
301
/* look for a BIOS with a matching name */
302
for (rom = rootdevice.rom_region(); !ROMENTRY_ISEND(rom); rom++)
303
if (ROMENTRY_ISSYSTEM_BIOS(rom))
305
const char *biosname = ROM_GETNAME(rom);
306
int bios_flags = ROM_GETBIOSFLAGS(rom);
307
char bios_number[20];
309
/* Allow '-bios n' to still be used */
310
sprintf(bios_number, "%d", bios_flags - 1);
311
if (mame_stricmp(bios_number, specbios) == 0 || mame_stricmp(biosname, specbios) == 0)
312
rootdevice.set_system_bios(bios_flags);
313
if (defaultname != NULL && mame_stricmp(biosname, defaultname) == 0)
314
default_no = bios_flags;
318
/* if none found, use the default */
319
if (rootdevice.system_bios() == 0 && bios_count > 0)
351
/* first determine the default BIOS name */
352
for (rom = source->rom_region(); !ROMENTRY_ISEND(rom); rom++)
353
if (ROMENTRY_ISDEFAULT_BIOS(rom))
354
defaultname = ROM_GETNAME(rom);
356
/* look for a BIOS with a matching name */
357
for (rom = source->rom_region(); !ROMENTRY_ISEND(rom); rom++)
358
if (ROMENTRY_ISSYSTEM_BIOS(rom))
360
const char *biosname = ROM_GETNAME(rom);
361
int bios_flags = ROM_GETBIOSFLAGS(rom);
362
char bios_number[20];
364
/* Allow '-bios n' to still be used */
365
sprintf(bios_number, "%d", bios_flags - 1);
366
if (mame_stricmp(bios_number, specbios) == 0 || mame_stricmp(biosname, specbios) == 0)
367
romdata->system_bios = bios_flags;
368
if (defaultname != NULL && mame_stricmp(biosname, defaultname) == 0)
369
default_no = bios_flags;
373
/* if none found, use the default */
374
if (romdata->system_bios == 0 && bios_count > 0)
321
/* if we got neither an empty string nor 'default' then warn the user */
322
if (specbios[0] != 0 && strcmp(specbios, "default") != 0 && romdata != NULL)
376
/* if we got neither an empty string nor 'default' then warn the user */
377
if (specbios[0] != 0 && strcmp(specbios, "default") != 0 && romdata != NULL)
379
romdata->errorstring.catprintf("%s: invalid bios\n", specbios);
384
romdata->system_bios = default_no;
324
romdata->errorstring.catprintf("%s: invalid bios\n", specbios);
386
romdata->default_bios = default_no;
387
LOG(("Using System BIOS: %d\n", romdata->system_bios));
329
rootdevice.set_system_bios(default_no);
331
rootdevice.set_default_bios(default_no);
332
LOG(("Using System BIOS: %d\n", rootdevice.system_bios()));
397
341
static void count_roms(rom_load_data *romdata)
399
343
const rom_entry *region, *rom;
400
const rom_source *source;
402
345
/* start with 0 */
403
346
romdata->romstotal = 0;
404
347
romdata->romstotalsize = 0;
406
349
/* loop over regions, then over files */
407
for (source = rom_first_source(romdata->machine().config()); source != NULL; source = rom_next_source(*source))
408
for (region = rom_first_region(*source); region != NULL; region = rom_next_region(region))
350
device_iterator deviter(romdata->machine().config().root_device());
351
for (device_t *device = deviter.first(); device != NULL; device = deviter.next())
352
for (region = rom_first_region(*device); region != NULL; region = rom_next_region(region))
409
353
for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
410
if (ROM_GETBIOSFLAGS(rom) == 0 || ROM_GETBIOSFLAGS(rom) == romdata->system_bios)
354
if (ROM_GETBIOSFLAGS(rom) == 0 || ROM_GETBIOSFLAGS(rom) == romdata->machine().config().root_device().system_bios())
412
356
romdata->romstotal++;
413
357
romdata->romstotalsize += rom_file_size(rom);
1012
948
-------------------------------------------------*/
1014
chd_error open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_entry *romp, emu_file **image_file, chd_file **image_chd, const char *locationtag)
950
int open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_entry *romp, chd_file &image_chd, const char *locationtag)
952
emu_file image_file(options.media_path(), OPEN_FLAG_READ);
1016
953
const rom_entry *region, *rom;
1017
const rom_source *source;
1018
954
file_error filerr;
1024
957
/* attempt to open the properly named file, scanning up through parent directories */
1025
958
filerr = FILERR_NOT_FOUND;
1026
959
for (int searchdrv = driver_list::find(*gamedrv); searchdrv != -1 && filerr != FILERR_NONE; searchdrv = driver_list::clone(searchdrv))
1104
1037
/* did the file open succeed? */
1105
1038
if (filerr == FILERR_NONE)
1040
astring fullpath(image_file.fullpath());
1107
1043
/* try to open the CHD */
1108
err = chd_open_file(**image_file, CHD_OPEN_READ, NULL, image_chd);
1044
err = image_chd.open(fullpath);
1109
1045
if (err == CHDERR_NONE)
1112
/* close the file on failure */
1113
global_free(*image_file);
1117
1049
err = CHDERR_FILE_NOT_FOUND;
1122
1054
for (int drv = driver_list::find(*gamedrv); drv != -1; drv = driver_list::clone(drv))
1124
1056
machine_config config(driver_list::driver(drv), options);
1125
for (source = rom_first_source(config); source != NULL; source = rom_next_source(*source))
1126
for (region = rom_first_region(*source); region != NULL; region = rom_next_region(region))
1057
device_iterator deviter(config.root_device());
1058
for (device_t *device = deviter.first(); device != NULL; device = deviter.next())
1059
for (region = rom_first_region(*device); region != NULL; region = rom_next_region(region))
1127
1060
if (ROMREGION_ISDISKDATA(region))
1128
1061
for (rom = rom_first_file(region); rom != NULL; rom = rom_next_file(rom))
1142
1075
/* did the file open succeed? */
1143
1076
if (filerr == FILERR_NONE)
1078
astring fullpath(image_file.fullpath());
1145
1081
/* try to open the CHD */
1146
err = chd_open_file(**image_file, CHD_OPEN_READ, NULL, image_chd);
1082
err = image_chd.open(fullpath);
1147
1083
if (err == CHDERR_NONE)
1150
/* close the file on failure */
1151
global_free(*image_file);
1162
1093
open_disk_diff - open a DISK diff file
1163
1094
-------------------------------------------------*/
1165
static chd_error open_disk_diff(emu_options &options, const rom_entry *romp, chd_file *source, emu_file **diff_file, chd_file **diff_chd)
1096
static chd_error open_disk_diff(emu_options &options, const rom_entry *romp, chd_file &source, chd_file &diff_chd)
1167
1098
astring fname(ROM_GETNAME(romp), ".dif");
1173
1100
/* try to open the diff */
1174
1101
LOG(("Opening differencing image file: %s\n", fname.cstr()));
1175
*diff_file = global_alloc(emu_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE));
1176
file_error filerr = (*diff_file)->open(fname);
1177
if (filerr != FILERR_NONE)
1179
/* didn't work; try creating it instead */
1180
LOG(("Creating differencing image: %s\n", fname.cstr()));
1181
(*diff_file)->set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
1182
filerr = (*diff_file)->open(fname);
1183
if (filerr != FILERR_NONE)
1185
err = CHDERR_FILE_NOT_FOUND;
1102
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
1103
file_error filerr = diff_file.open(fname);
1104
if (filerr == FILERR_NONE)
1106
astring fullpath(diff_file.fullpath());
1109
LOG(("Opening differencing image file: %s\n", fullpath.cstr()));
1110
return diff_chd.open(fullpath, true, &source);
1113
/* didn't work; try creating it instead */
1114
LOG(("Creating differencing image: %s\n", fname.cstr()));
1115
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
1116
filerr = diff_file.open(fname);
1117
if (filerr == FILERR_NONE)
1119
astring fullpath(diff_file.fullpath());
1189
1122
/* create the CHD */
1190
err = chd_create_file(**diff_file, 0, 0, CHDCOMPRESSION_NONE, source);
1123
LOG(("Creating differencing image file: %s\n", fullpath.cstr()));
1124
chd_codec_type compression[4] = { CHD_CODEC_NONE };
1125
chd_error err = diff_chd.create(fullpath, source.logical_bytes(), source.hunk_bytes(), compression, source);
1191
1126
if (err != CHDERR_NONE)
1195
LOG(("Opening differencing image file: %s\n", fname.cstr()));
1196
err = chd_open_file(**diff_file, CHD_OPEN_READWRITE, source, diff_chd);
1197
if (err != CHDERR_NONE)
1201
if ((err != CHDERR_NONE) && (*diff_file != NULL))
1203
global_free(*diff_file);
1129
return diff_chd.clone_all_metadata(source);
1132
return CHDERR_FILE_NOT_FOUND;
1220
1146
/* handle files */
1221
1147
if (ROMENTRY_ISFILE(romp))
1149
open_chd *chd = global_alloc(open_chd(regiontag));
1223
1151
hash_collection hashes(ROM_GETHASHDATA(romp));
1227
1154
/* make the filename of the source */
1228
1155
astring filename(ROM_GETNAME(romp), ".chd");
1230
1157
/* first open the source drive */
1233
1158
LOG(("Opening disk image: %s\n", filename.cstr()));
1234
err = open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, &origfile, &origchd, locationtag);
1159
err = chd_error(open_disk_image(romdata->machine().options(), &romdata->machine().system(), romp, chd->orig_chd(), locationtag));
1235
1160
if (err != CHDERR_NONE)
1237
1162
if (err == CHDERR_FILE_NOT_FOUND)
1238
1163
romdata->errorstring.catprintf("%s NOT FOUND\n", filename.cstr());
1240
romdata->errorstring.catprintf("%s CHD ERROR: %s\n", filename.cstr(), chd_error_string(err));
1165
romdata->errorstring.catprintf("%s CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err));
1242
1167
/* if this is NO_DUMP, keep going, though the system may not be able to handle it */
1243
1168
if (hashes.flag(hash_collection::FLAG_NO_DUMP))
1270
1195
/* if not read-only, make the diff file */
1271
chd_file *diffchd = NULL;
1272
emu_file *difffile = NULL;
1273
1196
if (!DISK_ISREADONLY(romp))
1275
1198
/* try to open or create the diff */
1276
err = open_disk_diff(romdata->machine().options(), romp, origchd, &difffile, &diffchd);
1199
err = open_disk_diff(romdata->machine().options(), romp, chd->orig_chd(), chd->diff_chd());
1277
1200
if (err != CHDERR_NONE)
1279
romdata->errorstring.catprintf("%s DIFF CHD ERROR: %s\n", filename.cstr(), chd_error_string(err));
1202
romdata->errorstring.catprintf("%s DIFF CHD ERROR: %s\n", filename.cstr(), chd_file::error_string(err));
1280
1203
romdata->errors++;
1285
1209
/* we're okay, add to the list of disks */
1286
1210
LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp)));
1287
romdata->machine().romload_data->chd_list.append(*global_alloc(open_chd(regiontag, *origfile, *origchd, difffile, diffchd)));
1211
romdata->machine().romload_data->chd_list.append(*chd);
1401
1325
/* if this is a device region, override with the device width and endianness */
1402
1326
endianness_t endianness = ROMREGION_ISBIGENDIAN(region) ? ENDIANNESS_BIG : ENDIANNESS_LITTLE;
1403
1327
UINT8 width = ROMREGION_GETWIDTH(region) / 8;
1404
const memory_region *memregion = romdata->machine().region(regiontag);
1328
memory_region *memregion = romdata->machine().root_device().memregion(regiontag);
1405
1329
if (memregion != NULL)
1407
1331
if (romdata->machine().device(regiontag) != NULL)
1408
1332
normalize_flags_for_device(romdata->machine(), regiontag, width, endianness);
1410
1334
/* clear old region (todo: should be moved to an image unload function) */
1411
romdata->machine().region_free(memregion->name());
1335
romdata->machine().memory().region_free(memregion->name());
1414
1338
/* remember the base and length */
1415
romdata->region = romdata->machine().region_alloc(regiontag, regionlength, width, endianness);
1339
romdata->region = romdata->machine().memory().region_alloc(regiontag, regionlength, width, endianness);
1416
1340
LOG(("Allocated %X bytes @ %p\n", romdata->region->bytes(), romdata->region->base()));
1418
1342
/* clear the region if it's requested */
1454
1378
static void process_region_list(rom_load_data *romdata)
1456
1380
astring regiontag;
1457
const rom_source *source;
1458
const rom_entry *region;
1460
1382
/* loop until we hit the end */
1461
for (source = rom_first_source(romdata->machine().config()); source != NULL; source = rom_next_source(*source))
1462
for (region = rom_first_region(*source); region != NULL; region = rom_next_region(region))
1383
device_iterator deviter(romdata->machine().root_device());
1384
for (device_t *device = deviter.first(); device != NULL; device = deviter.next())
1385
for (const rom_entry *region = rom_first_region(*device); region != NULL; region = rom_next_region(region))
1464
1387
UINT32 regionlength = ROMREGION_GETLENGTH(region);
1466
rom_region_name(regiontag, &romdata->machine().system(), source, region);
1389
rom_region_name(regiontag, *device, region);
1467
1390
LOG(("Processing region \"%s\" (length=%X)\n", regiontag.cstr(), regionlength));
1469
1392
/* the first entry must be a region */
1478
1401
normalize_flags_for_device(romdata->machine(), regiontag, width, endianness);
1480
1403
/* remember the base and length */
1481
romdata->region = romdata->machine().region_alloc(regiontag, regionlength, width, endianness);
1404
romdata->region = romdata->machine().memory().region_alloc(regiontag, regionlength, width, endianness);
1482
1405
LOG(("Allocated %X bytes @ %p\n", romdata->region->bytes(), romdata->region->base()));
1484
1407
/* clear the region if it's requested */
1498
1421
/* now process the entries in the region */
1499
process_rom_entries(romdata, (source->shortname()!=NULL) ? source->shortname() : NULL, region, region + 1);
1422
process_rom_entries(romdata, device->shortname(), region, region + 1);
1501
1424
else if (ROMREGION_ISDISKDATA(region))
1502
1425
process_disk_entries(romdata, regiontag, region, region + 1, NULL);
1505
1428
/* now go back and post-process all the regions */
1506
for (source = rom_first_source(romdata->machine().config()); source != NULL; source = rom_next_source(*source))
1507
for (region = rom_first_region(*source); region != NULL; region = rom_next_region(region)) {
1508
rom_region_name(regiontag, &romdata->machine().system(), source, region);
1429
for (device_t *device = deviter.first(); device != NULL; device = deviter.next())
1430
for (const rom_entry *region = rom_first_region(*device); region != NULL; region = rom_next_region(region))
1432
rom_region_name(regiontag, *device, region);
1509
1433
region_post_process(romdata, regiontag, ROMREGION_ISINVERTED(region));
1576
1500
return machine.romload_data->knownbad;
1580
/*-------------------------------------------------
1581
rom_system_bios - return id of selected bios
1582
-------------------------------------------------*/
1584
int rom_system_bios(running_machine &machine)
1586
return machine.romload_data->system_bios;
1589
/*-------------------------------------------------
1590
rom_default_bios - return id of default bios
1591
-------------------------------------------------*/
1593
int rom_default_bios(running_machine &machine)
1595
return machine.romload_data->default_bios;