Point conceded; it is not, at this point, sensible to make m_vblank_interrupt_screen a finder. Indeed, the need for it should be removed from diexec entirely. nw

This commit is contained in:
mooglyguy 2018-06-03 21:13:28 +02:00
parent 0015f48a75
commit daa92575c4
2 changed files with 20 additions and 13 deletions

View File

@ -46,7 +46,7 @@ device_execute_interface::device_execute_interface(const machine_config &mconfig
: device_interface(device, "execute") : device_interface(device, "execute")
, m_scheduler(nullptr) , m_scheduler(nullptr)
, m_disabled(false) , m_disabled(false)
, m_vblank_interrupt_screen(*this, finder_base::DUMMY_TAG) , m_vblank_interrupt_screen(nullptr)
, m_timed_interrupt_period(attotime::zero) , m_timed_interrupt_period(attotime::zero)
, m_nextexec(nullptr) , m_nextexec(nullptr)
, m_timedint_timer(nullptr) , m_timedint_timer(nullptr)
@ -345,13 +345,14 @@ void device_execute_interface::execute_set_input(int linenum, int state)
void device_execute_interface::interface_validity_check(validity_checker &valid) const void device_execute_interface::interface_validity_check(validity_checker &valid) const
{ {
// validate the interrupts // validate the interrupts
if (!m_vblank_interrupt_screen) if (m_vblank_interrupt.isnull())
{ {
if (m_vblank_interrupt_screen.finder_tag() != finder_base::DUMMY_TAG) screen_device_iterator iter(device().mconfig().root_device());
osd_printf_error("VBLANK interrupt references non-existent screen tag %s\n", m_vblank_interrupt_screen.finder_tag()); if (iter.first() == nullptr)
else if (!m_vblank_interrupt.isnull()) osd_printf_error("VBLANK interrupt specified, but the driver is screenless\n");
osd_printf_error("VBLANK interrupt specified, but no screen configured\n"); else if (m_vblank_interrupt_screen != nullptr && device().siblingdevice(m_vblank_interrupt_screen) == nullptr)
} osd_printf_error("VBLANK interrupt references a non-existant screen tag '%s'\n", m_vblank_interrupt_screen);
}
if (!m_timed_interrupt.isnull() && m_timed_interrupt_period == attotime::zero) if (!m_timed_interrupt.isnull() && m_timed_interrupt_period == attotime::zero)
osd_printf_error("Timed interrupt handler specified with 0 period\n"); osd_printf_error("Timed interrupt handler specified with 0 period\n");
@ -442,8 +443,14 @@ void device_execute_interface::interface_post_reset()
elem.reset(); elem.reset();
// reconfingure VBLANK interrupts // reconfingure VBLANK interrupts
if (m_vblank_interrupt_screen) if (m_vblank_interrupt_screen != nullptr)
m_vblank_interrupt_screen->register_vblank_callback(vblank_state_delegate(&device_execute_interface::on_vblank, this)); {
// get the screen that will trigger the VBLANK
screen_device * screen = device().siblingdevice<screen_device>(m_vblank_interrupt_screen);
assert(screen != nullptr);
screen->register_vblank_callback(vblank_state_delegate(&device_execute_interface::on_vblank, this));
}
// reconfigure periodic interrupts // reconfigure periodic interrupts
if (m_timed_interrupt_period != attotime::zero) if (m_timed_interrupt_period != attotime::zero)

View File

@ -86,7 +86,7 @@ enum
#define MCFG_DEVICE_VBLANK_INT_DEVICE(_tag, _devtag, _class, _func) \ #define MCFG_DEVICE_VBLANK_INT_DEVICE(_tag, _devtag, _class, _func) \
dynamic_cast<device_execute_interface &>(*device).set_vblank_int(device_interrupt_delegate(&_class::_func, #_class "::" #_func, _devtag, (_class *)nullptr), _tag); dynamic_cast<device_execute_interface &>(*device).set_vblank_int(device_interrupt_delegate(&_class::_func, #_class "::" #_func, _devtag, (_class *)nullptr), _tag);
#define MCFG_DEVICE_VBLANK_INT_REMOVE() \ #define MCFG_DEVICE_VBLANK_INT_REMOVE() \
dynamic_cast<device_execute_interface &>(*device).set_vblank_int(device_interrupt_delegate(), finder_base::DUMMY_TAG); dynamic_cast<device_execute_interface &>(*device).set_vblank_int(device_interrupt_delegate(), nullptr);
#define MCFG_DEVICE_PERIODIC_INT_DRIVER(_class, _func, _rate) \ #define MCFG_DEVICE_PERIODIC_INT_DRIVER(_class, _func, _rate) \
dynamic_cast<device_execute_interface &>(*device).set_periodic_int(device_interrupt_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr), attotime::from_hz(_rate)); dynamic_cast<device_execute_interface &>(*device).set_periodic_int(device_interrupt_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr), attotime::from_hz(_rate));
#define MCFG_DEVICE_PERIODIC_INT_DEVICE(_devtag, _class, _func, _rate) \ #define MCFG_DEVICE_PERIODIC_INT_DEVICE(_devtag, _class, _func, _rate) \
@ -140,10 +140,10 @@ public:
// inline configuration helpers // inline configuration helpers
void set_disable() { m_disabled = true; } void set_disable() { m_disabled = true; }
template <typename Object, typename T> void set_vblank_int(Object &&cb, T &&tag, int rate = 0) template <typename Object> void set_vblank_int(Object &&cb, const char *tag, int rate = 0)
{ {
m_vblank_interrupt = std::forward<Object>(cb); m_vblank_interrupt = std::forward<Object>(cb);
m_vblank_interrupt_screen.set_tag(std::forward<T>(tag)); m_vblank_interrupt_screen = tag;
} }
template <typename Object> void set_periodic_int(Object &&cb, const attotime &rate) template <typename Object> void set_periodic_int(Object &&cb, const attotime &rate)
{ {
@ -290,7 +290,7 @@ private:
// configuration // configuration
bool m_disabled; // disabled from executing? bool m_disabled; // disabled from executing?
device_interrupt_delegate m_vblank_interrupt; // for interrupts tied to VBLANK device_interrupt_delegate m_vblank_interrupt; // for interrupts tied to VBLANK
optional_device<screen_device> m_vblank_interrupt_screen; // the screen that causes the VBLANK interrupt const char * m_vblank_interrupt_screen; // the screen that causes the VBLANK interrupt
device_interrupt_delegate m_timed_interrupt; // for interrupts not tied to VBLANK device_interrupt_delegate m_timed_interrupt; // for interrupts not tied to VBLANK
attotime m_timed_interrupt_period; // period for periodic interrupts attotime m_timed_interrupt_period; // period for periodic interrupts