summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/pit8253.h
diff options
context:
space:
mode:
author Fabio Priuli <etabeta78@users.noreply.github.com>2013-06-03 11:39:54 +0000
committer Fabio Priuli <etabeta78@users.noreply.github.com>2013-06-03 11:39:54 +0000
commite098aab416851304b8fd12b126c6ec98aeca6742 (patch)
treeb760ba56173e31cec5ebad7a1f80814b759530e0 /src/emu/machine/pit8253.h
parentc601f928555dd0a4c2772803be7b224cda0c6e62 (diff)
Modernized the PIT8253 device. [Fabio Priuli]
Diffstat (limited to 'src/emu/machine/pit8253.h')
-rw-r--r--src/emu/machine/pit8253.h140
1 files changed, 103 insertions, 37 deletions
diff --git a/src/emu/machine/pit8253.h b/src/emu/machine/pit8253.h
index 45517d6c0a9..68aa25ad113 100644
--- a/src/emu/machine/pit8253.h
+++ b/src/emu/machine/pit8253.h
@@ -23,53 +23,144 @@
#ifndef __PIT8253_H__
#define __PIT8253_H__
-#include "devlegcy.h"
#include "devcb.h"
+#define PIT8253_MAX_TIMER 3
-struct pit8253_config
+
+/* device types */
+enum
+{
+ TYPE_PIT8253 = 0,
+ TYPE_PIT8254
+};
+
+struct pit8253_interface
{
struct
{
double clockin; /* timer clock */
devcb_read_line in_gate_func; /* gate signal */
devcb_write_line out_out_func; /* out signal */
- } timer[3];
+ } m_intf_timer[3];
+};
+
+
+
+struct pit8253_timer
+{
+ int index; /* index number of the timer */
+ double clockin; /* input clock frequency in Hz */
+ int clock; /* clock signal when clockin is 0 */
+
+ 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 */
+
+ emu_timer *updatetimer; /* MAME timer to process updates */
+
+ UINT16 value; /* current counter value ("CE" in Intel docs) */
+ UINT16 latch; /* latched counter value ("OL" in Intel docs) */
+ UINT16 count; /* new counter value ("CR" in Intel docs) */
+ UINT8 control; /* 6-bit control byte */
+ UINT8 status; /* status byte - 8254 only */
+ UINT8 lowcount; /* LSB of new counter value for 16-bit writes */
+ INT32 rmsb; /* 1 = Next read is MSB of 16-bit value */
+ INT32 wmsb; /* 1 = Next write is MSB of 16-bit value */
+ INT32 output; /* 0 = low, 1 = high */
+
+ INT32 gate; /* gate input (0 = low, 1 = high) */
+ INT32 latched_count; /* number of bytes of count latched */
+ INT32 latched_status; /* 1 = status latched (8254 only) */
+ INT32 null_count; /* 1 = mode control or count written, 0 = count loaded */
+ INT32 phase; /* see phase definition tables in simulate2(), below */
+
+ UINT32 cycles_to_output; /* cycles until output callback called */
};
-class pit8253_device : public device_t
+class pit8253_device : public device_t,
+ public pit8253_interface
{
public:
pit8253_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
pit8253_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
- ~pit8253_device() { global_free(m_token); }
-
- // access to legacy token
- void *token() const { assert(m_token != NULL); return m_token; }
+ ~pit8253_device() {}
+
+
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+
+ WRITE_LINE_MEMBER(clk0_w);
+ WRITE_LINE_MEMBER(clk1_w);
+ WRITE_LINE_MEMBER(clk2_w);
+
+ WRITE_LINE_MEMBER(gate0_w);
+ WRITE_LINE_MEMBER(gate1_w);
+ WRITE_LINE_MEMBER(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
+ clock to another timer.
+
+ 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_clkX_w to change
+ the state of the input CLKx signal.
+ */
+ int get_output(int timer);
+ void set_clockin(int timer, double new_clockin);
+
+
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
-private:
+
+
// internal state
- void *m_token;
+ void common_start(int device_type);
+ pit8253_timer *get_timer(int which);
+ int pit8253_gate(pit8253_timer *timer);
+ void decrease_counter_value(pit8253_timer *timer, UINT64 cycles);
+ void load_counter_value(pit8253_timer *timer);
+ void set_output(pit8253_timer *timer, int output);
+ void simulate2(pit8253_timer *timer, INT64 elapsed_cycles);
+ void simulate(pit8253_timer *timer, INT64 elapsed_cycles);
+ void update(pit8253_timer *timer);
+ UINT16 masked_value(pit8253_timer *timer);
+ void load_count(pit8253_timer *timer, UINT16 newcount);
+ void readback(pit8253_timer *timer, int command);
+ void gate_w(int gate, int state);
+ void set_clock_signal(int timerno, int state);
+
+ TIMER_CALLBACK_MEMBER(update_timer_cb);
+
+ int m_device_type;
+
+ pit8253_timer m_timers[PIT8253_MAX_TIMER];
};
-extern const device_type PIT8253;
+
class pit8254_device : public pit8253_device
{
public:
pit8254_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
protected:
// device-level overrides
virtual void device_start();
};
-extern const device_type PIT8254;
+extern const device_type PIT8253;
+extern const device_type PIT8254;
+
/***************************************************************************
DEVICE CONFIGURATION MACROS
@@ -85,29 +176,4 @@ extern const device_type PIT8254;
MCFG_DEVICE_CONFIG(_intrf)
-DECLARE_READ8_DEVICE_HANDLER( pit8253_r );
-DECLARE_WRITE8_DEVICE_HANDLER( pit8253_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
- clock to another timer.
-
- 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_clkX_w to change
- the state of the input CLKx signal.
- */
-int pit8253_get_output(device_t *device, int timer);
-void pit8253_set_clockin(device_t *device, int timer, double new_clockin);
-
-
#endif /* __PIT8253_H__ */