Timers in MAME are objects which can call you back after a very precise amount of emulated time has passed. You can use them in your drivers and devices to emulate hardware timers or do other kinds of periodic tasks.
Creating a timer
Each timer is an object which you refer to by an opaque pointer, like many other things in MAME. For timers, they are of type "emu_timer", like this:
To instantiate a timer, you call timer_alloc().
my_timer = timer_alloc(machine, callback, reference_pointer);
machine is the current machine pointer - you should be calling timer_alloc in either your MACHINE_INIT(), DRIVER_INIT(), or DEVICE_INIT()/CPU_INIT() functions, all of which have the current machine pointer available.
callback is your function that is called when the timer expires. It's of this form:
TIMER_CALLBACK( my_timer_callback )
reference_pointer is any value you want that you can fit into a pointer (beware of 32/64 bit issues here!). It is passed to your callback as a void * named ptr.
Your callback also gets a pointer to the current machine named machine and one more parameter we will discuss a little later.
Arming a timer
Timers can either be one-shot or periodic. One-shot timers fire once and then never again. Periodic timers automatically start over again after they fire and will keep going off until you stop them. You can change a timer's "mode" on the fly if you wish - each new arm call makes the timer mode behave as specified.
This is how you arm a timer for one-shot operation:
timer_adjust_oneshot(my_timer, time_to_fire, reference_integer);
my_timer is the emu_timer object pointer you allocated, time_to_fire is the amount of time from the current point in the emulation when the timer should fire, and reference_integer is a number for your own use which is passed to your callback as an int named param.
Here's the equivalent for periodic:
timer_adjust_periodic(my_timer, time_to_delay, reference_integer, time_to_fire);
This is quite similar, but it has two time parameters. The first (time_to_delay) is an optional amount of time to wait before beginning our periodic operation. The time_to_fire parameter gives the period of the timer.
About those time parameters
Time in MAME is in terms of "attotime", a high-precision 96 bit fixed point representation accurate to 1 attosecond. Fortunately a variety of helpers are provided in case you don't speak attoseconds:
attotime_never is a constant for infinity, or as close to it as MAME can get. If you use it as a timer's time value the timer will never go off. This is useful for when you're emulating a hardware timer and it's disabled.
attotime_zero is a constant for zero time. If you use this as a timer value the callback will occur immediately.
The following conversion macros are also available:
This creates an attotime for a timer which fires x number of times per second.
This creates an attotime for a timer which fires every x seconds.
These work similarly to ATTOTIME_IN_SEC but work in terms of milliseconds, microseconds, and nanoseconds. They are rarely used, obviously.
Math operations on attotime values are available; refer to the attotime.h file for more information.