From c0ca716e62f0cb6e0d677feb66cd81238d0a0c58 Mon Sep 17 00:00:00 2001 From: Zsolt Vasvari Date: Fri, 14 Mar 2008 00:27:07 +0000 Subject: [PATCH] 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)) --- src/emu/devintrf.h | 1 + src/emu/mconfig.h | 31 ++++++++++++ src/emu/timer.c | 66 +++++++++++++++++++++++++- src/emu/timer.h | 51 ++++++++++++++++++++ src/mame/audio/mw8080bw.c | 2 +- src/mame/drivers/mw8080bw.c | 92 ++++++++++++++---------------------- src/mame/includes/mw8080bw.h | 2 +- 7 files changed, 185 insertions(+), 60 deletions(-) diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h index 32c18b48bfc..df24f2145d9 100644 --- a/src/emu/devintrf.h +++ b/src/emu/devintrf.h @@ -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; diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index 93c56080167..0734b8ea943 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -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), \ diff --git a/src/emu/timer.c b/src/emu/timer.c index 2ae5f91d0f3..aa7aa68410b 100644 --- a/src/emu/timer.c +++ b/src/emu/timer.c @@ -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; + } +} diff --git a/src/emu/timer.h b/src/emu/timer.h index 6bb18d954d7..c2a142c4cd4 100644 --- a/src/emu/timer.h +++ b/src/emu/timer.h @@ -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__ */ diff --git a/src/mame/audio/mw8080bw.c b/src/mame/audio/mw8080bw.c index de73fe38f5f..1a37bc13e77 100644 --- a/src/mame/audio/mw8080bw.c +++ b/src/mame/audio/mw8080bw.c @@ -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); diff --git a/src/mame/drivers/mw8080bw.c b/src/mame/drivers/mw8080bw.c index 1ecae2a982e..bd18dfdbf48 100644 --- a/src/mame/drivers/mw8080bw.c +++ b/src/mame/drivers/mw8080bw.c @@ -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) diff --git a/src/mame/includes/mw8080bw.h b/src/mame/includes/mw8080bw.h index 2575ea36d9f..a770a5ad467 100644 --- a/src/mame/includes/mw8080bw.h +++ b/src/mame/includes/mw8080bw.h @@ -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);