summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2010-09-17 13:33:27 +0000
committer Aaron Giles <aaron@aarongiles.com>2010-09-17 13:33:27 +0000
commit1a066df97d68010ec0b332c696ead694dea51d0f (patch)
treee95d1f01b698400f89e4e7ce90c96fb54f3a73de
parent893c1f3e81f86921eaa27c48adf994f8a1c9d538 (diff)
Added an integral device_timer_id to device timers. This is a
cleaner way to differentiate between multiple timers rather than relying on the pointers. These values are also saved with the timers. Updated the few devices using device timers to leverage this. Added new function device_timer_call_after_resynch() which creates a temporary 0-length timer that calls back through the device's device_timer() method with a given device_timer_id. Updated i8257_device to initialize its state and use device timers. (Fixes 04032: All sets in dkong.c: [debug] Game does not start.)
-rw-r--r--src/emu/devintrf.c2
-rw-r--r--src/emu/devintrf.h8
-rw-r--r--src/emu/machine/6522via.c98
-rw-r--r--src/emu/machine/6522via.h6
-rw-r--r--src/emu/machine/8257dma.c134
-rw-r--r--src/emu/machine/8257dma.h14
-rw-r--r--src/emu/machine/intelfsh.c2
-rw-r--r--src/emu/machine/intelfsh.h2
-rw-r--r--src/emu/machine/mc146818.c2
-rw-r--r--src/emu/machine/mc146818.h2
-rw-r--r--src/emu/timer.c30
-rw-r--r--src/emu/timer.h5
12 files changed, 159 insertions, 146 deletions
diff --git a/src/emu/devintrf.c b/src/emu/devintrf.c
index a568b005ce9..a418deeecda 100644
--- a/src/emu/devintrf.c
+++ b/src/emu/devintrf.c
@@ -873,7 +873,7 @@ void device_t::device_debug_setup()
// fires
//-------------------------------------------------
-void device_t::device_timer(emu_timer &timer, int param, void *ptr)
+void device_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
// do nothing by default
}
diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h
index e4330d19fba..59cf5628647 100644
--- a/src/emu/devintrf.h
+++ b/src/emu/devintrf.h
@@ -137,6 +137,10 @@ class device_missing_dependencies : public emu_exception { };
typedef device_config *(*device_type)(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
+// timer IDs for devices
+typedef UINT32 device_timer_id;
+
+
// read/write types for I/O lines (similar to read/write handlers but no offset)
typedef int (*read_line_device_func)(device_t *device);
typedef void (*write_line_device_func)(device_t *device, int state);
@@ -425,7 +429,7 @@ public:
void set_clock_scale(double clockscale);
attotime clocks_to_attotime(UINT64 clocks) const;
UINT64 attotime_to_clocks(attotime duration) const;
- void timer_fired(emu_timer &timer, int param, void *ptr) { device_timer(timer, param, ptr); }
+ void timer_fired(emu_timer &timer, device_timer_id id, int param, void *ptr) { device_timer(timer, id, param, ptr); }
// debugging
device_debug *debug() const { return m_debug; }
@@ -460,7 +464,7 @@ protected:
virtual void device_post_load();
virtual void device_clock_changed();
virtual void device_debug_setup();
- virtual void device_timer(emu_timer &timer, int param, void *ptr);
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
//------------------- end derived class overrides
diff --git a/src/emu/machine/6522via.c b/src/emu/machine/6522via.c
index 48de6e08e32..70de6dc87b5 100644
--- a/src/emu/machine/6522via.c
+++ b/src/emu/machine/6522via.c
@@ -218,9 +218,9 @@ void via6522_device::device_start()
m_t2ll = 0xff; /* taken from vice */
m_t2lh = 0xff;
m_time2 = m_time1 = timer_get_time(&m_machine);
- m_t1 = device_timer_alloc(*this);
- m_t2 = device_timer_alloc(*this);
- m_shift_timer = device_timer_alloc(*this);
+ m_t1 = device_timer_alloc(*this, TIMER_T1);
+ m_t2 = device_timer_alloc(*this, TIMER_T2);
+ m_shift_timer = device_timer_alloc(*this, TIMER_SHIFT);
/* Default clock is from CPU1 */
if (clock() == 0)
@@ -415,54 +415,56 @@ void via6522_device::shift()
}
-void via6522_device::device_timer(emu_timer &timer, int param, void *ptr)
+void via6522_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- // shift timer
- if (&timer == m_shift_timer)
- shift();
-
- // t1 timeout
- else if (&timer == m_t1)
+ switch (id)
{
- if (T1_CONTINUOUS (m_acr))
- {
- if (T1_SET_PB7(m_acr))
- {
- m_out_b ^= 0x80;
- }
- timer_adjust_oneshot(m_t1, cycles_to_time(TIMER1_VALUE + IFR_DELAY), 0);
- }
- else
- {
- if (T1_SET_PB7(m_acr))
- {
- m_out_b |= 0x80;
- }
- m_t1_active = 0;
- m_time1 = timer_get_time(&m_machine);
- }
- if (m_ddr_b)
- {
- UINT8 write_data = (m_out_b & m_ddr_b) | (m_ddr_b ^ 0xff);
- devcb_call_write8(&m_out_b_func, 0, write_data);
- }
-
- if (!(m_ifr & INT_T1))
- {
- set_int(INT_T1);
- }
- }
-
- // t2 timeout
- else if (&timer == m_t2)
- {
- m_t2_active = 0;
- m_time2 = timer_get_time(&m_machine);
+ // shift timer
+ case TIMER_SHIFT:
+ shift();
+ break;
+
+ // t1 timeout
+ case TIMER_T1:
+ if (T1_CONTINUOUS (m_acr))
+ {
+ if (T1_SET_PB7(m_acr))
+ {
+ m_out_b ^= 0x80;
+ }
+ timer_adjust_oneshot(m_t1, cycles_to_time(TIMER1_VALUE + IFR_DELAY), 0);
+ }
+ else
+ {
+ if (T1_SET_PB7(m_acr))
+ {
+ m_out_b |= 0x80;
+ }
+ m_t1_active = 0;
+ m_time1 = timer_get_time(&m_machine);
+ }
+ if (m_ddr_b)
+ {
+ UINT8 write_data = (m_out_b & m_ddr_b) | (m_ddr_b ^ 0xff);
+ devcb_call_write8(&m_out_b_func, 0, write_data);
+ }
- if (!(m_ifr & INT_T2))
- {
- set_int(INT_T2);
- }
+ if (!(m_ifr & INT_T1))
+ {
+ set_int(INT_T1);
+ }
+ break;
+
+ // t2 timeout
+ case TIMER_T2:
+ m_t2_active = 0;
+ m_time2 = timer_get_time(&m_machine);
+
+ if (!(m_ifr & INT_T2))
+ {
+ set_int(INT_T2);
+ }
+ break;
}
}
diff --git a/src/emu/machine/6522via.h b/src/emu/machine/6522via.h
index f8729903332..a446df91cfe 100644
--- a/src/emu/machine/6522via.h
+++ b/src/emu/machine/6522via.h
@@ -133,9 +133,13 @@ protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
- virtual void device_timer(emu_timer &timer, int param, void *ptr);
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
+ static const device_timer_id TIMER_SHIFT = 0;
+ static const device_timer_id TIMER_T1 = 1;
+ static const device_timer_id TIMER_T2 = 2;
+
attotime cycles_to_time(int c);
UINT32 time_to_cycles(attotime t);
UINT16 get_counter1_value();
diff --git a/src/emu/machine/8257dma.c b/src/emu/machine/8257dma.c
index 9e0b9dd3574..810b3ff1b98 100644
--- a/src/emu/machine/8257dma.c
+++ b/src/emu/machine/8257dma.c
@@ -101,9 +101,17 @@ const device_type I8257 = i8257_device_config::static_alloc_device_config;
i8257_device::i8257_device(running_machine &_machine, const i8257_device_config &config)
: device_t(_machine, config),
+ m_mode(0),
+ m_rr(0),
+ m_msb(0),
+ m_drq(0),
+ m_status(0x0f),
m_config(config)
{
-
+ memset(m_registers, 0, sizeof(m_registers));
+ memset(m_address, 0, sizeof(m_address));
+ memset(m_count, 0, sizeof(m_count));
+ memset(m_rwmode, 0, sizeof(m_rwmode));
}
//-------------------------------------------------
@@ -129,9 +137,8 @@ void i8257_device::device_start()
}
/* set initial values */
- m_status = 0x0f;
- m_timer = timer_alloc(&m_machine, i8257_timerproc_callback, (void *) this);
- m_msbflip_timer = timer_alloc(&m_machine, i8257_msbflip_timerproc_callback, (void *) this);
+ m_timer = device_timer_alloc(*this, TIMER_OPERATION);
+ m_msbflip_timer = device_timer_alloc(*this, TIMER_MSBFLIP);
/* register for state saving */
state_save_register_device_item_array(this, 0, m_address);
@@ -243,55 +250,72 @@ int i8257_device::i8257_do_operation(int channel)
}
-TIMER_CALLBACK( i8257_device::i8257_timerproc_callback )
+void i8257_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- reinterpret_cast<i8257_device*>(ptr)->i8257_timerproc();
-}
-
-void i8257_device::i8257_timerproc()
-{
- int i, channel = 0, rr;
- int done;
-
- rr = DMA_MODE_ROTPRIO(m_mode) ? m_rr : 0;
- for (i = 0; i < I8257_NUM_CHANNELS; i++)
+ switch (id)
{
- channel = (i + rr) % I8257_NUM_CHANNELS;
- if ((m_status & (1 << channel)) == 0)
+ case TIMER_OPERATION:
{
- if (m_mode & m_drq & (1 << channel))
+ int i, channel = 0, rr;
+ int done;
+
+ rr = DMA_MODE_ROTPRIO(m_mode) ? m_rr : 0;
+ for (i = 0; i < I8257_NUM_CHANNELS; i++)
{
- break;
+ channel = (i + rr) % I8257_NUM_CHANNELS;
+ if ((m_status & (1 << channel)) == 0)
+ {
+ if (m_mode & m_drq & (1 << channel))
+ {
+ break;
+ }
+ }
}
- }
- }
- done = i8257_do_operation(channel);
+ done = i8257_do_operation(channel);
- m_rr = (channel + 1) & 0x03;
+ m_rr = (channel + 1) & 0x03;
- if (done)
- {
- m_drq &= ~(0x01 << channel);
- i8257_update_status();
- if (!(DMA_MODE_AUTOLOAD(m_mode) && channel==2))
- {
- if (DMA_MODE_TCSTOP(m_mode))
+ if (done)
{
- m_mode &= ~(0x01 << channel);
+ m_drq &= ~(0x01 << channel);
+ i8257_update_status();
+ if (!(DMA_MODE_AUTOLOAD(m_mode) && channel==2))
+ {
+ if (DMA_MODE_TCSTOP(m_mode))
+ {
+ m_mode &= ~(0x01 << channel);
+ }
+ }
}
+ break;
}
- }
-}
-
+
+ case TIMER_MSBFLIP:
+ m_msb ^= 1;
+ break;
+
+ case TIMER_DRQ_SYNC:
+ {
+ int channel = param >> 1;
+ int state = param & 0x01;
-TIMER_CALLBACK( i8257_device::i8257_msbflip_timerproc_callback )
-{
- reinterpret_cast<i8257_device*>(ptr)->i8257_msbflip_timerproc();
-}
+ /* normalize state */
+ if (state)
+ {
+ m_drq |= 0x01 << channel;
+ m_address[channel] = m_registers[channel * 2];
+ m_count[channel] = m_registers[channel * 2 + 1] & 0x3FFF;
+ m_rwmode[channel] = m_registers[channel * 2 + 1] >> 14;
+ /* clear channel TC */
+ m_status &= ~(0x01 << channel);
+ }
+ else
+ m_drq &= ~(0x01 << channel);
-void i8257_device::i8257_msbflip_timerproc()
-{
- m_msb ^= 1;
+ i8257_update_status();
+ break;
+ }
+ }
}
@@ -421,37 +445,11 @@ WRITE8_DEVICE_HANDLER_TRAMPOLINE(i8257, i8257_w)
}
-TIMER_CALLBACK( i8257_device::i8257_drq_write_callback )
-{
- reinterpret_cast<i8257_device*>(ptr)->i8257_drq_write_timerproc(param);
-}
-
-void i8257_device::i8257_drq_write_timerproc(INT32 param)
-{
- int channel = param >> 1;
- int state = param & 0x01;
-
- /* normalize state */
- if (state)
- {
- m_drq |= 0x01 << channel;
- m_address[channel] = m_registers[channel * 2];
- m_count[channel] = m_registers[channel * 2 + 1] & 0x3FFF;
- m_rwmode[channel] = m_registers[channel * 2 + 1] >> 14;
- /* clear channel TC */
- m_status &= ~(0x01 << channel);
- }
- else
- m_drq &= ~(0x01 << channel);
-
- i8257_update_status();
-}
-
void i8257_device::i8257_drq_w(int channel, int state)
{
int param = (channel << 1) | (state ? 1 : 0);
- timer_call_after_resynch(&m_machine, (void *)this, param, i8257_drq_write_callback);
+ device_timer_call_after_resynch(*this, TIMER_DRQ_SYNC, param);
}
WRITE_LINE_DEVICE_HANDLER( i8257_hlda_w ) { }
diff --git a/src/emu/machine/8257dma.h b/src/emu/machine/8257dma.h
index 48c14ff443c..3f25a79d2dc 100644
--- a/src/emu/machine/8257dma.h
+++ b/src/emu/machine/8257dma.h
@@ -117,22 +117,16 @@ public:
/* data request */
void i8257_drq_w(int channel, int state);
- void i8257_timerproc();
- void i8257_msbflip_timerproc();
- void i8257_drq_write_timerproc(INT32 param);
-
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
- virtual void device_post_load() { }
- virtual void device_clock_changed() { }
-
- static TIMER_CALLBACK( i8257_timerproc_callback );
- static TIMER_CALLBACK( i8257_msbflip_timerproc_callback );
- static TIMER_CALLBACK( i8257_drq_write_callback );
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
+ static const device_timer_id TIMER_OPERATION = 0;
+ static const device_timer_id TIMER_MSBFLIP = 1;
+ static const device_timer_id TIMER_DRQ_SYNC = 2;
int i8257_do_operation(int channel);
void i8257_update_status();
diff --git a/src/emu/machine/intelfsh.c b/src/emu/machine/intelfsh.c
index bc0f3b53df8..6ce1053a283 100644
--- a/src/emu/machine/intelfsh.c
+++ b/src/emu/machine/intelfsh.c
@@ -278,7 +278,7 @@ void intelfsh_device::device_start()
// device_timer - handler timer events
//-------------------------------------------------
-void intelfsh_device::device_timer(emu_timer &timer, int param, void *ptr)
+void intelfsh_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
switch( m_flash_mode )
{
diff --git a/src/emu/machine/intelfsh.h b/src/emu/machine/intelfsh.h
index 412ce4c0ac6..ebe3871dcc9 100644
--- a/src/emu/machine/intelfsh.h
+++ b/src/emu/machine/intelfsh.h
@@ -112,7 +112,7 @@ protected:
protected:
// device-level overrides
virtual void device_start();
- virtual void device_timer(emu_timer &timer, int param, void *ptr);
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// device_config_nvram_interface overrides
virtual void nvram_default();
diff --git a/src/emu/machine/mc146818.c b/src/emu/machine/mc146818.c
index 2abbda53669..8f5262a769e 100644
--- a/src/emu/machine/mc146818.c
+++ b/src/emu/machine/mc146818.c
@@ -192,7 +192,7 @@ void mc146818_device::device_start()
// device_timer - handler timer events
//-------------------------------------------------
-void mc146818_device::device_timer(emu_timer &timer, int param, void *ptr)
+void mc146818_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
int year/*, month*/;
diff --git a/src/emu/machine/mc146818.h b/src/emu/machine/mc146818.h
index 78a59747bb2..ec512175170 100644
--- a/src/emu/machine/mc146818.h
+++ b/src/emu/machine/mc146818.h
@@ -82,7 +82,7 @@ public:
protected:
// device-level overrides
virtual void device_start();
- virtual void device_timer(emu_timer &timer, int param, void *ptr);
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
// device_mc146818_interface overrides
virtual void nvram_default();
diff --git a/src/emu/timer.c b/src/emu/timer.c
index 55231d3ee24..a44057e7e2c 100644
--- a/src/emu/timer.c
+++ b/src/emu/timer.c
@@ -57,6 +57,7 @@ public:
attotime start; /* time when the timer was started */
attotime expire; /* time when the timer will expire */
device_t * device; /* for device timers, a pointer to the device */
+ device_timer_id id; /* for device timers, the ID of the timer */
};
@@ -372,7 +373,7 @@ void timer_execute_timers(running_machine *machine)
if (was_enabled)
{
if (timer->device != NULL)
- timer->device->timer_fired(*timer, timer->param, timer->ptr);
+ timer->device->timer_fired(*timer, timer->id, timer->param, timer->ptr);
else if (timer->callback != NULL)
{
LOG(("Timer %s:%d[%s] fired (expire=%s)\n", timer->file, timer->line, timer->func, attotime_string(timer->expire, 9)));
@@ -519,6 +520,8 @@ static void timer_register_save(emu_timer *timer)
state_save_register_item(timer->machine, "timer", timer->func, count, timer->start.attoseconds);
state_save_register_item(timer->machine, "timer", timer->func, count, timer->expire.seconds);
state_save_register_item(timer->machine, "timer", timer->func, count, timer->expire.attoseconds);
+ if (timer->device != NULL)
+ state_save_register_item(timer->machine, "timer", timer->func, count, timer->id);
}
@@ -594,7 +597,7 @@ int timer_count_anonymous(running_machine *machine)
isn't primed yet
-------------------------------------------------*/
-INLINE emu_timer *_timer_alloc_common(running_machine *machine, timer_fired_func callback, void *ptr, const char *file, int line, const char *func, int temp)
+INLINE emu_timer *_timer_alloc_common(running_machine *machine, device_t *device, device_timer_id id, timer_fired_func callback, void *ptr, const char *file, int line, const char *func, int temp)
{
attotime time = get_current_time(machine);
emu_timer *timer = timer_new(machine);
@@ -609,7 +612,8 @@ INLINE emu_timer *_timer_alloc_common(running_machine *machine, timer_fired_func
timer->file = file;
timer->line = line;
timer->func = func;
- timer->device = NULL;
+ timer->device = device;
+ timer->id = id;
/* compute the time of the next firing and insert into the list */
timer->start = time;
@@ -630,15 +634,12 @@ INLINE emu_timer *_timer_alloc_common(running_machine *machine, timer_fired_func
emu_timer *_timer_alloc_internal(running_machine *machine, timer_fired_func callback, void *ptr, const char *file, int line, const char *func)
{
- return _timer_alloc_common(machine, callback, ptr, file, line, func, FALSE);
+ return _timer_alloc_common(machine, NULL, 0, callback, ptr, file, line, func, FALSE);
}
-emu_timer *device_timer_alloc(device_t &device, void *ptr, int param)
+emu_timer *device_timer_alloc(device_t &device, UINT32 id, void *ptr)
{
- emu_timer *timer = _timer_alloc_common(device.machine, NULL, ptr, __FILE__, __LINE__, device.tag(), FALSE);
- timer->param = param;
- timer->device = &device;
- return timer;
+ return _timer_alloc_common(device.machine, &device, id, NULL, ptr, __FILE__, __LINE__, device.tag(), FALSE);
}
@@ -728,6 +729,13 @@ void timer_adjust_periodic(emu_timer *which, attotime start_delay, INT32 param,
SIMPLIFIED ANONYMOUS TIMER MANAGEMENT
***************************************************************************/
+void device_timer_call_after_resynch(device_t &device, device_timer_id id, INT32 param, void *ptr)
+{
+ emu_timer *timer = _timer_alloc_common(device.machine, &device, id, NULL, ptr, __FILE__, __LINE__, device.tag(), TRUE);
+ timer_adjust_oneshot(timer, attotime_zero, param);
+}
+
+
/*-------------------------------------------------
timer_pulse - allocate a pulse timer, which
repeatedly calls the callback using the given
@@ -736,7 +744,7 @@ void timer_adjust_periodic(emu_timer *which, attotime start_delay, INT32 param,
void _timer_pulse_internal(running_machine *machine, attotime period, void *ptr, INT32 param, timer_fired_func callback, const char *file, int line, const char *func)
{
- emu_timer *timer = _timer_alloc_common(machine, callback, ptr, file, line, func, FALSE);
+ emu_timer *timer = _timer_alloc_common(machine, NULL, 0, callback, ptr, file, line, func, FALSE);
timer_adjust_periodic(timer, period, param, period);
}
@@ -748,7 +756,7 @@ void _timer_pulse_internal(running_machine *machine, attotime period, void *ptr,
void _timer_set_internal(running_machine *machine, attotime duration, void *ptr, INT32 param, timer_fired_func callback, const char *file, int line, const char *func)
{
- emu_timer *timer = _timer_alloc_common(machine, callback, ptr, file, line, func, TRUE);
+ emu_timer *timer = _timer_alloc_common(machine, NULL, 0, callback, ptr, file, line, func, TRUE);
timer_adjust_oneshot(timer, duration, param);
}
diff --git a/src/emu/timer.h b/src/emu/timer.h
index 13972622485..516ceacc1e9 100644
--- a/src/emu/timer.h
+++ b/src/emu/timer.h
@@ -149,7 +149,7 @@ int timer_count_anonymous(running_machine *machine);
emu_timer *_timer_alloc_internal(running_machine *machine, timer_fired_func callback, void *param, const char *file, int line, const char *func);
/* allocate a permament device timer that isn't primed yet */
-emu_timer *device_timer_alloc(device_t &device, void *ptr = NULL, int param = 0);
+emu_timer *device_timer_alloc(device_t &device, device_timer_id id = 0, void *ptr = NULL);
/* adjust the time when this timer will fire and disable any periodic firings */
void timer_adjust_oneshot(emu_timer *which, attotime duration, INT32 param);
@@ -161,6 +161,9 @@ void timer_adjust_periodic(emu_timer *which, attotime start_delay, INT32 param,
/* ----- anonymous timer management ----- */
+/* request a one-shot temporary timer for a device */
+void device_timer_call_after_resynch(device_t &device, device_timer_id id = 0, INT32 param = 0, void *ptr = NULL);
+
/* allocate a one-shot timer, which calls the callback after the given duration */
void _timer_set_internal(running_machine *machine, attotime duration, void *ptr, INT32 param, timer_fired_func callback, const char *file, int line, const char *func);