Fix -slot card,bios=rev (selected BIOS was being applied to slot itself, not card)

This commit is contained in:
Vas Crabb 2017-08-04 13:07:34 +10:00
parent 00f6156cbb
commit 152ce7a3d9
3 changed files with 64 additions and 51 deletions

View File

@ -455,7 +455,7 @@ public:
ioport_constructor input_ports() const { return device_input_ports(); }
u8 default_bios() const { return m_default_bios; }
u8 system_bios() const { return m_system_bios; }
std::string default_bios_tag() const { return m_default_bios_tag; }
const std::string &default_bios_tag() const { return m_default_bios_tag; }
// interface helpers
interface_list &interfaces() { return m_interfaces; }
@ -495,7 +495,7 @@ public:
void add_machine_configuration(machine_config &config) { device_add_mconfig(config); }
static void static_set_clock(device_t &device, u32 clock);
static void static_set_input_default(device_t &device, const input_device_default *config) { device.m_input_defaults = config; }
static void static_set_default_bios_tag(device_t &device, const char *tag) { std::string default_bios_tag(tag); device.m_default_bios_tag = default_bios_tag; }
static void static_set_default_bios_tag(device_t &device, const char *tag) { device.m_default_bios_tag = tag; }
// state helpers
void config_complete();

View File

@ -39,7 +39,7 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
const char *slot_option_name = owner.tag() + 1;
// figure out which device goes into this slot
bool has_option = options.has_slot_option(slot_option_name);
bool const has_option = options.has_slot_option(slot_option_name);
const char *selval;
bool is_default;
if (!has_option)
@ -59,15 +59,14 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
if (selval && *selval)
{
const device_slot_option *option = slot.option(selval);
device_slot_option const *const option = slot.option(selval);
if (option && (is_default || option->selectable()))
{
// create the device
device_t *new_dev = device_add(&owner, option->name(), option->devtype(), option->clock());
slot.set_card_device(new_dev);
const char *default_bios = option->default_bios();
char const *const default_bios = option->default_bios();
if (default_bios != nullptr)
device_t::static_set_default_bios_tag(*new_dev, default_bios);
@ -75,7 +74,7 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
if (additions != nullptr)
(*additions)(*this, new_dev, new_dev);
const input_device_default *input_device_defaults = option->input_device_defaults();
input_device_default const *const input_device_defaults = option->input_device_defaults();
if (input_device_defaults)
device_t::static_set_input_default(*new_dev, input_device_defaults);
}

View File

@ -15,7 +15,7 @@
#define LOG_LOAD 0
#define LOG(x) do { if (LOG_LOAD) debugload x; } while(0)
#define LOG(...) do { if (LOG_LOAD) debugload(__VA_ARGS__); } while(0)
/***************************************************************************
@ -267,39 +267,44 @@ int rom_load_manager::set_disk_handle(const char *region, const char *fullpath)
void rom_load_manager::determine_bios_rom(device_t &device, const char *specbios)
{
const char *defaultname = nullptr;
int default_no = 1;
int bios_count = 0;
device.set_system_bios(0);
/* first determine the default BIOS name */
char const *defaultname(nullptr);
for (const rom_entry &rom : device.rom_region_vector())
{
if (ROMENTRY_ISDEFAULT_BIOS(&rom))
{
defaultname = ROM_GETNAME(&rom);
break;
}
}
/* look for a BIOS with a matching name */
int bios_count = 0, default_no = 1;
for (const rom_entry &rom : device.rom_region_vector())
{
if (ROMENTRY_ISSYSTEM_BIOS(&rom))
{
const char *biosname = ROM_GETNAME(&rom);
int bios_flags = ROM_GETBIOSFLAGS(&rom);
char const *const biosname = ROM_GETNAME(&rom);
int const bios_flags = ROM_GETBIOSFLAGS(&rom);
char bios_number[20];
/* Allow '-bios n' to still be used */
sprintf(bios_number, "%d", bios_flags - 1);
if (core_stricmp(bios_number, specbios) == 0 || core_stricmp(biosname, specbios) == 0)
if (!core_stricmp(bios_number, specbios) || !core_stricmp(biosname, specbios))
device.set_system_bios(bios_flags);
if (defaultname != nullptr && core_stricmp(biosname, defaultname) == 0)
if (defaultname && !core_stricmp(biosname, defaultname))
default_no = bios_flags;
bios_count++;
}
}
/* if none found, use the default */
if (device.system_bios() == 0 && bios_count > 0)
{
/* if we got neither an empty string nor 'default' then warn the user */
if (specbios[0] != 0 && strcmp(specbios, "default") != 0)
if (specbios[0] && !core_stricmp(specbios, "default"))
{
m_errorstring.append(string_format("%s: invalid bios, reverting to default\n", specbios));
m_warnings++;
@ -309,7 +314,7 @@ void rom_load_manager::determine_bios_rom(device_t &device, const char *specbios
device.set_system_bios(default_no);
}
device.set_default_bios(default_no);
LOG(("For \"%s\" using System BIOS: %d\n", device.tag(), device.system_bios()));
LOG("For \"%s\" using System BIOS: %d\n", device.tag(), device.system_bios());
}
@ -516,13 +521,13 @@ void rom_load_manager::region_post_process(const char *rgntag, bool invert)
if (region == nullptr)
return;
LOG(("+ datawidth=%dbit endian=%s\n", region->bitwidth(),
region->endianness() == ENDIANNESS_LITTLE ? "little" : "big"));
LOG("+ datawidth=%dbit endian=%s\n", region->bitwidth(),
region->endianness() == ENDIANNESS_LITTLE ? "little" : "big");
/* if the region is inverted, do that now */
if (invert)
{
LOG(("+ Inverting region\n"));
LOG("+ Inverting region\n");
for (i = 0, base = region->base(); i < region->bytes(); i++)
*base++ ^= 0xff;
}
@ -530,7 +535,7 @@ void rom_load_manager::region_post_process(const char *rgntag, bool invert)
/* swap the endianness if we need to */
if (region->bytewidth() > 1 && region->endianness() != ENDIANNESS_NATIVE)
{
LOG(("+ Byte swapping region\n"));
LOG("+ Byte swapping region\n");
int datawidth = region->bytewidth();
for (i = 0, base = region->base(); i < region->bytes(); i += datawidth)
{
@ -698,7 +703,7 @@ int rom_load_manager::read_rom_data(const rom_entry *parent_region, const rom_en
u32 tempbufsize;
int i;
LOG(("Loading ROM data: offs=%X len=%X mask=%02X group=%d skip=%d reverse=%d\n", ROM_GETOFFSET(romp), numbytes, datamask, groupsize, skip, reversed));
LOG("Loading ROM data: offs=%X len=%X mask=%02X group=%d skip=%d reverse=%d\n", ROM_GETOFFSET(romp), numbytes, datamask, groupsize, skip, reversed);
/* make sure the length was an even multiple of the group size */
if (numbytes % groupsize != 0)
@ -729,12 +734,12 @@ int rom_load_manager::read_rom_data(const rom_entry *parent_region, const rom_en
u8 *bufptr = &tempbuf[0];
/* read as much as we can */
LOG((" Reading %X bytes into buffer\n", bytesleft));
LOG(" Reading %X bytes into buffer\n", bytesleft);
if (rom_fread(bufptr, bytesleft, parent_region) != bytesleft)
return 0;
numbytes -= bytesleft;
LOG((" Copying to %p\n", base));
LOG(" Copying to %p\n", base);
/* unmasked cases */
if (datamask == 0xff)
@ -791,7 +796,7 @@ int rom_load_manager::read_rom_data(const rom_entry *parent_region, const rom_en
}
}
LOG((" All done\n"));
LOG(" All done\n");
return ROM_GETLENGTH(romp);
}
@ -901,7 +906,7 @@ void rom_load_manager::process_rom_entries(const char *regiontag, const rom_entr
int explength = 0;
/* open the file if it is a non-BIOS or matches the current BIOS */
LOG(("Opening ROM file: %s\n", ROM_GETNAME(romp)));
LOG("Opening ROM file: %s\n", ROM_GETNAME(romp));
std::string tried_file_names;
if (!irrelevantbios && !open_rom_file(regiontag, romp, tried_file_names, from_list))
handle_missing_file(romp, tried_file_names, CHDERR_NONE);
@ -932,9 +937,9 @@ void rom_load_manager::process_rom_entries(const char *regiontag, const rom_entr
/* if this was the first use of this file, verify the length and CRC */
if (baserom)
{
LOG(("Verifying length (%X) and checksums\n", explength));
LOG("Verifying length (%X) and checksums\n", explength);
verify_length_and_hash(ROM_GETNAME(baserom), explength, util::hash_collection(ROM_GETHASHDATA(baserom)));
LOG(("Verify finished\n"));
LOG("Verify finished\n");
}
/* reseek to the start and clear the baserom so we don't reverify */
@ -948,7 +953,7 @@ void rom_load_manager::process_rom_entries(const char *regiontag, const rom_entr
/* close the file */
if (m_file != nullptr)
{
LOG(("Closing ROM file\n"));
LOG("Closing ROM file\n");
m_file = nullptr;
}
}
@ -1144,7 +1149,7 @@ chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry
std::string fname = std::string(ROM_GETNAME(romp)).append(".dif");
/* try to open the diff */
LOG(("Opening differencing image file: %s\n", fname.c_str()));
LOG("Opening differencing image file: %s\n", fname.c_str());
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
osd_file::error filerr = diff_file.open(fname.c_str());
if (filerr == osd_file::error::NONE)
@ -1152,12 +1157,12 @@ chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry
std::string fullpath(diff_file.fullpath());
diff_file.close();
LOG(("Opening differencing image file: %s\n", fullpath.c_str()));
LOG("Opening differencing image file: %s\n", fullpath.c_str());
return diff_chd.open(fullpath.c_str(), true, &source);
}
/* didn't work; try creating it instead */
LOG(("Creating differencing image: %s\n", fname.c_str()));
LOG("Creating differencing image: %s\n", fname.c_str());
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
filerr = diff_file.open(fname.c_str());
if (filerr == osd_file::error::NONE)
@ -1166,7 +1171,7 @@ chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry
diff_file.close();
/* create the CHD */
LOG(("Creating differencing image file: %s\n", fullpath.c_str()));
LOG("Creating differencing image file: %s\n", fullpath.c_str());
chd_codec_type compression[4] = { CHD_CODEC_NONE };
chd_error err = diff_chd.create(fullpath.c_str(), source.logical_bytes(), source.hunk_bytes(), compression, source);
if (err != CHDERR_NONE)
@ -1201,7 +1206,7 @@ void rom_load_manager::process_disk_entries(const char *regiontag, const rom_ent
std::string filename = std::string(ROM_GETNAME(romp)).append(".chd");
/* first open the source drive */
LOG(("Opening disk image: %s\n", filename.c_str()));
LOG("Opening disk image: %s\n", filename.c_str());
err = chd_error(open_disk_image(machine().options(), &machine().system(), romp, chd->orig_chd(), locationtag));
if (err != CHDERR_NONE)
{
@ -1242,7 +1247,7 @@ void rom_load_manager::process_disk_entries(const char *regiontag, const rom_ent
}
/* we're okay, add to the list of disks */
LOG(("Assigning to handle %d\n", DISK_GETINDEX(romp)));
LOG("Assigning to handle %d\n", DISK_GETINDEX(romp));
m_chd_list.push_back(std::move(chd));
}
}
@ -1345,7 +1350,7 @@ void rom_load_manager::load_software_part_region(device_t &device, software_list
u32 regionlength = ROMREGION_GETLENGTH(region);
regiontag = device.subtag(ROMREGION_GETTAG(region));
LOG(("Processing region \"%s\" (length=%X)\n", regiontag.c_str(), regionlength));
LOG("Processing region \"%s\" (length=%X)\n", regiontag.c_str(), regionlength);
/* the first entry must be a region */
assert(ROMENTRY_ISREGION(region));
@ -1365,7 +1370,7 @@ void rom_load_manager::load_software_part_region(device_t &device, software_list
/* remember the base and length */
m_region = machine().memory().region_alloc(regiontag.c_str(), regionlength, width, endianness);
LOG(("Allocated %X bytes @ %p\n", m_region->bytes(), m_region->base()));
LOG("Allocated %X bytes @ %p\n", m_region->bytes(), m_region->base());
/* clear the region if it's requested */
if (ROMREGION_ISERASE(region))
@ -1423,7 +1428,7 @@ void rom_load_manager::process_region_list()
u32 regionlength = ROMREGION_GETLENGTH(region);
regiontag = rom_region_name(device, region);
LOG(("Processing region \"%s\" (length=%X)\n", regiontag.c_str(), regionlength));
LOG("Processing region \"%s\" (length=%X)\n", regiontag.c_str(), regionlength);
/* the first entry must be a region */
assert(ROMENTRY_ISREGION(region));
@ -1438,7 +1443,7 @@ void rom_load_manager::process_region_list()
/* remember the base and length */
m_region = machine().memory().region_alloc(regiontag.c_str(), regionlength, width, endianness);
LOG(("Allocated %X bytes @ %p\n", m_region->bytes(), m_region->base()));
LOG("Allocated %X bytes @ %p\n", m_region->bytes(), m_region->base());
/* clear the region if it's requested */
if (ROMREGION_ISERASE(region))
@ -1488,24 +1493,33 @@ rom_load_manager::rom_load_manager(running_machine &machine)
: m_machine(machine)
{
/* figure out which BIOS we are using */
std::map<std::string, std::string> card_bios;
for (device_t &device : device_iterator(machine.config().root_device()))
{
device_slot_interface const *const slot(dynamic_cast<device_slot_interface *>(&device));
if (slot)
{
device_t const *const card(slot->get_card_device());
slot_option const &slot_opt(machine.options().slot_option(slot->slot_name()));
if (card && !slot_opt.bios().empty())
card_bios.emplace(std::make_pair(std::string(card->tag()), slot_opt.bios()));
}
if (device.rom_region())
{
std::string specbios;
if (device.owner() == nullptr)
specbios.assign(machine.options().bios());
if (!device.owner())
{
specbios = machine.options().bios();
}
else
{
const device_slot_interface *slot = dynamic_cast<const device_slot_interface *>(&device);
const slot_option *slot_opt = slot
? &machine.options().slot_option(slot->slot_name())
: nullptr;
specbios = slot_opt && !slot_opt->bios().empty()
? slot_opt->bios().c_str()
: device.default_bios_tag();
auto const found(card_bios.find(device.tag()));
if (card_bios.end() != found)
{
specbios = std::move(found->second);
card_bios.erase(found);
}
}
determine_bios_rom(device, specbios.c_str());
}