diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/bus/intv/slot.cpp | 2 | ||||
-rw-r--r-- | src/emu/diimage.cpp | 26 | ||||
-rw-r--r-- | src/emu/romload.cpp | 189 | ||||
-rw-r--r-- | src/emu/romload.h | 5 | ||||
-rw-r--r-- | src/emu/softlist_dev.cpp | 140 | ||||
-rw-r--r-- | src/emu/validity.cpp | 2 | ||||
-rw-r--r-- | src/frontend/mame/audit.cpp | 28 | ||||
-rw-r--r-- | src/mame/drivers/gsword.cpp | 2 |
8 files changed, 195 insertions, 199 deletions
diff --git a/src/devices/bus/intv/slot.cpp b/src/devices/bus/intv/slot.cpp index 0adca238eb1..c0c39d5613d 100644 --- a/src/devices/bus/intv/slot.cpp +++ b/src/devices/bus/intv/slot.cpp @@ -385,7 +385,7 @@ image_init_result intv_cart_slot_device::call_load() else { uint16_t offset[] = { 0x400, 0x2000, 0x4000, 0x4800, 0x5000, 0x6000, 0x7000, 0x8000, 0x8800, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000}; - const char* region_name[] = {"0400", "2000", "4000", "4800", "5000", "6000", "7000", "8000", "8800", "9000", "A000", "B000", "C000", "D000", "E000", "F000"}; + const char* region_name[] = {"0400", "2000", "4000", "4800", "5000", "6000", "7000", "8000", "8800", "9000", "a000", "b000", "c000", "d000", "e000", "f000"}; const char *pcb_name = get_feature("slot"); bool extra_bank = false; diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp index 4ec5ff7898c..8a38739933a 100644 --- a/src/emu/diimage.cpp +++ b/src/emu/diimage.cpp @@ -906,31 +906,7 @@ bool device_image_interface::load_software(software_list_device &swlist, const c u32 crc = 0; const bool has_crc = util::hash_collection(ROM_GETHASHDATA(romp)).crc(crc); std::vector<const software_info *> parents; - std::vector<std::string> searchpath; - - // search <rompath>/<list>/<software> following parents - searchpath.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), swname)); - for (const software_info *i = swinfo; i && !i->parentname().empty(); i = swlist.find(i->parentname())) - { - if (std::find(parents.begin(), parents.end(), i) != parents.end()) - { - osd_printf_warning("WARNING: parent/clone relationships form a loop for software %s (in list %s)\n", swname, swlist.list_name()); - break; - } - parents.emplace_back(i); - searchpath.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), i->parentname())); - } - - // search <rompath>/<software> following parents - searchpath.emplace_back(swname); - parents.clear(); - for (software_info const *i = swinfo; i && !i->parentname().empty(); i = swlist.find(i->parentname())) - { - if (std::find(parents.begin(), parents.end(), i) != parents.end()) - break; - parents.emplace_back(i); - searchpath.emplace_back(i->parentname()); - } + std::vector<std::string> searchpath = rom_load_manager::get_software_searchpath(swlist, *swinfo); // for historical reasons, add the search path for the software list device's owner const device_t *const listowner = swlist.owner(); diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp index 4018cdf923e..63c518a13fb 100644 --- a/src/emu/romload.cpp +++ b/src/emu/romload.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Nicola Salmoria,Paul Priest,Aaron Giles +// copyright-holders:Nicola Salmoria,Paul Priest,Aaron Giles,Vas Crabb /********************************************************************* romload.cpp @@ -30,27 +30,72 @@ #define TEMPBUFFER_MAX_SIZE (1024 * 1024 * 1024) /*************************************************************************** - HELPERS (also used by diimage.cpp) + HELPERS ***************************************************************************/ namespace { -rom_entry const *next_parent_system(game_driver const *&system, std::vector<rom_entry> &rom_entries) +auto next_parent_system(game_driver const &system) { - if (!system) - return nullptr; - int const parent(driver_list::find(system->parent)); - if (0 > parent) - { - system = nullptr; - return nullptr; - } - else + return + [sys = &system, roms = std::vector<rom_entry>()] () mutable -> rom_entry const * + { + if (!sys) + return nullptr; + int const parent(driver_list::find(sys->parent)); + if (0 > parent) + { + sys = nullptr; + return nullptr; + } + else + { + sys = &driver_list::driver(parent); + roms = rom_build_entries(sys->rom); + return &roms[0]; + } + }; +} + + +auto next_parent_software(std::vector<software_info const *> const &parents) +{ + auto part(parents.front()->parts().end()); + return + [&parents, current = parents.cbegin(), part, end = part] () mutable -> const rom_entry * + { + if (part == end) + { + if (parents.end() == current) + return nullptr; + part = (*current)->parts().cbegin(); + end = (*current)->parts().cend(); + do { ++current; } while ((parents.cend() != current) && (*current)->parts().empty()); + } + return &(*part++).romdata()[0]; + }; +} + + +std::vector<std::string> make_software_searchpath(software_list_device &swlist, software_info const &swinfo, std::vector<software_info const *> &parents) +{ + std::vector<std::string> result; + + // search <rompath>/<list>/<software> following parents + for (software_info const *i = &swinfo; i; ) { - system = &driver_list::driver(parent); - rom_entries = rom_build_entries(system->rom); - return &rom_entries[0]; + if (std::find(parents.begin(), parents.end(), i) != parents.end()) + break; + parents.emplace_back(i); + result.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), i->shortname())); + i = i->parentname().empty() ? nullptr : swlist.find(i->parentname()); } + + // search <rompath>/<software> following parents + for (software_info const *i : parents) + result.emplace_back(i->shortname()); + + return result; } @@ -1068,6 +1113,23 @@ void rom_load_manager::process_disk_entries(std::initializer_list<std::reference } +/*------------------------------------------------- + get_software_searchpath - get search path + for a software list item +-------------------------------------------------*/ + +std::vector<std::string> rom_load_manager::get_software_searchpath(software_list_device &swlist, const software_info &swinfo) +{ + std::vector<software_info const *> parents; + return make_software_searchpath(swlist, swinfo, parents); +} + + +/*------------------------------------------------- + open_disk_image - open a disk image for a + device +-------------------------------------------------*/ + chd_error rom_load_manager::open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd) { const std::vector<std::string> searchpath(device.searchpath()); @@ -1075,47 +1137,24 @@ chd_error rom_load_manager::open_disk_image(const emu_options &options, const de driver_device const *const driver(dynamic_cast<driver_device const *>(&device)); std::function<const rom_entry * ()> next_parent; if (driver) - next_parent = [sys = &driver->system(), roms = std::vector<rom_entry>()] () mutable { return next_parent_system(sys, roms); }; + next_parent = next_parent_system(driver->system()); else next_parent = [] () { return nullptr; }; return do_open_disk(options, { searchpath }, romp, image_chd, std::move(next_parent)); } +/*------------------------------------------------- + open_disk_image - open a disk image for a + software item +-------------------------------------------------*/ + chd_error rom_load_manager::open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd) { std::vector<software_info const *> parents; - std::vector<std::string> listsearch, freesearch, disksearch; - disksearch.emplace_back(swlist.list_name()); - - for (software_info const *i = &swinfo; i; ) - { - if (std::find(parents.begin(), parents.end(), i) != parents.end()) - break; - parents.emplace_back(i); - listsearch.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), i->shortname())); - freesearch.emplace_back(i->shortname()); - i = i->parentname().empty() ? nullptr : swlist.find(i->parentname()); - } - - auto part(parents.front()->parts().end()); - return do_open_disk( - options, - { listsearch, freesearch, disksearch }, - romp, - image_chd, - [&parents, current = parents.cbegin(), part, end = part] () mutable -> const rom_entry * - { - if (part == end) - { - if (parents.end() == current) - return nullptr; - part = (*current)->parts().cbegin(); - end = (*current)->parts().cend(); - do { ++current; } while ((parents.cend() != current) && (*current)->parts().empty()); - } - return &(*part++).romdata()[0]; - }); + std::vector<std::string> searchpath = make_software_searchpath(swlist, swinfo, parents); + searchpath.emplace_back(swlist.list_name()); // look for loose disk images in software list directory + return do_open_disk(options, { searchpath }, romp, image_chd, next_parent_software(parents)); } @@ -1175,10 +1214,8 @@ void rom_load_manager::load_software_part_region(device_t &device, software_list m_romsloadedsize = 0; std::vector<const software_info *> parents; - std::vector<std::string> listsearch, freesearch, disksearch, devsearch; - listsearch.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), swname)); - freesearch.emplace_back(swname); - const software_info *swinfo = swlist.find(swname); + std::vector<std::string> swsearch, disksearch, devsearch; + const software_info *const swinfo = swlist.find(swname); if (swinfo) { // dispay a warning for unsupported software @@ -1196,21 +1233,12 @@ void rom_load_manager::load_software_part_region(device_t &device, software_list } // walk the chain of parents and add them to the search path - parents.emplace_back(swinfo); - swinfo = !swinfo->parentname().empty() ? swlist.find(swinfo->parentname()) : nullptr; - while (swinfo) - { - if (std::find(parents.begin(), parents.end(), swinfo) != parents.end()) - { - m_errorstring.append(util::string_format("WARNING: parent/clone relationships form a loop for software %s (in list %s)\n", swname, swlist.list_name())); - m_softwarningstring.append(util::string_format("Parent/clone relationships from a loop for software %s (in list %s)\n", swname, swlist.list_name())); - break; - } - parents.emplace_back(swinfo); - listsearch.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), swinfo->shortname())); - freesearch.emplace_back(swinfo->shortname()); - swinfo = !swinfo->parentname().empty() ? swlist.find(swinfo->parentname()) : nullptr; - } + swsearch = make_software_searchpath(swlist, *swinfo, parents); + } + else + { + swsearch.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), swname)); + swsearch.emplace_back(swname); } // this is convenient for CD-only lists so you don't need an extra level of directories containing one file each @@ -1269,40 +1297,23 @@ void rom_load_manager::load_software_part_region(device_t &device, software_list if (ROMREGION_ISROMDATA(region)) { if (devsearch.empty()) - process_rom_entries({ listsearch, freesearch }, 0U, region, region + 1, true); + process_rom_entries({ swsearch }, 0U, region, region + 1, true); else - process_rom_entries({ listsearch, freesearch, devsearch }, 0U, region, region + 1, true); + process_rom_entries({ swsearch, devsearch }, 0U, region, region + 1, true); } else if (ROMREGION_ISDISKDATA(region)) { if (!next_parent) { if (!parents.empty()) - { - auto part(parents.front()->parts().end()); - next_parent = - [&parents, current = parents.cbegin(), part, end = part] () mutable -> const rom_entry * - { - if (part == end) - { - if (parents.end() == current) - return nullptr; - part = (*current)->parts().cbegin(); - end = (*current)->parts().cend(); - do { ++current; } while ((parents.cend() != current) && (*current)->parts().empty()); - } - return &(*part++).romdata()[0]; - }; - } + next_parent = next_parent_software(parents); else - { next_parent = [] () { return nullptr; }; - } } if (devsearch.empty()) - process_disk_entries({ listsearch, freesearch, disksearch }, regiontag.c_str(), region + 1, next_parent); + process_disk_entries({ swsearch, disksearch }, regiontag.c_str(), region + 1, next_parent); else - process_disk_entries({ listsearch, freesearch, disksearch, devsearch }, regiontag.c_str(), region + 1, next_parent); + process_disk_entries({ swsearch, disksearch, devsearch }, regiontag.c_str(), region + 1, next_parent); } } @@ -1373,7 +1384,7 @@ void rom_load_manager::process_region_list() { driver_device const *const driver(dynamic_cast<driver_device const *>(&device)); if (driver) - next_parent = [sys = &driver->system(), roms = std::vector<rom_entry>()] () mutable { return next_parent_system(sys, roms); }; + next_parent = next_parent_system(driver->system()); else next_parent = [] () { return nullptr; }; } diff --git a/src/emu/romload.h b/src/emu/romload.h index 7db106a52ce..ca725f0e0fb 100644 --- a/src/emu/romload.h +++ b/src/emu/romload.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Nicola Salmoria,Aaron Giles +// copyright-holders:Nicola Salmoria,Aaron Giles,Vas Crabb /********************************************************************* romload.h @@ -423,6 +423,9 @@ public: void load_software_part_region(device_t &device, software_list_device &swlist, const char *swname, const rom_entry *start_region); + /* get search path for a software item */ + static std::vector<std::string> get_software_searchpath(software_list_device &swlist, const software_info &swinfo); + /* open a disk image, searching up the parent and loading by checksum */ static chd_error open_disk_image(const emu_options &options, const device_t &device, const rom_entry *romp, chd_file &image_chd); static chd_error open_disk_image(const emu_options &options, software_list_device &swlist, const software_info &swinfo, const rom_entry *romp, chd_file &image_chd); diff --git a/src/emu/softlist_dev.cpp b/src/emu/softlist_dev.cpp index d33e357ebc7..f3c584d1c4a 100644 --- a/src/emu/softlist_dev.cpp +++ b/src/emu/softlist_dev.cpp @@ -421,14 +421,15 @@ void software_list_device::device_validity_check(validity_checker &valid) const void software_list_device::internal_validity_check(validity_checker &valid) { - enum { NAME_LEN_PARENT = 16, NAME_LEN_CLONE = 16 }; + enum { NAME_LEN_PARENT = 16, NAME_LEN_CLONE = 16, NAME_LEN_PART = 16 }; + auto const valid_name_char = [] (char ch) { return ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || (ch == '_'); }; + auto const valid_tag_char = [] (char ch) { return ((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'z')) || strchr("$.:_", u8(ch)); }; + auto const valid_year_char = [] (char ch) { return isdigit(u8(ch)) || (ch == '?') || (ch == '+'); }; softlist_map names; softlist_map descriptions; for (const software_info &swinfo : get_info()) { - std::string const &shortname(swinfo.shortname()); - // first parse and output core errors if any if (m_errors.length() > 0) { @@ -437,48 +438,32 @@ void software_list_device::internal_validity_check(validity_checker &valid) } // Now check if the xml data is valid: + std::string const &shortname(swinfo.shortname()); - // Did we lost any description? if (swinfo.longname().empty()) - { osd_printf_error("%s: %s has no description\n", filename(), shortname); - break; - } - // Did we lost any year? if (swinfo.year().empty()) - { osd_printf_error("%s: %s has no year\n", filename(), shortname); - break; - } - // Did we lost any publisher? if (swinfo.publisher().empty()) - { osd_printf_error("%s: %s has no publisher\n", filename(), shortname); - break; - } // Did we lost the software parts? if (swinfo.parts().empty()) - { - osd_printf_error("%s: %s has no part\n", filename(), shortname); - break; - } + osd_printf_error("%s: %s has no parts\n", filename(), shortname); // Second, since the xml is fine, run additional checks: // check for duplicate names - if (!names.insert(std::make_pair(shortname, &swinfo)).second) - { - const software_info *match = names.find(shortname)->second; - osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), shortname, match->shortname()); - } + auto const dupname(names.emplace(shortname, &swinfo)); + if (!dupname.second) + osd_printf_error("%s: %s is a duplicate name (%s)\n", filename(), shortname, dupname.first->second->shortname()); // check for duplicate descriptions - std::string longname(swinfo.longname()); - if (!descriptions.insert(std::make_pair(strmakelower(longname), &swinfo)).second) - osd_printf_error("%s: %s is a duplicate description (%s)\n", filename(), swinfo.longname(), shortname); + auto const dupdesc(descriptions.emplace(swinfo.longname(), &swinfo)); + if (!dupdesc.second) + osd_printf_error("%s: %s has duplicate description '%s' (%s)\n", filename(), shortname, swinfo.longname(), dupdesc.first->second->shortname()); bool const is_clone(!swinfo.parentname().empty()); if (is_clone) @@ -486,16 +471,15 @@ void software_list_device::internal_validity_check(validity_checker &valid) if (swinfo.parentname() == shortname) { osd_printf_error("%s: %s is set as a clone of itself\n", filename(), shortname); - break; } - - // make sure the parent exists - const software_info *swinfo2 = find(swinfo.parentname()); - - if (swinfo2 == nullptr) - osd_printf_error("%s: parent '%s' software for '%s' not found\n", filename(), swinfo.parentname(), shortname); - else if (!swinfo2->parentname().empty()) - osd_printf_error("%s: %s is a clone of a clone\n", filename(), shortname); + else + { + software_info const *const parent = find(swinfo.parentname()); + if (!parent) + osd_printf_error("%s: %s is a clone of non-existent parent %s\n", filename(), shortname, swinfo.parentname()); + else if (!parent->parentname().empty()) + osd_printf_error("%s: %s is a clone %s which is a clone of %s\n", filename(), shortname, swinfo.parentname(), parent->parentname()); + } } // make sure the driver name isn't too long @@ -504,32 +488,80 @@ void software_list_device::internal_validity_check(validity_checker &valid) is_clone ? "clone" : "parent", is_clone ? NAME_LEN_CLONE : NAME_LEN_PARENT); // make sure the driver name doesn't contain invalid characters - for (char ch : shortname) - if (((ch < '0') || (ch > '9')) && ((ch < 'a') || (ch > 'z')) && (ch != '_')) - { - osd_printf_error("%s: %s contains invalid characters\n", filename(), shortname); - break; - } + if (std::find_if_not(shortname.begin(), shortname.end(), valid_name_char) != shortname.end()) + osd_printf_error("%s: %s contains invalid characters\n", filename(), shortname); // make sure the year is only digits, '?' or '+' - for (char ch : swinfo.year()) - if (!isdigit(u8(ch)) && (ch != '?') && (ch != '+')) - { - osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), shortname, swinfo.year()); - break; - } + if (std::find_if_not(swinfo.year().begin(), swinfo.year().end(), valid_year_char) != swinfo.year().end()) + osd_printf_error("%s: %s has an invalid year '%s'\n", filename(), shortname, swinfo.year()); - softlist_map part_names; - for (const software_part &part : swinfo.parts()) + std::set<std::string> part_names; + for (software_part const &part : swinfo.parts()) { if (part.interface().empty()) - osd_printf_error("%s: %s has a part (%s) without interface\n", filename(), shortname, part.name()); + osd_printf_error("%s: %s part %s has no interface\n", filename(), shortname, part.name()); if (part.romdata().empty()) - osd_printf_error("%s: %s has a part (%s) with no data\n", filename(), shortname, part.name()); + osd_printf_error("%s: %s part %s has no data areas\n", filename(), shortname, part.name()); + + if (!part_names.emplace(part.name()).second) + osd_printf_error("%s: %s part %s has duplicate name\n", filename(), shortname, part.name()); + + if (part.name().length() > NAME_LEN_PART) + osd_printf_error("%s: %s part %s name must be %d characters or less\n", filename(), shortname, part.name(), NAME_LEN_PART); + + if (std::find_if_not(part.name().begin(), part.name().end(), valid_name_char) != part.name().end()) + osd_printf_error("%s: %s part %s contains invalid characters\n", filename(), shortname, part.name()); + + // validate data areas + // based on ROM validation code from validity.cpp but adapted to work with rom_entry and ignore unavailable features like BIOS + if (!part.romdata().empty()) + { + std::map<std::string, u32> data_area_map; + char const *last_region_name = "???"; + char const *last_name = "???"; + u32 current_length = 0; + int items_since_region = 1; + for (rom_entry const *romp = &part.romdata().front(); romp && !ROMENTRY_ISEND(romp); ++romp) + { + if (ROMENTRY_ISREGION(romp)) // if this is a region, make sure it's valid, and record the length + { + // reset our region tracking states + items_since_region = (ROMREGION_ISERASE(romp) || ROMREGION_ISDISKDATA(romp)) ? 1 : 0; + last_region_name = romp->name().c_str(); - if (!part_names.insert(std::make_pair(part.name(), &swinfo)).second) - osd_printf_error("%s: %s has a part (%s) whose name is duplicate\n", filename(), shortname, part.name()); + // check for a valid tag + if (romp->name().size() < MIN_TAG_LENGTH) + osd_printf_error("%s: %s part %s data area name '%s' is too short (mut be at least %d characters)\n", filename(), shortname, part.name(), romp->name(), MIN_TAG_LENGTH); + + if (std::find_if_not(romp->name().begin(), romp->name().end(), valid_tag_char) != romp->name().end()) + osd_printf_error("%s: %s part %s data area name '%s' contains invalid characters\n", filename(), shortname, part.name(), romp->name()); + + // attempt to add it to the map, reporting duplicates as errors + current_length = ROMREGION_GETLENGTH(romp); + if (!data_area_map.emplace(romp->name(), current_length).second) + osd_printf_error("%s: %s part %s data area has duplicate name '%s'\n", filename(), shortname, part.name(), romp->name()); + } + else if (ROMENTRY_ISFILE(romp)) // if this is a file, make sure it is properly formatted + { + // track the last filename we found + last_name = romp->name().c_str(); + + // make sure the hash is valid + util::hash_collection hashes; + if (!hashes.from_internal_string(romp->hashdata().c_str())) + osd_printf_error("%s: %s part %s ROM '%s' has invalid hash string '%s'\n", filename(), shortname, part.name(), romp->name(), romp->hashdata()); + } + + // for any non-region ending entries, make sure they don't extend past the end + if (!ROMENTRY_ISREGIONEND(romp) && current_length > 0) + { + items_since_region++; + if (!ROMENTRY_ISIGNORE(romp) && (ROM_GETOFFSET(romp) + ROM_GETLENGTH(romp) > current_length)) + osd_printf_error("%s: %s part %s ROM '%s' extends past the defined data area\n", filename(), shortname, part.name(), last_name); + } + } + } } } diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp index 868f7c96935..3c402487bf4 100644 --- a/src/emu/validity.cpp +++ b/src/emu/validity.cpp @@ -1550,7 +1550,7 @@ void validity_checker::validate_roms(device_t &root) // attempt to add it to the map, reporting duplicates as errors current_length = ROMREGION_GETLENGTH(romp); - if (!m_region_map.insert(std::make_pair(fulltag, current_length)).second) + if (!m_region_map.emplace(fulltag, current_length).second) osd_printf_error("Multiple ROM_REGIONs with the same tag '%s' defined\n", fulltag); } else if (ROMENTRY_ISSYSTEM_BIOS(romp)) // If this is a system bios, make sure it is using the next available bios number diff --git a/src/frontend/mame/audit.cpp b/src/frontend/mame/audit.cpp index 3ff706d2c8a..6f2157a3ac4 100644 --- a/src/frontend/mame/audit.cpp +++ b/src/frontend/mame/audit.cpp @@ -187,33 +187,7 @@ media_auditor::summary media_auditor::audit_software(software_list_device &swlis if (ROMREGION_ISROMDATA(region)) { if (searchpath.empty()) - { - std::vector<software_info const *> parents; - - // search <rompath>/<list>/<software> following parents - searchpath.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), swinfo.shortname())); - for (software_info const *i = &swinfo; i && !i->parentname().empty(); i = swlist.find(i->parentname())) - { - if (std::find(parents.begin(), parents.end(), i) != parents.end()) - { - osd_printf_warning("WARNING: software parent/clone relationships form a loop (%s:%s)\n", swlist.list_name(), swinfo.shortname()); - break; - } - parents.emplace_back(i); - searchpath.emplace_back(util::string_format("%s" PATH_SEPARATOR "%s", swlist.list_name(), i->parentname())); - } - - // search <rompath>/<software> following parents - searchpath.emplace_back(swinfo.shortname()); - parents.clear(); - for (software_info const *i = &swinfo; i && !i->parentname().empty(); i = swlist.find(i->parentname())) - { - if (std::find(parents.begin(), parents.end(), i) != parents.end()) - break; - parents.emplace_back(i); - searchpath.emplace_back(i->parentname()); - } - } + searchpath = rom_load_manager::get_software_searchpath(swlist, swinfo); return &audit_one_rom(searchpath, rom); } else if (ROMREGION_ISDISKDATA(region)) diff --git a/src/mame/drivers/gsword.cpp b/src/mame/drivers/gsword.cpp index 6183e5ef561..a8f31293a9c 100644 --- a/src/mame/drivers/gsword.cpp +++ b/src/mame/drivers/gsword.cpp @@ -230,7 +230,7 @@ clock is supplied to both communication MCUs on T0. Outputs are set after detecting a rising edge on T0, and inputs are read after detecting a falling edge on T0. -A frame consists to five bytes send LSB first. Each byte is followed by +A frame consists to five bytes sent LSB first. Each byte is followed by an odd parity bit. Useful addresses for debugging communication: * $12A: Function for sending a frame from $21..$25 * $159: Function for receiving a frame to $29..$2D |