From fa9c035c8024e0f78fde882fb3e8437485ec91ae Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Mon, 6 Sep 2021 23:41:35 +1000 Subject: Allow devices to specify a parent for the purpose of searching for ROMs. --- src/devices/bus/a2bus/grappler.h | 14 +++--- src/devices/bus/a2bus/q68.h | 16 +++++-- src/devices/bus/amiga/keyboard/a2000.h | 30 +++++++----- src/devices/bus/amiga/keyboard/mitsumi.cpp | 70 +++++++++++++++++++++++++++ src/devices/bus/mackbd/keyboard.cpp | 10 ++++ src/devices/bus/mackbd/pluskbd.cpp | 4 ++ src/emu/device.cpp | 2 + src/emu/device.h | 14 ++++++ src/emu/validity.cpp | 27 ++++++++--- src/frontend/mame/infoxml.cpp | 76 ++++++++++++++++++++++-------- 10 files changed, 216 insertions(+), 47 deletions(-) diff --git a/src/devices/bus/a2bus/grappler.h b/src/devices/bus/a2bus/grappler.h index 8e3857414da..6106c9bbd96 100644 --- a/src/devices/bus/a2bus/grappler.h +++ b/src/devices/bus/a2bus/grappler.h @@ -58,6 +58,12 @@ #include "cpu/mcs48/mcs48.h" +DECLARE_DEVICE_TYPE(A2BUS_GRAPPLER, a2bus_grappler_device) +DECLARE_DEVICE_TYPE(A2BUS_GRAPPLERPLUS, a2bus_grapplerplus_device) +DECLARE_DEVICE_TYPE(A2BUS_BUFGRAPPLERPLUS, a2bus_buf_grapplerplus_device) +DECLARE_DEVICE_TYPE(A2BUS_BUFGRAPPLERPLUSA, a2bus_buf_grapplerplus_reva_device) + + class a2bus_grappler_device_base : public device_t, public device_a2bus_card_interface { public: @@ -270,15 +276,11 @@ class a2bus_buf_grapplerplus_reva_device : public a2bus_buf_grapplerplus_device public: a2bus_buf_grapplerplus_reva_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + static auto parent_rom_device_type() { return &A2BUS_BUFGRAPPLERPLUS; } + protected: // device_t implementation virtual void device_add_mconfig(machine_config &config) override; }; - -DECLARE_DEVICE_TYPE(A2BUS_GRAPPLER, a2bus_grappler_device) -DECLARE_DEVICE_TYPE(A2BUS_GRAPPLERPLUS, a2bus_grapplerplus_device) -DECLARE_DEVICE_TYPE(A2BUS_BUFGRAPPLERPLUS, a2bus_buf_grapplerplus_device) -DECLARE_DEVICE_TYPE(A2BUS_BUFGRAPPLERPLUSA, a2bus_buf_grapplerplus_reva_device) - #endif // MAME_BUS_A2BUS_GRAPPLERPLUS_H diff --git a/src/devices/bus/a2bus/q68.h b/src/devices/bus/a2bus/q68.h index c52c9567bc9..34664a284f0 100644 --- a/src/devices/bus/a2bus/q68.h +++ b/src/devices/bus/a2bus/q68.h @@ -15,6 +15,15 @@ #include "a2bus.h" + +//************************************************************************** +// DEVICE TYPE DECLARATION +//************************************************************************** + +DECLARE_DEVICE_TYPE(A2BUS_Q68, a2bus_q68_device) +DECLARE_DEVICE_TYPE(A2BUS_Q68PLUS, a2bus_q68plus_device) + + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -61,6 +70,8 @@ class a2bus_q68plus_device : public a2bus_68k_device public: a2bus_q68plus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static auto parent_rom_device_type() { return &A2BUS_Q68; } + protected: virtual void device_add_mconfig(machine_config &config) override; @@ -68,9 +79,4 @@ private: void m68008_mem(address_map &map); }; - -// device type definition -DECLARE_DEVICE_TYPE(A2BUS_Q68, a2bus_q68_device) -DECLARE_DEVICE_TYPE(A2BUS_Q68PLUS, a2bus_q68plus_device) - #endif // MAME_BUS_A2BUS_Q68_H diff --git a/src/devices/bus/amiga/keyboard/a2000.h b/src/devices/bus/amiga/keyboard/a2000.h index 7a710f6ad37..806991be949 100644 --- a/src/devices/bus/amiga/keyboard/a2000.h +++ b/src/devices/bus/amiga/keyboard/a2000.h @@ -14,6 +14,17 @@ #include "keyboard.h" +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_US, bus::amiga::keyboard, a2000_kbd_g80_us_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_DE, bus::amiga::keyboard, a2000_kbd_g80_de_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_SE, bus::amiga::keyboard, a2000_kbd_g80_se_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_DK, bus::amiga::keyboard, a2000_kbd_g80_dk_device) +DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_GB, bus::amiga::keyboard, a2000_kbd_g80_gb_device) + + namespace bus::amiga::keyboard { //************************************************************************** @@ -73,6 +84,8 @@ class a2000_kbd_g80_de_device : public a2000_kbd_g80_device public: a2000_kbd_g80_de_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + static auto parent_rom_device_type() { return &A2000_KBD_G80_US; } + protected: virtual ioport_constructor device_input_ports() const override; }; @@ -84,6 +97,8 @@ class a2000_kbd_g80_se_device : public a2000_kbd_g80_device public: a2000_kbd_g80_se_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + static auto parent_rom_device_type() { return &A2000_KBD_G80_US; } + protected: virtual ioport_constructor device_input_ports() const override; }; @@ -95,6 +110,8 @@ class a2000_kbd_g80_dk_device : public a2000_kbd_g80_device public: a2000_kbd_g80_dk_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + static auto parent_rom_device_type() { return &A2000_KBD_G80_US; } + protected: virtual ioport_constructor device_input_ports() const override; }; @@ -106,21 +123,12 @@ class a2000_kbd_g80_gb_device : public a2000_kbd_g80_device public: a2000_kbd_g80_gb_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + static auto parent_rom_device_type() { return &A2000_KBD_G80_US; } + protected: virtual ioport_constructor device_input_ports() const override; }; } // namespace bus::amiga::keyboard - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** - -DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_US, bus::amiga::keyboard, a2000_kbd_g80_us_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_DE, bus::amiga::keyboard, a2000_kbd_g80_de_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_SE, bus::amiga::keyboard, a2000_kbd_g80_se_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_DK, bus::amiga::keyboard, a2000_kbd_g80_dk_device) -DECLARE_DEVICE_TYPE_NS(A2000_KBD_G80_GB, bus::amiga::keyboard, a2000_kbd_g80_gb_device) - #endif // MAME_BUS_AMIGA_KEYBOARD_A2000_H diff --git a/src/devices/bus/amiga/keyboard/mitsumi.cpp b/src/devices/bus/amiga/keyboard/mitsumi.cpp index 038d8bb72d7..7557d04b95c 100644 --- a/src/devices/bus/amiga/keyboard/mitsumi.cpp +++ b/src/devices/bus/amiga/keyboard/mitsumi.cpp @@ -665,6 +665,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_US, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_us); } }; @@ -676,6 +678,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_DE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_de); } }; @@ -687,6 +691,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_FR, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_fr); } }; @@ -698,6 +704,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_IT, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_it); } }; @@ -709,6 +717,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_SE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_se); } }; @@ -720,6 +730,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_ES, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_es); } }; @@ -731,6 +743,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_DK, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_dk); } }; @@ -742,6 +756,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_CH, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_ch); } }; @@ -753,6 +769,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_NO, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_no); } }; @@ -764,6 +782,8 @@ public: : a500_keyboard_base(mconfig, A500_KBD_GB, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_gb); } }; @@ -780,6 +800,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_US, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_us); } }; @@ -791,6 +813,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_DE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_de); } }; @@ -802,6 +826,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_FR, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_fr); } }; @@ -813,6 +839,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_IT, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_it); } }; @@ -824,6 +852,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_SE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_se); } }; @@ -835,6 +865,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_ES, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_es); } }; @@ -846,6 +878,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_DK, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_dk); } }; @@ -857,6 +891,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_CH, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_ch); } }; @@ -868,6 +904,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_NO, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_no); } }; @@ -879,6 +917,8 @@ public: : a600_keyboard_base(mconfig, A600_KBD_GB, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(compact_gb); } }; @@ -906,6 +946,8 @@ public: : a1000_keyboard_base(mconfig, A1000_KBD_DE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A1000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(a1000_de); } }; @@ -917,6 +959,8 @@ public: : a1000_keyboard_base(mconfig, A1000_KBD_FR, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A1000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(a1000_fr); } }; @@ -928,6 +972,8 @@ public: : a1000_keyboard_base(mconfig, A1000_KBD_IT, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A1000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(a1000_it); } }; @@ -939,6 +985,8 @@ public: : a1000_keyboard_base(mconfig, A1000_KBD_SE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A1000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(a1000_se); } }; @@ -950,6 +998,8 @@ public: : a1000_keyboard_base(mconfig, A1000_KBD_DK, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A1000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(a1000_dk); } }; @@ -961,6 +1011,8 @@ public: : a1000_keyboard_base(mconfig, A1000_KBD_GB, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A1000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(a1000_gb); } }; @@ -988,6 +1040,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_DE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_de); } }; @@ -999,6 +1053,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_FR, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_fr); } }; @@ -1010,6 +1066,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_IT, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_it); } }; @@ -1021,6 +1079,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_SE, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_se); } }; @@ -1032,6 +1092,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_ES, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_es); } }; @@ -1043,6 +1105,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_DK, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_dk); } }; @@ -1054,6 +1118,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_CH, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_ch); } }; @@ -1065,6 +1131,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_NO, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_no); } }; @@ -1076,6 +1144,8 @@ public: : mitsumi_watchdog_keyboard_base(mconfig, A2000_KBD_GB, tag, owner, clock) { } + static auto parent_rom_device_type() { return &A2000_KBD_US; } + protected: virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(fullsize_gb); } }; diff --git a/src/devices/bus/mackbd/keyboard.cpp b/src/devices/bus/mackbd/keyboard.cpp index 4f0de812c19..7818797904b 100644 --- a/src/devices/bus/mackbd/keyboard.cpp +++ b/src/devices/bus/mackbd/keyboard.cpp @@ -742,6 +742,8 @@ public: { } + static auto parent_rom_device_type() { return &MACKBD_M0110; } + protected: virtual ioport_constructor device_input_ports() const override { @@ -757,6 +759,8 @@ public: { } + static auto parent_rom_device_type() { return &MACKBD_M0110; } + protected: virtual ioport_constructor device_input_ports() const override { @@ -772,6 +776,8 @@ public: { } + static auto parent_rom_device_type() { return &MACKBD_M0110; } + protected: virtual ioport_constructor device_input_ports() const override { @@ -839,6 +845,8 @@ public: { } + static auto parent_rom_device_type() { return &MACKBD_M0110; } + protected: virtual ioport_constructor device_input_ports() const override { @@ -854,6 +862,8 @@ public: { } + static auto parent_rom_device_type() { return &MACKBD_M0110; } + protected: virtual void device_add_mconfig(machine_config &config) override { diff --git a/src/devices/bus/mackbd/pluskbd.cpp b/src/devices/bus/mackbd/pluskbd.cpp index 6cc707607f4..de744f9219b 100644 --- a/src/devices/bus/mackbd/pluskbd.cpp +++ b/src/devices/bus/mackbd/pluskbd.cpp @@ -475,6 +475,8 @@ public: { } + static auto parent_rom_device_type() { return &MACKBD_M0110A; } + protected: virtual ioport_constructor device_input_ports() const override { @@ -490,6 +492,8 @@ public: { } + static auto parent_rom_device_type() { return &MACKBD_M0110A; } + protected: virtual ioport_constructor device_input_ports() const override { diff --git a/src/emu/device.cpp b/src/emu/device.cpp index 51088b02d4a..8e80fe3c809 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -136,6 +136,8 @@ std::vector device_t::searchpath() const system = system->owner(); if (system) result = system->searchpath(); + if (type().parent_rom_device_type()) + result.emplace(result.begin(), type().parent_rom_device_type()->shortname()); result.emplace(result.begin(), shortname()); return result; } diff --git a/src/emu/device.h b/src/emu/device.h index d5fe81dd305..04d1df34b7a 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -220,6 +220,7 @@ private: char const *const m_source; device_feature::type const m_unemulated_features; device_feature::type const m_imperfect_features; + device_type_impl_base const *const m_parent_rom; device_type_impl_base *m_next; @@ -234,6 +235,7 @@ public: , m_source(nullptr) , m_unemulated_features(device_feature::NONE) , m_imperfect_features(device_feature::NONE) + , m_parent_rom(nullptr) , m_next(nullptr) { } @@ -247,6 +249,7 @@ public: , m_source(Source) , m_unemulated_features(DeviceClass::unemulated_features()) , m_imperfect_features(DeviceClass::imperfect_features()) + , m_parent_rom(DeviceClass::parent_rom_device_type()) , m_next(device_registrar::register_device(*this)) { } @@ -260,6 +263,7 @@ public: , m_source(Source) , m_unemulated_features(DriverClass::unemulated_features() | Unemulated) , m_imperfect_features((DriverClass::imperfect_features() & ~Unemulated) | Imperfect) + , m_parent_rom(DriverClass::parent_rom_device_type()) , m_next(nullptr) { } @@ -270,6 +274,7 @@ public: char const *source() const { return m_source; } device_feature::type unemulated_features() const { return m_unemulated_features; } device_feature::type imperfect_features() const { return m_imperfect_features; } + device_type_impl_base const *parent_rom_device_type() const { return m_parent_rom; } std::unique_ptr create(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) const { @@ -517,6 +522,15 @@ public: /// \sa unemulated_features static constexpr feature_type imperfect_features() { return feature::NONE; } + /// \brief Get parent device type for ROM search + /// + /// Impement this member in a derived class to declare the parent + /// device type for the purpose of searching for ROMs. Only one + /// level is allowed. It is an error the parent device type itself + /// declares a parent device type. + /// \return Pointer to parent device type, or nullptr. + static auto parent_rom_device_type() { return nullptr; } + virtual ~device_t(); // getters diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp index 9bd9edb1ff0..fd8b8d4464b 100644 --- a/src/emu/validity.cpp +++ b/src/emu/validity.cpp @@ -1493,6 +1493,10 @@ void validity_checker::validate_driver(device_t &root) if (clone_of != -1 && (clone_of = driver_list::non_bios_clone(clone_of)) != -1) osd_printf_error("Driver is a clone of a clone\n"); + // look for drivers specifying a parent ROM device type + if (root.type().parent_rom_device_type()) + osd_printf_error("Driver has parent ROM device type '%s'\n", root.type().parent_rom_device_type()->shortname()); + // make sure the driver name is not too long if (!is_clone && strlen(m_current_driver->name) > 16) osd_printf_error("Parent driver name must be 16 characters or less\n"); @@ -1548,11 +1552,11 @@ void validity_checker::validate_driver(device_t &root) // catch invalid flag combinations if (unemulated & ~device_t::feature::ALL) - osd_printf_error("Driver has invalid unemulated feature flags (0x%08lX)\n", static_cast(unemulated & ~device_t::feature::ALL)); + osd_printf_error("Driver has invalid unemulated feature flags (0x%08X)\n", util::underlying_value(unemulated & ~device_t::feature::ALL)); if (imperfect & ~device_t::feature::ALL) - osd_printf_error("Driver has invalid imperfect feature flags (0x%08lX)\n", static_cast(imperfect & ~device_t::feature::ALL)); + osd_printf_error("Driver has invalid imperfect feature flags (0x%08X)\n", util::underlying_value(imperfect & ~device_t::feature::ALL)); if (unemulated & imperfect) - osd_printf_error("Driver cannot have features that are both unemulated and imperfect (0x%08lX)\n", static_cast(unemulated & imperfect)); + osd_printf_error("Driver cannot have features that are both unemulated and imperfect (0x%08X)\n", util::underlying_value(unemulated & imperfect)); if ((m_current_driver->flags & machine_flags::NO_SOUND_HW) && ((unemulated | imperfect) & device_t::feature::SOUND)) osd_printf_error("Machine without sound hardware cannot have unemulated/imperfect sound\n"); } @@ -2203,11 +2207,22 @@ void validity_checker::validate_device_types() device_t::feature_type const unemulated(dev->type().unemulated_features()); device_t::feature_type const imperfect(dev->type().imperfect_features()); if (unemulated & ~device_t::feature::ALL) - osd_printf_error("Device has invalid unemulated feature flags (0x%08lX)\n", static_cast(unemulated & ~device_t::feature::ALL)); + osd_printf_error("Device has invalid unemulated feature flags (0x%08X)\n", util::underlying_value(unemulated & ~device_t::feature::ALL)); if (imperfect & ~device_t::feature::ALL) - osd_printf_error("Device has invalid imperfect feature flags (0x%08lX)\n", static_cast(imperfect & ~device_t::feature::ALL)); + osd_printf_error("Device has invalid imperfect feature flags (0x%08X)\n", util::underlying_value(imperfect & ~device_t::feature::ALL)); if (unemulated & imperfect) - osd_printf_error("Device cannot have features that are both unemulated and imperfect (0x%08lX)\n", static_cast(unemulated & imperfect)); + osd_printf_error("Device cannot have features that are both unemulated and imperfect (0x%08X)\n", util::underlying_value(unemulated & imperfect)); + + // check that parents are only ever one generation deep + auto const parent(dev->type().parent_rom_device_type()); + if (parent) + { + auto const grandparent(parent->parent_rom_device_type()); + if ((dev->type() == *parent) || !strcmp(parent->shortname(), name)) + osd_printf_error("Device has parent ROM set that identical to its type\n"); + if (grandparent) + osd_printf_error("Device has parent ROM set '%s' which has parent ROM set '%s'\n", parent->shortname(), grandparent->shortname()); + } // give devices some of the same scrutiny that drivers get - necessary for cards not default for any slots validate_roms(*dev); diff --git a/src/frontend/mame/infoxml.cpp b/src/frontend/mame/infoxml.cpp index 276a2d308ef..44c4aac98d6 100644 --- a/src/frontend/mame/infoxml.cpp +++ b/src/frontend/mame/infoxml.cpp @@ -63,7 +63,7 @@ void output_footer(std::ostream &out); void output_one(std::ostream &out, driver_enumerator &drivlist, const game_driver &driver, device_type_set *devtypes); void output_sampleof(std::ostream &out, device_t &device); void output_bios(std::ostream &out, device_t const &device); -void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_driver *driver, device_t &device); +void output_rom(std::ostream &out, machine_config &config, driver_enumerator *drivlist, const game_driver *driver, device_t &device); void output_device_refs(std::ostream &out, device_t &root); void output_sample(std::ostream &out, device_t &device); void output_chips(std::ostream &out, device_t &device, const char *root_tag); @@ -84,7 +84,9 @@ void output_ramoptions(std::ostream &out, device_t &root); void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag); void output_devices(std::ostream &out, emu_options &lookup_options, device_type_set const *filter); -const char *get_merge_name(driver_enumerator &drivlist, const game_driver &driver, util::hash_collection const &romhashes); +char const *get_merge_name(driver_enumerator &drivlist, game_driver const &driver, util::hash_collection const &romhashes); +char const *get_merge_name(machine_config &config, device_t const &device, util::hash_collection const &romhashes); +char const *get_merge_name(tiny_rom_entry const *roms, util::hash_collection const &romhashes); //************************************************************************** @@ -658,7 +660,7 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive // now print various additional information output_bios(out, config.root_device()); - output_rom(out, &drivlist, &driver, config.root_device()); + output_rom(out, config, &drivlist, &driver, config.root_device()); output_device_refs(out, config.root_device()); output_sample(out, config.root_device()); output_chips(out, config.root_device(), ""); @@ -720,11 +722,14 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi std::string src(device.source()); strreplace(src,"../", ""); out << util::string_format(" sourcefile=\"%s\" isdevice=\"yes\" runnable=\"no\"", normalize_string(src.c_str())); + auto const parent(device.type().parent_rom_device_type()); + if (parent) + out << util::string_format(" romof=\"%s\"", normalize_string(parent->shortname())); output_sampleof(out, device); out << ">\n" << util::string_format("\t\t%s\n", normalize_string(device.name())); output_bios(out, device); - output_rom(out, nullptr, nullptr, device); + output_rom(out, config, nullptr, nullptr, device); output_device_refs(out, device); if (device.type().type() != typeid(samples_device)) // ignore samples_device itself @@ -857,7 +862,7 @@ void output_bios(std::ostream &out, device_t const &device) // the XML output //------------------------------------------------- -void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_driver *driver, device_t &device) +void output_rom(std::ostream &out, machine_config &config, driver_enumerator *drivlist, const game_driver *driver, device_t &device) { enum class type { BIOS, NORMAL, DISK }; std::map biosnames; @@ -895,7 +900,7 @@ void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_drive // loop until we run out of reloads do { - // loop until we run out of continues/ignores */ + // loop until we run out of continues/ignores u32 curlength(ROM_GETLENGTH(romp++)); while (ROMENTRY_ISCONTINUE(romp) || ROMENTRY_ISIGNORE(romp)) curlength += ROM_GETLENGTH(romp++); @@ -909,7 +914,7 @@ void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_drive }; // iterate over 3 different ROM "types": BIOS, ROMs, DISKs - bool const do_merge_name = drivlist && dynamic_cast(&device); + bool const driver_merge = drivlist && dynamic_cast(&device); for (type pass : { type::BIOS, type::NORMAL, type::DISK }) { tiny_rom_entry const *region(nullptr); @@ -937,7 +942,10 @@ void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_drive // 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, *driver, hashes) : nullptr); + char const *const merge_name( + hashes.flag(util::hash_collection::FLAG_NO_DUMP) ? nullptr : + driver_merge ? get_merge_name(*drivlist, *driver, hashes) : + get_merge_name(config, device, hashes)); // opening tag if (is_disk) @@ -945,7 +953,7 @@ void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_drive else out << "\t\tname); if (name && name[0]) out << util::string_format(" name=\"%s\"", normalize_string(name)); @@ -2041,21 +2049,51 @@ void output_ramoptions(std::ostream &out, device_t &root) // parent set //------------------------------------------------- -const char *get_merge_name(driver_enumerator &drivlist, const game_driver &driver, util::hash_collection const &romhashes) +char const *get_merge_name(driver_enumerator &drivlist, game_driver const &driver, util::hash_collection const &romhashes) { + char const *result = nullptr; + // walk the parent chain - for (int clone_of = drivlist.find(driver.parent); 0 <= clone_of; clone_of = drivlist.find(drivlist.driver(clone_of).parent)) + for (int clone_of = drivlist.find(driver.parent); !result && (0 <= clone_of); clone_of = drivlist.find(drivlist.driver(clone_of).parent)) + result = get_merge_name(drivlist.driver(clone_of).rom, romhashes); + + return result; +} + + +char const *get_merge_name(machine_config &config, device_t const &device, util::hash_collection const &romhashes) +{ + char const *result = nullptr; + + // check for a parent type + auto const parenttype(device.type().parent_rom_device_type()); + if (parenttype) { + // instantiate the parent device + machine_config::token const tok(config.begin_configuration(config.root_device())); + device_t *const parent = config.device_add("_parent", *parenttype, 0); + // look in the parent's ROMs - for (romload::region const &pregion : romload::entries(drivlist.driver(clone_of).rom).get_regions()) + result = get_merge_name(parent->rom_region(), romhashes); + + // remember to remove the device + config.device_remove("_parent"); + } + + return result; +} + + +char const *get_merge_name(tiny_rom_entry const *roms, util::hash_collection const &romhashes) +{ + for (romload::region const &pregion : romload::entries(roms).get_regions()) + { + for (romload::file const &prom : pregion.get_files()) { - for (romload::file const &prom : pregion.get_files()) - { - // stop when we find a match - util::hash_collection const phashes(prom.get_hashdata()); - if (!phashes.flag(util::hash_collection::FLAG_NO_DUMP) && (romhashes == phashes)) - return prom.get_name(); - } + // stop when we find a match + util::hash_collection const phashes(prom.get_hashdata()); + if (!phashes.flag(util::hash_collection::FLAG_NO_DUMP) && (romhashes == phashes)) + return prom.get_name(); } } -- cgit v1.2.3