1 // license:BSD-3-Clause 2 // copyright-holders:Aaron Giles 3 /*************************************************************************** 4 5 timer.h 6 7 Timer devices. 8 9 ***************************************************************************/ 10 #ifndef MAME_MACHINE_TIMER_H 11 #define MAME_MACHINE_TIMER_H 12 13 #pragma once 14 15 #include "screen.h" 16 17 18 //************************************************************************** 19 // MACROS 20 //************************************************************************** 21 22 // macros for a timer callback functions 23 #define TIMER_DEVICE_CALLBACK_MEMBER(name) void name(timer_device &timer, void *ptr, s32 param) 24 25 //************************************************************************** 26 // TYPE DEFINITIONS 27 //************************************************************************** 28 29 // ======================> timer_device 30 31 class timer_device : public device_t 32 { 33 public: 34 // a timer callbacks look like this 35 typedef device_delegate<void (timer_device &, void *, s32)> expired_delegate; 36 37 // construction/destruction 38 timer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); 39 40 // inline configuration helpers configure_generic(T &&...args)41 template <typename... T> void configure_generic(T &&... args) 42 { 43 m_type = TIMER_TYPE_GENERIC; 44 m_callback.set(std::forward<T>(args)...); 45 } 46 configure_periodic(F && callback,const char * name,const attotime & period)47 template <typename F> void configure_periodic(F &&callback, const char *name, const attotime &period) 48 { 49 m_type = TIMER_TYPE_PERIODIC; 50 m_callback.set(std::forward<F>(callback), name); 51 m_period = period; 52 } configure_periodic(T && target,F && callback,const char * name,const attotime & period)53 template <typename T, typename F> void configure_periodic(T &&target, F &&callback, const char *name, const attotime &period) 54 { 55 m_type = TIMER_TYPE_PERIODIC; 56 m_callback.set(std::forward<T>(target), std::forward<F>(callback), name); 57 m_period = period; 58 } 59 configure_scanline(F && callback,const char * name,U && screen,int first_vpos,int increment)60 template <typename F, typename U> void configure_scanline(F &&callback, const char *name, U &&screen, int first_vpos, int increment) 61 { 62 m_type = TIMER_TYPE_SCANLINE; 63 m_callback.set(std::forward<F>(callback), name); 64 m_screen.set_tag(std::forward<U>(screen)); 65 m_first_vpos = first_vpos; 66 m_increment = increment; 67 } configure_scanline(T && target,F && callback,const char * name,U && screen,int first_vpos,int increment)68 template <typename T, typename F, typename U> void configure_scanline(T &&target, F &&callback, const char *name, U &&screen, int first_vpos, int increment) 69 { 70 m_type = TIMER_TYPE_SCANLINE; 71 m_callback.set(std::forward<T>(target), std::forward<F>(callback), name); 72 m_screen.set_tag(std::forward<U>(screen)); 73 m_first_vpos = first_vpos; 74 m_increment = increment; 75 } 76 set_callback(T &&...args)77 template <typename... T> void set_callback(T &&... args) { m_callback.set(std::forward<T>(args)...); } 78 set_start_delay(const attotime & delay)79 void set_start_delay(const attotime &delay) { m_start_delay = delay; } config_param(int param)80 void config_param(int param) { m_param = param; } 81 82 // property getters param()83 int param() const { return m_timer->param(); } ptr()84 void *ptr() const { return m_ptr; } enabled()85 bool enabled() const { return m_timer->enabled(); } 86 87 // property setters set_param(int param)88 void set_param(int param) const { if(m_type != TIMER_TYPE_GENERIC) fatalerror("Cannot change parameter on a non-generic timer.\n"); m_timer->set_param(param); } set_ptr(void * ptr)89 void set_ptr(void *ptr) { m_ptr = ptr; } 90 void enable(bool enable = true) const { m_timer->enable(enable); } 91 92 // adjustments reset()93 void reset() { adjust(attotime::never, 0, attotime::never); } 94 void adjust(const attotime &duration, s32 param = 0, const attotime &period = attotime::never) const 95 { 96 if(m_type != TIMER_TYPE_GENERIC) 97 fatalerror("Cannot adjust a non-generic timer.\n"); 98 m_timer->adjust(duration, param, period); 99 } 100 101 // timing information time_elapsed()102 attotime time_elapsed() const { return m_timer->elapsed(); } time_left()103 attotime time_left() const { return m_timer->remaining(); } start_time()104 attotime start_time() const { return m_timer->start(); } fire_time()105 attotime fire_time() const { return m_timer->expire(); } period()106 attotime period() const { return m_timer ? m_timer->period() : m_period; } 107 108 private: 109 // device-level overrides 110 virtual void device_validity_check(validity_checker &valid) const override; 111 virtual void device_start() override; 112 virtual void device_reset() override; 113 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; 114 115 // timer types 116 enum timer_type 117 { 118 TIMER_TYPE_PERIODIC, 119 TIMER_TYPE_SCANLINE, 120 TIMER_TYPE_GENERIC 121 }; 122 123 // configuration data 124 timer_type m_type; // type of timer 125 expired_delegate m_callback; // the timer's callback function 126 void * m_ptr; // the pointer parameter passed to the timer callback 127 128 // periodic timers only 129 attotime m_start_delay; // delay before the timer fires for the first time 130 attotime m_period; // period of repeated timer firings 131 s32 m_param; // the integer parameter passed to the timer callback 132 133 // scanline timers only 134 optional_device<screen_device> m_screen; // pointer to the screen device 135 u32 m_first_vpos; // the first vertical scanline position the timer fires on 136 u32 m_increment; // the number of scanlines between firings 137 138 // internal state 139 emu_timer * m_timer; // the backing timer 140 bool m_first_time; // indicates that the system is starting (scanline timers only) 141 }; 142 143 144 145 //************************************************************************** 146 // GLOBAL VARIABLES 147 //************************************************************************** 148 149 DECLARE_DEVICE_TYPE(TIMER, timer_device) 150 151 152 #endif // MAME_MACHINE_TIMER_H 153