From da7cd69f881d30af8a9cac40746ee2bbfc74a75b Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 1 Oct 2017 22:45:43 -0400 Subject: Remove timer_device from emu.h and move it out of src/emu (nw) --- src/devices/machine/timer.cpp | 291 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 src/devices/machine/timer.cpp (limited to 'src/devices/machine/timer.cpp') diff --git a/src/devices/machine/timer.cpp b/src/devices/machine/timer.cpp new file mode 100644 index 00000000000..1bc10dab25a --- /dev/null +++ b/src/devices/machine/timer.cpp @@ -0,0 +1,291 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + timer.cpp + + Timer devices. + +***************************************************************************/ + +#include "emu.h" +#include "machine/timer.h" +#include "screen.h" + + +/*************************************************************************** +// DEBUGGING +***************************************************************************/ + +#define VERBOSE 0 + +#define LOG(x) do { if (VERBOSE) logerror x; } while (0) + + + + +//************************************************************************** +// LIVE TIMER DEVICE +//************************************************************************** + +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) +{ +} + + +//------------------------------------------------- +// static_configure_generic - configuration +// helper to set up a generic timer +//------------------------------------------------- + +void timer_device::static_configure_generic(device_t &device, expired_delegate callback) +{ + timer_device &timer = downcast(device); + timer.m_type = TIMER_TYPE_GENERIC; + timer.m_callback = callback; +} + + +//------------------------------------------------- +// static_configure_periodic - configuration +// helper to set up a periodic timer +//------------------------------------------------- + +void timer_device::static_configure_periodic(device_t &device, expired_delegate callback, const attotime &period) +{ + timer_device &timer = downcast(device); + timer.m_type = TIMER_TYPE_PERIODIC; + timer.m_callback = callback; + timer.m_period = period; +} + + +//------------------------------------------------- +// static_configure_scanline - configuration +// helper to set up a scanline timer +//------------------------------------------------- + +void timer_device::static_configure_scanline(device_t &device, expired_delegate callback, const char *screen, int first_vpos, int increment) +{ + timer_device &timer = downcast(device); + timer.m_type = TIMER_TYPE_SCANLINE; + timer.m_callback = callback; + timer.m_screen_tag = screen; + timer.m_first_vpos = first_vpos; + timer.m_increment = increment; +} + + +//------------------------------------------------- +// static_set_callback - configuration helper +// to set the callback +//------------------------------------------------- + +void timer_device::static_set_callback(device_t &device, expired_delegate callback) +{ + timer_device &timer = downcast(device); + timer.m_callback = callback; +} + + +//------------------------------------------------- +// static_set_start_delay - configuration helper +// to set the starting delay +//------------------------------------------------- + +void timer_device::static_set_start_delay(device_t &device, const attotime &delay) +{ + timer_device &timer = downcast(device); + timer.m_start_delay = delay; +} + + +//------------------------------------------------- +// static_set_param - configuration helper to set +// the integer parameter +//------------------------------------------------- + +void timer_device::static_set_param(device_t &device, int param) +{ + timer_device &timer = downcast(device); + timer.m_param = param; +} + + +//------------------------------------------------- +// static_set_ptr - configuration helper to set +// the pointer parameter +//------------------------------------------------- + +void timer_device::static_set_ptr(device_t &device, void *ptr) +{ + timer_device &timer = downcast(device); + timer.m_ptr = ptr; +} + + +//------------------------------------------------- +// device_validity_check - validate the device +// configuration +//------------------------------------------------- + +void timer_device::device_validity_check(validity_checker &valid) const +{ + // type based configuration + switch (m_type) + { + case TIMER_TYPE_GENERIC: + if (m_screen_tag != nullptr || 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) + 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"); + break; + + case TIMER_TYPE_SCANLINE: + if (m_period != attotime::zero || m_start_delay != attotime::zero) + 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_first_vpos < 0) +// osd_printf_error("Scanline timer specified invalid initial position\n"); +// if (m_increment < 0) +// osd_printf_error("Scanline timer specified invalid increment\n"); + break; + + default: + osd_printf_error("Invalid type specified\n"); + break; + } +} + + +//------------------------------------------------- +// device_start - perform device-specific +// startup +//------------------------------------------------- + +void timer_device::device_start() +{ + // fetch the screen + if (m_screen_tag != nullptr) + m_screen = machine().device(m_screen_tag); + + // allocate the timer + m_timer = timer_alloc(); + + m_callback.bind_relative_to(*owner()); + + // register for save states + save_item(NAME(m_first_time)); +} + + +//------------------------------------------------- +// device_reset - reset the device +//------------------------------------------------- + +void timer_device::device_reset() +{ + // type based configuration + switch (m_type) + { + case TIMER_TYPE_GENERIC: + case TIMER_TYPE_PERIODIC: + { + // convert the period into attotime + attotime period; + if (m_period > attotime::zero) + { + period = m_period; + + // convert the start_delay into attotime + attotime start_delay = attotime::zero; + if (m_start_delay > attotime::zero) + start_delay = m_start_delay; + + // allocate and start the backing timer + m_timer->adjust(start_delay, m_param, period); + } + break; + } + + case TIMER_TYPE_SCANLINE: + if (m_screen == nullptr) + fatalerror("timer '%s': unable to find screen '%s'\n", tag(), m_screen_tag); + + // set the timer to fire immediately + m_first_time = true; + m_timer->adjust(attotime::zero, m_param); + break; + } +} + + +//------------------------------------------------- +// device_timer - handle timer expiration events +//------------------------------------------------- + +void timer_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + 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 additiona bookkeeping + case TIMER_TYPE_SCANLINE: + { + // by default, we fire at the first position + int next_vpos = m_first_vpos; + + // 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; + + // adjust the timer + m_timer->adjust(m_screen->time_until_pos(next_vpos)); + break; + } + } +} -- cgit v1.2.3-70-g09d2