Implements the periodic timer device functionality

This commit is contained in:
Zsolt Vasvari 2008-03-14 09:52:28 +00:00
parent a7cf2c0493
commit e42b02f565
4 changed files with 198 additions and 23 deletions

View File

@ -57,6 +57,21 @@ struct _emu_timer
};
/*-------------------------------------------------
timer_state - configuration of a single
timer device
-------------------------------------------------*/
typedef struct _timer_state timer_state;
struct _timer_state
{
emu_timer *timer; /* the backing timer */
attotime duration; /* duration before the timer fires */
attotime period; /* period of repeated timer firings */
INT32 param; /* the integer parameter passed to the timer callback */
void *ptr; /* the pointer parameter passed to the timer callback */
};
/***************************************************************************
GLOBAL VARIABLES
@ -194,6 +209,21 @@ INLINE void timer_list_insert(emu_timer *timer)
}
/*-------------------------------------------------
get_safe_token - makes sure that the passed
in device is, in fact, a timer
-------------------------------------------------*/
INLINE timer_state *get_safe_token(const device_config *device)
{
assert(device != NULL);
assert(device->token != NULL);
assert(device->type == TIMER);
return (timer_state *)device->token;
}
/*-------------------------------------------------
timer_list_remove - remove a timer from the
linked list
@ -536,6 +566,12 @@ void timer_adjust_oneshot(emu_timer *which, attotime duration, INT32 param)
}
void timer_device_adjust_oneshot(const device_config *timer, attotime duration, INT32 param)
{
timer_device_adjust_periodic(timer, duration, param, attotime_never);
}
/*-------------------------------------------------
timer_adjust_periodic - adjust the time when
this timer will fire and specify a period for
@ -574,6 +610,19 @@ void timer_adjust_periodic(emu_timer *which, attotime duration, INT32 param, att
}
void timer_device_adjust_periodic(const device_config *timer, attotime duration, INT32 param, attotime period)
{
timer_state *state = get_safe_token(timer);
state->duration = duration;
state->period = period;
state->param = param;
/* adjust the timer */
timer_adjust_periodic(state->timer, state->duration, 0, state->period);
}
/***************************************************************************
SIMPLIFIED ANONYMOUS TIMER MANAGEMENT
@ -619,6 +668,13 @@ void timer_reset(emu_timer *which, attotime duration)
}
void timer_device_reset(const device_config *timer, attotime duration)
{
timer_state *state = get_safe_token(timer);
timer_adjust_periodic(state->timer, state->duration, 0, state->period);
}
/*-------------------------------------------------
timer_enable - enable/disable a timer
-------------------------------------------------*/
@ -639,6 +695,13 @@ int timer_enable(emu_timer *which, int enable)
}
int timer_device_enable(const device_config *timer, int enable)
{
timer_state *state = get_safe_token(timer);
return timer_enable(state->timer, enable);
}
/*-------------------------------------------------
timer_enabled - determine if a timer is
enabled
@ -650,6 +713,13 @@ int timer_enabled(emu_timer *which)
}
int timer_device_enabled(const device_config *timer)
{
timer_state *state = get_safe_token(timer);
return timer_enabled(state->timer);
}
/*-------------------------------------------------
timer_get_param
timer_get_param_ptr - returns the callback
@ -662,12 +732,25 @@ int timer_get_param(emu_timer *which)
}
int timer_device_get_param(const device_config *timer)
{
timer_state *state = get_safe_token(timer);
return state->param;
}
void *timer_get_param_ptr(emu_timer *which)
{
return which->ptr;
}
void *timer_device_get_param_ptr(const device_config *timer)
{
timer_state *state = get_safe_token(timer);
return state->ptr;
}
/***************************************************************************
TIMING FUNCTIONS
@ -684,6 +767,13 @@ attotime timer_timeelapsed(emu_timer *which)
}
attotime timer_device_timeelapsed(const device_config *timer)
{
timer_state *state = get_safe_token(timer);
return timer_timeelapsed(state->timer);
}
/*-------------------------------------------------
timer_timeleft - return the time until the
next trigger
@ -695,6 +785,13 @@ attotime timer_timeleft(emu_timer *which)
}
attotime timer_device_timeleft(const device_config *timer)
{
timer_state *state = get_safe_token(timer);
return timer_timeleft(state->timer);
}
/*-------------------------------------------------
timer_get_time - return the current time
-------------------------------------------------*/
@ -716,6 +813,13 @@ attotime timer_starttime(emu_timer *which)
}
attotime timer_device_starttime(const device_config *timer)
{
timer_state *state = get_safe_token(timer);
return timer_starttime(state->timer);
}
/*-------------------------------------------------
timer_firetime - return the time when this
timer will fire next
@ -727,6 +831,29 @@ attotime timer_firetime(emu_timer *which)
}
attotime timer_device_firetime(const device_config *timer)
{
timer_state *state = get_safe_token(timer);
return timer_firetime(state->timer);
}
/*-------------------------------------------------
timer_device_timer_callback - calls
the timer device specific callback
-------------------------------------------------*/
static TIMER_CALLBACK( timer_device_timer_callback )
{
const device_config *timer_device = ptr;
timer_state *state = get_safe_token(timer_device);
timer_config *config = timer_device->inline_config;
/* call the real callback */
config->callback(timer_device, state->ptr, state->param);
}
/***************************************************************************
DEBUGGING
@ -772,14 +899,72 @@ static void timer_logtimers(void)
static DEVICE_START( timer )
{
// timer_config *config = device->inline_config;
char unique_tag[40];
timer_state *state;
timer_config *config;
void *param;
// fprintf(stderr, "tag = %s\n", device->tag);
// fprintf(stderr, " duration = %s\n", attotime_string(UINT64_ATTOTIME_TO_ATTOTIME(config->duration), 3));
// fprintf(stderr, " period = %s\n", attotime_string(UINT64_ATTOTIME_TO_ATTOTIME(config->period), 3));
// fprintf(stderr, " param = %d\n", config->param);
/* validate some basic stuff */
assert(device != NULL);
assert(device->static_config == NULL);
assert(device->inline_config != NULL);
assert(device->machine != NULL);
assert(device->machine->config != NULL);
return auto_malloc(1);
/* get and validate the configuration */
config = device->inline_config;
assert(config->type == TIMER_TYPE_PERIODIC);
assert(config->callback != NULL);
/* everything checks out so far, allocate the state object */
state = auto_malloc(sizeof(*state));
memset(state, 0, sizeof(*state));
/* allocate the backing timer */
param = (void *)device;
state->timer = timer_alloc(timer_device_timer_callback, param);
/* copy the parameters */
state->param = config->param;
state->ptr = config->ptr;
/* switch on the type */
switch (config->type)
{
case TIMER_TYPE_PERIODIC:
/* validate that we have at least a duration or period */
assert((config->duration > 0) || (config->period > 0));
/* convert the duration and period into attotime */
if (config->duration > 0)
state->duration = UINT64_ATTOTIME_TO_ATTOTIME(config->duration);
else
state->duration = attotime_zero;
if (config->period > 0)
state->period = UINT64_ATTOTIME_TO_ATTOTIME(config->period);
else
state->period = attotime_never;
/* finally, start the timer */
timer_adjust_periodic(state->timer, state->duration, 0, state->period);
break;
default:
fatalerror("Unknown timer device type");
break;
}
/* register for save states */
assert(strlen(device->tag) < 30);
state_save_combine_module_and_tag(unique_tag, "timer_device", device->tag);
state_save_register_item(unique_tag, 0, state->duration.seconds);
state_save_register_item(unique_tag, 0, state->duration.attoseconds);
state_save_register_item(unique_tag, 0, state->period.seconds);
state_save_register_item(unique_tag, 0, state->period.attoseconds);
state_save_register_item(unique_tag, 0, state->param);
return state;
}

View File

@ -2731,7 +2731,7 @@ WRITE8_HANDLER( spcenctr_audio_3_w )
discrete_sound_w(machine, SPCENCTR_ENEMY_SHIP_SHOT_EN, (data >> 1) & 0x01);
spcenctr_set_strobe_state(machine, (data >> 2) & 0x01);
spcenctr_set_strobe_state((data >> 2) & 0x01);
output_set_value("LAMP", (data >> 3) & 0x01);

View File

@ -2008,7 +2008,7 @@ MACHINE_DRIVER_END
*************************************/
#define SPCENCTR_STROBE_FREQ (9.00) /* Hz - calculated from the 555 timer */
#define SPCENCTR_DUTY_CYCLE (95) /* % */
#define SPCENCTR_STROBE_DUTY_CYCLE (95) /* % */
static UINT8 spcenctr_strobe_state;
@ -2019,7 +2019,7 @@ static UINT8 spcenctr_trench_slope[16]; /* 16x4 bit RAM */
static TIMER_DEVICE_CALLBACK( spcenctr_strobe_timer_callback )
{
output_set_value("STROBE", param);
output_set_value("STROBE", param && spcenctr_strobe_state);
}
@ -2035,19 +2035,9 @@ static MACHINE_START( spcenctr )
}
void spcenctr_set_strobe_state(running_machine *machine, UINT8 data)
void spcenctr_set_strobe_state(UINT8 data)
{
if (data != spcenctr_strobe_state)
{
#if 0
const device_config *on_timer = device_list_find_by_tag(machine->config->devicelist, TIMER, "STROBE_ON");
const device_config *off_timer = device_list_find_by_tag(machine->config->devicelist, TIMER, "STROBE_OFF");
timer_device_enable(on_timer, data);
timer_device_enable(off_timer, data);
#endif
spcenctr_strobe_state = data;
}
spcenctr_strobe_state = data;
}
@ -2177,7 +2167,7 @@ static MACHINE_DRIVER_START( spcenctr )
MDRV_TIMER_ADD("STROBE_OFF", PERIODIC, spcenctr_strobe_timer_callback)
MDRV_TIMER_PARAM(FALSE) /* indicates strobe OFF */
MDRV_TIMER_DURATION(UINT64_ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ * 100 / SPCENCTR_DUTY_CYCLE))
MDRV_TIMER_DURATION(UINT64_ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ * 100 / SPCENCTR_STROBE_DUTY_CYCLE))
MDRV_TIMER_PERIOD(UINT64_ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ))
/* video hardware */

View File

@ -48,7 +48,7 @@ void desertgun_set_controller_select(UINT8 data);
void clowns_set_controller_select(UINT8 data);
void spcenctr_set_strobe_state(running_machine *machine, UINT8 data);
void spcenctr_set_strobe_state(UINT8 data);
UINT8 spcenctr_get_trench_width(void);
UINT8 spcenctr_get_trench_center(void);
UINT8 spcenctr_get_trench_slope(UINT8 addr);