summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/mconfig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/mconfig.cpp')
-rw-r--r--src/emu/mconfig.cpp175
1 files changed, 93 insertions, 82 deletions
diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp
index 7f142ab5958..342651818bc 100644
--- a/src/emu/mconfig.cpp
+++ b/src/emu/mconfig.cpp
@@ -116,6 +116,61 @@ machine_config::~machine_config()
//-------------------------------------------------
+// device_add - configuration helper to add a
+// new device
+//-------------------------------------------------
+
+device_t *machine_config::device_add(const char *tag, device_type type, u32 clock)
+{
+ std::pair<const char *, device_t *> const owner(resolve_owner(tag));
+ return &add_device(type.create(*this, owner.first, owner.second, clock), owner.second);
+}
+
+
+//-------------------------------------------------
+// device_replace - configuration helper to
+// replace one device with a new device
+//-------------------------------------------------
+
+device_t *machine_config::device_replace(const char *tag, device_type type, u32 clock)
+{
+ std::tuple<const char *, device_t *, device_t *> const existing(prepare_replace(tag));
+ std::unique_ptr<device_t> device(type.create(*this, std::get<0>(existing), std::get<1>(existing), clock));
+ return &replace_device(std::move(device), *std::get<1>(existing), std::get<2>(existing));
+}
+
+
+//-------------------------------------------------
+// device_remove - configuration helper to
+// remove a device
+//-------------------------------------------------
+
+device_t *machine_config::device_remove(const char *tag)
+{
+ // find the original device by relative tag (must exist)
+ assert(m_current_device);
+ device_t *const device = m_current_device->subdevice(tag);
+ if (device == nullptr)
+ {
+ osd_printf_warning("Warning: attempting to remove non-existent device '%s'\n", tag);
+ }
+ else
+ {
+ // make sure we have the old device's actual owner
+ device_t *const owner = device->owner();
+ assert(owner);
+
+ // remove references to the old device
+ remove_references(*device);
+
+ // let the device's owner do the work
+ owner->subdevices().m_list.remove(*device);
+ }
+ return nullptr;
+}
+
+
+//-------------------------------------------------
// resolve_owner - get the actual owner and base
// tag given tag relative to current context
//-------------------------------------------------
@@ -134,11 +189,12 @@ std::pair<const char *, device_t *> machine_config::resolve_owner(const char *ta
}
// go down the path until we're done with it
+ std::string part;
while (strchr(tag, ':'))
{
const char *next = strchr(tag, ':');
assert(next != tag);
- std::string part(tag, next-tag);
+ part.assign(tag, next - tag);
owner = owner->subdevices().find(part);
if (!owner)
throw emu_fatalerror("Could not find %s when looking up path for device %s\n", part.c_str(), orig_tag);
@@ -151,18 +207,40 @@ std::pair<const char *, device_t *> machine_config::resolve_owner(const char *ta
//-------------------------------------------------
+// prepare_replace - ensure owner is present and
+// existing device is removed if necessary
+//-------------------------------------------------
+
+std::tuple<const char *, device_t *, device_t *> machine_config::prepare_replace(const char *tag)
+{
+ // make sure we have the old device's actual owner
+ std::pair<const char *, device_t *> const owner(resolve_owner(tag));
+ assert(owner.second);
+
+ // remove references to the old device
+ device_t *const old_device(owner.second->subdevice(owner.first));
+ if (old_device)
+ remove_references(*old_device);
+ else
+ osd_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag);
+
+ return std::make_tuple(owner.first, owner.second, old_device);
+}
+
+
+//-------------------------------------------------
// add_device - add a new device at the correct
// point in the hierarchy
//-------------------------------------------------
-device_t *machine_config::add_device(std::unique_ptr<device_t> &&device, device_t *owner)
+device_t &machine_config::add_device(std::unique_ptr<device_t> &&device, device_t *owner)
{
- current_device_stack context(*this);
+ current_device_stack const context(*this);
if (owner)
{
// allocate the new device and append it to the owner's list
- device_t *const result = &owner->subdevices().m_list.append(*device.release());
- result->add_machine_configuration(*this);
+ device_t &result(owner->subdevices().m_list.append(*device.release()));
+ result.add_machine_configuration(*this);
return result;
}
else
@@ -174,91 +252,24 @@ device_t *machine_config::add_device(std::unique_ptr<device_t> &&device, device_
if (driver)
driver->set_game_driver(m_gamedrv);
m_root_device->add_machine_configuration(*this);
- return m_root_device.get();
+ return *m_root_device;
}
}
//-------------------------------------------------
-// device_add - configuration helper to add a
-// new device
-//-------------------------------------------------
-
-device_t *machine_config::device_add(const char *tag, device_type type, u32 clock)
-{
- std::pair<const char *, device_t *> const owner(resolve_owner(tag));
- return add_device(type.create(*this, owner.first, owner.second, clock), owner.second);
-}
-
-
-//-------------------------------------------------
-// device_replace - configuration helper to
-// replace one device with a new device
+// replace_device - substitute the new device for
+// the old one in the owner's list
//-------------------------------------------------
-device_t *machine_config::device_replace(const char *tag, device_type type, u32 clock)
+device_t &machine_config::replace_device(std::unique_ptr<device_t> &&device, device_t &owner, device_t *existing)
{
- // find the original device by relative tag (must exist)
- assert(m_current_device);
- device_t *old_device = m_current_device->subdevice(tag);
- if (!old_device)
- {
- osd_printf_warning("Warning: attempting to replace non-existent device '%s'\n", tag);
- return device_add(tag, type, clock);
- }
- else
- {
- // make sure we have the old device's actual owner
- device_t *const owner = old_device->owner();
- assert(owner);
-
- // remove references to the old device
- remove_references(*old_device);
-
- // allocate the new device and substitute it for the old one in the owner's list
- device_t *const new_device = &owner->subdevices().m_list.replace_and_remove(*type.create(*this, tag, owner, clock).release(), *old_device);
- current_device_stack context(*this);
- new_device->add_machine_configuration(*this);
- return new_device;
- }
-}
-
-
-device_t *machine_config::device_replace(const char *tag, device_type type, const XTAL &clock)
-{
- std::string msg = std::string("Replacing device ") + tag;
- clock.validate(msg);
- return device_replace(tag, type, clock.value());
-}
-
-
-//-------------------------------------------------
-// device_remove - configuration helper to
-// remove a device
-//-------------------------------------------------
-
-device_t *machine_config::device_remove(const char *tag)
-{
- // find the original device by relative tag (must exist)
- assert(m_current_device);
- device_t *const device = m_current_device->subdevice(tag);
- if (device == nullptr)
- {
- osd_printf_warning("Warning: attempting to remove non-existent device '%s'\n", tag);
- }
- else
- {
- // make sure we have the old device's actual owner
- device_t *const owner = device->owner();
- assert(owner);
-
- // remove references to the old device
- remove_references(*device);
-
- // let the device's owner do the work
- owner->subdevices().m_list.remove(*device);
- }
- return nullptr;
+ current_device_stack const context(*this);
+ device_t &result(existing
+ ? owner.subdevices().m_list.replace_and_remove(*device.release(), *existing)
+ : owner.subdevices().m_list.append(*device.release()));
+ result.add_machine_configuration(*this);
+ return result;
}