pit8253: Updated to use devcb calls, cleanups

This commit is contained in:
Dirk Best 2010-02-25 14:59:25 +00:00
parent e32607b73e
commit 4bfcd73cc3
11 changed files with 157 additions and 116 deletions

View File

@ -56,7 +56,8 @@ struct pit8253_timer
double clockin; /* input clock frequency in Hz */
int clock; /* clock signal when clockin is 0 */
pit8253_output_changed_func output_changed; /* callback function for when output changes */
devcb_resolved_read_line in_gate_func; /* callback for gate input */
devcb_resolved_write_line out_out_func; /* callback function for when output changes */
attotime last_updated; /* time when last updated */
@ -119,6 +120,15 @@ static struct pit8253_timer *get_timer(struct _pit8253_t *pit,int which)
}
static int pit8253_gate(struct pit8253_timer *timer)
{
if (timer->in_gate_func.read != NULL)
return devcb_call_read_line(&timer->in_gate_func);
else
return timer->gate;
}
INLINE UINT32 decimal_from_bcd(UINT16 val)
{
/* In BCD mode, a nybble loaded with value A-F counts down the same as in
@ -219,10 +229,7 @@ static void set_output(running_device *device, struct pit8253_timer *timer,int o
if (output != timer->output)
{
timer->output = output;
if (timer->output_changed != NULL)
{
timer->output_changed(device, output);
}
devcb_call_write_line(&timer->out_out_func, timer->output);
}
}
@ -237,7 +244,7 @@ static void simulate2(running_device *device, struct pit8253_timer *timer, INT64
int cycles_to_output = 0;
LOG2(("pit8253: simulate2(): simulating %d cycles for %d in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x\n",
(int)elapsed_cycles,timer->index,mode,bcd,timer->phase,timer->gate,timer->output,timer->value));
(int)elapsed_cycles,timer->index,mode,bcd,timer->phase,pit8253_gate(timer),timer->output,timer->value));
switch (mode) {
case 0:
@ -276,7 +283,7 @@ static void simulate2(running_device *device, struct pit8253_timer *timer, INT64
load_counter_value( device, timer );
}
if ( timer->gate == 0 )
if ( pit8253_gate(timer) == 0 )
{
cycles_to_output = CYCLES_NEVER;
}
@ -387,7 +394,7 @@ static void simulate2(running_device *device, struct pit8253_timer *timer, INT64
Rising-edge reloads count and initiates counting
Gate high enables counting. */
if (timer->gate == 0 || timer->phase == 0)
if (pit8253_gate(timer) == 0 || timer->phase == 0)
{
/* Gate low or mode control write forces output high */
set_output(device, timer, 1);
@ -466,7 +473,7 @@ static void simulate2(running_device *device, struct pit8253_timer *timer, INT64
Rising-edge reloads count and initiates counting
Gate high enables counting. */
if (timer->gate == 0 || timer->phase == 0)
if (pit8253_gate(timer) == 0 || timer->phase == 0)
{
/* Gate low or mode control write forces output high */
set_output(device, timer, 1);
@ -549,7 +556,7 @@ static void simulate2(running_device *device, struct pit8253_timer *timer, INT64
Mode 4 only: Gate level sensitive only. Low disables counting, high enables it.
Mode 5 only: Gate rising-edge sensitive only. Rising edge initiates counting */
if (timer->gate == 0 && mode == 4)
if (pit8253_gate(timer) == 0 && mode == 4)
{
cycles_to_output = CYCLES_NEVER;
}
@ -611,7 +618,7 @@ static void simulate2(running_device *device, struct pit8253_timer *timer, INT64
}
LOG2(("pit8253: simulate2(): simulating %d cycles for %d in mode %d, bcd = %d, phase = %d, gate = %d, output %d, value = 0x%04x, cycles_to_output = %04x\n",
(int)elapsed_cycles,timer->index,mode,bcd,timer->phase,timer->gate,timer->output,timer->value,cycles_to_output));
(int)elapsed_cycles,timer->index,mode,bcd,timer->phase,pit8253_gate(timer),timer->output,timer->value,cycles_to_output));
}
@ -974,33 +981,40 @@ WRITE8_DEVICE_HANDLER( pit8253_w )
}
}
WRITE8_DEVICE_HANDLER( pit8253_gate_w )
static void pit8253_gate_w(running_device *device, int gate, int state)
{
pit8253_t *pit8253 = get_safe_token(device);
struct pit8253_timer *timer = get_timer(pit8253,offset);
int mode;
int gate = (data!=0 ? 1 : 0);
struct pit8253_timer *timer = get_timer(pit8253, gate);
LOG2(("pit8253_gate_w(): offset=%d gate=%d\n", offset, data));
LOG2(("pit8253_gate_w(): gate=%d state=%d\n", gate, state));
if (timer == NULL)
return;
mode = CTRL_MODE(timer->control);
if (gate != timer->gate)
if (timer->in_gate_func.read != NULL)
{
update(device, timer);
timer->gate = gate;
if (gate != 0 && ( mode == 1 || mode == 2 || mode == 5 ))
logerror("pit8253_gate_w: write has no effect because a read handler is already defined!\n");
}
else
{
if (state != timer->gate)
{
timer->phase = 1;
int mode = CTRL_MODE(timer->control);
update(device, timer);
timer->gate = state;
if (state != 0 && ( mode == 1 || mode == 2 || mode == 5 ))
{
timer->phase = 1;
}
update(device, timer);
}
update(device, timer);
}
}
WRITE_LINE_DEVICE_HANDLER( pit8253_gate0_w ) { pit8253_gate_w(device, 0, state); }
WRITE_LINE_DEVICE_HANDLER( pit8253_gate1_w ) { pit8253_gate_w(device, 1, state); }
WRITE_LINE_DEVICE_HANDLER( pit8253_gate2_w ) { pit8253_gate_w(device, 2, state); }
/* ----------------------------------------------------------------------- */
@ -1032,7 +1046,7 @@ void pit8253_set_clockin(running_device *device, int timerno, double new_clockin
}
void pit8253_set_clock_signal(running_device *device, int timerno, int state)
static void pit8253_set_clock_signal(running_device *device, int timerno, int state)
{
pit8253_t *pit8253 = get_safe_token(device);
struct pit8253_timer *timer = get_timer(pit8253,timerno);
@ -1048,6 +1062,10 @@ void pit8253_set_clock_signal(running_device *device, int timerno, int state)
timer->clock = state;
}
WRITE_LINE_DEVICE_HANDLER( pit8253_clk0_w ) { pit8253_set_clock_signal(device, 0, state); }
WRITE_LINE_DEVICE_HANDLER( pit8253_clk1_w ) { pit8253_set_clock_signal(device, 1, state); }
WRITE_LINE_DEVICE_HANDLER( pit8253_clk2_w ) { pit8253_set_clock_signal(device, 2, state); }
static void common_start( running_device *device, int device_type ) {
pit8253_t *pit8253 = get_safe_token(device);
@ -1059,14 +1077,17 @@ static void common_start( running_device *device, int device_type ) {
/* register for state saving */
for (timerno = 0; timerno < MAX_TIMER; timerno++)
{
struct pit8253_timer *timer = get_timer(pit8253,timerno);
struct pit8253_timer *timer = get_timer(pit8253, timerno);
/* initialize timer */
timer->clockin = pit8253->config->timer[timerno].clockin;
timer->output_changed = pit8253->config->timer[timerno].output_changed;
timer->updatetimer = timer_alloc(device->machine, update_timer_cb, (void *)device);
timer_adjust_oneshot(timer->updatetimer, attotime_never, timerno);
/* resolve callbacks */
devcb_resolve_read_line(&timer->in_gate_func, &pit8253->config->timer[timerno].in_gate_func, device);
devcb_resolve_write_line(&timer->out_out_func, &pit8253->config->timer[timerno].out_out_func, device);
/* set up state save values */
state_save_register_device_item(device, timerno, timer->clockin);
state_save_register_device_item(device, timerno, timer->control);
@ -1116,7 +1137,12 @@ static DEVICE_RESET( pit8253 ) {
timer->rmsb = timer->wmsb = 0;
timer->count = timer->value = timer->latch = 0;
timer->lowcount = 0;
timer->gate = 1;
if (timer->in_gate_func.read != NULL)
timer->gate = devcb_call_read_line(&timer->in_gate_func);
else
timer->gate = 1;
timer->output = 2; /* output is undetermined */
timer->latched_count = 0;
timer->latched_status = 0;

View File

@ -1,30 +1,41 @@
/*****************************************************************************
*
* Programmable Interval Timer 8253/8254
*
*****************************************************************************/
/***************************************************************************
Intel 8253/8254
Programmable Interval Timer
_____ _____
D7 1 |* \_/ | 24 VCC
D6 2 | | 23 _WR
D5 3 | | 22 _RD
D4 4 | | 21 _CS
D3 5 | | 20 A1
D2 6 | | 19 A0
D1 7 | 8259A | 18 CLK2
D0 8 | | 17 OUT2
CLK0 9 | | 16 GATE2
OUT0 10 | | 15 CLK1
GATE0 11 | | 14 GATE1
GND 12 |_____________| 13 OUT1
***************************************************************************/
#ifndef __PIT8253_H__
#define __PIT8253_H__
#include "devcb.h"
#ifndef __PIT8253_H_
#define __PIT8253_H_
#define PIT8253 DEVICE_GET_INFO_NAME(pit8253)
#define PIT8254 DEVICE_GET_INFO_NAME(pit8254)
typedef void (*pit8253_output_changed_func)(running_device *device, int state);
#define PIT8253_OUTPUT_CHANGED(name) void name(running_device *device, int state )
struct pit8253_config
{
struct
{
/* Input clock for this timer */
double clockin;
/* If specified, this gets called whenever the output for this timer changes */
pit8253_output_changed_func output_changed;
double clockin; /* timer clock */
devcb_read_line in_gate_func; /* gate signal */
devcb_write_line out_out_func; /* out signal */
} timer[3];
};
@ -50,8 +61,13 @@ DEVICE_GET_INFO( pit8254 );
READ8_DEVICE_HANDLER( pit8253_r );
WRITE8_DEVICE_HANDLER( pit8253_w );
WRITE8_DEVICE_HANDLER( pit8253_gate_w );
WRITE_LINE_DEVICE_HANDLER( pit8253_clk0_w );
WRITE_LINE_DEVICE_HANDLER( pit8253_clk1_w );
WRITE_LINE_DEVICE_HANDLER( pit8253_clk2_w );
WRITE_LINE_DEVICE_HANDLER( pit8253_gate0_w );
WRITE_LINE_DEVICE_HANDLER( pit8253_gate1_w );
WRITE_LINE_DEVICE_HANDLER( pit8253_gate2_w );
/* In the 8253/8254 the CLKx input lines can be attached to a regular clock
signal. Another option is to use the output from one timer as the input
@ -60,13 +76,11 @@ WRITE8_DEVICE_HANDLER( pit8253_gate_w );
The functions below should supply both functionalities. If the signal is
a regular clock signal, use the pit8253_set_clockin function. If the
CLKx input signal is the output of the different source, set the new_clockin
to 0 with pit8253_set_clockin and call pit8253_set_clock_signal to change
to 0 with pit8253_set_clockin and call pit8253_clkX_w to change
the state of the input CLKx signal.
*/
int pit8253_get_output(running_device *device, int timer);
void pit8253_set_clockin(running_device *device, int timer, double new_clockin);
void pit8253_set_clock_signal(running_device *device, int timer, int state);
#endif /* __PIT8253_H_ */
#endif /* __PIT8253_H__ */

View File

@ -595,23 +595,21 @@ static const struct pic8259_interface calchase_pic8259_2_config =
*
*************************************************************/
static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
{
pic8259_ir0_w(calchase_devices.pic8259_1, state);
}
static const struct pit8253_config calchase_pit8254_config =
{
{
{
4772720/4, /* heartbeat IRQ */
pc_timer0_w
DEVCB_NULL,
DEVCB_DEVICE_LINE("pic8259_1", pic8259_ir0_w)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
NULL
DEVCB_NULL,
DEVCB_NULL
}
}
};

View File

@ -637,23 +637,21 @@ static const struct pic8259_interface gamecstl_pic8259_2_config =
*
*************************************************************/
static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
{
pic8259_ir0_w(gamecstl_devices.pic8259_1, state);
}
static const struct pit8253_config gamecstl_pit8254_config =
{
{
{
4772720/4, /* heartbeat IRQ */
pc_timer0_w
DEVCB_NULL,
DEVCB_DEVICE_LINE("pic8259_1", pic8259_ir0_w)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
NULL
DEVCB_NULL,
DEVCB_NULL
}
}
};

View File

@ -1014,24 +1014,21 @@ static const struct pic8259_interface mediagx_pic8259_2_config =
*
*************************************************************/
static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
{
pic8259_ir0_w(mediagx_devices.pic8259_1, state);
}
static const struct pit8253_config mediagx_pit8254_config =
{
{
{
4772720/4, /* heartbeat IRQ */
pc_timer0_w
DEVCB_NULL,
DEVCB_DEVICE_LINE("pic8259_master", pic8259_ir0_w)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
NULL
DEVCB_NULL,
DEVCB_NULL
}
}
};

View File

@ -257,7 +257,7 @@ static IRQ_CALLBACK(irq_callback)
return r;
}
static PIT8253_OUTPUT_CHANGED( at_pit8254_out0_changed )
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out0_changed )
{
if ( pcat_dyn_devices.pic8259_1 )
{
@ -266,7 +266,7 @@ static PIT8253_OUTPUT_CHANGED( at_pit8254_out0_changed )
}
static PIT8253_OUTPUT_CHANGED( at_pit8254_out2_changed )
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out2_changed )
{
//at_speaker_set_input( state ? 1 : 0 );
}
@ -277,13 +277,16 @@ static const struct pit8253_config at_pit8254_config =
{
{
4772720/4, /* heartbeat IRQ */
at_pit8254_out0_changed
DEVCB_NULL,
DEVCB_LINE(at_pit8254_out0_changed)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
at_pit8254_out2_changed
DEVCB_NULL,
DEVCB_LINE(at_pit8254_out2_changed)
}
}
};

View File

@ -320,7 +320,7 @@ static IRQ_CALLBACK(irq_callback)
return r;
}
static PIT8253_OUTPUT_CHANGED( at_pit8254_out0_changed )
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out0_changed )
{
if ( streetg2_devices.pic8259_1 )
{
@ -329,7 +329,7 @@ static PIT8253_OUTPUT_CHANGED( at_pit8254_out0_changed )
}
static PIT8253_OUTPUT_CHANGED( at_pit8254_out2_changed )
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out2_changed )
{
//at_speaker_set_input( state ? 1 : 0 );
}
@ -340,13 +340,16 @@ static const struct pit8253_config at_pit8254_config =
{
{
4772720/4, /* heartbeat IRQ */
at_pit8254_out0_changed
DEVCB_NULL,
DEVCB_LINE(at_pit8254_out0_changed)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
at_pit8254_out2_changed
DEVCB_NULL,
DEVCB_LINE(at_pit8254_out2_changed)
}
}
};

View File

@ -394,23 +394,21 @@ static WRITE8_HANDLER( disk_iobank_w )
Pit8253
*********************************/
static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
{
pic8259_ir0_w(filetto_devices.pic8259_1, state);
}
static const struct pit8253_config pc_pit8253_config =
{
{
{
4772720/4, /* heartbeat IRQ */
pc_timer0_w
DEVCB_NULL,
DEVCB_DEVICE_LINE("pic8259_1", pic8259_ir0_w)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
NULL
DEVCB_NULL,
DEVCB_NULL
}
}
};

View File

@ -251,7 +251,7 @@ static IRQ_CALLBACK(irq_callback)
return r;
}
static PIT8253_OUTPUT_CHANGED( at_pit8254_out0_changed )
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out0_changed )
{
if ( photoply_devices.pic8259_1 )
{
@ -260,7 +260,7 @@ static PIT8253_OUTPUT_CHANGED( at_pit8254_out0_changed )
}
static PIT8253_OUTPUT_CHANGED( at_pit8254_out2_changed )
static WRITE_LINE_DEVICE_HANDLER( at_pit8254_out2_changed )
{
//at_speaker_set_input( state ? 1 : 0 );
}
@ -271,13 +271,16 @@ static const struct pit8253_config at_pit8254_config =
{
{
4772720/4, /* heartbeat IRQ */
at_pit8254_out0_changed
DEVCB_NULL,
DEVCB_LINE(at_pit8254_out0_changed)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
at_pit8254_out2_changed
DEVCB_NULL,
DEVCB_LINE(at_pit8254_out2_changed)
}
}
};

View File

@ -578,23 +578,21 @@ static const struct pic8259_interface taitowlf_pic8259_2_config =
*
*************************************************************/
static PIT8253_OUTPUT_CHANGED( pc_timer0_w )
{
pic8259_ir0_w(taitowlf_devices.pic8259_1, state);
}
static const struct pit8253_config taitowlf_pit8254_config =
{
{
{
4772720/4, /* heartbeat IRQ */
pc_timer0_w
DEVCB_NULL,
DEVCB_DEVICE_LINE("pic8259_1", pic8259_ir0_w)
}, {
4772720/4, /* dram refresh */
NULL
DEVCB_NULL,
DEVCB_NULL
}, {
4772720/4, /* pio port c pin 4, and speaker polling enough */
NULL
DEVCB_NULL,
DEVCB_NULL
}
}
};

View File

@ -21,8 +21,8 @@ static running_device *ttl74148;
*
*************************************/
static PIT8253_OUTPUT_CHANGED( v_irq4_w );
static PIT8253_OUTPUT_CHANGED( v_irq3_w );
static WRITE_LINE_DEVICE_HANDLER( v_irq4_w );
static WRITE_LINE_DEVICE_HANDLER( v_irq3_w );
@ -49,13 +49,16 @@ const struct pit8253_config vertigo_pit8254_config =
{
{
240000,
v_irq4_w
DEVCB_NULL,
DEVCB_LINE(v_irq4_w)
}, {
240000,
v_irq3_w
DEVCB_NULL,
DEVCB_LINE(v_irq3_w)
}, {
240000,
NULL
DEVCB_NULL,
DEVCB_NULL
}
}
};
@ -89,7 +92,7 @@ static void update_irq_encoder(running_machine *machine, int line, int state)
}
static PIT8253_OUTPUT_CHANGED( v_irq4_w )
static WRITE_LINE_DEVICE_HANDLER( v_irq4_w )
{
update_irq_encoder(device->machine, INPUT_LINE_IRQ4, state);
vertigo_vproc(cputag_attotime_to_clocks(device->machine, "maincpu", attotime_sub(timer_get_time(device->machine), irq4_time)), state);
@ -97,7 +100,7 @@ static PIT8253_OUTPUT_CHANGED( v_irq4_w )
}
static PIT8253_OUTPUT_CHANGED( v_irq3_w )
static WRITE_LINE_DEVICE_HANDLER( v_irq3_w )
{
if (state)
cputag_set_input_line(device->machine, "audiocpu", INPUT_LINE_IRQ0, ASSERT_LINE);