diff options
Diffstat (limited to 'src/devices/machine/timer.cpp')
-rw-r--r-- | src/devices/machine/timer.cpp | 114 |
1 files changed, 48 insertions, 66 deletions
diff --git a/src/devices/machine/timer.cpp b/src/devices/machine/timer.cpp index b30471279f0..f2dc8464578 100644 --- a/src/devices/machine/timer.cpp +++ b/src/devices/machine/timer.cpp @@ -9,8 +9,7 @@ ***************************************************************************/ #include "emu.h" -#include "machine/timer.h" -#include "screen.h" +#include "timer.h" /*************************************************************************** @@ -34,20 +33,18 @@ DEFINE_DEVICE_TYPE(TIMER, timer_device, "timer", "Timer") // timer_device - constructor //------------------------------------------------- -timer_device::timer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : device_t(mconfig, TIMER, tag, owner, clock), - m_type(TIMER_TYPE_GENERIC), - m_callback(), - m_ptr(nullptr), - m_start_delay(attotime::zero), - m_period(attotime::zero), - m_param(0), - m_screen_tag(nullptr), - m_screen(nullptr), - m_first_vpos(0), - m_increment(0), - m_timer(nullptr), - m_first_time(true) +timer_device::timer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, TIMER, tag, owner, clock), + m_type(TIMER_TYPE_GENERIC), + m_callback(*this), + m_start_delay(attotime::zero), + m_period(attotime::zero), + m_param(0), + m_screen(*this, finder_base::DUMMY_TAG), + m_first_vpos(0), + m_increment(0), + m_timer(nullptr), + m_first_time(true) { } @@ -63,14 +60,14 @@ void timer_device::device_validity_check(validity_checker &valid) const switch (m_type) { case TIMER_TYPE_GENERIC: - if (m_screen_tag != nullptr || m_first_vpos != 0 || m_start_delay != attotime::zero) + if (m_screen.finder_tag() != finder_base::DUMMY_TAG || m_first_vpos != 0 || m_start_delay != attotime::zero) osd_printf_warning("Generic timer specified parameters for a scanline timer\n"); if (m_period != attotime::zero || m_start_delay != attotime::zero) osd_printf_warning("Generic timer specified parameters for a periodic timer\n"); break; case TIMER_TYPE_PERIODIC: - if (m_screen_tag != nullptr || m_first_vpos != 0) + if (m_screen.finder_tag() != finder_base::DUMMY_TAG || m_first_vpos != 0) osd_printf_warning("Periodic timer specified parameters for a scanline timer\n"); if (m_period <= attotime::zero) osd_printf_error("Periodic timer specified invalid period\n"); @@ -81,10 +78,10 @@ void timer_device::device_validity_check(validity_checker &valid) const osd_printf_warning("Scanline timer specified parameters for a periodic timer\n"); if (m_param != 0) osd_printf_warning("Scanline timer specified parameter which is ignored\n"); - if (m_screen_tag == nullptr) + if (m_screen.finder_tag() == finder_base::DUMMY_TAG) osd_printf_error("Scanline timer has no screen specified\n"); - else if (dynamic_cast<screen_device *>(siblingdevice(m_screen_tag)) == nullptr) - osd_printf_error("Scanline timer specifies nonexistent screen %s\n", m_screen_tag); + else if (!m_screen) + osd_printf_error("Scanline timer specifies nonexistent screen %s\n", m_screen.finder_tag()); // if (m_first_vpos < 0) // osd_printf_error("Scanline timer specified invalid initial position\n"); // if (m_increment < 0) @@ -105,14 +102,12 @@ void timer_device::device_validity_check(validity_checker &valid) const void timer_device::device_start() { - // fetch the screen - if (m_screen_tag != nullptr) - m_screen = siblingdevice<screen_device>(m_screen_tag); + if (m_type == TIMER_TYPE_SCANLINE) + m_timer = timer_alloc(FUNC(timer_device::scanline_tick), this); + else + m_timer = timer_alloc(FUNC(timer_device::generic_tick), this); - // allocate the timer - m_timer = timer_alloc(); - - m_callback.bind_relative_to(*owner()); + m_callback.resolve(); // register for save states save_item(NAME(m_first_time)); @@ -149,8 +144,8 @@ void timer_device::device_reset() } case TIMER_TYPE_SCANLINE: - if (m_screen == nullptr) - fatalerror("timer '%s': unable to find screen '%s'\n", tag(), m_screen_tag); + if (!m_screen) + fatalerror("timer '%s': unable to find screen '%s'\n", tag(), m_screen.finder_tag()); // set the timer to fire immediately m_first_time = true; @@ -160,44 +155,31 @@ void timer_device::device_reset() } -//------------------------------------------------- -// device_timer - handle timer expiration events -//------------------------------------------------- - -void timer_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(timer_device::generic_tick) { - switch (m_type) - { - // general periodic timers just call through - case TIMER_TYPE_GENERIC: - case TIMER_TYPE_PERIODIC: - if (!m_callback.isnull()) - (m_callback)(*this, m_ptr, param); - break; - - // scanline timers have to do some additional bookkeeping - case TIMER_TYPE_SCANLINE: - { - // by default, we fire at the first position - int next_vpos = m_first_vpos; + if (!m_callback.isnull()) + (m_callback)(*this, param); +} - // the first time through we just go with the default position - if (!m_first_time) - { - // call the real callback - int vpos = m_screen->vpos(); - if (!m_callback.isnull()) - (m_callback)(*this, m_ptr, vpos); - - // advance by the increment only if we will still be within the screen bounds - if (m_increment != 0 && (vpos + m_increment) < m_screen->height()) - next_vpos = vpos + m_increment; - } - m_first_time = false; +TIMER_CALLBACK_MEMBER(timer_device::scanline_tick) +{ + // by default, we fire at the first position + int next_vpos = m_first_vpos; - // adjust the timer - m_timer->adjust(m_screen->time_until_pos(next_vpos)); - break; - } + // the first time through we just go with the default position + if (!m_first_time) + { + // call the real callback + int vpos = m_screen->vpos(); + if (!m_callback.isnull()) + (m_callback)(*this, vpos); + + // advance by the increment only if we will still be within the screen bounds + if (m_increment != 0 && (vpos + m_increment) < m_screen->height()) + next_vpos = vpos + m_increment; } + m_first_time = false; + + // adjust the timer + m_timer->adjust(m_screen->time_until_pos(next_vpos)); } |