summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend/mame/info.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/mame/info.cpp')
-rw-r--r--src/frontend/mame/info.cpp191
1 files changed, 117 insertions, 74 deletions
diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp
index 42c1667f86a..fb61543c875 100644
--- a/src/frontend/mame/info.cpp
+++ b/src/frontend/mame/info.cpp
@@ -25,6 +25,7 @@
#include "xmlfile.h"
#include <ctype.h>
+#include <map>
#define XML_ROOT "mame"
@@ -680,97 +681,139 @@ void info_xml_creator::output_bios(device_t const &device)
void info_xml_creator::output_rom(driver_enumerator *drivlist, device_t &device)
{
- // iterate over 3 different ROM "types": BIOS, ROMs, DISKs
- bool const do_merge_name = drivlist && dynamic_cast<driver_device *>(&device);
- for (int rom_type = 0; rom_type < 3; rom_type++)
- for (const rom_entry *region = rom_first_region(device); region != nullptr; region = rom_next_region(region))
- {
- bool const is_disk = ROMREGION_ISDISKDATA(region);
-
- // disk regions only work for disks
- if ((is_disk && rom_type != 2) || (!is_disk && rom_type == 2))
- continue;
-
- // iterate through ROM entries
- std::string bios_name;
- for (const rom_entry *rom = rom_first_file(region); rom != nullptr; rom = rom_next_file(rom))
+ enum class type { BIOS, NORMAL, DISK };
+ std::map<u32, char const *> biosnames;
+ bool bios_scanned(false);
+ auto const get_biosname =
+ [&biosnames, &bios_scanned] (tiny_rom_entry const *rom) -> char const *
{
- // BIOS ROMs only apply to bioses
- bool const is_bios = ROM_GETBIOSFLAGS(rom);
- if ((is_bios && rom_type != 0) || (!is_bios && rom_type == 0))
- continue;
-
- // if we have a valid ROM and we are a clone, see if we can find the parent ROM
- util::hash_collection hashes(ROM_GETHASHDATA(rom));
- const char *const merge_name = (do_merge_name && !hashes.flag(util::hash_collection::FLAG_NO_DUMP)) ? get_merge_name(*drivlist, hashes) : nullptr;
-
- // scan for a BIOS name
- bios_name.clear();
- if (!is_disk && is_bios)
+ u32 const biosflags(ROM_GETBIOSFLAGS(rom));
+ std::map<u32, char const *>::const_iterator const found(biosnames.find(biosflags));
+ if (biosnames.end() != found)
+ return found->second;
+
+ char const *result(nullptr);
+ if (!bios_scanned)
{
- // scan backwards through the ROM entries
- for (const rom_entry *brom = rom - 1; brom != &device.rom_region_vector().front(); brom--)
+ for (++rom; !ROMENTRY_ISEND(rom); ++rom)
{
- if (ROMENTRY_ISSYSTEM_BIOS(brom))
+ if (ROMENTRY_ISSYSTEM_BIOS(rom))
{
- bios_name = ROM_GETNAME(brom);
- break;
+ u32 const biosno(ROM_GETBIOSFLAGS(rom));
+ biosnames.emplace(biosno, rom->name);
+ if (biosflags == biosno)
+ result = rom->name;
}
}
+ bios_scanned = true;
}
+ return result;
+ };
+ auto const rom_file_size = // FIXME: need a common way to do this without the cost of allocating rom_entry
+ [] (tiny_rom_entry const *romp) -> u32
+ {
+ u32 maxlength = 0;
- std::ostringstream output;
-
- // opening tag
- if (!is_disk)
- output << "\t\t<rom";
- else
- output << "\t\t<disk";
-
- // add name, merge, bios, and size tags */
- const char *const name = ROM_GETNAME(rom);
- if (name && name[0])
- util::stream_format(output, " name=\"%s\"", util::xml::normalize_string(name));
- if (merge_name)
- util::stream_format(output, " merge=\"%s\"", util::xml::normalize_string(merge_name));
- if (!bios_name.empty())
- util::stream_format(output, " bios=\"%s\"", util::xml::normalize_string(bios_name.c_str()));
- if (!is_disk)
- util::stream_format(output, " size=\"%u\"", rom_file_size(rom));
-
- // dump checksum information only if there is a known dump
- if (!hashes.flag(util::hash_collection::FLAG_NO_DUMP))
+ // loop until we run out of reloads
+ do
{
- // iterate over hash function types and print m_output their values
- output << " " << hashes.attribute_string();
+ // loop until we run out of continues/ignores */
+ u32 curlength(ROM_GETLENGTH(romp++));
+ while (ROMENTRY_ISCONTINUE(romp) || ROMENTRY_ISIGNORE(romp))
+ curlength += ROM_GETLENGTH(romp++);
+
+ // track the maximum length
+ maxlength = (std::max)(maxlength, curlength);
}
- else
- output << " status=\"nodump\"";
+ while (ROMENTRY_ISRELOAD(romp));
- // append a region name
- util::stream_format(output, " region=\"%s\"", ROMREGION_GETTAG(region));
+ return maxlength;
+ };
- if (!is_disk)
- {
- // for non-disk entries, print offset
- util::stream_format(output, " offset=\"%x\"", ROM_GETOFFSET(rom));
- }
- else
- {
- // for disk entries, add the disk index
- util::stream_format(output, " index=\"%x\"", DISK_GETINDEX(rom));
- util::stream_format(output, " writable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes");
- }
+ // iterate over 3 different ROM "types": BIOS, ROMs, DISKs
+ bool const do_merge_name = drivlist && dynamic_cast<driver_device *>(&device);
+ for (type pass : { type::BIOS, type::NORMAL, type::DISK })
+ {
+ tiny_rom_entry const *region(nullptr);
+ for (tiny_rom_entry const *rom = device.rom_region(); rom && !ROMENTRY_ISEND(rom); ++rom)
+ {
+ if (ROMENTRY_ISREGION(rom))
+ region = rom;
+ else if (ROMENTRY_ISSYSTEM_BIOS(rom))
+ biosnames.emplace(ROM_GETBIOSFLAGS(rom), rom->name);
- // add optional flag
- if (ROM_ISOPTIONAL(rom))
- output << " optional=\"yes\"";
+ if (!ROMENTRY_ISFILE(rom))
+ continue;
+
+ // only list disks on the disk pass
+ bool const is_disk = ROMREGION_ISDISKDATA(region);
+ if ((type::DISK == pass) != is_disk)
+ continue;
- output << "/>\n";
+ // BIOS ROMs only apply to bioses
+ // FIXME: disk images associated with a system BIOS will never be listed
+ u32 const biosno(ROM_GETBIOSFLAGS(rom));
+ if ((type::BIOS == pass) != bool(biosno))
+ continue;
+ char const *const bios_name((!is_disk && biosno) ? get_biosname(rom) : nullptr);
- fprintf(m_output, "%s", output.str().c_str());
+ // if we have a valid ROM and we are a clone, see if we can find the parent ROM
+ util::hash_collection const hashes(rom->hashdata);
+ char const *const merge_name((do_merge_name && !hashes.flag(util::hash_collection::FLAG_NO_DUMP)) ? get_merge_name(*drivlist, hashes) : nullptr);
+
+ std::ostringstream output;
+
+ // opening tag
+ if (is_disk)
+ output << "\t\t<disk";
+ else
+ output << "\t\t<rom";
+
+ // add name, merge, bios, and size tags */
+ char const *const name(rom->name);
+ if (name && name[0])
+ util::stream_format(output, " name=\"%s\"", util::xml::normalize_string(name));
+ if (merge_name)
+ util::stream_format(output, " merge=\"%s\"", util::xml::normalize_string(merge_name));
+ if (bios_name)
+ util::stream_format(output, " bios=\"%s\"", util::xml::normalize_string(bios_name));
+ if (!is_disk)
+ util::stream_format(output, " size=\"%u\"", rom_file_size(rom));
+
+ // dump checksum information only if there is a known dump
+ if (!hashes.flag(util::hash_collection::FLAG_NO_DUMP))
+ {
+ // iterate over hash function types and print m_output their values
+ output << " " << hashes.attribute_string();
+ }
+ else
+ output << " status=\"nodump\"";
+
+ // append a region name
+ util::stream_format(output, " region=\"%s\"", region->name);
+
+ if (!is_disk)
+ {
+ // for non-disk entries, print offset
+ util::stream_format(output, " offset=\"%x\"", ROM_GETOFFSET(rom));
}
+ else
+ {
+ // for disk entries, add the disk index
+ util::stream_format(output, " index=\"%x\"", DISK_GETINDEX(rom));
+ util::stream_format(output, " writable=\"%s\"", DISK_ISREADONLY(rom) ? "no" : "yes");
+ }
+
+ // add optional flag
+ if (ROM_ISOPTIONAL(rom))
+ output << " optional=\"yes\"";
+
+ output << "/>\n";
+
+ fprintf(m_output, "%s", output.str().c_str());
}
+ bios_scanned = true;
+ }
}