summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2018-05-01 04:19:51 +1000
committer Vas Crabb <vas@vastheman.com>2018-05-01 04:19:51 +1000
commit2047471723e83ba31b6a3f14150438556659b4ee (patch)
tree7d5dd8c4fdd23266ac9c87a202566c43a00b1268 /src/emu
parent359c61e86e8986a49b3987202f72ef24f2bba239 (diff)
Bind devcb relative to current device. This is probably going to break
plenty of things with late bind errors. Sorry. Remaining things to switch over include sound routes and things with custom delegates.
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/devcb.cpp143
-rw-r--r--src/emu/devcb.h10
-rw-r--r--src/emu/disound.cpp2
-rw-r--r--src/emu/divideo.cpp4
-rw-r--r--src/emu/emucore.h4
5 files changed, 85 insertions, 78 deletions
diff --git a/src/emu/devcb.cpp b/src/emu/devcb.cpp
index fe8deacfba1..495f8d1abe6 100644
--- a/src/emu/devcb.cpp
+++ b/src/emu/devcb.cpp
@@ -21,17 +21,18 @@
//-------------------------------------------------
devcb_base::devcb_base(device_t &device, u64 defmask)
- : m_device(device),
- m_type(CALLBACK_NONE),
- m_target_tag(nullptr),
- m_target_int(0),
- m_space_tag(nullptr),
- m_space_num(0),
- m_space(nullptr),
- m_rshift(0),
- m_mask(defmask),
- m_defmask(defmask),
- m_xor(0)
+ : m_owner(device)
+ , m_base(device)
+ , m_type(CALLBACK_NONE)
+ , m_target_tag(nullptr)
+ , m_target_int(0)
+ , m_space_tag(nullptr)
+ , m_space_num(0)
+ , m_space(nullptr)
+ , m_rshift(0)
+ , m_mask(defmask)
+ , m_defmask(defmask)
+ , m_xor(0)
{
m_target.ptr = nullptr;
}
@@ -52,6 +53,12 @@ devcb_base::~devcb_base()
void devcb_base::reset(callback_type type)
{
+ reset(m_owner.mconfig().current_device(), type);
+}
+
+void devcb_base::reset(device_t &base, callback_type type)
+{
+ m_base = base;
m_type = type;
m_target_tag = nullptr;
m_target_int = 0;
@@ -74,9 +81,9 @@ void devcb_base::reset(callback_type type)
void devcb_base::resolve_ioport()
{
// attempt to resolve, fatal error if fail
- m_target.ioport = (m_target_tag != nullptr) ? m_device.owner()->ioport(m_target_tag) : nullptr;
- if (m_target.ioport == nullptr)
- throw emu_fatalerror("Unable to resolve I/O port callback reference to '%s' in device '%s'\n", m_target_tag, m_device.tag());
+ m_target.ioport = m_target_tag ? m_base.get().ioport(m_target_tag) : nullptr;
+ if (!m_target.ioport)
+ throw emu_fatalerror("Unable to resolve I/O port callback reference to '%s' in device '%s'\n", m_target_tag, m_base.get().tag());
// adjust the mask to match the port bits
u64 port_mask = 0;
@@ -94,9 +101,9 @@ void devcb_base::resolve_ioport()
void devcb_base::resolve_membank()
{
// attempt to resolve, fatal error if fail
- m_target.membank = (m_target_tag != nullptr) ? m_device.owner()->membank(m_target_tag) : nullptr;
- if (m_target.membank == nullptr)
- throw emu_fatalerror("Unable to resolve memory bank callback reference to '%s' in device '%s'\n", m_target_tag, m_device.tag());
+ m_target.membank = m_target_tag ? m_base.get().membank(m_target_tag) : nullptr;
+ if (!m_target.membank)
+ throw emu_fatalerror("Unable to resolve memory bank callback reference to '%s' in device '%s'\n", m_target_tag, m_base.get().tag());
}
@@ -106,8 +113,8 @@ void devcb_base::resolve_membank()
void devcb_base::resolve_output()
{
- assert(m_target_tag != nullptr);
- m_target.item = &m_device.machine().output().find_or_create_item(m_target_tag, 0);
+ assert(m_target_tag);
+ m_target.item = &m_base.get().machine().output().find_or_create_item(m_target_tag, 0);
}
@@ -119,14 +126,14 @@ void devcb_base::resolve_output()
void devcb_base::resolve_inputline()
{
// attempt to resolve, fatal error if fail
- m_target.device = (m_target_tag != nullptr) ? m_device.owner()->subdevice(m_target_tag) : nullptr;
- if (m_target.device == nullptr)
- throw emu_fatalerror("Unable to resolve device reference to '%s' in device '%s'\n", m_target_tag, m_device.tag());
+ m_target.device = m_target_tag ? m_base.get().subdevice(m_target_tag) : nullptr;
+ if (!m_target.device)
+ throw emu_fatalerror("Unable to resolve device reference to '%s' in device '%s'\n", m_target_tag, m_base.get().tag());
// make sure we have an execute interface
device_execute_interface *exec;
if (!m_target.device->interface(exec))
- throw emu_fatalerror("No execute interface found for device reference to '%s' in device '%s'\n", m_target_tag, m_device.tag());
+ throw emu_fatalerror("No execute interface found for device reference to '%s' in device '%s'\n", m_target_tag, m_base.get().tag());
}
@@ -138,11 +145,11 @@ void devcb_base::resolve_inputline()
void devcb_base::resolve_space()
{
// attempt to resolve, fatal error if fail
- device_t *spacedev = (m_space_tag != nullptr) ? m_device.owner()->subdevice(m_space_tag) : nullptr;
- if (spacedev == nullptr)
- throw emu_fatalerror("Unable to resolve device reference to '%s' in device '%s'\n", m_space_tag, m_device.tag());
+ device_t *const spacedev(m_space_tag ? m_base.get().subdevice(m_space_tag) : nullptr);
+ if (!spacedev)
+ throw emu_fatalerror("Unable to resolve device reference to '%s' in device '%s'\n", m_space_tag, m_base.get().tag());
if (!spacedev->memory().has_space(m_space_num))
- throw emu_fatalerror("Unable to resolve device address space %d on '%s' in device '%s'\n", m_space_num, m_space_tag, m_device.tag());
+ throw emu_fatalerror("Unable to resolve device address space %d on '%s' in device '%s'\n", m_space_num, m_space_tag, m_base.get().tag());
m_space = &spacedev->memory().space(m_space_num);
}
@@ -189,7 +196,7 @@ void devcb_read_base::devcb_reset()
devcb_read_base &devcb_read_base::chain_alloc()
{
// set up the chained callback pointer
- m_chain.reset(new devcb_read_base(m_device, m_defmask, true));
+ m_chain.reset(new devcb_read_base(m_owner, m_defmask, true));
return *m_chain;
}
@@ -202,10 +209,10 @@ devcb_read_base &devcb_read_base::chain_alloc()
void devcb_read_base::resolve()
{
// first resolve any address spaces
- if (m_space_tag != nullptr)
+ if (m_space_tag)
resolve_space();
else
- m_space = &m_device.machine().dummy_space();
+ m_space = &m_owner.machine().dummy_space();
// then handle the various types
const char *name = "unknown";
@@ -218,7 +225,7 @@ void devcb_read_base::resolve()
case CALLBACK_LINE:
name = m_readline.name();
- m_readline.bind_relative_to(*m_device.owner());
+ m_readline.bind_relative_to(m_base);
m_target_int = 0;
m_adapter = m_readline.isnull() ? &devcb_read_base::read_constant_adapter : &devcb_read_base::read_line_adapter;
m_mask = shift_mask(1);
@@ -226,7 +233,7 @@ void devcb_read_base::resolve()
case CALLBACK_8:
name = m_read8.name();
- m_read8.bind_relative_to(*m_device.owner());
+ m_read8.bind_relative_to(m_base);
m_target_int = 0;
m_adapter = m_read8.isnull() ? &devcb_read_base::read_constant_adapter : &devcb_read_base::read8_adapter;
m_mask = shift_mask(0xff);
@@ -234,7 +241,7 @@ void devcb_read_base::resolve()
case CALLBACK_16:
name = m_read16.name();
- m_read16.bind_relative_to(*m_device.owner());
+ m_read16.bind_relative_to(m_base);
m_target_int = 0;
m_adapter = m_read16.isnull() ? &devcb_read_base::read_constant_adapter : &devcb_read_base::read16_adapter;
m_mask = shift_mask(0xffff);
@@ -242,7 +249,7 @@ void devcb_read_base::resolve()
case CALLBACK_32:
name = m_read32.name();
- m_read32.bind_relative_to(*m_device.owner());
+ m_read32.bind_relative_to(m_base);
m_target_int = 0;
m_adapter = m_read32.isnull() ? &devcb_read_base::read_constant_adapter : &devcb_read_base::read32_adapter;
m_mask = shift_mask(0xffffffff);
@@ -250,7 +257,7 @@ void devcb_read_base::resolve()
case CALLBACK_64:
name = m_read64.name();
- m_read64.bind_relative_to(*m_device.owner());
+ m_read64.bind_relative_to(m_base);
m_target_int = 0;
m_adapter = m_read64.isnull() ? &devcb_read_base::read_constant_adapter : &devcb_read_base::read64_adapter;
break;
@@ -299,7 +306,7 @@ void devcb_read_base::resolve()
// protect against bus contention (the masks must not overlap)
for (const devcb_read_base *chained_cb = m_chain.get(); chained_cb != nullptr; chained_cb = chained_cb->m_chain.get())
if ((m_mask & chained_cb->m_mask) != 0)
- throw emu_fatalerror("Device %s read callback (name=%s) overlaps with chained callback (%lX & %lX)", m_device.tag(), name, (unsigned long)m_mask, (unsigned long)chained_cb->m_mask);
+ throw emu_fatalerror("Device %s read callback (name=%s) overlaps with chained callback (%lX & %lX)", m_owner.tag(), name, (unsigned long)m_mask, (unsigned long)chained_cb->m_mask);
}
@@ -399,7 +406,7 @@ u64 devcb_read_base::read_ioport_adapter(address_space &space, offs_t offset, u6
u64 devcb_read_base::read_logged_adapter(address_space &space, offs_t offset, u64 mask)
{
- m_device.logerror("%s: %s\n", m_device.machine().describe_context(), m_target_tag);
+ m_owner.logerror("%s: %s\n", m_base.get().machine().describe_context(), m_target_tag);
return 0;
}
@@ -430,27 +437,27 @@ void devcb_read_base::validity_check(validity_checker &valid) const
break;
case CALLBACK_LINE:
- if (m_device.owner()->subdevice(m_readline.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_readline.device_name()))
osd_printf_error("Device %s not found for READLINE callback (%s)\n", m_readline.device_name(), m_readline.name());
break;
case CALLBACK_8:
- if (m_device.owner()->subdevice(m_read8.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_read8.device_name()))
osd_printf_error("Device %s not found for READ8 callback (%s)\n", m_read8.device_name(), m_read8.name());
break;
case CALLBACK_16:
- if (m_device.owner()->subdevice(m_read16.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_read16.device_name()))
osd_printf_error("Device %s not found for READ16 callback (%s)\n", m_read16.device_name(), m_read16.name());
break;
case CALLBACK_32:
- if (m_device.owner()->subdevice(m_read32.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_read32.device_name()))
osd_printf_error("Device %s not found for READ32 callback (%s)\n", m_read32.device_name(), m_read32.name());
break;
case CALLBACK_64:
- if (m_device.owner()->subdevice(m_read64.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_read64.device_name()))
osd_printf_error("Device %s not found for READ64 callback (%s)\n", m_read64.device_name(), m_read64.name());
break;
@@ -467,10 +474,9 @@ void devcb_read_base::validity_check(validity_checker &valid) const
case CALLBACK_CLEARLINE:
case CALLBACK_HOLDLINE:
throw emu_fatalerror("Device read callbacks can't be connected to input lines\n");
- break;
}
- if (m_chain != nullptr)
+ if (m_chain)
m_chain->validity_check(valid);
}
@@ -517,7 +523,7 @@ void devcb_write_base::devcb_reset()
devcb_write_base &devcb_write_base::chain_alloc()
{
// set up the chained callback pointer
- m_chain.reset(new devcb_write_base(m_device, m_defmask, true));
+ m_chain.reset(new devcb_write_base(m_owner, m_defmask, true));
return *m_chain;
}
@@ -530,10 +536,10 @@ devcb_write_base &devcb_write_base::chain_alloc()
void devcb_write_base::resolve()
{
// first resolve any address spaces
- if (m_space_tag != nullptr)
+ if (m_space_tag)
resolve_space();
else
- m_space = &m_device.machine().dummy_space();
+ m_space = &m_owner.machine().dummy_space();
// then handle the various types
const char *name = "unknown";
@@ -546,47 +552,47 @@ void devcb_write_base::resolve()
case CALLBACK_LINE:
name = m_writeline.name();
- m_writeline.bind_relative_to(*m_device.owner());
+ m_writeline.bind_relative_to(m_base);
m_adapter = m_writeline.isnull() ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_line_adapter;
break;
case CALLBACK_8:
name = m_write8.name();
- m_write8.bind_relative_to(*m_device.owner());
+ m_write8.bind_relative_to(m_base);
m_adapter = m_write8.isnull() ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write8_adapter;
break;
case CALLBACK_16:
name = m_write16.name();
- m_write16.bind_relative_to(*m_device.owner());
+ m_write16.bind_relative_to(m_base);
m_adapter = m_write16.isnull() ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write16_adapter;
break;
case CALLBACK_32:
name = m_write32.name();
- m_write32.bind_relative_to(*m_device.owner());
+ m_write32.bind_relative_to(m_base);
m_adapter = m_write32.isnull() ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write32_adapter;
break;
case CALLBACK_64:
name = m_write64.name();
- m_write64.bind_relative_to(*m_device.owner());
+ m_write64.bind_relative_to(m_base);
m_adapter = m_write64.isnull() ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write64_adapter;
break;
case CALLBACK_IOPORT:
resolve_ioport();
- m_adapter = (m_target.ioport == nullptr) ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_ioport_adapter;
+ m_adapter = !m_target.ioport ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_ioport_adapter;
break;
case CALLBACK_MEMBANK:
resolve_membank();
- m_adapter = (m_target.membank == nullptr) ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_membank_adapter;
+ m_adapter = !m_target.membank ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_membank_adapter;
break;
case CALLBACK_OUTPUT:
resolve_output();
- m_adapter = (m_target.item == nullptr) ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_output_adapter;
+ m_adapter = !m_target.item ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_output_adapter;
break;
case CALLBACK_LOG:
@@ -624,7 +630,7 @@ void devcb_write_base::resolve()
}
// resolve callback chain recursively
- if (m_chain != nullptr)
+ if (m_chain)
m_chain->resolve();
}
@@ -663,27 +669,27 @@ void devcb_write_base::validity_check(validity_checker &valid) const
break;
case CALLBACK_LINE:
- if (m_device.owner()->subdevice(m_writeline.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_writeline.device_name()))
osd_printf_error("Device %s not found for WRITELINE callback (%s)\n", m_writeline.device_name(), m_writeline.name());
break;
case CALLBACK_8:
- if (m_device.owner()->subdevice(m_write8.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_write8.device_name()))
osd_printf_error("Device %s not found for WRITE8 callback (%s)\n", m_write8.device_name(), m_write8.name());
break;
case CALLBACK_16:
- if (m_device.owner()->subdevice(m_write16.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_write16.device_name()))
osd_printf_error("Device %s not found for WRITE16 callback (%s)\n", m_write16.device_name(), m_write16.name());
break;
case CALLBACK_32:
- if (m_device.owner()->subdevice(m_write32.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_write32.device_name()))
osd_printf_error("Device %s not found for WRITE32 callback (%s)\n", m_write32.device_name(), m_write32.name());
break;
case CALLBACK_64:
- if (m_device.owner()->subdevice(m_write64.device_name()) == nullptr)
+ if (!m_base.get().subdevice(m_write64.device_name()))
osd_printf_error("Device %s not found for WRITE64 callback (%s)\n", m_write64.device_name(), m_write64.name());
break;
@@ -691,21 +697,18 @@ void devcb_write_base::validity_check(validity_checker &valid) const
case CALLBACK_ASSERTLINE:
case CALLBACK_CLEARLINE:
case CALLBACK_HOLDLINE:
- {
- device_t *device = m_device.owner()->subdevice(m_target_tag);
- if (device == nullptr)
- osd_printf_error("Device %s not found for INPUTLINE callback (%d)\n", m_target_tag, int(m_target_int));
- else
{
+ device_t *const device = m_base.get().subdevice(m_target_tag);
device_execute_interface *execute;
- if (!device->interface(execute))
+ if (!device)
+ osd_printf_error("Device %s not found for INPUTLINE callback (%d)\n", m_target_tag, int(m_target_int));
+ else if (!device->interface(execute))
osd_printf_error("Device %s has no interface for INPUTLINE callback (%d)\n", m_target_tag, int(m_target_int));
}
break;
}
- }
- if (m_chain != nullptr)
+ if (m_chain)
m_chain->validity_check(valid);
}
@@ -812,7 +815,7 @@ void devcb_write_base::write_output_adapter(address_space &space, offs_t offset,
void devcb_write_base::write_logged_adapter(address_space &space, offs_t offset, u64 data, u64 mask)
{
if (unshift_mask_xor(data) != 0)
- m_device.logerror("%s: %s\n", m_device.machine().describe_context(), m_target_tag);
+ m_owner.logerror("%s: %s\n", m_owner.machine().describe_context(), m_base.get().subtag(m_target_tag));
}
diff --git a/src/emu/devcb.h b/src/emu/devcb.h
index bbfc273f0be..f884dc7a517 100644
--- a/src/emu/devcb.h
+++ b/src/emu/devcb.h
@@ -17,6 +17,8 @@
#ifndef MAME_EMU_DEVCB_H
#define MAME_EMU_DEVCB_H
+#include <functional>
+
//**************************************************************************
// MACROS
@@ -206,7 +208,7 @@ public:
devcb_base &set_callback(output_desc output) { reset(CALLBACK_OUTPUT); m_target_tag = output.m_tag; return *this; }
devcb_base &set_callback(constant_desc constant) { reset(CALLBACK_CONSTANT); m_target_int = constant.m_value; return *this; }
devcb_base &set_callback(logger_desc logger) { reset(CALLBACK_LOG); m_target_tag = logger.m_string; return *this; }
- void reset() { reset(CALLBACK_NONE); }
+ void reset() { reset(m_owner, CALLBACK_NONE); }
protected:
// internal helpers
@@ -215,6 +217,7 @@ protected:
inline u64 unshift_mask(u64 value) const { return (m_rshift < 0) ? ((value & m_mask) >> -m_rshift) : ((value & m_mask) << m_rshift); }
inline u64 unshift_mask_xor(u64 value) const { return (m_rshift < 0) ? (((value ^ m_xor) & m_mask) >> -m_rshift) : (((value ^ m_xor) & m_mask) << m_rshift); }
void reset(callback_type type);
+ void reset(device_t &base, callback_type type);
virtual void devcb_reset() = 0;
void resolve_ioport();
void resolve_membank();
@@ -233,12 +236,13 @@ protected:
};
// configuration
- device_t & m_device; // reference to our owning device
+ device_t & m_owner; // reference to our owning device
+ std::reference_wrapper<device_t> m_base; // device to resolve relative to
callback_type m_type; // type of callback registered
const char * m_target_tag; // tag of target object
u64 m_target_int; // integer value of target object
const char * m_space_tag; // tag of address space device
- int m_space_num; // address space number of space device
+ int m_space_num; // address space number of space device
// derived state
address_space * m_space; // target address space
diff --git a/src/emu/disound.cpp b/src/emu/disound.cpp
index 3d84a24db71..f8931ae6d24 100644
--- a/src/emu/disound.cpp
+++ b/src/emu/disound.cpp
@@ -207,7 +207,7 @@ void device_sound_interface::interface_validity_check(validity_checker &valid) c
// find a device with the requested tag
const device_t *target = device().siblingdevice(route->m_target.c_str());
if (target == nullptr)
- osd_printf_error("Attempting to route sound to non-existant device '%s'\n", route->m_target.c_str());
+ osd_printf_error("Attempting to route sound to non-existent device '%s'\n", route->m_target.c_str());
// if it's not a speaker or a sound device, error
const device_sound_interface *sound;
diff --git a/src/emu/divideo.cpp b/src/emu/divideo.cpp
index 66cbd6105e9..437cd20a31b 100644
--- a/src/emu/divideo.cpp
+++ b/src/emu/divideo.cpp
@@ -113,14 +113,14 @@ void device_video_interface::interface_pre_start()
}
// fatal error if no screen is found
- if (!m_screen)
+ if (!m_screen && m_screen_required)
throw emu_fatalerror("Device '%s' requires a screen", device().tag());
// if we have a screen and it's not started, wait for it
- device_palette_interface *palintf;
if (m_screen && !m_screen->started())
{
// avoid circular dependency if we are also a palette device
+ device_palette_interface *palintf;
if (!device().interface(palintf))
throw device_missing_dependencies();
diff --git a/src/emu/emucore.h b/src/emu/emucore.h
index dda0b3da1ea..c663909e675 100644
--- a/src/emu/emucore.h
+++ b/src/emu/emucore.h
@@ -236,8 +236,8 @@ inline TYPE &operator|=(TYPE &a, TYPE b) { return a = a | b; }
// macros to convert radians to degrees and degrees to radians
-#define RADIAN_TO_DEGREE(x) ((180.0 / M_PI) * (x))
-#define DEGREE_TO_RADIAN(x) ((M_PI / 180.0) * (x))
+template <typename T> constexpr auto RADIAN_TO_DEGREE(T const &x) { return (180.0 / M_PI) * x; }
+template <typename T> constexpr auto DEGREE_TO_RADIAN(T const &x) { return (M_PI / 180.0) * x; }
// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian