From 96101a5bd0d05ef498481b5aeb2a65b8c23164b3 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Thu, 26 Jan 2012 21:16:17 +0000 Subject: [PATCH] Change device reset so that the resets proceed hierarchically. Added a device_reset_after_children() hook for things that need to wait for the children to finish. Moved calling the driver/machine/sound/video reset callbacks to the after children time, to align more with how it was happening before. Fixed siblingdevice("") so that it returns the current device and not the owner. --- src/emu/device.c | 20 ++++++++++++++++++++ src/emu/device.h | 23 ++++++++++++++++++++++- src/emu/machine.c | 13 ++++++------- src/emu/machine.h | 2 +- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/emu/device.c b/src/emu/device.c index 9b166287dc4..c9c83b12cbd 100644 --- a/src/emu/device.c +++ b/src/emu/device.c @@ -262,6 +262,13 @@ void device_t::reset() // reset the device device_reset(); + + // reset all child devices + for (device_t *child = m_subdevice_list.first(); child != NULL; child = child->next()) + child->reset(); + + // now allow for some post-child reset action + device_reset_after_children(); // let the interfaces do their post-work for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next()) @@ -579,6 +586,19 @@ void device_t::device_reset() } +//------------------------------------------------- +// device_reset_after_children - hook to do +// reset logic that must happen after the children +// are reset; designed to be overriden by the +// actual device implementation +//------------------------------------------------- + +void device_t::device_reset_after_children() +{ + // do nothing by default +} + + //------------------------------------------------- // device_stop - clean up anything that needs to // happen before the running_machine goes away diff --git a/src/emu/device.h b/src/emu/device.h index 4be5c1c1170..fbe3fbaff0b 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -186,7 +186,7 @@ public: astring &siblingtag(astring &dest, const char *tag) const { return (this != NULL && m_owner != NULL) ? m_owner->subtag(dest, tag) : dest.cpy(tag); } const memory_region *subregion(const char *tag) const; device_t *subdevice(const char *tag) const; - device_t *siblingdevice(const char *tag) const { return (this != NULL && m_owner != NULL) ? m_owner->subdevice(tag) : NULL; } + device_t *siblingdevice(const char *tag) const; template inline _DeviceClass *subdevice(const char *tag) const { return downcast<_DeviceClass *>(subdevice(tag)); } template inline _DeviceClass *siblingdevice(const char *tag) const { return downcast<_DeviceClass *>(siblingdevice(tag)); } const memory_region *region() const { return m_region; } @@ -248,6 +248,7 @@ protected: virtual void device_start() ATTR_COLD = 0; virtual void device_stop() ATTR_COLD; virtual void device_reset() ATTR_COLD; + virtual void device_reset_after_children() ATTR_COLD; virtual void device_pre_save() ATTR_COLD; virtual void device_post_load() ATTR_COLD; virtual void device_clock_changed(); @@ -753,6 +754,26 @@ inline device_t *device_t::subdevice(const char *tag) const } +//------------------------------------------------- +// siblingdevice - given a tag, find the device +// by name relative to this device's parent +//------------------------------------------------- + +inline device_t *device_t::siblingdevice(const char *tag) const +{ + // safety first + if (this == NULL) + return NULL; + + // empty string or NULL means this device + if (tag == NULL || *tag == 0) + return const_cast(this); + + // query relative to the parent + return (m_owner != NULL) ? m_owner->subdevice(tag) : NULL; +} + + //------------------------------------------------- // bind_relative_to - perform a late binding of // a device_delegate diff --git a/src/emu/machine.c b/src/emu/machine.c index 4118d3b0370..2206628b4e4 100644 --- a/src/emu/machine.c +++ b/src/emu/machine.c @@ -932,10 +932,8 @@ void running_machine::start_all_devices() void running_machine::reset_all_devices() { - // iterate over devices and reset them - device_iterator iter(root_device()); - for (device_t *device = iter.first(); device != NULL; device = iter.next()) - device->reset(); + // reset the root and it will reset children + root_device().reset(); } @@ -1268,11 +1266,12 @@ void driver_device::device_start() //------------------------------------------------- -// device_reset - device override which calls -// the various helpers +// device_reset_after_children - device override +// which calls the various helpers; must happen +// after all child devices are reset //------------------------------------------------- -void driver_device::device_reset() +void driver_device::device_reset_after_children() { // reset each piece driver_reset(); diff --git a/src/emu/machine.h b/src/emu/machine.h index dbaf69f93fc..ba99c76534b 100644 --- a/src/emu/machine.h +++ b/src/emu/machine.h @@ -682,7 +682,7 @@ protected: virtual const rom_entry *device_rom_region() const; virtual ioport_constructor device_input_ports() const; virtual void device_start(); - virtual void device_reset(); + virtual void device_reset_after_children(); // internal helpers inline UINT16 paletteram16_le(offs_t offset) const { return m_generic_paletteram[offset & ~1] | (m_generic_paletteram[offset | 1] << 8); }