Added skeletion device interface for timers. Just wanted to get feedback.

- Where applicable, added a parallel set of timer functions that take a device_config instead of emu_timer:
	void timer_device_adjust_oneshot(const device_config *timer, attotime duration, INT32 param);
	void timer_device_adjust_periodic(const device_config *timer, attotime duration, INT32 param, attotime period);
	void timer_device_reset(const device_config *timer, attotime duration);
	int timer_device_enable(const device_config *timer, int enable);
	int timer_device_enabled(const device_config *timer);
	int timer_device_get_param(const device_config *timer);
	void *timer_device_get_param_ptr(const device_config *timer);
	attotime timer_device_timeelapsed(const device_config *timer);
	attotime timer_device_timeleft(const device_config *timer);
	attotime timer_device_starttime(const device_config *timer);
	attotime timer_device_firetime(const device_config *timer);

- Added MACHINE_CONFIG macros:
	MDRV_TIMER_ADD(_tag, _type, _callback)	/* type can only be PERIODIC right now (can scanline based later, or even NE555) */
	MDRV_TIMER_REMOVE(_tag)
	MDRV_TIMER_MODIFY(_tag)
	MDRV_TIMER_TYPE(_type)
	MDRV_TIMER_CALLBACK(_callback) 
	MDRV_TIMER_DURATION(_duration)
	MDRV_TIMER_PERIOD(_period)
	MDRV_TIMER_PARAM(_param)
	MDRV_TIMER_PTR(_ptr)

- Modified Space Encounters to create two timers and use those:

	MDRV_TIMER_ADD("STROBE_ON", PERIODIC, spcenctr_strobe_timer_callback)
	MDRV_TIMER_PARAM(TRUE)	/* indicates strobe ON */
	MDRV_TIMER_PERIOD(UINT64_ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ))

	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_PERIOD(UINT64_ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ))
This commit is contained in:
Zsolt Vasvari 2008-03-14 00:27:07 +00:00
parent a6b4a6ad50
commit c0ca716e62
7 changed files with 185 additions and 60 deletions

View File

@ -30,6 +30,7 @@ enum _device_class
DEVICE_CLASS_VIDEO, /* video devices, including screens */
DEVICE_CLASS_CPU_CHIP, /* CPU chips; only CPU cores should return this class */
DEVICE_CLASS_SOUND_CHIP, /* sound chips; only sound cores should return this class */
DEVICE_CLASS_TIMER, /* timer devices */
DEVICE_CLASS_OTHER /* anything else (the list may expand in the future) */
};
typedef enum _device_class device_class;

View File

@ -436,6 +436,37 @@ union _machine_config_token
MDRV_SPEAKER_ADD(_tagr, 0.2, 0.0, 1.0)
/* add/remove timers */
#define MDRV_TIMER_ADD(_tag, _type, _callback) \
MDRV_DEVICE_ADD(_tag, TIMER) \
MDRV_DEVICE_CONFIG_DATA32(timer_config, type, TIMER_TYPE_##_type) \
MDRV_DEVICE_CONFIG_DATAPTR(timer_config, callback, _callback)
#define MDRV_TIMER_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag, TIMER_SCREEN)
#define MDRV_TIMER_MODIFY(_tag) \
MDRV_DEVICE_MODIFY(_tag, TIMER_SCREEN)
#define MDRV_TIMER_TYPE(_type) \
MDRV_DEVICE_CONFIG_DATA32(timer_config, type, TIMER_TYPE_##_type)
#define MDRV_TIMER_CALLBACK(_callback) \
MDRV_DEVICE_CONFIG_DATAPTR(timer_config, callback, _callback)
#define MDRV_TIMER_DURATION(_duration) \
MDRV_DEVICE_CONFIG_DATA64(timer_config, duration, _duration)
#define MDRV_TIMER_PERIOD(_period) \
MDRV_DEVICE_CONFIG_DATA64(timer_config, period, _period)
#define MDRV_TIMER_PARAM(_param) \
MDRV_DEVICE_CONFIG_DATA32(timer_config, param, _param)
#define MDRV_TIMER_PTR(_ptr) \
MDRV_DEVICE_CONFIG_DATAPTR(timer_config, ptr, _ptr)
/* core sound functions */
#define MDRV_SOUND_START(_func) \
TOKEN_UINT32_PACK1(MCONFIG_TOKEN_SOUND_START, 8), \

View File

@ -479,7 +479,7 @@ INLINE emu_timer *_timer_alloc_common(timer_fired_func callback, void *ptr, cons
timer->expire = attotime_never;
timer_list_insert(timer);
/* if we're not temporary, register ourselve with the save state system */
/* if we're not temporary, register ourselves with the save state system */
if (!temp)
{
timer_register_save(timer);
@ -758,3 +758,67 @@ static void timer_logtimers(void)
logerror("TIMER LOG STOP\n");
logerror("==============\n");
}
/***************************************************************************
TIMER DEVICE INTERFACE
***************************************************************************/
/*-------------------------------------------------
timer_start - device start callback
for a timer device
-------------------------------------------------*/
static DEVICE_START( timer )
{
// timer_config *config = device->inline_config;
// 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);
return auto_malloc(1);
}
/*-------------------------------------------------
timer_set_info - device set info callback
-------------------------------------------------*/
static DEVICE_SET_INFO( timer )
{
switch (state)
{
/* no parameters to set */
}
}
/*-------------------------------------------------
timer_get_info - device get info callback
-------------------------------------------------*/
DEVICE_GET_INFO( timer )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = sizeof(timer_config); break;
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_TIMER; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(timer); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(timer); break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: /* Nothing */ break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: info->s = "Generic"; break;
case DEVINFO_STR_FAMILY: info->s = "Timer"; break;
case DEVINFO_STR_VERSION: info->s = "1.0"; break;
case DEVINFO_STR_SOURCE_FILE: info->s = __FILE__; break;
case DEVINFO_STR_CREDITS: info->s = "Copyright Nicola Salmoria and the MAME Team"; break;
}
}

View File

@ -16,9 +16,21 @@
#define __TIMER_H__
#include "mamecore.h"
#include "devintrf.h"
#include "attotime.h"
/***************************************************************************
CONSTANTS
***************************************************************************/
/* timer types */
enum
{
TIMER_TYPE_PERIODIC = 0
};
/***************************************************************************
MACROS
***************************************************************************/
@ -46,6 +58,7 @@
/* macros for a timer callback functions */
#define TIMER_CALLBACK(name) void name(running_machine *machine, void *ptr, int param)
#define TIMER_DEVICE_CALLBACK(name) void name(const device_config *timer, void *ptr, INT32 param)
@ -55,6 +68,25 @@
/* a timer callback looks like this */
typedef void (*timer_fired_func)(running_machine *machine, void *ptr, INT32 param);
typedef void (*timer_device_fired_func)(const device_config *timer, void *ptr, INT32 param);
/*-------------------------------------------------
timer_config - configuration of a single
timer
-------------------------------------------------*/
typedef struct _timer_config timer_config;
struct _timer_config
{
int type; /* type of timer */
timer_device_fired_func callback; /* the timer's callback function */
UINT64 duration; /* duration before the timer fires */
UINT64 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 */
};
/* opaque type for representing a timer */
typedef struct _emu_timer emu_timer;
@ -110,9 +142,11 @@ emu_timer *_timer_alloc_internal(timer_fired_func callback, void *param, const c
/* adjust the time when this timer will fire and disable any periodic firings */
void timer_adjust_oneshot(emu_timer *which, attotime duration, INT32 param);
void timer_device_adjust_oneshot(const device_config *timer, attotime duration, INT32 param);
/* adjust the time when this timer will fire and specify a period for subsequent firings */
void timer_adjust_periodic(emu_timer *which, attotime duration, INT32 param, attotime period);
void timer_device_adjust_periodic(const device_config *timer, attotime duration, INT32 param, attotime period);
@ -130,16 +164,22 @@ void _timer_pulse_internal(attotime period, void *ptr, INT32 param, timer_fired_
/* reset the timing on a timer */
void timer_reset(emu_timer *which, attotime duration);
void timer_device_reset(const device_config *timer, attotime duration);
/* enable/disable a timer */
int timer_enable(emu_timer *which, int enable);
int timer_device_enable(const device_config *timer, int enable);
/* determine if a timer is enabled */
int timer_enabled(emu_timer *which);
int timer_device_enabled(const device_config *timer);
/* returns the callback parameter of a timer */
int timer_get_param(emu_timer *which);
int timer_device_get_param(const device_config *timer);
void *timer_get_param_ptr(emu_timer *which);
void *timer_device_get_param_ptr(const device_config *timer);
@ -147,18 +187,29 @@ void *timer_get_param_ptr(emu_timer *which);
/* return the time since the last trigger */
attotime timer_timeelapsed(emu_timer *which);
attotime timer_device_timeelapsed(const device_config *timer);
/* return the time until the next trigger */
attotime timer_timeleft(emu_timer *which);
attotime timer_device_timeleft(const device_config *timer);
/* return the current time */
attotime timer_get_time(void);
/* return the time when this timer started counting */
attotime timer_starttime(emu_timer *which);
attotime timer_device_starttime(const device_config *timer);
/* return the time when this timer will fire next */
attotime timer_firetime(emu_timer *which);
attotime timer_device_firetime(const device_config *timer);
/* ----- timer device interface ----- */
/* device get info callback */
#define TIMER DEVICE_GET_INFO_NAME(timer)
DEVICE_GET_INFO( timer );
#endif /* __TIMER_H__ */

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((data >> 2) & 0x01);
spcenctr_set_strobe_state(machine, (data >> 2) & 0x01);
output_set_value("LAMP", (data >> 3) & 0x01);

View File

@ -2008,39 +2008,16 @@ MACHINE_DRIVER_END
*************************************/
#define SPCENCTR_STROBE_FREQ (9.00) /* Hz - calculated from the 555 timer */
#define SPCENCTR_STROBE_PERIOD ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ)
#define SPCENCTR_DUTY_CYCLE (95) /* % */
#define SPCENCTR_DUTY_CYCLE (95) /* % */
static emu_timer *spcenctr_strobe_on_timer;
static emu_timer *spcenctr_strobe_off_timer;
static UINT8 spcenctr_strobe_state;
static UINT8 spcenctr_trench_width;
static UINT8 spcenctr_trench_center;
static UINT8 spcenctr_trench_slope[16]; /* 16x4 bit RAM */
static void adjust_strobe_timers(void)
{
/* the strobe light is controlled by a 555 timer, which appears to have a
frequency of 9Hz and a duty cycle of 95% */
if (spcenctr_strobe_state)
{
/* multiply by the precentage and divide by 100 to get the ON period */
attotime on_period = attotime_div(attotime_mul(SPCENCTR_STROBE_PERIOD, SPCENCTR_DUTY_CYCLE), 100);
timer_adjust_periodic(spcenctr_strobe_on_timer, attotime_zero, 1, SPCENCTR_STROBE_PERIOD);
timer_adjust_periodic(spcenctr_strobe_off_timer, on_period, 0, SPCENCTR_STROBE_PERIOD);
}
else
{
timer_adjust_oneshot(spcenctr_strobe_on_timer, attotime_never, 0);
timer_adjust_oneshot(spcenctr_strobe_off_timer, attotime_zero, 0);
}
}
static TIMER_CALLBACK( spcenctr_strobe_timer_callback )
static TIMER_DEVICE_CALLBACK( spcenctr_strobe_timer_callback )
{
output_set_value("STROBE", param);
}
@ -2048,28 +2025,28 @@ static TIMER_CALLBACK( spcenctr_strobe_timer_callback )
static MACHINE_START( spcenctr )
{
/* create timers */
spcenctr_strobe_on_timer = timer_alloc(spcenctr_strobe_timer_callback, NULL);
spcenctr_strobe_off_timer = timer_alloc(spcenctr_strobe_timer_callback, NULL);
/* setup for save states */
state_save_register_global(spcenctr_strobe_state);
state_save_register_global(spcenctr_trench_width);
state_save_register_global(spcenctr_trench_center);
state_save_register_global_array(spcenctr_trench_slope);
state_save_register_func_postload(adjust_strobe_timers);
MACHINE_START_CALL(mw8080bw);
}
void spcenctr_set_strobe_state(UINT8 data)
void spcenctr_set_strobe_state(running_machine *machine, UINT8 data)
{
if (data != spcenctr_strobe_state)
{
spcenctr_strobe_state = data;
#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");
adjust_strobe_timers();
timer_device_enable(on_timer, data);
timer_device_enable(off_timer, data);
#endif
spcenctr_strobe_state = data;
}
}
@ -2093,41 +2070,32 @@ UINT8 spcenctr_get_trench_slope(UINT8 addr)
static WRITE8_HANDLER( spcenctr_io_w )
{ /* A7 A6 A5 A4 A3 A2 A1 A0 */
{ /* A7 A6 A5 A4 A3 A2 A1 A0 */
if ((offset & 0x07) == 0x02)
{
watchdog_reset_w(machine, 0, data); /* - - - - - 0 1 0 */
}
watchdog_reset_w(machine, 0, data); /* - - - - - 0 1 0 */
else if ((offset & 0x5f) == 0x01)
{
spcenctr_audio_1_w(machine, 0, data); /* - 0 - 0 0 0 0 1 */
}
spcenctr_audio_1_w(machine, 0, data); /* - 0 - 0 0 0 0 1 */
else if ((offset & 0x5f) == 0x09)
{
spcenctr_audio_2_w(machine, 0, data); /* - 0 - 0 1 0 0 1 */
}
spcenctr_audio_2_w(machine, 0, data); /* - 0 - 0 1 0 0 1 */
else if ((offset & 0x5f) == 0x11)
{
spcenctr_audio_3_w(machine, 0, data); /* - 0 - 1 0 0 0 1 */
}
spcenctr_audio_3_w(machine, 0, data); /* - 0 - 1 0 0 0 1 */
else if ((offset & 0x07) == 0x03)
{ /* - - - - - 0 1 1 */
{ /* - - - - - 0 1 1 */
UINT8 addr = ((offset & 0xc0) >> 4) | ((offset & 0x18) >> 3);
spcenctr_trench_slope[addr] = data;
}
else if ((offset & 0x07) == 0x04)
{
spcenctr_trench_center = data; /* - - - - - 1 0 0 */
}
spcenctr_trench_center = data; /* - - - - - 1 0 0 */
else if ((offset & 0x07) == 0x07)
{
spcenctr_trench_width = data; /* - - - - - 1 1 1 */
}
spcenctr_trench_width = data; /* - - - - - 1 1 1 */
else
{
logerror("%04x: Unmapped I/O port write to %02x = %02x\n",
activecpu_get_pc(), offset, data);
}
logerror("%04x: Unmapped I/O port write to %02x = %02x\n", activecpu_get_pc(), offset, data);
}
@ -2202,6 +2170,16 @@ static MACHINE_DRIVER_START( spcenctr )
MDRV_MACHINE_START(spcenctr)
MDRV_WATCHDOG_TIME_INIT(UINT64_ATTOTIME_IN_USEC(255000000 / (MW8080BW_PIXEL_CLOCK / MW8080BW_HTOTAL / MW8080BW_VTOTAL)))
/* timers */
MDRV_TIMER_ADD("STROBE_ON", PERIODIC, spcenctr_strobe_timer_callback)
MDRV_TIMER_PARAM(TRUE) /* indicates strobe ON */
MDRV_TIMER_PERIOD(UINT64_ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ))
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_PERIOD(UINT64_ATTOTIME_IN_HZ(SPCENCTR_STROBE_FREQ))
/* video hardware */
MDRV_VIDEO_UPDATE(spcenctr)

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(UINT8 data);
void spcenctr_set_strobe_state(running_machine *machine, UINT8 data);
UINT8 spcenctr_get_trench_width(void);
UINT8 spcenctr_get_trench_center(void);
UINT8 spcenctr_get_trench_slope(UINT8 addr);