summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
authorGravatarGravatar Vas Crabb <vas@vastheman.com>2019-10-26 12:47:04 +1100
committerGravatarGravatar Vas Crabb <vas@vastheman.com>2019-10-26 12:47:04 +1100
commitf81fbdb8d4356b7a526a902726463e2f1af00615 (patch)
treef73f8746dc3cd1feb81afdb3cb4e6b0b99141ea0 /src/emu
parentbc7c6ea17e1b38f6fb488177e01c63577fbbcf71 (diff)
Make devdelegate more like devcb for configuration. This is a
fundamental change to show device delegates are configured. Device delegates are now aware of the current device during configuration and will resolve string tags relative to it. This means that device delegates need a device to be supplied on construction so they can find the machine configuration object. There's a one-dimensional array helper to make it easier to construct arrays of device delegates with the same owner. (I didn't make an n-dimensional one because I didn't hit a use case, but it would be a simple addition.) There's no more bind_relative_to member - just call resolve() like you would for a devcb. There's also no need to cast nullptr when creating a late bind device delegate. The flip side is that for an overloaded or non-capturing lambda you'll need to cast to the desired type. There is one less conditional branch in the hot path for calls for delegates bound to a function pointer of member function pointer. This comes at the cost of one additional unconditional branch in the hot path for calls to delegates bound to functoids (lambdas, functions that don't take an object reference, other callable objects). This applies to all delegates, not just device delegates. Address spaces will now print an error message if a late bind error is encountered while installing a handler. This will give the range and address range, hopefully making it easier to guess which memory map is faulty. For the simple case of allowing a device_delegate member to be configured, use a member like this: template <typename... T> void set_foo(T &&...args) { m_foo_cb.set(std::forward<T>(args)...); } For a case where different delegates need to be used depending on the function signature, see src/emu/screen.h (the screen update function setters). Device delegates now take a target specification and function pointer. The target may be: * Target omitted, implying the current device being configured. This can only be used during configuration. It will work as long as the current device is not removed/replaced. * A tag string relative to the current device being configured. This can only be used during configuration. It will not be callable until .resolve() is called. It will work as long as the current device is not removed/replaced. * A device finder (required_device/optional_device). The delegate will late bind to the current target of the device finder. It will not be callable until .resolve() is called. It will work properly if the target device is replaced, as long as the device finder's base object isn't removed/replaced. * A reference to an object. It will be callable immediately. It will work as long as the target object is not removed/replaced. The target types and restrictions are pretty similar to what you already have on object finders and devcb, so it shouldn't cause any surprises. Note that dereferencing a device finder will changes the effect. To illustrate this: ... required_device<some_device> m_dev; ... m_dev(*this, "dev") ... // will late bind to "dev" relative to *this // will work if "dev" hasn't been created yet or is replaced later // won't work if *this is removed/replaced // won't be callable until resolve() is called cb1.set(m_dev, FUNC(some_device::w)); ... // will bind to current target of m_dev // will not work if m_dev is not resolved // will not work if "dev" is replaced later // will be callable immediately cb2.set(*m_dev, FUNC(some_device::w)); ... The order of the target and name has been reversed for functoids (lambdas and other callable objects). This allows the NAME macro to be used on lambdas and functoids. For example: foo.set_something(NAME([this] (u8 data) { m_something = data; })); I realise the diagnostic messages get ugly if you use NAME on a large lambda. You can still give a literal name, you just have to place it after the lambda rather than before. This is uglier, but it's intentional. I'm trying to drive developers away from a certain style. While it's nice that you can put half the driver code in the memory map, it detracts from readability. It's hard to visualise the memory range mappings if the memory map functions are punctuated by large lambdas. There's also slightly higher overhead for calling a delegate bound to a functoid. If the code is prettier for trivial lambdas but uglier for non-trivial lambdas in address maps, it will hopefully steer people away from putting non-trivial lambdas in memory maps. There were some devices that were converted from using plain delegates without adding bind_relative_to calls. I fixed some of them (e.g. LaserDisc) but I probably missed some. These will likely crash on unresolved delegate calls. There are some devices that reset delegates at configuration complete or start time, preventing them from being set up during configuration (e.g. src/devices/video/ppu2c0x.cpp and src/devices/machine/68307.cpp). This goes against the design principles of how device delegates should be used, but I didn't change them because I don't trust myself to find all the places they're used. I've definitely broken some stuff with this (I know about asterix), so report issues and bear with me until I get it all fixed.
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/addrmap.cpp186
-rw-r--r--src/emu/addrmap.h96
-rw-r--r--src/emu/devcb.h91
-rw-r--r--src/emu/devdelegate.cpp31
-rw-r--r--src/emu/devdelegate.h262
-rw-r--r--src/emu/device.cpp2
-rw-r--r--src/emu/device.h1
-rw-r--r--src/emu/device.ipp13
-rw-r--r--src/emu/didisasm.cpp4
-rw-r--r--src/emu/didisasm.h8
-rw-r--r--src/emu/diexec.cpp9
-rw-r--r--src/emu/diexec.h46
-rw-r--r--src/emu/emumem.cpp819
-rw-r--r--src/emu/emumem.h438
-rw-r--r--src/emu/emumem_hedp.h4
-rw-r--r--src/emu/emupal.cpp39
-rw-r--r--src/emu/emupal.h58
-rw-r--r--src/emu/ioport.cpp9
-rw-r--r--src/emu/ioport.h34
-rw-r--r--src/emu/screen.cpp6
-rw-r--r--src/emu/screen.h40
-rw-r--r--src/emu/tilemap.cpp122
-rw-r--r--src/emu/tilemap.h55
23 files changed, 1110 insertions, 1263 deletions
diff --git a/src/emu/addrmap.cpp b/src/emu/addrmap.cpp
index eca9457e76e..c1ba4545492 100644
--- a/src/emu/addrmap.cpp
+++ b/src/emu/addrmap.cpp
@@ -61,21 +61,69 @@ static char *core_i64_hex_format(u64 value, u8 mindigits)
//-------------------------------------------------
address_map_entry::address_map_entry(device_t &device, address_map &map, offs_t start, offs_t end)
- : m_next(nullptr),
- m_map(map),
- m_devbase(device),
- m_addrstart(start),
- m_addrend(end),
- m_addrmirror(0),
- m_addrmask(0),
- m_addrselect(0),
- m_mask(0),
- m_cswidth(0),
- m_share(nullptr),
- m_region(nullptr),
- m_rgnoffs(0),
- m_submap_device(nullptr),
- m_memory(nullptr)
+ : m_next(nullptr)
+ , m_map(map)
+ , m_devbase(device)
+ , m_addrstart(start)
+ , m_addrend(end)
+ , m_addrmirror(0)
+ , m_addrmask(0)
+ , m_addrselect(0)
+ , m_mask(0)
+ , m_cswidth(0)
+ , m_share(nullptr)
+ , m_region(nullptr)
+ , m_rgnoffs(0)
+ , m_rproto8(device)
+ , m_rproto16(device)
+ , m_rproto32(device)
+ , m_rproto64(device)
+ , m_wproto8(device)
+ , m_wproto16(device)
+ , m_wproto32(device)
+ , m_wproto64(device)
+ , m_rproto8m(device)
+ , m_rproto16m(device)
+ , m_rproto32m(device)
+ , m_rproto64m(device)
+ , m_wproto8m(device)
+ , m_wproto16m(device)
+ , m_wproto32m(device)
+ , m_wproto64m(device)
+ , m_rproto8s(device)
+ , m_rproto16s(device)
+ , m_rproto32s(device)
+ , m_rproto64s(device)
+ , m_wproto8s(device)
+ , m_wproto16s(device)
+ , m_wproto32s(device)
+ , m_wproto64s(device)
+ , m_rproto8sm(device)
+ , m_rproto16sm(device)
+ , m_rproto32sm(device)
+ , m_rproto64sm(device)
+ , m_wproto8sm(device)
+ , m_wproto16sm(device)
+ , m_wproto32sm(device)
+ , m_wproto64sm(device)
+ , m_rproto8mo(device)
+ , m_rproto16mo(device)
+ , m_rproto32mo(device)
+ , m_rproto64mo(device)
+ , m_wproto8mo(device)
+ , m_wproto16mo(device)
+ , m_wproto32mo(device)
+ , m_wproto64mo(device)
+ , m_rproto8smo(device)
+ , m_rproto16smo(device)
+ , m_rproto32smo(device)
+ , m_rproto64smo(device)
+ , m_wproto8smo(device)
+ , m_wproto16smo(device)
+ , m_wproto32smo(device)
+ , m_wproto64smo(device)
+ , m_submap_device(nullptr)
+ , m_memory(nullptr)
{
}
@@ -1142,71 +1190,71 @@ void address_map::map_validity_check(validity_checker &valid, int spacenum) cons
if (entry.m_read.m_type == AMH_DEVICE_DELEGATE || entry.m_read.m_type == AMH_DEVICE_DELEGATE_M || entry.m_read.m_type == AMH_DEVICE_DELEGATE_S || entry.m_read.m_type == AMH_DEVICE_DELEGATE_SM || entry.m_read.m_type == AMH_DEVICE_DELEGATE_MO || entry.m_read.m_type == AMH_DEVICE_DELEGATE_SMO)
{
// extract the device tag from the proto-delegate
- const char *devtag = nullptr;
+ std::pair<std::reference_wrapper<device_t>, const char *> devtag(entry.m_devbase, nullptr);
switch (entry.m_read.m_bits)
{
case 8:
if (entry.m_read.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_rproto8.device_name();
+ devtag = entry.m_rproto8.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_rproto8m.device_name();
+ devtag = entry.m_rproto8m.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_rproto8s.device_name();
+ devtag = entry.m_rproto8s.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_rproto8sm.device_name();
+ devtag = entry.m_rproto8sm.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_rproto8mo.device_name();
+ devtag = entry.m_rproto8mo.finder_target();
else
- devtag = entry.m_rproto8smo.device_name();
+ devtag = entry.m_rproto8smo.finder_target();
break;
case 16:
if (entry.m_read.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_rproto16.device_name();
+ devtag = entry.m_rproto16.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_rproto16m.device_name();
+ devtag = entry.m_rproto16m.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_rproto16s.device_name();
+ devtag = entry.m_rproto16s.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_rproto16sm.device_name();
+ devtag = entry.m_rproto16sm.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_rproto16mo.device_name();
+ devtag = entry.m_rproto16mo.finder_target();
else
- devtag = entry.m_rproto16smo.device_name();
+ devtag = entry.m_rproto16smo.finder_target();
break;
case 32:
if (entry.m_read.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_rproto32.device_name();
+ devtag = entry.m_rproto32.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_rproto32m.device_name();
+ devtag = entry.m_rproto32m.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_rproto32s.device_name();
+ devtag = entry.m_rproto32s.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_rproto32sm.device_name();
+ devtag = entry.m_rproto32sm.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_rproto32mo.device_name();
+ devtag = entry.m_rproto32mo.finder_target();
else
- devtag = entry.m_rproto32smo.device_name();
+ devtag = entry.m_rproto32smo.finder_target();
break;
case 64:
if (entry.m_read.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_rproto64.device_name();
+ devtag = entry.m_rproto64.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_rproto64m.device_name();
+ devtag = entry.m_rproto64m.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_rproto64s.device_name();
+ devtag = entry.m_rproto64s.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_rproto64sm.device_name();
+ devtag = entry.m_rproto64sm.finder_target();
else if (entry.m_read.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_rproto64mo.device_name();
+ devtag = entry.m_rproto64mo.finder_target();
else
- devtag = entry.m_rproto64smo.device_name();
+ devtag = entry.m_rproto64smo.finder_target();
break;
}
- if (entry.m_devbase.subdevice(devtag) == nullptr)
- osd_printf_error("%s space memory map entry reads from nonexistent device '%s'\n", spaceconfig.m_name, devtag ? devtag : "<unspecified>");
+ if (devtag.second && !devtag.first.get().subdevice(devtag.second))
+ osd_printf_error("%s space memory map entry reads from nonexistent device '%s'\n", spaceconfig.m_name, devtag.first.get().subtag(devtag.second).c_str());
#ifndef MAME_DEBUG // assert will catch this earlier
(void)entry.unitmask_is_appropriate(entry.m_read.m_bits, entry.m_mask, entry.m_read.m_name);
#endif
@@ -1214,71 +1262,71 @@ void address_map::map_validity_check(validity_checker &valid, int spacenum) cons
if (entry.m_write.m_type == AMH_DEVICE_DELEGATE || entry.m_read.m_type == AMH_DEVICE_DELEGATE_M || entry.m_write.m_type == AMH_DEVICE_DELEGATE_S || entry.m_write.m_type == AMH_DEVICE_DELEGATE_SM || entry.m_read.m_type == AMH_DEVICE_DELEGATE_MO || entry.m_write.m_type == AMH_DEVICE_DELEGATE_SMO)
{
// extract the device tag from the proto-delegate
- const char *devtag = nullptr;
+ std::pair<std::reference_wrapper<device_t>, const char *> devtag(entry.m_devbase, nullptr);
switch (entry.m_write.m_bits)
{
case 8:
if (entry.m_write.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_wproto8.device_name();
+ devtag = entry.m_wproto8.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_wproto8m.device_name();
+ devtag = entry.m_wproto8m.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_wproto8s.device_name();
+ devtag = entry.m_wproto8s.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_wproto8sm.device_name();
+ devtag = entry.m_wproto8sm.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_wproto8mo.device_name();
+ devtag = entry.m_wproto8mo.finder_target();
else
- devtag = entry.m_wproto8smo.device_name();
+ devtag = entry.m_wproto8smo.finder_target();
break;
case 16:
if (entry.m_write.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_wproto16.device_name();
+ devtag = entry.m_wproto16.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_wproto16m.device_name();
+ devtag = entry.m_wproto16m.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_wproto16s.device_name();
+ devtag = entry.m_wproto16s.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_wproto16sm.device_name();
+ devtag = entry.m_wproto16sm.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_wproto16mo.device_name();
+ devtag = entry.m_wproto16mo.finder_target();
else
- devtag = entry.m_wproto16smo.device_name();
+ devtag = entry.m_wproto16smo.finder_target();
break;
case 32:
if (entry.m_write.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_wproto32.device_name();
+ devtag = entry.m_wproto32.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_wproto32m.device_name();
+ devtag = entry.m_wproto32m.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_wproto32s.device_name();
+ devtag = entry.m_wproto32s.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_wproto32sm.device_name();
+ devtag = entry.m_wproto32sm.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_wproto32mo.device_name();
+ devtag = entry.m_wproto32mo.finder_target();
else
- devtag = entry.m_wproto32smo.device_name();
+ devtag = entry.m_wproto32smo.finder_target();
break;
case 64:
if (entry.m_write.m_type == AMH_DEVICE_DELEGATE)
- devtag = entry.m_wproto64.device_name();
+ devtag = entry.m_wproto64.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_M)
- devtag = entry.m_wproto64m.device_name();
+ devtag = entry.m_wproto64m.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_S)
- devtag = entry.m_wproto64s.device_name();
+ devtag = entry.m_wproto64s.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_SM)
- devtag = entry.m_wproto64sm.device_name();
+ devtag = entry.m_wproto64sm.finder_target();
else if (entry.m_write.m_type == AMH_DEVICE_DELEGATE_MO)
- devtag = entry.m_wproto64mo.device_name();
+ devtag = entry.m_wproto64mo.finder_target();
else
- devtag = entry.m_wproto64smo.device_name();
+ devtag = entry.m_wproto64smo.finder_target();
break;
}
- if (entry.m_devbase.subdevice(devtag) == nullptr)
- osd_printf_error("%s space memory map entry writes to nonexistent device '%s'\n", spaceconfig.m_name, devtag ? devtag : "<unspecified>");
+ if (devtag.second && !devtag.first.get().subdevice(devtag.second))
+ osd_printf_error("%s space memory map entry writes to nonexistent device '%s'\n", spaceconfig.m_name, devtag.first.get().subtag(devtag.second).c_str());
#ifndef MAME_DEBUG // assert will catch this earlier
(void)entry.unitmask_is_appropriate(entry.m_write.m_bits, entry.m_mask, entry.m_write.m_name);
#endif
diff --git a/src/emu/addrmap.h b/src/emu/addrmap.h
index ee6b0e4e3b6..b201201c4dd 100644
--- a/src/emu/addrmap.h
+++ b/src/emu/addrmap.h
@@ -81,7 +81,7 @@ class address_map_entry
static device_t &find_device(const device_finder<T, Reqd> &finder) {
const std::pair<device_t &, const char *> target(finder.finder_target());
device_t *device(target.first.subdevice(target.second));
- if (device == nullptr)
+ if (!device)
throw emu_fatalerror("Device %s not found in %s\n", target.second, target.first.tag());
return *device;
}
@@ -186,15 +186,15 @@ public:
// implicit base -> delegate converter
template <typename T, typename Ret, typename... Params>
address_map_entry &r(Ret (T::*read)(Params...), const char *read_name)
- { return r(emu::detail::make_delegate(read, read_name, m_devbase.tag(), make_pointer<T>(m_devbase))); }
+ { return r(emu::detail::make_delegate(*make_pointer<T>(m_devbase), read, read_name)); }
template <typename T, typename Ret, typename... Params>
address_map_entry &w(Ret (T::*write)(Params...), const char *write_name)
- { return w(emu::detail::make_delegate(write, write_name, m_devbase.tag(), make_pointer<T>(m_devbase))); }
+ { return w(emu::detail::make_delegate(*make_pointer<T>(m_devbase), write, write_name)); }
template <typename T, typename RetR, typename... ParamsR, typename U, typename RetW, typename... ParamsW>
address_map_entry &rw(RetR (T::*read)(ParamsR...), const char *read_name, RetW (U::*write)(ParamsW...), const char *write_name)
- { return r(emu::detail::make_delegate(read, read_name, m_devbase.tag(), make_pointer<T>(m_devbase))).w(emu::detail::make_delegate(write, write_name, m_devbase.tag(), make_pointer<U>(m_devbase))); }
+ { return r(emu::detail::make_delegate(*make_pointer<T>(m_devbase), read, read_name)).w(emu::detail::make_delegate(*make_pointer<U>(m_devbase), write, write_name)); }
template <typename T, typename Ret, typename... Params>
address_map_entry &m(Ret (T::*map)(Params...), const char *map_name)
@@ -204,15 +204,15 @@ public:
// device tag -> delegate converter
template <typename T, typename Ret, typename... Params>
address_map_entry &r(const char *tag, Ret (T::*read)(Params...), const char *read_name)
- { return r(emu::detail::make_delegate(read, read_name, tag, nullptr)); }
+ { return r(emu::detail::make_delegate(m_devbase, tag, read, read_name)); }
template <typename T, typename Ret, typename... Params>
address_map_entry &w(const char *tag, Ret (T::*write)(Params...), const char *write_name)
- { return w(emu::detail::make_delegate(write, write_name, tag, nullptr)); }
+ { return w(emu::detail::make_delegate(m_devbase, tag, write, write_name)); }
template <typename T, typename RetR, typename... ParamsR, typename U, typename RetW, typename... ParamsW>
address_map_entry &rw(const char *tag, RetR (T::*read)(ParamsR...), const char *read_name, RetW (U::*write)(ParamsW...), const char *write_name)
- { return r(emu::detail::make_delegate(read, read_name, tag, nullptr)).w(emu::detail::make_delegate(write, write_name, tag, nullptr)); }
+ { return r(emu::detail::make_delegate(m_devbase, tag, read, read_name)).w(emu::detail::make_delegate(m_devbase, tag, write, write_name)); }
template <typename T, typename Ret, typename... Params>
address_map_entry &m(const char *tag, Ret (T::*map)(Params...), const char *map_name)
@@ -222,15 +222,15 @@ public:
// device reference -> delegate converter
template <typename T, typename U, typename Ret, typename... Params>
address_map_entry &r(T &obj, Ret (U::*read)(Params...), const char *read_name)
- { return r(emu::detail::make_delegate(read, read_name, get_tag(obj), make_pointer<U>(obj))); }
+ { return r(emu::detail::make_delegate(*make_pointer<U>(obj), read, read_name)); }
template <typename T, typename U, typename Ret, typename... Params>
address_map_entry &w(T &obj, Ret (U::*write)(Params...), const char *write_name)
- { return w(emu::detail::make_delegate(write, write_name, get_tag(obj), make_pointer<U>(obj))); }
+ { return w(emu::detail::make_delegate(*make_pointer<U>(obj), write, write_name)); }
template <typename T, typename U, typename RetR, typename... ParamsR, typename V, typename RetW, typename... ParamsW>
address_map_entry &rw(T &obj, RetR (U::*read)(ParamsR...), const char *read_name, RetW (V::*write)(ParamsW...), const char *write_name)
- { return r(emu::detail::make_delegate(read, read_name, get_tag(obj), make_pointer<U>(obj))).w(emu::detail::make_delegate(write, write_name, get_tag(obj), make_pointer<V>(obj))); }
+ { return r(emu::detail::make_delegate(*make_pointer<U>(obj), read, read_name)).w(emu::detail::make_delegate(make_pointer<V>(obj), write, write_name)); }
template <typename T, typename U, typename Ret, typename... Params>
address_map_entry &m(T &obj, Ret (U::*map)(Params...), const char *map_name)
@@ -241,39 +241,39 @@ public:
template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
address_map_entry &r(device_finder<T, Reqd> &finder, Ret (U::*read)(Params...), const char *read_name) {
device_t &device(find_device(finder));
- return r(emu::detail::make_delegate(read, read_name, device.tag(), make_pointer<U>(device)));
+ return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name));
}
template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
address_map_entry &r(const device_finder<T, Reqd> &finder, Ret (U::*read)(Params...), const char *read_name) {
device_t &device(find_device(finder));
- return r(emu::detail::make_delegate(read, read_name, device.tag(), make_pointer<U>(device)));
+ return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name));
}
template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
address_map_entry &w(device_finder<T, Reqd> &finder, Ret (U::*write)(Params...), const char *write_name) {
device_t &device(find_device(finder));
- return w(emu::detail::make_delegate(write, write_name, device.tag(), make_pointer<U>(device)));
+ return w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
}
template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
address_map_entry &w(const device_finder<T, Reqd> &finder, Ret (U::*write)(Params...), const char *write_name) {
device_t &device(find_device(finder));
- return w(emu::detail::make_delegate(write, write_name, device.tag(), make_pointer<U>(device)));
+ return w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
}
template <typename T, bool Reqd, typename U, typename RetR, typename... ParamsR, typename V, typename RetW, typename... ParamsW>
address_map_entry &rw(device_finder<T, Reqd> &finder, RetR (U::*read)(ParamsR...), const char *read_name, RetW (V::*write)(ParamsW...), const char *write_name) {
device_t &device(find_device(finder));
- return r(emu::detail::make_delegate(read, read_name, device.tag(), make_pointer<U>(device)))
- .w(emu::detail::make_delegate(write, write_name, device.tag(), make_pointer<V>(device)));
+ return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name))
+ .w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
}
template <typename T, bool Reqd, typename U, typename RetR, typename... ParamsR, typename V, typename RetW, typename... ParamsW>
address_map_entry &rw(const device_finder<T, Reqd> &finder, RetR (U::*read)(ParamsR...), const char *read_name, RetW (V::*write)(ParamsW...), const char *write_name) {
device_t &device(find_device(finder));
- return r(emu::detail::make_delegate(read, read_name, device.tag(), make_pointer<U>(device)))
- .w(emu::detail::make_delegate(write, write_name, device.tag(), make_pointer<V>(device)));
+ return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name))
+ .w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
}
template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
@@ -290,53 +290,41 @@ public:
// lambda -> delegate converter
- template<typename _lr> address_map_entry &lr8(const char *name, _lr &&read) {
- return r(emu::detail::make_lr8_delegate(read, name));
- }
+ template <typename T> address_map_entry &lr8(T &&read, const char *name)
+ { return r(emu::detail::make_lr8_delegate(m_devbase, std::forward<T>(read), name)); }
- template<typename _lr> address_map_entry &lr16(const char *name, _lr &&read) {
- return r(emu::detail::make_lr16_delegate(read, name));
- }
+ template <typename T> address_map_entry &lr16(T &&read, const char *name)
+ { return r(emu::detail::make_lr16_delegate(m_devbase, std::forward<T>(read), name)); }
- template<typename _lr> address_map_entry &lr32(const char *name, _lr &&read) {
- return r(emu::detail::make_lr32_delegate(read, name));
- }
+ template <typename T> address_map_entry &lr32(T &&read, const char *name)
+ { return r(emu::detail::make_lr32_delegate(m_devbase, std::forward<T>(read), name)); }
- template<typename _lr> address_map_entry &lr64(const char *name, _lr &&read) {
- return r(emu::detail::make_lr64_delegate(read, name));
- }
+ template <typename T> address_map_entry &lr64(T &&read, const char *name)
+ { return r(emu::detail::make_lr64_delegate(m_devbase, std::forward<T>(read), name)); }
- template<typename _lw> address_map_entry &lw8(const char *name, _lw &&write) {
- return w(emu::detail::make_lw8_delegate(write, name));
- }
+ template <typename T> address_map_entry &lw8(T &&write, const char *name)
+ { return w(emu::detail::make_lw8_delegate(m_devbase, std::forward<T>(write), name)); }
- template<typename _lw> address_map_entry &lw16(const char *name, _lw &&write) {
- return w(emu::detail::make_lw16_delegate(write, name));
- }
+ template <typename T> address_map_entry &lw16(T &&write, const char *name)
+ { return w(emu::detail::make_lw16_delegate(m_devbase, std::forward<T>(write), name)); }
- template<typename _lw> address_map_entry &lw32(const char *name, _lw &&write) {
- return w(emu::detail::make_lw32_delegate(write, name));
- }
+ template <typename T> address_map_entry &lw32(T &&write, const char *name)
+ { return w(emu::detail::make_lw32_delegate(m_devbase, std::forward<T>(write), name)); }
- template<typename _lw> address_map_entry &lw64(const char *name, _lw &&write) {
- return w(emu::detail::make_lw64_delegate(write, name));
- }
+ template <typename T> address_map_entry &lw64(T &&write, const char *name)
+ { return w(emu::detail::make_lw64_delegate(m_devbase, std::forward<T>(write), name)); }
- template<typename _lr, typename _lw> address_map_entry &lrw8(const char *name, _lr &&read, _lw &&write) {
- return r(emu::detail::make_lr8_delegate(read, name)).w(emu::detail::make_lw8_delegate(write, name));
- }
+ template <typename T, typename U> address_map_entry &lrw8(T &&read, const char *read_name, U &&write, const char *write_name)
+ { return r(emu::detail::make_lr8_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw8_delegate(m_devbase, std::forward<U>(write), write_name)); }
- template<typename _lr, typename _lw> address_map_entry &lrw16(const char *name, _lr &&read, _lw &&write) {
- return r(emu::detail::make_lr16_delegate(read, name)).w(emu::detail::make_lw16_delegate(write, name));
- }
+ template <typename T, typename U> address_map_entry &lrw16(T &&read, const char *read_name, U &&write, const char *write_name)
+ { return r(emu::detail::make_lr16_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw16_delegate(m_devbase, std::forward<U>(write), write_name)); }
- template<typename _lr, typename _lw> address_map_entry &lrw32(const char *name, _lr &&read, _lw &&write) {
- return r(emu::detail::make_lr32_delegate(read, name)).w(emu::detail::make_lw32_delegate(write, name));
- }
+ template <typename T, typename U> address_map_entry &lrw32(T &&read, const char *read_name, U &&write, const char *write_name)
+ { return r(emu::detail::make_lr32_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw32_delegate(m_devbase, std::forward<U>(write), write_name)); }
- template<typename _lr, typename _lw> address_map_entry &lrw64(const char *name, _lr &&read, _lw &&write) {
- return r(emu::detail::make_lr64_delegate(read, name)).w(emu::detail::make_lw64_delegate(write, name));
- }
+ template <typename T, typename U> address_map_entry &lrw64(T &&read, const char *read_name, U &&write, const char *write_name)
+ { return r(emu::detail::make_lr64_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw64_delegate(m_devbase, std::forward<U>(write), write_name)); }
// public state
address_map_entry * m_next; // pointer to the next entry
diff --git a/src/emu/devcb.h b/src/emu/devcb.h
index 6b16c37b33a..321d0831fe1 100644
--- a/src/emu/devcb.h
+++ b/src/emu/devcb.h
@@ -44,16 +44,8 @@ typedef device_delegate<void (int)> write_line_delegate;
namespace emu { namespace detail {
-template <typename T, typename Enable = void> struct read_line_device_class { };
-template <typename T, typename Enable = void> struct write_line_device_class { };
-
-template <typename T>
-inline read_line_delegate make_delegate(T &&func, char const *name, char const *tag, rw_device_class_t<read_line_delegate, std::remove_reference_t<T> > *obj)
-{ return read_line_delegate(func, name, tag, obj); }
-
-template <typename T>
-inline write_line_delegate make_delegate(T &&func, char const *name, char const *tag, rw_device_class_t<write_line_delegate, std::remove_reference_t<T> > *obj)
-{ return write_line_delegate(func, name, tag, obj); }
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read_line_delegate, std::remove_reference_t<T> > > > { using type = read_line_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write_line_delegate, std::remove_reference_t<T> > > > { using type = write_line_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
} } // namespace emu::detail
@@ -115,43 +107,8 @@ protected:
template <typename Input, typename Result, typename Func> using transform_result_t = typename transform_result<Input, Result, Func>::type;
// Mapping method types to delegate types
- template <typename T, typename Enable = void> struct delegate_type;
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read8_delegate, std::remove_reference_t<T> > > > { using type = read8_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read16_delegate, std::remove_reference_t<T> > > > { using type = read16_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read32_delegate, std::remove_reference_t<T> > > > { using type = read32_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read64_delegate, std::remove_reference_t<T> > > > { using type = read64_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read8s_delegate, std::remove_reference_t<T> > > > { using type = read8s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read16s_delegate, std::remove_reference_t<T> > > > { using type = read16s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read32s_delegate, std::remove_reference_t<T> > > > { using type = read32s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read64s_delegate, std::remove_reference_t<T> > > > { using type = read64s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read8sm_delegate, std::remove_reference_t<T> > > > { using type = read8sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read16sm_delegate, std::remove_reference_t<T> > > > { using type = read16sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read32sm_delegate, std::remove_reference_t<T> > > > { using type = read32sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read64sm_delegate, std::remove_reference_t<T> > > > { using type = read64sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read8smo_delegate, std::remove_reference_t<T> > > > { using type = read8smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read16smo_delegate, std::remove_reference_t<T> > > > { using type = read16smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read32smo_delegate, std::remove_reference_t<T> > > > { using type = read32smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read64smo_delegate, std::remove_reference_t<T> > > > { using type = read64smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<read_line_delegate, std::remove_reference_t<T> > > > { using type = read_line_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write8_delegate, std::remove_reference_t<T> > > > { using type = write8_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write16_delegate, std::remove_reference_t<T> > > > { using type = write16_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write32_delegate, std::remove_reference_t<T> > > > { using type = write32_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write64_delegate, std::remove_reference_t<T> > > > { using type = write64_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write8s_delegate, std::remove_reference_t<T> > > > { using type = write8s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write16s_delegate, std::remove_reference_t<T> > > > { using type = write16s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write32s_delegate, std::remove_reference_t<T> > > > { using type = write32s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write64s_delegate, std::remove_reference_t<T> > > > { using type = write64s_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write8sm_delegate, std::remove_reference_t<T> > > > { using type = write8sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write16sm_delegate, std::remove_reference_t<T> > > > { using type = write16sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write32sm_delegate, std::remove_reference_t<T> > > > { using type = write32sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write64sm_delegate, std::remove_reference_t<T> > > > { using type = write64sm_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write8smo_delegate, std::remove_reference_t<T> > > > { using type = write8smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write16smo_delegate, std::remove_reference_t<T> > > > { using type = write16smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write32smo_delegate, std::remove_reference_t<T> > > > { using type = write32smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write64smo_delegate, std::remove_reference_t<T> > > > { using type = write64smo_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> struct delegate_type<T, void_t<emu::detail::rw_device_class_t<write_line_delegate, std::remove_reference_t<T> > > > { using type = write_line_delegate; using device_class = emu::detail::rw_device_class_t<type, std::remove_reference_t<T> >; };
- template <typename T> using delegate_type_t = typename delegate_type<T>::type;
- template <typename T> using delegate_device_class_t = typename delegate_type<T>::device_class;
+ template <typename T> using delegate_type_t = emu::detail::rw_delegate_type_t<T>;
+ template <typename T> using delegate_device_class_t = emu::detail::rw_delegate_device_class_t<T>;
// Invoking transform callbacks
template <typename Input, typename Result, typename T> static std::enable_if_t<is_transform_form1<Input, Result, T>::value, mask_t<transform_result_t<Input, Result, T>, Result> > invoke_transform(T const &cb, address_space &space, offs_t &offset, Input data, std::make_unsigned_t<Input> &mem_mask) { return std::make_unsigned_t<transform_result_t<Input, Result, T> >(cb(space, offset, data, mem_mask)); }
@@ -638,20 +595,17 @@ private:
delegate_builder(devcb_read &target, bool append, device_t &devbase, char const *tag, T &&func, char const *name)
: builder_base(target, append)
, transform_base<output_t, delegate_builder>(DefaultMask & delegate_traits<Delegate>::default_mask)
- , m_devbase(devbase)
- , m_delegate(std::forward<T>(func), name, tag, std::add_pointer_t<devcb_read::delegate_device_class_t<T> >(nullptr))
+ , m_delegate(devbase, tag, std::forward<T>(func), name)
{ }
template <typename T>
delegate_builder(devcb_read &target, bool append, device_t &devbase, devcb_read::delegate_device_class_t<T> &obj, T &&func, char const *name)
: builder_base(target, append)
, transform_base<output_t, delegate_builder>(DefaultMask & delegate_traits<Delegate>::default_mask)
- , m_devbase(devbase)
- , m_delegate(std::forward<T>(func), name, devcb_read::get_tag(obj), &obj)
+ , m_delegate(obj, std::forward<T>(func), name)
{ }
delegate_builder(delegate_builder &&that)
: builder_base(std::move(that))
, transform_base<output_t, delegate_builder>(std::move(that))
- , m_devbase(that.m_devbase)
, m_delegate(std::move(that.m_delegate))
{
that.consume();
@@ -670,8 +624,9 @@ private:
void validity_check(validity_checker &valid) const
{
- if (!m_devbase.subdevice(m_delegate.device_name()))
- osd_printf_error("Read callback bound to non-existent object tag %s (%s)\n", m_delegate.device_name(), m_delegate.name());
+ auto const target(m_delegate.finder_target());
+ if (target.second && !target.first.subdevice(target.second))
+ osd_printf_error("Read callback bound to non-existent object tag %s (%s)\n", target.first.subtag(target.second).c_str(), m_delegate.name());
}
template <typename T>
@@ -679,7 +634,7 @@ private:
{
assert(this->m_consumed);
this->built();
- m_delegate.bind_relative_to(m_devbase);
+ m_delegate.resolve();
chain(
[cb = std::move(this->m_delegate), exor = this->exor(), mask = this->mask()] (address_space &space, offs_t offset, input_mask_t mem_mask)
{ return (devcb_read::invoke_read<Result>(cb, space, offset, mem_mask & mask) ^ exor) & mask; });
@@ -690,7 +645,6 @@ private:
delegate_builder &operator=(delegate_builder const &) = delete;
delegate_builder &operator=(delegate_builder &&that) = delete;
- device_t &m_devbase;
Delegate m_delegate;
};
@@ -1328,7 +1282,6 @@ private:
wrapped_builder(delegate_builder &&that)
: builder_base(std::move(that))
- , m_devbase(that.m_devbase)
, m_delegate(std::move(that.m_delegate))
{
that.consume();
@@ -1336,7 +1289,6 @@ private:
}
wrapped_builder(wrapped_builder &&that)
: builder_base(std::move(that))
- , m_devbase(that.m_devbase)
, m_delegate(std::move(that.m_delegate))
{
that.consume();
@@ -1345,15 +1297,16 @@ private:
void validity_check(validity_checker &valid) const
{
- if (!m_devbase.subdevice(m_delegate.device_name()))
- osd_printf_error("Write callback bound to non-existent object tag %s (%s)\n", m_delegate.device_name(), m_delegate.name());
+ auto const target(m_delegate.finder_target());
+ if (target.second && !target.first.subdevice(target.second))
+ osd_printf_error("Write callback bound to non-existent object tag %s (%s)\n", target.first.subtag(target.second).c_str(), m_delegate.name());
}
auto build()
{
assert(this->m_consumed);
this->built();
- m_delegate.bind_relative_to(m_devbase);
+ m_delegate.resolve();
return
[cb = std::move(this->m_delegate)] (address_space &space, offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{ devcb_write::invoke_write<Input>(cb, space, offset, data, mem_mask); };
@@ -1364,7 +1317,6 @@ private:
wrapped_builder operator=(wrapped_builder const &) = delete;
wrapped_builder operator=(wrapped_builder &&that) = delete;
- device_t &m_devbase;
Delegate m_delegate;
};
@@ -1374,7 +1326,6 @@ private:
delegate_builder &operator=(delegate_builder const &) = delete;
delegate_builder &operator=(delegate_builder &&that) = delete;
- device_t &m_devbase;
Delegate m_delegate;
public:
@@ -1384,20 +1335,17 @@ private:
delegate_builder(devcb_write &target, bool append, device_t &devbase, char const *tag, T &&func, char const *name)
: builder_base(target, append)
, transform_base<mask_t<Input, typename delegate_traits<Delegate>::input_t>, delegate_builder>(DefaultMask & delegate_traits<Delegate>::default_mask)
- , m_devbase(devbase)
- , m_delegate(std::forward<T>(func), name, tag, std::add_pointer_t<devcb_write::delegate_device_class_t<T> >(nullptr))
+ , m_delegate(devbase, tag, std::forward<T>(func), name)
{ }
template <typename T>
delegate_builder(devcb_write &target, bool append, device_t &devbase, devcb_write::delegate_device_class_t<T> &obj, T &&func, char const *name)
: builder_base(target, append)
, transform_base<mask_t<Input, typename delegate_traits<Delegate>::input_t>, delegate_builder>(DefaultMask & delegate_traits<Delegate>::default_mask)
- , m_devbase(devbase)
- , m_delegate(std::forward<T>(func), name, devcb_write::get_tag(obj), &obj)
+ , m_delegate(obj, std::forward<T>(func), name)
{ }
delegate_builder(delegate_builder &&that)
: builder_base(std::move(that))
, transform_base<mask_t<Input, typename delegate_traits<Delegate>::input_t>, delegate_builder>(std::move(that))
- , m_devbase(that.m_devbase)
, m_delegate(std::move(that.m_delegate))
{
that.consume();
@@ -1415,15 +1363,16 @@ private:
void validity_check(validity_checker &valid) const
{
- if (!m_devbase.subdevice(m_delegate.device_name()))
- osd_printf_error("Write callback bound to non-existent object tag %s (%s)\n", m_delegate.device_name(), m_delegate.name());
+ auto const target(m_delegate.finder_target());
+ if (target.second && !target.first.subdevice(target.second))
+ osd_printf_error("Write callback bound to non-existent object tag %s (%s)\n", target.first.subtag(target.second).c_str(), m_delegate.name());
}
auto build()
{
assert(this->m_consumed);
this->built();
- m_delegate.bind_relative_to(m_devbase);
+ m_delegate.resolve();
return
[cb = std::move(this->m_delegate), exor = this->exor(), mask = this->mask()] (address_space &space, offs_t offset, input_t data, std::make_unsigned_t<input_t> mem_mask)
{ devcb_write::invoke_write<Input>(cb, space, offset, (data ^ exor) & mask, mem_mask & mask); };
diff --git a/src/emu/devdelegate.cpp b/src/emu/devdelegate.cpp
index 380f01180e2..0396b583706 100644
--- a/src/emu/devdelegate.cpp
+++ b/src/emu/devdelegate.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/***************************************************************************
devdelegate.c
@@ -9,29 +9,26 @@
***************************************************************************/
#include "emu.h"
+#include "devdelegate.h"
-//-------------------------------------------------
-// bound_object - use the device name to locate
-// a device relative to the given search root;
-// fatal error if not found
-//-------------------------------------------------
+namespace emu { namespace detail {
-delegate_late_bind &device_delegate_helper::bound_object(device_t &search_root) const
+delegate_late_bind &device_delegate_helper::bound_object() const
{
- device_t *device = search_root.subdevice(m_device_name);
- if (device == nullptr)
- throw emu_fatalerror("Unable to locate device '%s' relative to '%s'\n", m_device_name, search_root.tag());
+ if (!m_tag)
+ return m_base.get();
+ device_t *const device(m_base.get().subdevice(m_tag));
+ if (!device)
+ throw emu_fatalerror("Unable to locate device '%s' relative to '%s'\n", m_tag, m_base.get().tag());
return *device;
}
-//-------------------------------------------------
-// safe_tag - return a tag string or (unknown) if
-// the object is not valid
-//-------------------------------------------------
-
-const char *device_delegate_helper::safe_tag(device_t *object)
+void device_delegate_helper::set_tag(char const *tag)
{
- return (object != nullptr) ? object->tag() : "(unknown)";
+ m_base = m_base.get().mconfig().current_device();
+ m_tag = tag;
}
+
+} } // namespace emu::detail
diff --git a/src/emu/devdelegate.h b/src/emu/devdelegate.h
index 8bdef60f880..bbb94930d43 100644
--- a/src/emu/devdelegate.h
+++ b/src/emu/devdelegate.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/***************************************************************************
devdelegate.h
@@ -7,7 +7,6 @@
Delegates that are late-bound to MAME devices.
***************************************************************************/
-
#ifndef MAME_EMU_DEVDELEGATE_H
#define MAME_EMU_DEVDELEGATE_H
@@ -15,28 +14,59 @@
#include "delegate.h"
+#include <array>
+#include <functional>
+#include <type_traits>
+#include <utility>
+
+
+namespace emu {
+
+//**************************************************************************
+// FORWARD DECLARATIONS
+//**************************************************************************
+
+template <typename Signature, unsigned Count> class device_delegate_array;
+
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
+namespace detail {
+
// ======================> device_delegate_helper
// device_delegate_helper does non-template work
class device_delegate_helper
{
+public:
+ // accessors
+ char const *finder_tag() const { return m_tag; }
+ std::pair<device_t &, char const *> finder_target() const { return std::make_pair(m_base, m_tag); }
+
protected:
- // constructor
- device_delegate_helper(const char *devname) : m_device_name(devname) { }
+ // construct/assign
+ device_delegate_helper(device_t &owner, char const *tag = nullptr) : m_base(owner), m_tag(tag) { }
+ template <class DeviceClass, bool Required> device_delegate_helper(device_finder<DeviceClass, Required> const &finder);
+ device_delegate_helper(device_delegate_helper const &) = default;
+ device_delegate_helper &operator=(device_delegate_helper const &) = default;
// internal helpers
- delegate_late_bind &bound_object(device_t &search_root) const;
- static const char *safe_tag(device_t *object);
+ delegate_late_bind &bound_object() const;
+ void set_tag(device_t &object) { m_base = object; m_tag = nullptr; }
+ void set_tag(device_t &base, char const *tag) { m_base = base; m_tag = tag; }
+ void set_tag(char const *tag);
+ template <class DeviceClass, bool Required> void set_tag(device_finder<DeviceClass, Required> const &finder);
- // internal state
- const char *m_device_name;
+private:
+ std::reference_wrapper<device_t> m_base;
+ char const *m_tag;
};
+} // namespace detail
+
// ======================> named_delegate
template <typename Signature>
@@ -45,7 +75,7 @@ class named_delegate : public delegate<Signature>
private:
using basetype = delegate<Signature>;
- const char * m_name; // name string
+ char const *m_name = nullptr; // name string
protected:
template <class FunctionClass> using member_func_type = typename basetype::template member_func_type<FunctionClass>;
@@ -54,59 +84,193 @@ protected:
public:
// create a standard set of constructors
- named_delegate() : basetype(), m_name(nullptr) { }
- explicit named_delegate(const basetype &src) : basetype(src), m_name(src.m_name) { }
- named_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), m_name(src.m_name) { }
- template <class FunctionClass> named_delegate(member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
- template <class FunctionClass> named_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
- explicit named_delegate(std::function<Signature> funcptr, const char *name) : basetype(funcptr), m_name(name) { }
- template <class FunctionClass> named_delegate(static_ref_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
- named_delegate &operator=(const basetype &src) { basetype::operator=(src); m_name = src.m_name; return *this; }
-
- const char *name() const { return m_name; }
+ named_delegate() = default;
+ named_delegate(named_delegate const &) = default;
+ named_delegate(named_delegate const &src, delegate_late_bind &object) : basetype(src, object), m_name(src.m_name) { }
+ template <class FunctionClass> named_delegate(member_func_type<FunctionClass> funcptr, char const *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
+ template <class FunctionClass> named_delegate(const_member_func_type<FunctionClass> funcptr, char const *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
+ template <class FunctionClass> named_delegate(static_ref_func_type<FunctionClass> funcptr, char const *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
+ template <typename T> named_delegate(T &&funcptr, std::enable_if_t<std::is_constructible<std::function<Signature>, T>::value, char const *> name) : basetype(std::forward<T>(funcptr)), m_name(name) { }
+
+ // allow assignment
+ named_delegate &operator=(named_delegate const &src) = default;
+
+ char const *name() const { return m_name; }
};
// ======================> device_delegate
// device_delegate is a delegate that wraps with a device tag and can be easily
// late bound without replicating logic everywhere
-template <typename Signature>
-class device_delegate : public named_delegate<Signature>, public device_delegate_helper
+template <typename Signature> class device_delegate;
+
+template <typename ReturnType, typename... Params>
+class device_delegate<ReturnType (Params...)> : protected named_delegate<ReturnType (Params...)>, public detail::device_delegate_helper
{
- using thistype = device_delegate<Signature>;
- using basetype = named_delegate<Signature>;
- template <class FunctionClass> using member_func_type = typename basetype::template member_func_type<FunctionClass>;
- template <class FunctionClass> using const_member_func_type = typename basetype::template const_member_func_type<FunctionClass>;
- template <class FunctionClass> using static_ref_func_type = typename basetype::template static_ref_func_type<FunctionClass>;
+private:
+ using basetype = named_delegate<ReturnType (Params...)>;
+
+ template <class T, class U> struct is_related_device_implementation
+ { static constexpr bool value = std::is_base_of<T, U>::value && std::is_base_of<device_t, U>::value; };
+ template <class T, class U> struct is_related_device_interface
+ { static constexpr bool value = std::is_base_of<T, U>::value && std::is_base_of<device_interface, U>::value && !std::is_base_of<device_t, U>::value; };
+ template <class T, class U> struct is_related_device
+ { static constexpr bool value = is_related_device_implementation<T, U>::value || is_related_device_interface<T, U>::value; };
+
+ template <class T> static std::enable_if_t<is_related_device_implementation<T, T>::value, device_t &> get_device(T &object) { return object; }
+ template <class T> static std::enable_if_t<is_related_device_interface<T, T>::value, device_t &> get_device(T &object) { return object.device(); }
public:
- // provide the same constructors as the base class
- device_delegate() : basetype(), device_delegate_helper(nullptr) { }
- device_delegate(const basetype &src) : basetype(src), device_delegate_helper(src.m_device_name) { }
- device_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), device_delegate_helper(src.m_device_name) { }
- template <class FunctionClass> device_delegate(member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
- template <class FunctionClass> device_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
- template <class FunctionClass> device_delegate(static_ref_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
- device_delegate(std::function<Signature> funcptr, const char *name) : basetype(funcptr, name), device_delegate_helper(nullptr) { }
- device_delegate &operator=(const thistype &src) { basetype::operator=(src); m_device_name = src.m_device_name; return *this; }
-
- // provide additional constructors that take a device name string
- template <class FunctionClass> device_delegate(member_func_type<FunctionClass> funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
- template <class FunctionClass> device_delegate(member_func_type<FunctionClass> funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
- template <class FunctionClass> device_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
- template <class FunctionClass> device_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
- template <class FunctionClass> device_delegate(static_ref_func_type<FunctionClass> funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
- device_delegate(static_ref_func_type<device_t> funcptr, const char *name) : basetype(funcptr, name, static_cast<device_t *>(nullptr)), device_delegate_helper(nullptr) { }
-
- // and constructors that provide a search root
- device_delegate(const thistype &src, device_t &search_root) : basetype(src), device_delegate_helper(src.m_device_name) { bind_relative_to(search_root); }
+ template <unsigned Count> using array = device_delegate_array<ReturnType (Params...), Count>;
+
+ template <typename T> struct supports_callback
+ { static constexpr bool value = std::is_constructible<device_delegate, device_t &, char const *, T, char const *>::value; };
+
+ // construct/assign
+ explicit device_delegate(device_t &owner) : basetype(), detail::device_delegate_helper(owner) { }
+ device_delegate(device_delegate const &) = default;
+ device_delegate &operator=(device_delegate const &) = default;
+
+ // construct with prototype and target
+ device_delegate(basetype const &proto, device_t &object) : basetype(proto, object), detail::device_delegate_helper(object) { }
+ device_delegate(device_delegate const &proto, device_t &object) : basetype(proto, object), detail::device_delegate_helper(object) { }
+
+ // construct with base and tag
+ template <class D>
+ device_delegate(device_t &base, char const *tag, ReturnType (D::*funcptr)(Params...), char const *name)
+ : basetype(funcptr, name, static_cast<D *>(nullptr))
+ , detail::device_delegate_helper(base, tag)
+ { }
+ template <class D>
+ device_delegate(device_t &base, char const *tag, ReturnType (D::*funcptr)(Params...) const, char const *name)
+ : basetype(funcptr, name, static_cast<D *>(nullptr))
+ , detail::device_delegate_helper(base, tag)
+ { }
+ template <class D>
+ device_delegate(device_t &base, char const *tag, ReturnType (*funcptr)(D &, Params...), char const *name)
+ : basetype(funcptr, name, static_cast<D *>(nullptr))
+ , detail::device_delegate_helper(base, tag)
+ { }
+
+ // construct with device finder
+ template <class D, bool R, class E>
+ device_delegate(device_finder<D, R> const &finder, ReturnType (E::*funcptr)(Params...), char const *name)
+ : basetype(funcptr, name, static_cast<E *>(nullptr))
+ , detail::device_delegate_helper(finder)
+ { }
+ template <class D, bool R, class E>
+ device_delegate(device_finder<D, R> const &finder, ReturnType (E::*funcptr)(Params...) const, char const *name)
+ : basetype(funcptr, name, static_cast<E *>(nullptr))
+ , detail::device_delegate_helper(finder)
+ { }
+ template <class D, bool R, class E>
+ device_delegate(device_finder<D, R> const &finder, ReturnType (*funcptr)(E &, Params...), char const *name)
+ : basetype(funcptr, name, static_cast<E *>(nullptr))
+ , detail::device_delegate_helper(finder)
+ { }
+
+ // construct with target object
+ template <class T, class D>
+ device_delegate(T &object, ReturnType (D::*funcptr)(Params...), std::enable_if_t<is_related_device<D, T>::value, char const *> name)
+ : basetype(funcptr, name, static_cast<D *>(&object))
+ , detail::device_delegate_helper(get_device(object))
+ { }
+ template <class T, class D>
+ device_delegate(T &object, ReturnType (D::*funcptr)(Params...) const, std::enable_if_t<is_related_device<D, T>::value, char const *> name)
+ : basetype(funcptr, name, static_cast<D *>(&object))
+ , detail::device_delegate_helper(get_device(object))
+ { }
+ template <class T, class D>
+ device_delegate(T &object, ReturnType (*funcptr)(D &, Params...), std::enable_if_t<is_related_device<D, T>::value, char const *> name)
+ : basetype(funcptr, name, static_cast<D *>(&object))
+ , detail::device_delegate_helper(get_device(object))
+ { }
+
+ // construct with callable object
+ template <typename T>
+ device_delegate(device_t &owner, T &&funcptr, std::enable_if_t<std::is_constructible<std::function<ReturnType (Params...)>, T>::value, char const *> name)
+ : basetype(std::forward<T>(funcptr), name)
+ , detail::device_delegate_helper(owner)
+ { basetype::operator=(basetype(std::forward<T>(funcptr), name)); }
+
+ // setters that implicitly bind to the current device
+ template <class D> void set(ReturnType (D::*funcptr)(Params...), char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(nullptr))); set_tag(nullptr); }
+ template <class D> void set(ReturnType (D::*funcptr)(Params...) const, char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(nullptr))); set_tag(nullptr); }
+ template <class D> void set(ReturnType (*funcptr)(D &, Params...), char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(nullptr))); set_tag(nullptr); }
+
+ // setters that take a tag-like object specifying the target
+ template <typename T, class D> void set(T &&tag, ReturnType (D::*funcptr)(Params...), char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(nullptr))); set_tag(std::forward<T>(tag)); }
+ template <typename T, class D> void set(T &&tag, ReturnType (D::*funcptr)(Params...) const, char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(nullptr))); set_tag(std::forward<T>(tag)); }
+ template <typename T, class D> void set(T &&tag, ReturnType (*funcptr)(D &, Params...), char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(nullptr))); set_tag(std::forward<T>(tag)); }
+
+ // setters that take a target object
+ template <class T, class D> std::enable_if_t<std::is_base_of<D, T>::value> set(T &object, ReturnType (D::*funcptr)(Params...), char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(&object))); set_tag(finder_target().first); }
+ template <class T, class D> std::enable_if_t<std::is_base_of<D, T>::value> set(T &object, ReturnType (D::*funcptr)(Params...) const, char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(&object))); set_tag(finder_target().first); }
+ template <class T, class D> std::enable_if_t<std::is_base_of<D, T>::value> set(T &object, ReturnType (*funcptr)(D &, Params...), char const *name)
+ { basetype::operator=(basetype(funcptr, name, static_cast<D *>(&object))); set_tag(finder_target().first); }
+
+ // setter that takes a functoid
+ template <typename T> std::enable_if_t<std::is_constructible<std::function<ReturnType (Params...)>, T>::value> set(T &&funcptr, char const *name)
+ { basetype::operator=(basetype(std::forward<T>(funcptr), name)); }
+
+ // unsetter
+ void set(std::nullptr_t)
+ { basetype::operator=(basetype()); set_tag(finder_target().first); }
// perform the binding
- void bind_relative_to(device_t &search_root) { if (!basetype::isnull()) basetype::late_bind(bound_object(search_root)); }
+ void resolve() { if (!basetype::isnull() && !basetype::has_object()) basetype::late_bind(bound_object()); }
- // getter (for validation purposes)
- const char *device_name() const { return m_device_name; }
+ // accessors
+ using basetype::operator();
+ using basetype::isnull;
+ using basetype::has_object;
+ using basetype::name;
};
+// simplifies constructing an array of delegates with a single owner
+template <typename Signature, unsigned Count>
+class device_delegate_array : public std::array<device_delegate<Signature>, Count>
+{
+private:
+ template <unsigned... V>
+ device_delegate_array(device_t &owner, std::integer_sequence<unsigned, V...> const &)
+ : std::array<device_delegate<Signature>, Count>{ make_one<V>(owner)... }
+ {
+ }
+
+ template <unsigned N> device_delegate<Signature> make_one(device_t &owner)
+ {
+ return device_delegate<Signature>(owner);
+ }
+
+public:
+ using std::array<device_delegate<Signature>, Count>::array;
+
+ device_delegate_array(device_t &owner)
+ : device_delegate_array(owner, std::make_integer_sequence<unsigned, Count>())
+ {
+ }
+
+ void resolve_all()
+ {
+ for (device_delegate<Signature> &elem : *this)
+ elem.resolve();
+ }
+};
+
+} // namespace emu
+
+
+using emu::named_delegate;
+using emu::device_delegate;
+
#endif // MAME_EMU_DEVDELEGATE_H
diff --git a/src/emu/device.cpp b/src/emu/device.cpp
index 42edf893168..5dc0366d99e 100644
--- a/src/emu/device.cpp
+++ b/src/emu/device.cpp
@@ -852,7 +852,7 @@ device_t *device_t::subdevice_slow(const char *tag) const
// we presume the result is a rooted path; also doubled colons mess up our
// tree walk, so catch them early
assert(fulltag[0] == ':');
- assert(fulltag.find("::") == -1);
+ assert(fulltag.find("::") == std::string::npos);
// walk the device list to the final path
device_t *curdevice = &mconfig().root_device();
diff --git a/src/emu/device.h b/src/emu/device.h
index 257311deb7f..a99c4589eab 100644
--- a/src/emu/device.h
+++ b/src/emu/device.h
@@ -596,6 +596,7 @@ public:
u32 unscaled_clock() const { return m_unscaled_clock; }
void set_unscaled_clock(u32 clock);
void set_unscaled_clock(const XTAL &xtal) { set_unscaled_clock(xtal.value()); }
+ void set_unscaled_clock_int(u32 clock) { set_unscaled_clock(clock); } // non-overloaded name because binding to overloads is ugly
double clock_scale() const { return m_clock_scale; }
void set_clock_scale(double clockscale);
attotime clocks_to_attotime(u64 clocks) const;
diff --git a/src/emu/device.ipp b/src/emu/device.ipp
index 9cc7a791278..2d7a5a29b7b 100644
--- a/src/emu/device.ipp
+++ b/src/emu/device.ipp
@@ -60,6 +60,19 @@ inline DeviceClass &device_type_impl<DeviceClass>::operator()(machine_config_rep
return finder = result;
}
+
+template <class DeviceClass, bool Required>
+inline device_delegate_helper::device_delegate_helper(device_finder<DeviceClass, Required> const &finder)
+ : device_delegate_helper(finder.finder_target().first, finder.finder_tag())
+{
+}
+
+template <class DeviceClass, bool Required>
+inline void device_delegate_helper::set_tag(device_finder<DeviceClass, Required> const &finder)
+{
+ std::tie(m_base, m_tag) = finder.finder_target();
+}
+
} } // namespace emu::detail
diff --git a/src/emu/didisasm.cpp b/src/emu/didisasm.cpp
index 7454e54ec3c..cd30ae6fd9a 100644
--- a/src/emu/didisasm.cpp
+++ b/src/emu/didisasm.cpp
@@ -49,7 +49,7 @@ private:
device_disasm_interface::device_disasm_interface(const machine_config &mconfig, device_t &device)
- : device_interface(device, "disasm"), m_disasm(), m_dasm_override(), m_started(false)
+ : device_interface(device, "disasm"), m_disasm(), m_dasm_override(device), m_started(false)
{
}
@@ -69,6 +69,6 @@ void device_disasm_interface::interface_pre_start()
if (!m_started)
{
m_started = true;
- m_dasm_override.bind_relative_to(*device().owner());
+ m_dasm_override.resolve();
}
}
diff --git a/src/emu/didisasm.h b/src/emu/didisasm.h
index c63fe0cc421..4a727dc7834 100644
--- a/src/emu/didisasm.h
+++ b/src/emu/didisasm.h
@@ -35,13 +35,7 @@ public:
virtual ~device_disasm_interface() = default;
// Override
- template <typename Obj> void set_dasm_override(Obj &&cb) { m_dasm_override = std::forward<Obj>(cb); }
- void set_dasm_override(dasm_override_delegate callback) { m_dasm_override = callback; }
- template <class FunctionClass> void set_dasm_override(offs_t (FunctionClass::*callback)(std::ostream &, offs_t,
- const util::disasm_interface::data_buffer &, const util::disasm_interface::data_buffer &), const char *name)
- {
- set_dasm_override(dasm_override_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
- }
+ template <typename... T> void set_dasm_override(T &&... args) { m_dasm_override.set(std::forward<T>(args)...); }
// disassembler request
util::disasm_interface &get_disassembler();
diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp
index fba63aa1e7d..4df8bb33493 100644
--- a/src/emu/diexec.cpp
+++ b/src/emu/diexec.cpp
@@ -46,9 +46,12 @@ device_execute_interface::device_execute_interface(const machine_config &mconfig
: device_interface(device, "execute")
, m_scheduler(nullptr)
, m_disabled(false)
+ , m_vblank_interrupt(device)
, m_vblank_interrupt_screen(nullptr)
+ , m_timed_interrupt(device)
, m_timed_interrupt_period(attotime::zero)
, m_nextexec(nullptr)
+ , m_driver_irq(device)
, m_timedint_timer(nullptr)
, m_profiler(PROFILER_IDLE)
, m_icountptr(nullptr)
@@ -371,9 +374,9 @@ void device_execute_interface::interface_pre_start()
m_scheduler = &device().machine().scheduler();
// bind delegates
- m_vblank_interrupt.bind_relative_to(*device().owner());
- m_timed_interrupt.bind_relative_to(*device().owner());
- m_driver_irq.bind_relative_to(*device().owner());
+ m_vblank_interrupt.resolve();
+ m_timed_interrupt.resolve();
+ m_driver_irq.resolve();
// fill in the initial states
int const index = device_iterator(device().machine().root_device()).indexof(*this);
diff --git a/src/emu/diexec.h b/src/emu/diexec.h
index 663cc6ddb1c..056033b95c6 100644
--- a/src/emu/diexec.h
+++ b/src/emu/diexec.h
@@ -114,53 +114,41 @@ public:
// inline configuration helpers
void set_disable() { m_disabled = true; }
- template <typename Object> void set_vblank_int(Object &&cb, const char *tag)
- {
- m_vblank_interrupt = std::forward<Object>(cb);
- m_vblank_interrupt_screen = tag;
- }
- void set_vblank_int(device_interrupt_delegate callback, const char *tag)
+
+ template <typename... T> void set_vblank_int(const char *tag, T &&... args)
{
- m_vblank_interrupt = callback;
+ m_vblank_interrupt.set(std::forward<T>(args)...);
m_vblank_interrupt_screen = tag;
}
- template <class FunctionClass> void set_vblank_int(const char *tag, const char *devname, void (FunctionClass::*callback)(device_t &), const char *name)
+ void remove_vblank_int()
{
- set_vblank_int(device_interrupt_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)), tag);
- }
- template <class FunctionClass> void set_vblank_int(const char *tag, void (FunctionClass::*callback)(device_t &), const char *name)
- {
- set_vblank_int(device_interrupt_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)), tag);
+ m_vblank_interrupt = device_interrupt_delegate(*this);
+ m_vblank_interrupt_screen = nullptr;
}
- template <typename Object> void set_periodic_int(Object &&cb, const attotime &rate)
+ template <typename F> void set_periodic_int(F &&cb, const char *name, const attotime &rate)
{
- m_timed_interrupt = std::forward<Object>(cb);
+ m_timed_interrupt.set(std::forward<F>(cb), name);
m_timed_interrupt_period = rate;
}
- void set_periodic_int(device_interrupt_delegate callback, const attotime &rate)
+ template <typename T, typename F> void set_periodic_int(T &&target, F &&cb, const char *name, const attotime &rate)
{
- m_timed_interrupt = callback;
+ m_timed_interrupt.set(std::forward<T>(target), std::forward<F>(cb), name);
m_timed_interrupt_period = rate;
}
- template <class FunctionClass> void set_periodic_int(const char *devname, void (FunctionClass::*callback)(device_t &), const char *name, const attotime &rate)
- {
- set_periodic_int(device_interrupt_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)), rate);
- }
- template <class FunctionClass> void set_periodic_int(void (FunctionClass::*callback)(device_t &), const char *name, const attotime &rate)
+ void remove_periodic_int()
{
- set_periodic_int(device_interrupt_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)), rate);
+ m_timed_interrupt = device_interrupt_delegate(*this);
+ m_timed_interrupt_period = attotime();
}
- template <typename Object> void set_irq_acknowledge_callback(Object &&cb) { m_driver_irq = std::forward<Object>(cb); }
- void set_irq_acknowledge_callback(device_irq_acknowledge_delegate callback) { m_driver_irq = callback; }
- template <class FunctionClass> void set_irq_acknowledge_callback(const char *devname, int (FunctionClass::*callback)(device_t &, int), const char *name)
+ template <typename... T> void set_irq_acknowledge_callback(T &&... args)
{
- set_irq_acknowledge_callback(device_irq_acknowledge_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
+ m_driver_irq.set(std::forward<T>(args)...);
}
- template <class FunctionClass> void set_irq_acknowledge_callback(int (FunctionClass::*callback)(device_t &, int), const char *name)
+ void remove_irq_acknowledge_callback()
{
- set_irq_acknowledge_callback(device_irq_acknowledge_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
+ m_driver_irq = device_irq_acknowledge_delegate(*this);
}
// execution management
diff --git a/src/emu/emumem.cpp b/src/emu/emumem.cpp
index 57032751880..cccee057ad1 100644
--- a/src/emu/emumem.cpp
+++ b/src/emu/emumem.cpp
@@ -226,6 +226,56 @@ class address_space_specific : public address_space
using NativeType = uX;
using this_type = address_space_specific<Width, AddrShift, Endian>;
+ template <typename Delegate, typename Dummy = void> struct handler_width;
+ template <typename Dummy> struct handler_width<read8_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<read8m_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<read8s_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<read8sm_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<read8mo_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<read8smo_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<write8_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<write8m_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<write8s_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<write8sm_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<write8mo_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<write8smo_delegate, Dummy> { static constexpr int value = 0; };
+ template <typename Dummy> struct handler_width<read16_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<read16m_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<read16s_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<read16sm_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<read16mo_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<read16smo_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<write16_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<write16m_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<write16s_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<write16sm_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<write16mo_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<write16smo_delegate, Dummy> { static constexpr int value = 1; };
+ template <typename Dummy> struct handler_width<read32_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<read32m_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<read32s_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<read32sm_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<read32mo_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<read32smo_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<write32_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<write32m_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<write32s_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<write32sm_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<write32mo_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<write32smo_delegate, Dummy> { static constexpr int value = 2; };
+ template <typename Dummy> struct handler_width<read64_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<read64m_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<read64s_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<read64sm_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<read64mo_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<read64smo_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<write64_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<write64m_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<write64s_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<write64sm_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<write64mo_delegate, Dummy> { static constexpr int value = 3; };
+ template <typename Dummy> struct handler_width<write64smo_delegate, Dummy> { static constexpr int value = 3; };
+
// constants describing the native size
static constexpr u32 NATIVE_BYTES = 1 << Width;
static constexpr u32 NATIVE_STEP = AddrShift >= 0 ? NATIVE_BYTES << iabs(AddrShift) : NATIVE_BYTES >> iabs(AddrShift);
@@ -245,83 +295,155 @@ public:
void install_readwrite_port(offs_t addrstart, offs_t addrend, offs_t addrmirror, std::string rtag, std::string wtag) override;
void install_device_delegate(offs_t addrstart, offs_t addrend, device_t &device, address_map_constructor &map, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8_delegate rhandler, write8_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16_delegate rhandler, write16_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32_delegate rhandler, write32_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64_delegate rhandler, write64_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
-
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8m_delegate rhandler, write8m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16m_delegate rhandler, write16m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32m_delegate rhandler, write32m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64m_delegate rhandler, write64m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
-
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8s_delegate rhandler, write8s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16s_delegate rhandler, write16s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32s_delegate rhandler, write32s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64s_delegate rhandler, write64s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
-
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8sm_delegate rhandler, write8sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16sm_delegate rhandler, write16sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32sm_delegate rhandler, write32sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64sm_delegate rhandler, write64sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
-
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8mo_delegate rhandler, write8mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16mo_delegate rhandler, write16mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32mo_delegate rhandler, write32mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64mo_delegate rhandler, write64mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
-
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8smo_delegate rhandler, write8smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16smo_delegate rhandler, write16smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32smo_delegate rhandler, write32smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
- void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64smo_delegate rhandler, write64smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override;
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8_delegate rhandler, write8_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16_delegate rhandler, write16_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32_delegate rhandler, write32_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64_delegate rhandler, write64_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8m_delegate rhandler, write8m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16m_delegate rhandler, write16m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32m_delegate rhandler, write32m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64m_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64m_delegate rhandler, write64m_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8s_delegate rhandler, write8s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16s_delegate rhandler, write16s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32s_delegate rhandler, write32s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64s_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64s_delegate rhandler, write64s_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8sm_delegate rhandler, write8sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16sm_delegate rhandler, write16sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32sm_delegate rhandler, write32sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64sm_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64sm_delegate rhandler, write64sm_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8mo_delegate rhandler, write8mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16mo_delegate rhandler, write16mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32mo_delegate rhandler, write32mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64mo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64mo_delegate rhandler, write64mo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8smo_delegate rhandler, write8smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16smo_delegate rhandler, write16smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32smo_delegate rhandler, write32smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
+ void install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64smo_delegate rhandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_read_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler); }
+ void install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_write_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, whandler); }
+ void install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64smo_delegate rhandler, write64smo_delegate whandler, u64 unitmask = 0, int cswidth = 0) override
+ { install_readwrite_handler_impl(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler); }
using address_space::install_read_tap;
using address_space::install_write_tap;
@@ -537,9 +659,47 @@ public:
std::unordered_set<handler_entry *> m_delayed_unrefs;
private:
+ template<typename READ>
+ void install_read_handler_impl(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth, READ &handler_r)
+ {
+ try { handler_r.resolve(); }
+ catch (const binding_type_exception &) {
+ osd_printf_error("Binding error while installing read handler %s for range 0x%X-0x%X mask 0x%X mirror 0x%X select 0x%X umask 0x%X\n", handler_r.name(), addrstart, addrend, addrmask, addrmirror, addrselect, unitmask);
+ throw;
+ }
+ install_read_handler_helper<handler_width<READ>::value>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler_r);
+ }
+
+ template<typename WRITE>
+ void install_write_handler_impl(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth, WRITE &handler_w)
+ {
+ try { handler_w.resolve(); }
+ catch (const binding_type_exception &) {
+ osd_printf_error("Binding error while installing write handler %s for range 0x%X-0x%X mask 0x%X mirror 0x%X select 0x%X umask 0x%X\n", handler_w.name(), addrstart, addrend, addrmask, addrmirror, addrselect, unitmask);
+ throw;
+ }
+ install_write_handler_helper<handler_width<WRITE>::value>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler_w);
+ }
+
+ template<typename READ, typename WRITE>
+ void install_readwrite_handler_impl(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth, READ &handler_r, WRITE &handler_w)
+ {
+ static_assert(handler_width<READ>::value == handler_width<WRITE>::value, "handler widths do not match");
+ try { handler_r.resolve(); }
+ catch (const binding_type_exception &) {
+ osd_printf_error("Binding error while installing read handler %s for range 0x%X-0x%X mask 0x%X mirror 0x%X select 0x%X umask 0x%X\n", handler_r.name(), addrstart, addrend, addrmask, addrmirror, addrselect, unitmask);
+ throw;
+ }
+ try { handler_w.resolve(); }
+ catch (const binding_type_exception &) {
+ osd_printf_error("Binding error while installing write handler %s for range 0x%X-0x%X mask 0x%X mirror 0x%X select 0x%X umask 0x%X\n", handler_w.name(), addrstart, addrend, addrmask, addrmirror, addrselect, unitmask);
+ throw;
+ }
+ install_readwrite_handler_helper<handler_width<READ>::value>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler_r, handler_w);
+ }
+
template<int AccessWidth, typename READ> std::enable_if_t<(Width == AccessWidth)>
- install_read_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- READ handler_r)
+ install_read_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth, const READ &handler_r)
{
VPRINTF(("address_space::install_read_handler(%s-%s mask=%s mirror=%s, space width=%d, handler width=%d, %s, %s)\n",
core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars),
@@ -560,7 +720,7 @@ private:
template<int AccessWidth, typename READ> std::enable_if_t<(Width > AccessWidth)>
install_read_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- READ handler_r)
+ const READ &handler_r)
{
VPRINTF(("address_space::install_read_handler(%s-%s mask=%s mirror=%s, space width=%d, handler width=%d, %s, %s)\n",
core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars),
@@ -584,14 +744,14 @@ private:
template<int AccessWidth, typename READ> std::enable_if_t<(Width < AccessWidth)>
install_read_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- READ handler_r)
+ const READ &handler_r)
{
fatalerror("install_read_handler: cannot install a %d-wide handler in a %d-wide bus", 8 << AccessWidth, 8 << Width);
}
template<int AccessWidth, typename WRITE> std::enable_if_t<(Width == AccessWidth)>
install_write_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- WRITE handler_w)
+ const WRITE &handler_w)
{
VPRINTF(("address_space::install_write_handler(%s-%s mask=%s mirror=%s, space width=%d, handler width=%d, %s, %s)\n",
core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars),
@@ -612,7 +772,7 @@ private:
template<int AccessWidth, typename WRITE> std::enable_if_t<(Width > AccessWidth)>
install_write_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- WRITE handler_w)
+ const WRITE &handler_w)
{
VPRINTF(("address_space::install_write_handler(%s-%s mask=%s mirror=%s, space width=%d, handler width=%d, %s, %s)\n",
core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars),
@@ -636,7 +796,7 @@ private:
template<int AccessWidth, typename WRITE> std::enable_if_t<(Width < AccessWidth)>
install_write_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- WRITE handler_w)
+ const WRITE &handler_w)
{
fatalerror("install_write_handler: cannot install a %d-wide handler in a %d-wide bus", 8 << AccessWidth, 8 << Width);
}
@@ -645,8 +805,8 @@ private:
template<int AccessWidth, typename READ, typename WRITE> std::enable_if_t<(Width == AccessWidth)>
install_readwrite_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- READ handler_r,
- WRITE handler_w)
+ const READ &handler_r,
+ const WRITE &handler_w)
{
VPRINTF(("address_space::install_readwrite_handler(%s-%s mask=%s mirror=%s, space width=%d, handler width=%d, %s, %s, %s)\n",
core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars),
@@ -672,8 +832,8 @@ private:
template<int AccessWidth, typename READ, typename WRITE> std::enable_if_t<(Width > AccessWidth)>
install_readwrite_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- READ handler_r,
- WRITE handler_w)
+ const READ &handler_r,
+ const WRITE &handler_w)
{
VPRINTF(("address_space::install_readwrite_handler(%s-%s mask=%s mirror=%s, space width=%d, handler width=%d, %s, %s, %s)\n",
core_i64_hex_format(addrstart, m_addrchars), core_i64_hex_format(addrend, m_addrchars),
@@ -704,8 +864,8 @@ private:
template<int AccessWidth, typename READ, typename WRITE> std::enable_if_t<(Width < AccessWidth)>
install_readwrite_handler_helper(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, u64 unitmask, int cswidth,
- READ handler_r,
- WRITE handler_w)
+ const READ &handler_r,
+ const WRITE &handler_w)
{
fatalerror("install_readwrite_handler: cannot install a %d-wide handler in a %d-wide bus", 8 << AccessWidth, 8 << Width);
}
@@ -1370,18 +1530,18 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
if (readorwrite == read_or_write::READ)
switch (data.m_bits)
{
- case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read8_delegate(entry.m_rproto8, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read16_delegate(entry.m_rproto16, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read32_delegate(entry.m_rproto32, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read64_delegate(entry.m_rproto64, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto8, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto16, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto32, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto64, entry.m_mask, entry.m_cswidth); break;
}
else
switch (data.m_bits)
{
- case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write8_delegate(entry.m_wproto8, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write16_delegate(entry.m_wproto16, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write32_delegate(entry.m_wproto32, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write64_delegate(entry.m_wproto64, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto8, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto16, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto32, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto64, entry.m_mask, entry.m_cswidth); break;
}
break;
@@ -1389,18 +1549,18 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
if (readorwrite == read_or_write::READ)
switch (data.m_bits)
{
- case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read8m_delegate(entry.m_rproto8m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read16m_delegate(entry.m_rproto16m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read32m_delegate(entry.m_rproto32m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read64m_delegate(entry.m_rproto64m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto8m, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto16m, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto32m, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto64m, entry.m_mask, entry.m_cswidth); break;
}
else
switch (data.m_bits)
{
- case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write8m_delegate(entry.m_wproto8m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write16m_delegate(entry.m_wproto16m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write32m_delegate(entry.m_wproto32m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write64m_delegate(entry.m_wproto64m, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto8m, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto16m, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto32m, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto64m, entry.m_mask, entry.m_cswidth); break;
}
break;
@@ -1408,18 +1568,18 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
if (readorwrite == read_or_write::READ)
switch (data.m_bits)
{
- case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read8s_delegate(entry.m_rproto8s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read16s_delegate(entry.m_rproto16s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read32s_delegate(entry.m_rproto32s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read64s_delegate(entry.m_rproto64s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto8s, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto16s, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto32s, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto64s, entry.m_mask, entry.m_cswidth); break;
}
else
switch (data.m_bits)
{
- case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write8s_delegate(entry.m_wproto8s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write16s_delegate(entry.m_wproto16s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write32s_delegate(entry.m_wproto32s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write64s_delegate(entry.m_wproto64s, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto8s, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto16s, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto32s, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto64s, entry.m_mask, entry.m_cswidth); break;
}
break;
@@ -1427,18 +1587,18 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
if (readorwrite == read_or_write::READ)
switch (data.m_bits)
{
- case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read8sm_delegate(entry.m_rproto8sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read16sm_delegate(entry.m_rproto16sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read32sm_delegate(entry.m_rproto32sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read64sm_delegate(entry.m_rproto64sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto8sm, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto16sm, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto32sm, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto64sm, entry.m_mask, entry.m_cswidth); break;
}
else
switch (data.m_bits)
{
- case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write8sm_delegate(entry.m_wproto8sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write16sm_delegate(entry.m_wproto16sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write32sm_delegate(entry.m_wproto32sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write64sm_delegate(entry.m_wproto64sm, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto8sm, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto16sm, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto32sm, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto64sm, entry.m_mask, entry.m_cswidth); break;
}
break;
@@ -1446,18 +1606,18 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
if (readorwrite == read_or_write::READ)
switch (data.m_bits)
{
- case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read8mo_delegate(entry.m_rproto8mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read16mo_delegate(entry.m_rproto16mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read32mo_delegate(entry.m_rproto32mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read64mo_delegate(entry.m_rproto64mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto8mo, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto16mo, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto32mo, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto64mo, entry.m_mask, entry.m_cswidth); break;
}
else
switch (data.m_bits)
{
- case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write8mo_delegate(entry.m_wproto8mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write16mo_delegate(entry.m_wproto16mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write32mo_delegate(entry.m_wproto32mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write64mo_delegate(entry.m_wproto64mo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto8mo, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto16mo, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto32mo, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto64mo, entry.m_mask, entry.m_cswidth); break;
}
break;
@@ -1465,18 +1625,18 @@ void address_space::populate_map_entry(const address_map_entry &entry, read_or_w
if (readorwrite == read_or_write::READ)
switch (data.m_bits)
{
- case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read8smo_delegate(entry.m_rproto8smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read16smo_delegate(entry.m_rproto16smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read32smo_delegate(entry.m_rproto32smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, read64smo_delegate(entry.m_rproto64smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto8smo, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto16smo, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto32smo, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_read_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_rproto64smo, entry.m_mask, entry.m_cswidth); break;
}
else
switch (data.m_bits)
{
- case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write8smo_delegate(entry.m_wproto8smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write16smo_delegate(entry.m_wproto16smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write32smo_delegate(entry.m_wproto32smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
- case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, write64smo_delegate(entry.m_wproto64smo, entry.m_devbase), entry.m_mask, entry.m_cswidth); break;
+ case 8: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto8smo, entry.m_mask, entry.m_cswidth); break;
+ case 16: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto16smo, entry.m_mask, entry.m_cswidth); break;
+ case 32: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto32smo, entry.m_mask, entry.m_cswidth); break;
+ case 64: install_write_handler(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror, entry.m_addrselect, entry.m_wproto64smo, entry.m_mask, entry.m_cswidth); break;
}
break;
@@ -2080,389 +2240,6 @@ template<int Width, int AddrShift, endianness_t Endian> void address_space_speci
}
-//-------------------------------------------------
-// install_handler - install 8-bit read/write
-// delegate handlers for the space
-//-------------------------------------------------
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8_delegate rhandler, write8_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8m_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8m_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8m_delegate rhandler, write8m_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8s_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8s_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8s_delegate rhandler, write8s_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8sm_delegate rhandler, write8sm_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8mo_delegate rhandler, write8mo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write8smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read8smo_delegate rhandler, write8smo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<0>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-
-//-------------------------------------------------
-// install_handler - install 16-bit read/write
-// delegate handlers for the space
-//-------------------------------------------------
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16_delegate rhandler, write16_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16m_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16m_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16m_delegate rhandler, write16m_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16s_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16s_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16s_delegate rhandler, write16s_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16sm_delegate rhandler, write16sm_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16smo_delegate rhandler, write16smo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write16mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read16mo_delegate rhandler, write16mo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<1>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-
-//-------------------------------------------------
-// install_handler - install 32-bit read/write
-// delegate handlers for the space
-//-------------------------------------------------
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32_delegate rhandler, write32_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32m_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32m_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32m_delegate rhandler, write32m_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32s_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32s_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32s_delegate rhandler, write32s_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32sm_delegate rhandler, write32sm_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32mo_delegate rhandler, write32mo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write32smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read32smo_delegate rhandler, write32smo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<2>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-
-//-------------------------------------------------
-// install_handler64 - install 64-bit read/write
-// delegate handlers for the space
-//-------------------------------------------------
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64_delegate rhandler, write64_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64m_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64m_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64m_delegate rhandler, write64m_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64s_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64s_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64s_delegate rhandler, write64s_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64sm_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64sm_delegate rhandler, write64sm_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64mo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64mo_delegate rhandler, write64mo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_read_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_read_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_write_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, write64smo_delegate handler, u64 unitmask, int cswidth)
-{
- install_write_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, handler);
-}
-
-template<int Width, int AddrShift, endianness_t Endian> void address_space_specific<Width, AddrShift, Endian>::install_readwrite_handler(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, read64smo_delegate rhandler, write64smo_delegate whandler, u64 unitmask, int cswidth)
-{
- install_readwrite_handler_helper<3>(addrstart, addrend, addrmask, addrmirror, addrselect, unitmask, cswidth, rhandler, whandler);
-}
-
//**************************************************************************
// MEMORY MAPPING HELPERS
//**************************************************************************
diff --git a/src/emu/emumem.h b/src/emu/emumem.h
index 0bd3de898ca..4e0cf858bb4 100644
--- a/src/emu/emumem.h
+++ b/src/emu/emumem.h
@@ -156,372 +156,275 @@ using write64smo_delegate = device_delegate<void (u64)>;
namespace emu { namespace detail {
+// TODO: replace with std::void_t when we move to C++17
+template <typename... T> struct void_wrapper { using type = void; };
+template <typename... T> using void_t = typename void_wrapper<T...>::type;
+
template <typename D, typename T, typename Enable = void> struct rw_device_class { };
template <typename D, typename T, typename Ret, typename... Params>
-struct rw_device_class<D, Ret (T::*)(Params...), std::enable_if_t<std::is_constructible<D, Ret (T::*)(Params...), const char *, const char *, T *>::value> > { using type = T; };
+struct rw_device_class<D, Ret (T::*)(Params...), std::enable_if_t<std::is_constructible<D, device_t &, const char *, Ret (T::*)(Params...), const char *>::value> > { using type = T; };
template <typename D, typename T, typename Ret, typename... Params>
-struct rw_device_class<D, Ret (T::*)(Params...) const, std::enable_if_t<std::is_constructible<D, Ret (T::*)(Params...) const, const char *, const char *, T *>::value> > { using type = T; };
+struct rw_device_class<D, Ret (T::*)(Params...) const, std::enable_if_t<std::is_constructible<D, device_t &, const char *, Ret (T::*)(Params...) const, const char *>::value> > { using type = T; };
template <typename D, typename T, typename Ret, typename... Params>
-struct rw_device_class<D, Ret (*)(T &, Params...), std::enable_if_t<std::is_constructible<D, Ret (*)(T &, Params...), const char *, const char *, T *>::value> > { using type = T; };
-
-template <typename D, typename T> using rw_device_class_t = typename rw_device_class <D, T>::type;
-
-template <typename T>
-inline read8_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read8_delegate, std::remove_reference_t<T> > *obj)
-{ return read8_delegate(func, name, tag, obj); }
-template <typename T>
-inline read16_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read16_delegate, std::remove_reference_t<T> > *obj)
-{ return read16_delegate(func, name, tag, obj); }
-template <typename T>
-inline read32_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read32_delegate, std::remove_reference_t<T> > *obj)
-{ return read32_delegate(func, name, tag, obj); }
-template <typename T>
-inline read64_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read64_delegate, std::remove_reference_t<T> > *obj)
-{ return read64_delegate(func, name, tag, obj); }
-
-template <typename T>
-inline write8_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write8_delegate, std::remove_reference_t<T> > *obj)
-{ return write8_delegate(func, name, tag, obj); }
-template <typename T>
-inline write16_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write16_delegate, std::remove_reference_t<T> > *obj)
-{ return write16_delegate(func, name, tag, obj); }
-template <typename T>
-inline write32_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write32_delegate, std::remove_reference_t<T> > *obj)
-{ return write32_delegate(func, name, tag, obj); }
-template <typename T>
-inline write64_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write64_delegate, std::remove_reference_t<T> > *obj)
-{ return write64_delegate(func, name, tag, obj); }
-
-
-template <typename T>
-inline read8m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read8m_delegate, std::remove_reference_t<T> > *obj)
-{ return read8m_delegate(func, name, tag, obj); }
-template <typename T>
-inline read16m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read16m_delegate, std::remove_reference_t<T> > *obj)
-{ return read16m_delegate(func, name, tag, obj); }
-template <typename T>
-inline read32m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read32m_delegate, std::remove_reference_t<T> > *obj)
-{ return read32m_delegate(func, name, tag, obj); }
-template <typename T>
-inline read64m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read64m_delegate, std::remove_reference_t<T> > *obj)
-{ return read64m_delegate(func, name, tag, obj); }
-
-template <typename T>
-inline write8m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write8m_delegate, std::remove_reference_t<T> > *obj)
-{ return write8m_delegate(func, name, tag, obj); }
-template <typename T>
-inline write16m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write16m_delegate, std::remove_reference_t<T> > *obj)
-{ return write16m_delegate(func, name, tag, obj); }
-template <typename T>
-inline write32m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write32m_delegate, std::remove_reference_t<T> > *obj)
-{ return write32m_delegate(func, name, tag, obj); }
-template <typename T>
-inline write64m_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write64m_delegate, std::remove_reference_t<T> > *obj)
-{ return write64m_delegate(func, name, tag, obj); }
-
-
-template <typename T>
-inline read8s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read8s_delegate, std::remove_reference_t<T> > *obj)
-{ return read8s_delegate(func, name, tag, obj); }
-template <typename T>
-inline read16s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read16s_delegate, std::remove_reference_t<T> > *obj)
-{ return read16s_delegate(func, name, tag, obj); }
-template <typename T>
-inline read32s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read32s_delegate, std::remove_reference_t<T> > *obj)
-{ return read32s_delegate(func, name, tag, obj); }
-template <typename T>
-inline read64s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read64s_delegate, std::remove_reference_t<T> > *obj)
-{ return read64s_delegate(func, name, tag, obj); }
-
-template <typename T>
-inline write8s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write8s_delegate, std::remove_reference_t<T> > *obj)
-{ return write8s_delegate(func, name, tag, obj); }
-template <typename T>
-inline write16s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write16s_delegate, std::remove_reference_t<T> > *obj)
-{ return write16s_delegate(func, name, tag, obj); }
-template <typename T>
-inline write32s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write32s_delegate, std::remove_reference_t<T> > *obj)
-{ return write32s_delegate(func, name, tag, obj); }
-template <typename T>
-inline write64s_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write64s_delegate, std::remove_reference_t<T> > *obj)
-{ return write64s_delegate(func, name, tag, obj); }
-
-
-template <typename T>
-inline read8sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read8sm_delegate, std::remove_reference_t<T> > *obj)
-{ return read8sm_delegate(func, name, tag, obj); }
-template <typename T>
-inline read16sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read16sm_delegate, std::remove_reference_t<T> > *obj)
-{ return read16sm_delegate(func, name, tag, obj); }
-template <typename T>
-inline read32sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read32sm_delegate, std::remove_reference_t<T> > *obj)
-{ return read32sm_delegate(func, name, tag, obj); }
-template <typename T>
-inline read64sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read64sm_delegate, std::remove_reference_t<T> > *obj)
-{ return read64sm_delegate(func, name, tag, obj); }
-
-template <typename T>
-inline write8sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write8sm_delegate, std::remove_reference_t<T> > *obj)
-{ return write8sm_delegate(func, name, tag, obj); }
-template <typename T>
-inline write16sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write16sm_delegate, std::remove_reference_t<T> > *obj)
-{ return write16sm_delegate(func, name, tag, obj); }
-template <typename T>
-inline write32sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write32sm_delegate, std::remove_reference_t<T> > *obj)
-{ return write32sm_delegate(func, name, tag, obj); }
-template <typename T>
-inline write64sm_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write64sm_delegate, std::remove_reference_t<T> > *obj)
-{ return write64sm_delegate(func, name, tag, obj); }
-
-
-template <typename T>
-inline read8mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read8mo_delegate, std::remove_reference_t<T> > *obj)
-{ return read8mo_delegate(func, name, tag, obj); }
-template <typename T>
-inline read16mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read16mo_delegate, std::remove_reference_t<T> > *obj)
-{ return read16mo_delegate(func, name, tag, obj); }
-template <typename T>
-inline read32mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read32mo_delegate, std::remove_reference_t<T> > *obj)
-{ return read32mo_delegate(func, name, tag, obj); }
-template <typename T>
-inline read64mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read64mo_delegate, std::remove_reference_t<T> > *obj)
-{ return read64mo_delegate(func, name, tag, obj); }
-
-template <typename T>
-inline write8mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write8mo_delegate, std::remove_reference_t<T> > *obj)
-{ return write8mo_delegate(func, name, tag, obj); }
-template <typename T>
-inline write16mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write16mo_delegate, std::remove_reference_t<T> > *obj)
-{ return write16mo_delegate(func, name, tag, obj); }
-template <typename T>
-inline write32mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write32mo_delegate, std::remove_reference_t<T> > *obj)
-{ return write32mo_delegate(func, name, tag, obj); }
-template <typename T>
-inline write64mo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write64mo_delegate, std::remove_reference_t<T> > *obj)
-{ return write64mo_delegate(func, name, tag, obj); }
+struct rw_device_class<D, Ret (*)(T &, Params...), std::enable_if_t<std::is_constructible<D, device_t &, const char *, Ret (*)(T &, Params...), const char *>::value> > { using type = T; };
+
+template <typename D, typename T> using rw_device_class_t = typename rw_device_class<D, T>::type;
+
+template <typename T, typename Enable = void> struct rw_delegate_type;
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read8_delegate, std::remove_reference_t<T> > > > { using type = read8_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read16_delegate, std::remove_reference_t<T> > > > { using type = read16_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read32_delegate, std::remove_reference_t<T> > > > { using type = read32_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read64_delegate, std::remove_reference_t<T> > > > { using type = read64_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read8m_delegate, std::remove_reference_t<T> > > > { using type = read8m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read16m_delegate, std::remove_reference_t<T> > > > { using type = read16m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read32m_delegate, std::remove_reference_t<T> > > > { using type = read32m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read64m_delegate, std::remove_reference_t<T> > > > { using type = read64m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read8s_delegate, std::remove_reference_t<T> > > > { using type = read8s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read16s_delegate, std::remove_reference_t<T> > > > { using type = read16s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read32s_delegate, std::remove_reference_t<T> > > > { using type = read32s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read64s_delegate, std::remove_reference_t<T> > > > { using type = read64s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read8sm_delegate, std::remove_reference_t<T> > > > { using type = read8sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read16sm_delegate, std::remove_reference_t<T> > > > { using type = read16sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read32sm_delegate, std::remove_reference_t<T> > > > { using type = read32sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read64sm_delegate, std::remove_reference_t<T> > > > { using type = read64sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read8mo_delegate, std::remove_reference_t<T> > > > { using type = read8mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read16mo_delegate, std::remove_reference_t<T> > > > { using type = read16mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read32mo_delegate, std::remove_reference_t<T> > > > { using type = read32mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read64mo_delegate, std::remove_reference_t<T> > > > { using type = read64mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read8smo_delegate, std::remove_reference_t<T> > > > { using type = read8smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read16smo_delegate, std::remove_reference_t<T> > > > { using type = read16smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read32smo_delegate, std::remove_reference_t<T> > > > { using type = read32smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<read64smo_delegate, std::remove_reference_t<T> > > > { using type = read64smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write8_delegate, std::remove_reference_t<T> > > > { using type = write8_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write16_delegate, std::remove_reference_t<T> > > > { using type = write16_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write32_delegate, std::remove_reference_t<T> > > > { using type = write32_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write64_delegate, std::remove_reference_t<T> > > > { using type = write64_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write8m_delegate, std::remove_reference_t<T> > > > { using type = write8m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write16m_delegate, std::remove_reference_t<T> > > > { using type = write16m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write32m_delegate, std::remove_reference_t<T> > > > { using type = write32m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write64m_delegate, std::remove_reference_t<T> > > > { using type = write64m_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write8s_delegate, std::remove_reference_t<T> > > > { using type = write8s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write16s_delegate, std::remove_reference_t<T> > > > { using type = write16s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write32s_delegate, std::remove_reference_t<T> > > > { using type = write32s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write64s_delegate, std::remove_reference_t<T> > > > { using type = write64s_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write8sm_delegate, std::remove_reference_t<T> > > > { using type = write8sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write16sm_delegate, std::remove_reference_t<T> > > > { using type = write16sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write32sm_delegate, std::remove_reference_t<T> > > > { using type = write32sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write64sm_delegate, std::remove_reference_t<T> > > > { using type = write64sm_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write8mo_delegate, std::remove_reference_t<T> > > > { using type = write8mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write16mo_delegate, std::remove_reference_t<T> > > > { using type = write16mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write32mo_delegate, std::remove_reference_t<T> > > > { using type = write32mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write64mo_delegate, std::remove_reference_t<T> > > > { using type = write64mo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write8smo_delegate, std::remove_reference_t<T> > > > { using type = write8smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write16smo_delegate, std::remove_reference_t<T> > > > { using type = write16smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write32smo_delegate, std::remove_reference_t<T> > > > { using type = write32smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> struct rw_delegate_type<T, void_t<rw_device_class_t<write64smo_delegate, std::remove_reference_t<T> > > > { using type = write64smo_delegate; using device_class = rw_device_class_t<type, std::remove_reference_t<T> >; };
+template <typename T> using rw_delegate_type_t = typename rw_delegate_type<T>::type;
+template <typename T> using rw_delegate_device_class_t = typename rw_delegate_type<T>::device_class;
template <typename T>
-inline read8smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read8smo_delegate, std::remove_reference_t<T> > *obj)
-{ return read8smo_delegate(func, name, tag, obj); }
-template <typename T>
-inline read16smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read16smo_delegate, std::remove_reference_t<T> > *obj)
-{ return read16smo_delegate(func, name, tag, obj); }
-template <typename T>
-inline read32smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read32smo_delegate, std::remove_reference_t<T> > *obj)
-{ return read32smo_delegate(func, name, tag, obj); }
-template <typename T>
-inline read64smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<read64smo_delegate, std::remove_reference_t<T> > *obj)
-{ return read64smo_delegate(func, name, tag, obj); }
+inline rw_delegate_type_t<T> make_delegate(device_t &base, char const *tag, T &&func, char const *name)
+{ return rw_delegate_type_t<T>(base, tag, std::forward<T>(func), name); }
template <typename T>
-inline write8smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write8smo_delegate, std::remove_reference_t<T> > *obj)
-{ return write8smo_delegate(func, name, tag, obj); }
-template <typename T>
-inline write16smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write16smo_delegate, std::remove_reference_t<T> > *obj)
-{ return write16smo_delegate(func, name, tag, obj); }
-template <typename T>
-inline write32smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write32smo_delegate, std::remove_reference_t<T> > *obj)
-{ return write32smo_delegate(func, name, tag, obj); }
-template <typename T>
-inline write64smo_delegate make_delegate(T &&func, const char *name, const char *tag, rw_device_class_t<write64smo_delegate, std::remove_reference_t<T> > *obj)
-{ return write64smo_delegate(func, name, tag, obj); }
-
+inline rw_delegate_type_t<T> make_delegate(rw_delegate_device_class_t<T> &object, T &&func, char const *name)
+{ return rw_delegate_type_t<T>(object, std::forward<T>(func), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read8_delegate, L, const char *>::value, read8_delegate> make_lr8_delegate(L l, const char *name)
-{ return read8_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read8_delegate, device_t &, L, const char *>::value, read8_delegate> make_lr8_delegate(device_t &owner, L &&l, const char *name)
+{ return read8_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read8m_delegate, L, const char *>::value, read8m_delegate> make_lr8_delegate(L l, const char *name)
-{ return read8m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read8m_delegate, device_t &, L, const char *>::value, read8m_delegate> make_lr8_delegate(device_t &owner, L &&l, const char *name)
+{ return read8m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read8s_delegate, L, const char *>::value, read8s_delegate> make_lr8_delegate(L l, const char *name)
-{ return read8s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read8s_delegate, device_t &, L, const char *>::value, read8s_delegate> make_lr8_delegate(device_t &owner, L &&l, const char *name)
+{ return read8s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read8sm_delegate, L, const char *>::value, read8sm_delegate> make_lr8_delegate(L l, const char *name)
-{ return read8sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read8sm_delegate, device_t &, L, const char *>::value, read8sm_delegate> make_lr8_delegate(device_t &owner, L &&l, const char *name)
+{ return read8sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read8mo_delegate, L, const char *>::value, read8mo_delegate> make_lr8_delegate(L l, const char *name)
-{ return read8mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read8mo_delegate, device_t &, L, const char *>::value, read8mo_delegate> make_lr8_delegate(device_t &owner, L &&l, const char *name)
+{ return read8mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read8smo_delegate, L, const char *>::value, read8smo_delegate> make_lr8_delegate(L l, const char *name)
-{ return read8smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read8smo_delegate, device_t &, L, const char *>::value, read8smo_delegate> make_lr8_delegate(device_t &owner, L &&l, const char *name)
+{ return read8smo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read16_delegate, L, const char *>::value, read16_delegate> make_lr16_delegate(L l, const char *name)
-{ return read16_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read16_delegate, device_t &, L, const char *>::value, read16_delegate> make_lr16_delegate(device_t &owner, L &&l, const char *name)
+{ return read16_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read16m_delegate, L, const char *>::value, read16m_delegate> make_lr16_delegate(L l, const char *name)
-{ return read16m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read16m_delegate, device_t &, L, const char *>::value, read16m_delegate> make_lr16_delegate(device_t &owner, L &&l, const char *name)
+{ return read16m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read16s_delegate, L, const char *>::value, read16s_delegate> make_lr16_delegate(L l, const char *name)
-{ return read16s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read16s_delegate, device_t &, L, const char *>::value, read16s_delegate> make_lr16_delegate(device_t &owner, L &&l, const char *name)
+{ return read16s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read16sm_delegate, L, const char *>::value, read16sm_delegate> make_lr16_delegate(L l, const char *name)
-{ return read16sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read16sm_delegate, device_t &, L, const char *>::value, read16sm_delegate> make_lr16_delegate(device_t &owner, L &&l, const char *name)
+{ return read16sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read16mo_delegate, L, const char *>::value, read16mo_delegate> make_lr16_delegate(L l, const char *name)
-{ return read16mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read16mo_delegate, device_t &, L, const char *>::value, read16mo_delegate> make_lr16_delegate(device_t &owner, L &&l, const char *name)
+{ return read16mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read16smo_delegate, L, const char *>::value, read16smo_delegate> make_lr16_delegate(L l, const char *name)
-{ return read16smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read16smo_delegate, device_t &, L, const char *>::value, read16smo_delegate> make_lr16_delegate(device_t &owner, L &&l, const char *name)
+{ return read16smo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read32_delegate, L, const char *>::value, read32_delegate> make_lr32_delegate(L l, const char *name)
-{ return read32_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read32_delegate, device_t &, L, const char *>::value, read32_delegate> make_lr32_delegate(device_t &owner, L &&l, const char *name)
+{ return read32_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read32m_delegate, L, const char *>::value, read32m_delegate> make_lr32_delegate(L l, const char *name)
-{ return read32m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read32m_delegate, device_t &, L, const char *>::value, read32m_delegate> make_lr32_delegate(device_t &owner, L &&l, const char *name)
+{ return read32m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read32s_delegate, L, const char *>::value, read32s_delegate> make_lr32_delegate(L l, const char *name)
-{ return read32s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read32s_delegate, device_t &, L, const char *>::value, read32s_delegate> make_lr32_delegate(device_t &owner, L &&l, const char *name)
+{ return read32s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read32sm_delegate, L, const char *>::value, read32sm_delegate> make_lr32_delegate(L l, const char *name)
-{ return read32sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read32sm_delegate, device_t &, L, const char *>::value, read32sm_delegate> make_lr32_delegate(device_t &owner, L &&l, const char *name)
+{ return read32sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read32mo_delegate, L, const char *>::value, read32mo_delegate> make_lr32_delegate(L l, const char *name)
-{ return read32mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read32mo_delegate, device_t &, L, const char *>::value, read32mo_delegate> make_lr32_delegate(device_t &owner, L &&l, const char *name)
+{ return read32mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read32smo_delegate, L, const char *>::value, read32smo_delegate> make_lr32_delegate(L l, const char *name)
-{ return read32smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read32smo_delegate, device_t &, L, const char *>::value, read32smo_delegate> make_lr32_delegate(device_t &owner, L &&l, const char *name)
+{ return read32smo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read64_delegate, L, const char *>::value, read64_delegate> make_lr64_delegate(L l, const char *name)
-{ return read64_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read64_delegate, device_t &, L, const char *>::value, read64_delegate> make_lr64_delegate(device_t &owner, L &&l, const char *name)
+{ return read64_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read64m_delegate, L, const char *>::value, read64m_delegate> make_lr64_delegate(L l, const char *name)
-{ return read64m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read64m_delegate, device_t &, L, const char *>::value, read64m_delegate> make_lr64_delegate(device_t &owner, L &&l, const char *name)
+{ return read64m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read64s_delegate, L, const char *>::value, read64s_delegate> make_lr64_delegate(L l, const char *name)
-{ return read64s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read64s_delegate, device_t &, L, const char *>::value, read64s_delegate> make_lr64_delegate(device_t &owner, L &&l, const char *name)
+{ return read64s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read64sm_delegate, L, const char *>::value, read64sm_delegate> make_lr64_delegate(L l, const char *name)
-{ return read64sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read64sm_delegate, device_t &, L, const char *>::value, read64sm_delegate> make_lr64_delegate(device_t &owner, L &&l, const char *name)
+{ return read64sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read64mo_delegate, L, const char *>::value, read64mo_delegate> make_lr64_delegate(L l, const char *name)
-{ return read64mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read64mo_delegate, device_t &, L, const char *>::value, read64mo_delegate> make_lr64_delegate(device_t &owner, L &&l, const char *name)
+{ return read64mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<read64smo_delegate, L, const char *>::value, read64smo_delegate> make_lr64_delegate(L l, const char *name)
-{ return read64smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<read64smo_delegate, device_t &, L, const char *>::value, read64smo_delegate> make_lr64_delegate(device_t &owner, L &&l, const char *name)
+{ return read64smo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write8_delegate, L, const char *>::value, write8_delegate> make_lw8_delegate(L l, const char *name)
-{ return write8_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write8_delegate, device_t &, L, const char *>::value, write8_delegate> make_lw8_delegate(device_t &owner, L &&l, const char *name)
+{ return write8_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write8m_delegate, L, const char *>::value, write8m_delegate> make_lw8_delegate(L l, const char *name)
-{ return write8m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write8m_delegate, device_t &, L, const char *>::value, write8m_delegate> make_lw8_delegate(device_t &owner, L &&l, const char *name)
+{ return write8m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write8s_delegate, L, const char *>::value, write8s_delegate> make_lw8_delegate(L l, const char *name)
-{ return write8s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write8s_delegate, device_t &, L, const char *>::value, write8s_delegate> make_lw8_delegate(device_t &owner, L &&l, const char *name)
+{ return write8s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write8sm_delegate, L, const char *>::value, write8sm_delegate> make_lw8_delegate(L l, const char *name)
-{ return write8sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write8sm_delegate, device_t &, L, const char *>::value, write8sm_delegate> make_lw8_delegate(device_t &owner, L &&l, const char *name)
+{ return write8sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write8mo_delegate, L, const char *>::value, write8mo_delegate> make_lw8_delegate(L l, const char *name)
-{ return write8mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write8mo_delegate, device_t &, L, const char *>::value, write8mo_delegate> make_lw8_delegate(device_t &owner, L &&l, const char *name)
+{ return write8mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write8smo_delegate, L, const char *>::value, write8smo_delegate> make_lw8_delegate(L l, const char *name)
-{ return write8smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write8smo_delegate, device_t &, L, const char *>::value, write8smo_delegate> make_lw8_delegate(device_t &owner, L &&l, const char *name)
+{ return write8smo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write16_delegate, L, const char *>::value, write16_delegate> make_lw16_delegate(L l, const char *name)
-{ return write16_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write16_delegate, device_t &, L, const char *>::value, write16_delegate> make_lw16_delegate(device_t &owner, L &&l, const char *name)
+{ return write16_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write16m_delegate, L, const char *>::value, write16m_delegate> make_lw16_delegate(L l, const char *name)
-{ return write16m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write16m_delegate, device_t &, L, const char *>::value, write16m_delegate> make_lw16_delegate(device_t &owner, L &&l, const char *name)
+{ return write16m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write16s_delegate, L, const char *>::value, write16s_delegate> make_lw16_delegate(L l, const char *name)
-{ return write16s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write16s_delegate, device_t &, L, const char *>::value, write16s_delegate> make_lw16_delegate(device_t &owner, L &&l, const char *name)
+{ return write16s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write16sm_delegate, L, const char *>::value, write16sm_delegate> make_lw16_delegate(L l, const char *name)
-{ return write16sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write16sm_delegate, device_t &, L, const char *>::value, write16sm_delegate> make_lw16_delegate(device_t &owner, L &&l, const char *name)
+{ return write16sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write16mo_delegate, L, const char *>::value, write16mo_delegate> make_lw16_delegate(L l, const char *name)
-{ return write16mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write16mo_delegate, device_t &, L, const char *>::value, write16mo_delegate> make_lw16_delegate(device_t &owner, L &&l, const char *name)
+{ return write16mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write16smo_delegate, L, const char *>::value, write16smo_delegate> make_lw16_delegate(L l, const char *name)
-{ return write16smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write16smo_delegate, device_t &, L, const char *>::value, write16smo_delegate> make_lw16_delegate(device_t &owner, L &&l, const char *name)
+{ return write16smo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write32_delegate, L, const char *>::value, write32_delegate> make_lw32_delegate(L l, const char *name)
-{ return write32_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write32_delegate, device_t &, L, const char *>::value, write32_delegate> make_lw32_delegate(device_t &owner, L &&l, const char *name)
+{ return write32_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write32m_delegate, L, const char *>::value, write32m_delegate> make_lw32_delegate(L l, const char *name)
-{ return write32m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write32m_delegate, device_t &, L, const char *>::value, write32m_delegate> make_lw32_delegate(device_t &owner, L &&l, const char *name)
+{ return write32m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write32s_delegate, L, const char *>::value, write32s_delegate> make_lw32_delegate(L l, const char *name)
-{ return write32s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write32s_delegate, device_t &, L, const char *>::value, write32s_delegate> make_lw32_delegate(device_t &owner, L &&l, const char *name)
+{ return write32s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write32sm_delegate, L, const char *>::value, write32sm_delegate> make_lw32_delegate(L l, const char *name)
-{ return write32sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write32sm_delegate, device_t &, L, const char *>::value, write32sm_delegate> make_lw32_delegate(device_t &owner, L &&l, const char *name)
+{ return write32sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write32mo_delegate, L, const char *>::value, write32mo_delegate> make_lw32_delegate(L l, const char *name)
-{ return write32mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write32mo_delegate, device_t &, L, const char *>::value, write32mo_delegate> make_lw32_delegate(device_t &owner, L &&l, const char *name)
+{ return write32mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write32smo_delegate, L, const char *>::value, write32smo_delegate> make_lw32_delegate(L l, const char *name)
-{ return write32smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write32smo_delegate, device_t &, L, const char *>::value, write32smo_delegate> make_lw32_delegate(device_t &owner, L &&l, const char *name)
+{ return write32smo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write64_delegate, L, const char *>::value, write64_delegate> make_lw64_delegate(L l, const char *name)
-{ return write64_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write64_delegate, device_t &, L, const char *>::value, write64_delegate> make_lw64_delegate(device_t &owner, L &&l, const char *name)
+{ return write64_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write64m_delegate, L, const char *>::value, write64m_delegate> make_lw64_delegate(L l, const char *name)
-{ return write64m_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write64m_delegate, device_t &, L, const char *>::value, write64m_delegate> make_lw64_delegate(device_t &owner, L &&l, const char *name)
+{ return write64m_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write64s_delegate, L, const char *>::value, write64s_delegate> make_lw64_delegate(L l, const char *name)
-{ return write64s_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write64s_delegate, device_t &, L, const char *>::value, write64s_delegate> make_lw64_delegate(device_t &owner, L &&l, const char *name)
+{ return write64s_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write64sm_delegate, L, const char *>::value, write64sm_delegate> make_lw64_delegate(L l, const char *name)
-{ return write64sm_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write64sm_delegate, device_t &, L, const char *>::value, write64sm_delegate> make_lw64_delegate(device_t &owner, L &&l, const char *name)
+{ return write64sm_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write64mo_delegate, L, const char *>::value, write64mo_delegate> make_lw64_delegate(L l, const char *name)
-{ return write64mo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write64mo_delegate, device_t &, L, const char *>::value, write64mo_delegate> make_lw64_delegate(device_t &owner, L &&l, const char *name)
+{ return write64mo_delegate(owner, std::forward<L>(l), name); }
template <typename L>
-inline std::enable_if_t<std::is_constructible<write64smo_delegate, L, const char *>::value, write64smo_delegate> make_lw64_delegate(L l, const char *name)
-{ return write64smo_delegate(l, name); }
+inline std::enable_if_t<std::is_constructible<write64smo_delegate, device_t &, L, const char *>::value, write64smo_delegate> make_lw64_delegate(device_t &owner, L &&l, const char *name)
+{ return write64smo_delegate(owner, std::forward<L>(l), name); }
@@ -1837,25 +1740,6 @@ private:
#define DECLARE_READ64_MEMBER(name) u64 name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED u64 mem_mask = 0xffffffffffffffffU)
#define DECLARE_WRITE64_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED u64 data, ATTR_UNUSED u64 mem_mask = 0xffffffffffffffffU)
-// device delegate macros
-#define READ8_DELEGATE(_class, _member) read8_delegate(FUNC(_class::_member), this)
-#define WRITE8_DELEGATE(_class, _member) write8_delegate(FUNC(_class::_member), this)
-#define READ16_DELEGATE(_class, _member) read16_delegate(FUNC(_class::_member), this)
-#define WRITE16_DELEGATE(_class, _member) write16_delegate(FUNC(_class::_member), this)
-#define READ32_DELEGATE(_class, _member) read32_delegate(FUNC(_class::_member), this)
-#define WRITE32_DELEGATE(_class, _member) write32_delegate(FUNC(_class::_member), this)
-#define READ64_DELEGATE(_class, _member) read64_delegate(FUNC(_class::_member), this)
-#define WRITE64_DELEGATE(_class, _member) write64_delegate(FUNC(_class::_member), this)
-
-#define READ8_DEVICE_DELEGATE(_device, _class, _member) read8_delegate(FUNC(_class::_member), (_class *)_device)
-#define WRITE8_DEVICE_DELEGATE(_device, _class, _member) write8_delegate(FUNC(_class::_member), (_class *)_device)
-#define READ16_DEVICE_DELEGATE(_device, _class, _member) read16_delegate(FUNC(_class::_member), (_class *)_device)
-#define WRITE16_DEVICE_DELEGATE(_device, _class, _member) write16_delegate(FUNC(_class::_member), (_class *)_device)
-#define READ32_DEVICE_DELEGATE(_device, _class, _member) read32_delegate(FUNC(_class::_member), (_class *)_device)
-#define WRITE32_DEVICE_DELEGATE(_device, _class, _member) write32_delegate(FUNC(_class::_member), (_class *)_device)
-#define READ64_DEVICE_DELEGATE(_device, _class, _member) read64_delegate(FUNC(_class::_member), (_class *)_device)
-#define WRITE64_DEVICE_DELEGATE(_device, _class, _member) write64_delegate(FUNC(_class::_member), (_class *)_device)
-
// helper macro for merging data with the memory mask
#define COMBINE_DATA(varptr) (*(varptr) = (*(varptr) & ~mem_mask) | (data & mem_mask))
diff --git a/src/emu/emumem_hedp.h b/src/emu/emumem_hedp.h
index cba4877b20c..37b47747d61 100644
--- a/src/emu/emumem_hedp.h
+++ b/src/emu/emumem_hedp.h
@@ -11,7 +11,7 @@ public:
using uX = typename emu::detail::handler_entry_size<Width>::uX;
using inh = handler_entry_read_address<Width, AddrShift, Endian>;
- handler_entry_read_delegate(address_space *space, READ delegate) : handler_entry_read_address<Width, AddrShift, Endian>(space, 0), m_delegate(delegate) {}
+ handler_entry_read_delegate(address_space *space, const READ &delegate) : handler_entry_read_address<Width, AddrShift, Endian>(space, 0), m_delegate(delegate) {}
~handler_entry_read_delegate() = default;
uX read(offs_t offset, uX mem_mask) override;
@@ -70,7 +70,7 @@ public:
using uX = typename emu::detail::handler_entry_size<Width>::uX;
using inh = handler_entry_write_address<Width, AddrShift, Endian>;
- handler_entry_write_delegate(address_space *space, WRITE delegate) : handler_entry_write_address<Width, AddrShift, Endian>(space, 0), m_delegate(delegate) {}
+ handler_entry_write_delegate(address_space *space, const WRITE &delegate) : handler_entry_write_address<Width, AddrShift, Endian>(space, 0), m_delegate(delegate) {}
~handler_entry_write_delegate() = default;
void write(offs_t offset, uX data, uX mem_mask) override;
diff --git a/src/emu/emupal.cpp b/src/emu/emupal.cpp
index 6d0955f3484..536eff6577d 100644
--- a/src/emu/emupal.cpp
+++ b/src/emu/emupal.cpp
@@ -21,83 +21,82 @@ DEFINE_DEVICE_TYPE(PALETTE, palette_device, "palette", "palette")
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, init_delegate &&init, u32 entries, u32 indirect)
: palette_device(mconfig, tag, owner, 0U)
{
- set_entries(entries);
- set_indirect_entries(indirect);
- set_init(std::move(init));
+ set_entries(entries, indirect);
+ m_init = std::move(init);
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, black_t, u32 entries)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_all_black), tag, this), entries)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_all_black)), entries)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, mono_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_monochrome), tag, this), 2)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_monochrome)), 2)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, mono_inv_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_monochrome_inverted), tag, this), 2)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_monochrome_inverted)), 2)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, mono_hi_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_monochrome_highlight), tag, this), 3)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_monochrome_highlight)), 3)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, rgb_3b_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_3bit_rgb), tag, this), 8)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_3bit_rgb)), 8)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, rbg_3b_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_3bit_rbg), tag, this), 8)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_3bit_rbg)), 8)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, grb_3b_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_3bit_grb), tag, this), 8)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_3bit_grb)), 8)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, gbr_3b_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_3bit_gbr), tag, this), 8)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_3bit_gbr)), 8)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, brg_3b_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_3bit_brg), tag, this), 8)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_3bit_brg)), 8)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, bgr_3b_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_3bit_bgr), tag, this), 8)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_3bit_bgr)), 8)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, rgb_555_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_rgb_555), tag, this), 32768)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_rgb_555)), 32768)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, grb_555_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_grb_555), tag, this), 32768)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_grb_555)), 32768)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, bgr_555_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_bgr_555), tag, this), 32768)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_bgr_555)), 32768)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, rgb_565_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_rgb_565), tag, this), 65536)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_rgb_565)), 65536)
{
}
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, bgr_565_t)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_bgr_565), tag, this), 65536)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_bgr_565)), 65536)
{
}
@@ -114,7 +113,7 @@ palette_device::palette_device(const machine_config &mconfig, const char *tag, d
, m_endianness()
, m_endianness_supplied(false)
, m_prom_region(*this, finder_base::DUMMY_TAG)
- , m_init()
+ , m_init(*this)
, m_raw_to_rgb()
{
}
@@ -495,7 +494,7 @@ void palette_device::write_indirect_ext(offs_t offset, u8 data)
void palette_device::device_start()
{
// bind the init function
- m_init.bind_relative_to(*owner());
+ m_init.resolve();
// find the memory, if present
const memory_share *share = memshare(tag());
diff --git a/src/emu/emupal.h b/src/emu/emupal.h
index acc528110f1..9e6ffb62a9b 100644
--- a/src/emu/emupal.h
+++ b/src/emu/emupal.h
@@ -95,15 +95,14 @@
#pragma once
+#include <type_traits>
+#include <utility>
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
-class palette_device;
-typedef device_delegate<void (palette_device &)> palette_init_delegate;
-
-
// ======================> raw_to_rgb_converter
class raw_to_rgb_converter
@@ -271,31 +270,22 @@ public:
template <typename T>
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, rgb_444_prom_t, T &&region, u32 entries)
- : palette_device(mconfig, tag, owner, init_delegate(FUNC(palette_device::palette_init_rgb_444_proms), tag, this), entries)
+ : palette_device(mconfig, tag, owner, init_delegate(*this, FUNC(palette_device::palette_init_rgb_444_proms)), entries)
{
set_prom_region(std::forward<T>(region));
}
- // FIXME: these should be aware of current device for resolving the tag
- template <class FunctionClass>
- palette_device(const machine_config &mconfig, const char *tag, device_t *owner, void (FunctionClass::*init)(palette_device &), const char *name, u32 entries = 0U, u32 indirect = 0U)
- : palette_device(mconfig, tag, owner, init_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr)), entries, indirect)
- { }
- template <class FunctionClass>
- palette_device(const machine_config &mconfig, const char *tag, device_t *owner, void (FunctionClass::*init)(palette_device &) const, const char *name, u32 entries = 0U, u32 indirect = 0U)
- : palette_device(mconfig, tag, owner, init_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr)), entries, indirect)
- { }
- template <class FunctionClass>
- palette_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *devname, void (FunctionClass::*init)(palette_device &), const char *name, u32 entries = 0U, u32 indirect = 0U)
- : palette_device(mconfig, tag, owner, init_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr)), entries, indirect)
- { }
- template <class FunctionClass>
- palette_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *devname, void (FunctionClass::*init)(palette_device &) const, const char *name, u32 entries = 0U, u32 indirect = 0U)
- : palette_device(mconfig, tag, owner, init_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr)), entries, indirect)
- { }
+ template <typename F>
+ palette_device(const machine_config &mconfig, const char *tag, device_t *owner, F &&init, std::enable_if_t<init_delegate::supports_callback<F>::value, const char *> name, u32 entries = 0U, u32 indirect = 0U)
+ : palette_device(mconfig, tag, owner, 0U)
+ { set_init(std::forward<F>(init), name).set_entries(entries, indirect); }
+ template <typename T, typename F>
+ palette_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&devname, F &&init, std::enable_if_t<init_delegate::supports_callback<F>::value, const char *> name, u32 entries = 0U, u32 indirect = 0U)
+ : palette_device(mconfig, tag, owner, 0U)
+ { set_init(std::forward<T>(devname), std::forward<F>(init), name).set_entries(entries, indirect); }
// configuration
- template <typename Object> void set_init(Object &&init) { m_init = std::forward<Object>(init); }
+ template <typename... T> palette_device &set_init(T &&... args) { m_init.set(std::forward<T>(args)...); return *this; }
palette_device &set_format(raw_to_rgb_converter raw_to_rgb) { m_raw_to_rgb = raw_to_rgb; return *this; }
palette_device &set_format(int bytes_per_entry, raw_to_rgb_converter::raw_to_rgb_func func, u32 entries);
palette_device &set_format(rgb_332_t, u32 entries);
@@ -347,28 +337,6 @@ public:
palette_device &enable_hilights() { m_enable_hilights = true; return *this; }
template <typename T> palette_device &set_prom_region(T &&region) { m_prom_region.set_tag(std::forward<T>(region)); return *this; }
- // FIXME: these should be aware of current device for resolving the tag
- template <class FunctionClass>
- void set_init(void (FunctionClass::*init)(palette_device &), const char *name)
- {
- m_init = init_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr));
- }
- template <class FunctionClass>
- void set_init(void (FunctionClass::*init)(palette_device &) const, const char *name)
- {
- m_init = init_delegate(init, name, nullptr, static_cast<FunctionClass *>(nullptr));
- }
- template <class FunctionClass>
- void set_init(const char *devname, void (FunctionClass::*init)(palette_device &), const char *name)
- {
- m_init = init_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr));
- }
- template <class FunctionClass>
- void set_init(const char *devname, void (FunctionClass::*init)(palette_device &) const, const char *name)
- {
- m_init = init_delegate(init, name, devname, static_cast<FunctionClass *>(nullptr));
- }
-
// palette RAM accessors
memory_array &basemem() { return m_paletteram; }
memory_array &extmem() { return m_paletteram_ext; }
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 58161b78a83..7e064e27698 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -597,6 +597,8 @@ ioport_field::ioport_field(ioport_port &port, ioport_type type, ioport_value def
m_flags(0),
m_impulse(0),
m_name(name),
+ m_read(port.device()),
+ m_write(port.device()),
m_write_param(0),
m_digital_value(false),
m_min(0),
@@ -608,6 +610,7 @@ ioport_field::ioport_field(ioport_port &port, ioport_type type, ioport_value def
m_crosshair_scale(1.0),
m_crosshair_offset(0),
m_crosshair_altaxis(0),
+ m_crosshair_mapper(port.device()),
m_full_turn_count(0),
m_remap_table(nullptr),
m_way(0)
@@ -1329,9 +1332,9 @@ void ioport_field::expand_diplocation(const char *location, std::string &errorbu
void ioport_field::init_live_state(analog_field *analog)
{
// resolve callbacks
- m_read.bind_relative_to(device());
- m_write.bind_relative_to(device());
- m_crosshair_mapper.bind_relative_to(device());
+ m_read.resolve();
+ m_write.resolve();
+ m_crosshair_mapper.resolve();
// allocate live state
m_live = std::make_unique<ioport_field_live>(*this, analog);
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index df7d2ad026b..bb9a8f47830 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -1710,25 +1710,45 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
// read callbacks
#define PORT_CUSTOM_MEMBER(_class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate(&_class::_member, #_class "::" #_member, DEVICE_SELF, (_class *)nullptr));
+ configurer.field_set_dynamic_read(ioport_field_read_delegate(owner, DEVICE_SELF, &_class::_member, #_class "::" #_member));
#define PORT_CUSTOM_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)nullptr));
+ configurer.field_set_dynamic_read(ioport_field_read_delegate(owner, _device, &_class::_member, #_class "::" #_member));
// write callbacks
#define PORT_CHANGED_MEMBER(_device, _class, _member, _param) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)nullptr), (_param));
+ configurer.field_set_dynamic_write(ioport_field_write_delegate(owner, _device, &_class::_member, #_class "::" #_member), (_param));
// input device handler
#define PORT_READ_LINE_MEMBER(_class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate([](_class &device)->ioport_value { return (device._member() & 1) ? ~ioport_value(0) : 0; } , #_class "::" #_member, DEVICE_SELF, (_class *)nullptr));
+ configurer.field_set_dynamic_read( \
+ ioport_field_read_delegate( \
+ owner, \
+ DEVICE_SELF, \
+ static_cast<ioport_value (*)(_class &)>([] (_class &device) -> ioport_value { return (device._member() & 1) ? ~ioport_value(0) : 0; }), \
+ #_class "::" #_member));
#define PORT_READ_LINE_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate([](_class &device)->ioport_value { return (device._member() & 1) ? ~ioport_value(0) : 0; } , #_class "::" #_member, _device, (_class *)nullptr));
+ configurer.field_set_dynamic_read( \
+ ioport_field_read_delegate( \
+ owner, \
+ _device, \
+ static_cast<ioport_value (*)(_class &)>([] (_class &device) -> ioport_value { return (device._member() & 1) ? ~ioport_value(0) : 0; }), \
+ #_class "::" #_member));
// output device handler
#define PORT_WRITE_LINE_MEMBER(_class, _member) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate([](_class &device, ioport_field &field, u32 param, ioport_value oldval, ioport_value newval) { device._member(newval); }, #_class "::" #_member, DEVICE_SELF, (_class *)nullptr));
+ configurer.field_set_dynamic_write( \
+ ioport_field_write_delegate( \
+ owner, \
+ DEVICE_SELF, \
+ static_cast<void (*)(_class &, ioport_field &, u32, ioport_value, ioport_value)>([] (_class &device, ioport_field &field, u32 param, ioport_value oldval, ioport_value newval) { device._member(newval); }), \
+ #_class "::" #_member));
#define PORT_WRITE_LINE_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate([](_class &device, ioport_field &field, u32 param, ioport_value oldval, ioport_value newval) { device._member(newval); }, #_class "::" #_member, _device, (_class *)nullptr));
+ configurer.field_set_dynamic_write( \
+ ioport_field_write_delegate( \
+ owner, \
+ _device, \
+ static_cast<void (*)(_class &, ioport_field &, u32, ioport_value, ioport_value)>([] (_class &device, ioport_field &field, u32 param, ioport_value oldval, ioport_value newval) { device._member(newval); }), \
+ #_class "::" #_member));
// dip switch definition
#define PORT_DIPNAME(_mask, _default, _name) \
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index a946fb22bd2..647bce77425 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -542,6 +542,8 @@ screen_device::screen_device(const machine_config &mconfig, const char *tag, dev
, m_yoffset(0.0f)
, m_xscale(1.0f)
, m_yscale(1.0f)
+ , m_screen_update_ind16(*this)
+ , m_screen_update_rgb32(*this)
, m_screen_vblank(*this)
, m_scanline_cb(*this)
, m_palette(*this, finder_base::DUMMY_TAG)
@@ -700,8 +702,8 @@ std::pair<unsigned, unsigned> screen_device::physical_aspect() const
void screen_device::device_resolve_objects()
{
// bind our handlers
- m_screen_update_ind16.bind_relative_to(*owner());
- m_screen_update_rgb32.bind_relative_to(*owner());
+ m_screen_update_ind16.resolve();
+ m_screen_update_rgb32.resolve();
m_screen_vblank.resolve_safe();
m_scanline_cb.resolve();
diff --git a/src/emu/screen.h b/src/emu/screen.h
index c43c5fe7278..3842a65b2e6 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -12,6 +12,7 @@
#pragma once
+#include <type_traits>
#include <utility>
@@ -338,36 +339,29 @@ public:
m_yoffset = yoffs;
}
- // FIXME: these should be aware of current device for resolving the tag
- template <class FunctionClass>
- void set_screen_update(u32 (FunctionClass::*callback)(screen_device &, bitmap_ind16 &, const rectangle &), const char *name)
+ template <typename F>
+ std::enable_if_t<screen_update_ind16_delegate::supports_callback<F>::value> set_screen_update(F &&callback, const char *name)
{
- set_screen_update(screen_update_ind16_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
+ m_screen_update_ind16.set(std::forward<F>(callback), name);
+ m_screen_update_rgb32 = screen_update_rgb32_delegate(*this);
}
- template <class FunctionClass>
- void set_screen_update(u32 (FunctionClass::*callback)(screen_device &, bitmap_rgb32 &, const rectangle &), const char *name)
+ template <typename F>
+ std::enable_if_t<screen_update_rgb32_delegate::supports_callback<F>::value> set_screen_update(F &&callback, const char *name)
{
- set_screen_update(screen_update_rgb32_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
+ m_screen_update_ind16 = screen_update_ind16_delegate(*this);
+ m_screen_update_rgb32.set(std::forward<F>(callback), name);
}
- template <class FunctionClass>
- void set_screen_update(const char *devname, u32 (FunctionClass::*callback)(screen_device &, bitmap_ind16 &, const rectangle &), const char *name)
+ template <typename T, typename F>
+ std::enable_if_t<screen_update_ind16_delegate::supports_callback<F>::value> set_screen_update(T &&target, F &&callback, const char *name)
{
- set_screen_update(screen_update_ind16_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
+ m_screen_update_ind16.set(std::forward<T>(target), std::forward<F>(callback), name);
+ m_screen_update_rgb32 = screen_update_rgb32_delegate(*this);
}
- template <class FunctionClass>
- void set_screen_update(const char *devname, u32 (FunctionClass::*callback)(screen_device &, bitmap_rgb32 &, const rectangle &), const char *name)
+ template <typename T, typename F>
+ std::enable_if_t<screen_update_rgb32_delegate::supports_callback<F>::value> set_screen_update(T &&target, F &&callback, const char *name)
{
- set_screen_update(screen_update_rgb32_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
- }
- void set_screen_update(screen_update_ind16_delegate callback)
- {
- m_screen_update_ind16 = callback;
- m_screen_update_rgb32 = screen_update_rgb32_delegate();
- }
- void set_screen_update(screen_update_rgb32_delegate callback)
- {
- m_screen_update_ind16 = screen_update_ind16_delegate();
- m_screen_update_rgb32 = callback;
+ m_screen_update_ind16 = screen_update_ind16_delegate(*this);
+ m_screen_update_rgb32.set(std::forward<T>(target), std::forward<F>(callback), name);
}
auto screen_vblank() { return m_screen_vblank.bind(); }
diff --git a/src/emu/tilemap.cpp b/src/emu/tilemap.cpp
index 083b4b4ef5a..44360a2a486 100644
--- a/src/emu/tilemap.cpp
+++ b/src/emu/tilemap.cpp
@@ -336,7 +336,9 @@ inline void tilemap_t::scanline_draw_masked_rgb32_alpha(u32 *dest, const u16 *so
// tilemap_t - constructor
//-------------------------------------------------
-tilemap_t::tilemap_t()
+tilemap_t::tilemap_t(device_t &owner)
+ : m_mapper(owner)
+ , m_tile_get_info(owner)
{
// until init() is called, data is floating; this is deliberate
}
@@ -346,11 +348,18 @@ tilemap_t::tilemap_t()
// init - initialize the tilemap
//-------------------------------------------------
-tilemap_t &tilemap_t::init(tilemap_manager &manager, device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows)
+void tilemap_t::init_common(
+ tilemap_manager &manager,
+ device_gfx_interface &decoder,
+ tilemap_get_info_delegate tile_get_info,
+ u16 tilewidth,
+ u16 tileheight,
+ u32 cols,
+ u32 rows)
{
// populate managers and devices
m_manager = &manager;
- m_device = dynamic_cast<tilemap_device *>(this);
+ m_device = dynamic_cast<device_t *>(this);
m_palette = &decoder.palette();
m_next = nullptr;
m_user_data = nullptr;
@@ -363,9 +372,6 @@ tilemap_t &tilemap_t::init(tilemap_manager &manager, device_gfx_interface &decod
m_width = cols * tilewidth;
m_height = rows * tileheight;
- // populate logical <-> memory mappings
- m_mapper = mapper;
-
// initialize tile information geters
m_tile_get_info = tile_get_info;
@@ -426,6 +432,52 @@ tilemap_t &tilemap_t::init(tilemap_manager &manager, device_gfx_interface &decod
// reset everything after a load
machine().save().register_postload(save_prepost_delegate(FUNC(tilemap_t::postload), this));
+}
+
+tilemap_t &tilemap_t::init(
+ tilemap_manager &manager,
+ device_gfx_interface &decoder,
+ tilemap_get_info_delegate tile_get_info,
+ tilemap_mapper_delegate mapper,
+ u16 tilewidth,
+ u16 tileheight,
+ u32 cols,
+ u32 rows)
+{
+ // populate logical <-> memory mappings
+ m_mapper = mapper;
+
+ init_common(manager, decoder, tile_get_info, tilewidth, tileheight, cols, rows);
+
+ return *this;
+}
+
+tilemap_t &tilemap_t::init(
+ tilemap_manager &manager,
+ device_gfx_interface &decoder,
+ tilemap_get_info_delegate tile_get_info,
+ tilemap_standard_mapper mapper,
+ u16 tilewidth,
+ u16 tileheight,
+ u32 cols,
+ u32 rows)
+{
+ // populate logical <-> memory mappings
+ switch (mapper)
+ {
+ case TILEMAP_SCAN_ROWS: m_mapper.set(*this, FUNC(tilemap_t::scan_rows)); break;
+ case TILEMAP_SCAN_ROWS_FLIP_X: m_mapper.set(*this, FUNC(tilemap_t::scan_rows_flip_x)); break;
+ case TILEMAP_SCAN_ROWS_FLIP_Y: m_mapper.set(*this, FUNC(tilemap_t::scan_rows_flip_y)); break;
+ case TILEMAP_SCAN_ROWS_FLIP_XY: m_mapper.set(*this, FUNC(tilemap_t::scan_rows_flip_xy)); break;
+ case TILEMAP_SCAN_COLS: m_mapper.set(*this, FUNC(tilemap_t::scan_cols)); break;
+ case TILEMAP_SCAN_COLS_FLIP_X: m_mapper.set(*this, FUNC(tilemap_t::scan_cols_flip_x)); break;
+ case TILEMAP_SCAN_COLS_FLIP_Y: m_mapper.set(*this, FUNC(tilemap_t::scan_cols_flip_y)); break;
+ case TILEMAP_SCAN_COLS_FLIP_XY: m_mapper.set(*this, FUNC(tilemap_t::scan_cols_flip_xy)); break;
+ default: throw emu_fatalerror("Tilemap init unknown mapper %d", mapper);
+ }
+
+ init_common(manager, decoder, tile_get_info, tilewidth, tileheight, cols, rows);
+
return *this;
}
@@ -1529,14 +1581,13 @@ tilemap_manager::tilemap_manager(running_machine &machine)
tilemap_manager::~tilemap_manager()
{
- // detach all device tilemaps since they will be destroyed
- // as subdevices elsewhere
+ // detach all device tilemaps since they will be destroyed as subdevices elsewhere
bool found = true;
while (found)
{
found = false;
for (tilemap_t &tmap : m_tilemap_list)
- if (tmap.device() != nullptr)
+ if (tmap.m_device)
{
found = true;
m_tilemap_list.detach(tmap);
@@ -1553,28 +1604,16 @@ tilemap_manager::~tilemap_manager()
tilemap_t &tilemap_manager::create(device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows, tilemap_t *allocated)
{
- if (allocated == nullptr)
- allocated = global_alloc(tilemap_t);
+ if (!allocated)
+ allocated = global_alloc(tilemap_t)(machine().root_device());
return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, mapper, tilewidth, tileheight, cols, rows));
}
tilemap_t &tilemap_manager::create(device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_standard_mapper mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows, tilemap_t *allocated)
{
- if (allocated == nullptr)
- allocated = global_alloc(tilemap_t);
-
- switch (mapper)
- {
- case TILEMAP_SCAN_ROWS :return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_rows), allocated), tilewidth, tileheight, cols, rows));
- case TILEMAP_SCAN_ROWS_FLIP_X:return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_rows_flip_x), allocated), tilewidth, tileheight, cols, rows));
- case TILEMAP_SCAN_ROWS_FLIP_Y:return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_rows_flip_y), allocated), tilewidth, tileheight, cols, rows));
- case TILEMAP_SCAN_ROWS_FLIP_XY:return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_rows_flip_xy),allocated), tilewidth, tileheight, cols, rows));
- case TILEMAP_SCAN_COLS:return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_cols),allocated), tilewidth, tileheight, cols, rows));
- case TILEMAP_SCAN_COLS_FLIP_X:return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_cols_flip_x),allocated), tilewidth, tileheight, cols, rows));
- case TILEMAP_SCAN_COLS_FLIP_Y:return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_cols_flip_y),allocated), tilewidth, tileheight, cols, rows));
- case TILEMAP_SCAN_COLS_FLIP_XY:return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, tilemap_mapper_delegate(FUNC(tilemap_t::scan_cols_flip_xy),allocated), tilewidth, tileheight, cols, rows));
- default: throw emu_fatalerror("Tilemap manager create unknown mapper %d", mapper);
- }
+ if (!allocated)
+ allocated = global_alloc(tilemap_t)(machine().root_device());
+ return m_tilemap_list.append(allocated->init(*this, decoder, tile_get_info, mapper, tilewidth, tileheight, cols, rows));
}
@@ -1615,16 +1654,19 @@ DEFINE_DEVICE_TYPE(TILEMAP, tilemap_device, "tilemap", "Tilemap")
//-------------------------------------------------
tilemap_device::tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : device_t(mconfig, TILEMAP, tag, owner, clock),
- m_gfxdecode(*this, finder_base::DUMMY_TAG),
- m_standard_mapper(TILEMAP_STANDARD_COUNT),
- m_bytes_per_entry(0),
- m_tile_width(8),
- m_tile_height(8),
- m_num_columns(64),
- m_num_rows(64),
- m_transparent_pen_set(false),
- m_transparent_pen(0)
+ : device_t(mconfig, TILEMAP, tag, owner, clock)
+ , tilemap_t(static_cast<device_t &>(*this))
+ , m_gfxdecode(*this, finder_base::DUMMY_TAG)
+ , m_get_info(*this)
+ , m_standard_mapper(TILEMAP_STANDARD_COUNT)
+ , m_mapper(*this)
+ , m_bytes_per_entry(0)
+ , m_tile_width(8)
+ , m_tile_height(8)
+ , m_num_columns(64)
+ , m_num_rows(64)
+ , m_transparent_pen_set(false)
+ , m_transparent_pen(0)
{
}
@@ -1719,14 +1761,14 @@ void tilemap_device::device_start()
throw device_missing_dependencies();
// bind our callbacks
- m_get_info.bind_relative_to(*owner());
- m_mapper.bind_relative_to(*owner());
+ m_get_info.resolve();
+ m_mapper.resolve();
// allocate the tilemap
if (m_standard_mapper == TILEMAP_STANDARD_COUNT)
- machine().tilemap().create(*m_gfxdecode, m_get_info, m_mapper, m_tile_width, m_tile_height, m_num_columns, m_num_rows, this);
+ machine().tilemap().create(*m_gfxdecode, m_get_info, m_mapper, m_tile_width, m_tile_height, m_num_columns, m_num_rows, *this);
else
- machine().tilemap().create(*m_gfxdecode, m_get_info, m_standard_mapper, m_tile_width, m_tile_height, m_num_columns, m_num_rows, this);
+ machine().tilemap().create(*m_gfxdecode, m_get_info, m_standard_mapper, m_tile_width, m_tile_height, m_num_columns, m_num_rows, *this);
// find the memory, if present
const memory_share *share = memshare(tag());
diff --git a/src/emu/tilemap.h b/src/emu/tilemap.h
index a116f019c6c..e9ed1a3b66d 100644
--- a/src/emu/tilemap.h
+++ b/src/emu/tilemap.h
@@ -303,6 +303,10 @@
#pragma once
+#include <type_traits>
+#include <utility>
+#include <vector>
+
//**************************************************************************
// CONSTANTS
@@ -419,17 +423,19 @@ class tilemap_t
// maximum index in each array
static const pen_t MAX_PEN_TO_FLAGS = 256;
+ void init_common(tilemap_manager &manager, device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, u16 tilewidth, u16 tileheight, u32 cols, u32 rows);
+
protected:
// tilemap_manager controls our allocations
- tilemap_t();
+ tilemap_t(device_t &owner);
virtual ~tilemap_t();
tilemap_t &init(tilemap_manager &manager, device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows);
+ tilemap_t &init(tilemap_manager &manager, device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_standard_mapper mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows);
public:
// getters
running_machine &machine() const;
- tilemap_device *device() const { return m_device; }
device_palette_interface &palette() const { return *m_palette; }
device_gfx_interface &decoder() const { return *m_tileinfo.decoder; }
@@ -554,7 +560,7 @@ private:
// managers and devices
tilemap_manager * m_manager; // reference to the owning manager
- tilemap_device * m_device; // pointer to our owning device
+ device_t * m_device; // pointer to our owning device
device_palette_interface * m_palette; // palette used for drawing
tilemap_t * m_next; // pointer to next tilemap
void * m_user_data; // user data value
@@ -621,8 +627,12 @@ public:
running_machine &machine() const { return m_machine; }
// tilemap creation
- tilemap_t &create(device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows, tilemap_t *allocated = nullptr);
- tilemap_t &create(device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_standard_mapper mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows, tilemap_t *allocated = nullptr);
+ template <typename T, typename U>
+ tilemap_t &create(device_gfx_interface &decoder, T &&tile_get_info, U &&mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows)
+ { return create(decoder, std::forward<T>(tile_get_info), std::forward<U>(mapper), tilewidth, tileheight, cols, rows, nullptr); }
+ template <typename T, typename U, class V>
+ std::enable_if_t<std::is_base_of<device_t, V>::value, tilemap_t &> create(device_gfx_interface &decoder, T &&tile_get_info, U &&mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows, V &allocated)
+ { return create(decoder, std::forward<T>(tile_get_info), std::forward<U>(mapper), tilewidth, tileheight, cols, rows, &static_cast<tilemap_t &>(allocated)); }
// tilemap list information
tilemap_t *find(int index) { return m_tilemap_list.find(index); }
@@ -633,6 +643,10 @@ public:
void set_flip_all(u32 attributes);
private:
+ // tilemap creation
+ tilemap_t &create(device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_mapper_delegate mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows, tilemap_t *allocated);
+ tilemap_t &create(device_gfx_interface &decoder, tilemap_get_info_delegate tile_get_info, tilemap_standard_mapper mapper, u16 tilewidth, u16 tileheight, u32 cols, u32 rows, tilemap_t *allocated);
+
// allocate an instance index
int alloc_instance() { return ++m_instance; }
@@ -689,29 +703,28 @@ public:
template <typename T> void set_gfxdecode(T &&tag) { m_gfxdecode.set_tag(std::forward<T>(tag)); }
void set_bytes_per_entry(int bpe) { m_bytes_per_entry = bpe; }
- void set_info_callback(tilemap_get_info_delegate tile_get_info) { m_get_info = tile_get_info; }
- template <class FunctionClass> void set_info_callback(const char *devname, void (FunctionClass::*callback)(tilemap_t &, tile_data &, tilemap_memory_index), const char *name)
- {
- set_info_callback(tilemap_get_info_delegate(callback, name, devname, static_cast<FunctionClass *>(nullptr)));
- }
- template <class FunctionClass> void set_info_callback(void (FunctionClass::*callback)(tilemap_t &, tile_data &, tilemap_memory_index), const char *name)
- {
- set_info_callback(tilemap_get_info_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)));
- }
+ template <typename... T> void set_info_callback(T &&... args) { m_get_info.set(std::forward<T>(args)...); }
- template <class FunctionClass> void set_layout(tilemap_memory_index (FunctionClass::*callback)(u32, u32, u32, u32), const char *name, u32 columns, u32 rows)
+ void set_layout(tilemap_standard_mapper mapper, u32 columns, u32 rows)
{
- set_layout(tilemap_mapper_delegate(callback, name, nullptr, static_cast<FunctionClass *>(nullptr)), columns, rows);
- }
-
- void set_layout(tilemap_standard_mapper mapper, u32 columns, u32 rows) {
+ assert(TILEMAP_STANDARD_COUNT > mapper);
m_standard_mapper = mapper;
m_num_columns = columns;
m_num_rows = rows;
}
- void set_layout(tilemap_mapper_delegate mapper, u32 columns, u32 rows) {
+ template <typename F>
+ void set_layout(F &&callback, const char *name, u32 columns, u32 rows)
+ {
+ m_standard_mapper = TILEMAP_STANDARD_COUNT;
+ m_mapper.set(std::forward<F>(callback), name);
+ m_num_columns = columns;
+ m_num_rows = rows;
+ }
+ template <typename T, typename F>
+ void set_layout(T &&target, F &&callback, const char *name, u32 columns, u32 rows)
+ {
m_standard_mapper = TILEMAP_STANDARD_COUNT;
- m_mapper = mapper;
+ m_mapper.set(std::forward<T>(target), std::forward<F>(callback), name);
m_num_columns = columns;
m_num_rows = rows;
}