summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/pit8253.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/pit8253.h')
-rw-r--r--src/devices/machine/pit8253.h184
1 files changed, 95 insertions, 89 deletions
diff --git a/src/devices/machine/pit8253.h b/src/devices/machine/pit8253.h
index 69f25ba7484..4dc50854882 100644
--- a/src/devices/machine/pit8253.h
+++ b/src/devices/machine/pit8253.h
@@ -35,46 +35,111 @@
***************************************************************************/
#define MCFG_PIT8253_CLK0(_clk) \
- downcast<pit8253_device &>(*device).set_clk0(_clk);
+ downcast<pit8253_device &>(*device).set_clk<0>(_clk);
#define MCFG_PIT8253_CLK1(_clk) \
- downcast<pit8253_device &>(*device).set_clk1(_clk);
+ downcast<pit8253_device &>(*device).set_clk<1>(_clk);
#define MCFG_PIT8253_CLK2(_clk) \
- downcast<pit8253_device &>(*device).set_clk2(_clk);
+ downcast<pit8253_device &>(*device).set_clk<2>(_clk);
#define MCFG_PIT8253_OUT0_HANDLER(_devcb) \
- devcb = &downcast<pit8253_device &>(*device).set_out0_handler(DEVCB_##_devcb);
+ devcb = &downcast<pit8253_device &>(*device).set_out_handler<0>(DEVCB_##_devcb);
#define MCFG_PIT8253_OUT1_HANDLER(_devcb) \
- devcb = &downcast<pit8253_device &>(*device).set_out1_handler(DEVCB_##_devcb);
+ devcb = &downcast<pit8253_device &>(*device).set_out_handler<1>(DEVCB_##_devcb);
#define MCFG_PIT8253_OUT2_HANDLER(_devcb) \
- devcb = &downcast<pit8253_device &>(*device).set_out2_handler(DEVCB_##_devcb);
+ devcb = &downcast<pit8253_device &>(*device).set_out_handler<2>(DEVCB_##_devcb);
+enum class pit_type
+{
+ I8254,
+ I8253,
+ FE2010
+};
+
+class pit_counter_device : public device_t
+{
+ friend class pit8253_device;
+ friend class pit8254_device;
+
+public:
+ // construction/destruction
+ pit_counter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+ inline uint32_t adjusted_count() const;
+ void decrease_counter_value(int64_t cycles);
+ void load_counter_value();
+ void set_output(int output);
+ void simulate2(int64_t elapsed_cycles);
+ void simulate(int64_t elapsed_cycles);
+ void update();
+ uint16_t masked_value() const;
+ uint8_t read();
+ void load_count(uint16_t newcount);
+ void readback(int command);
+ void control_w(uint8_t data);
+ void count_w(uint8_t data);
+ void gate_w(int state);
+ void set_clock_signal(int state);
+ void set_clockin(double new_clockin);
+
+ // internal state
+ int m_index; // index number of the timer
+ double m_clockin; // input clock frequency in Hz
+ int m_clock_signal; // clock signal when clockin is 0
+
+ attotime m_last_updated; // time when last updated
+
+ emu_timer *m_updatetimer; // MAME timer to process updates
+
+ uint16_t m_value; // current counter value ("CE" in Intel docs)
+ uint16_t m_latch; // latched counter value ("OL" in Intel docs)
+ uint16_t m_count; // new counter value ("CR" in Intel docs)
+ uint8_t m_control; // 6-bit control byte
+ uint8_t m_status; // status byte - 8254 only
+ uint8_t m_lowcount; // LSB of new counter value for 16-bit writes
+ bool m_rmsb; // true = Next read is MSB of 16-bit value
+ bool m_wmsb; // true = Next write is MSB of 16-bit value
+ int m_output; // 0 = low, 1 = high
+
+ int m_gate; // gate input (0 = low, 1 = high)
+ int m_latched_count; // number of bytes of count latched
+ int m_latched_status; // 1 = status latched (8254 only)
+ int m_null_count; // 1 = mode control or count written, 0 = count loaded
+ int m_phase; // see phase definition tables in simulate2(), below
+};
+
+DECLARE_DEVICE_TYPE(PIT_COUNTER, pit_counter_device)
+
class pit8253_device : public device_t
{
+ friend class pit_counter_device;
+
public:
+ // construction/destruction
pit8253_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// configuration helpers
- void set_clk0(double clk0) { m_clk0 = clk0; }
- void set_clk1(double clk1) { m_clk1 = clk1; }
- void set_clk2(double clk2) { m_clk2 = clk2; }
- void set_clk0(const XTAL &xtal) { set_clk0(xtal.dvalue()); }
- void set_clk1(const XTAL &xtal) { set_clk1(xtal.dvalue()); }
- void set_clk2(const XTAL &xtal) { set_clk2(xtal.dvalue()); }
- template <class Object> devcb_base &set_out0_handler(Object &&cb) { return m_out0_handler.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out1_handler(Object &&cb) { return m_out1_handler.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out2_handler(Object &&cb) { return m_out2_handler.set_callback(std::forward<Object>(cb)); }
+ template <unsigned N> void set_clk(double clk) { m_clk[N] = clk; }
+ template <unsigned N> void set_clk(const XTAL &xtal) { set_clk<N>(xtal.dvalue()); }
+ template <unsigned N, class Object> devcb_base &set_out_handler(Object &&cb) { return m_out_handler[N].set_callback(std::forward<Object>(cb)); }
DECLARE_READ8_MEMBER(read);
DECLARE_WRITE8_MEMBER(write);
- WRITE_LINE_MEMBER(write_gate0);
- WRITE_LINE_MEMBER(write_gate1);
- WRITE_LINE_MEMBER(write_gate2);
+ WRITE_LINE_MEMBER(write_gate0) { m_counter[0]->gate_w(state); }
+ WRITE_LINE_MEMBER(write_gate1) { m_counter[1]->gate_w(state); }
+ WRITE_LINE_MEMBER(write_gate2) { m_counter[2]->gate_w(state); }
/* 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
@@ -86,87 +151,28 @@ public:
to 0 with pit8253_set_clockin and call pit8253_clkX_w to change
the state of the input CLKx signal.
*/
- WRITE_LINE_MEMBER(write_clk0);
- WRITE_LINE_MEMBER(write_clk1);
- WRITE_LINE_MEMBER(write_clk2);
+ WRITE_LINE_MEMBER(write_clk0) { m_counter[0]->set_clock_signal(state); }
+ WRITE_LINE_MEMBER(write_clk1) { m_counter[1]->set_clock_signal(state); }
+ WRITE_LINE_MEMBER(write_clk2) { m_counter[2]->set_clock_signal(state); }
- void set_clockin(int timer, double new_clockin);
+ void set_clockin(int timer, double new_clockin) { m_counter[timer]->set_clockin(new_clockin); }
protected:
- pit8253_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int chip_type);
+ pit8253_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, pit_type chip_type);
// device-level overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_resolve_objects() override;
virtual void device_start() override;
- virtual void device_reset() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
- // internal state
- 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 */
-
- attotime last_updated; /* time when last updated */
-
- emu_timer *updatetimer; /* MAME timer to process updates */
-
- uint16_t value; /* current counter value ("CE" in Intel docs) */
- uint16_t latch; /* latched counter value ("OL" in Intel docs) */
- uint16_t count; /* new counter value ("CR" in Intel docs) */
- uint8_t control; /* 6-bit control byte */
- uint8_t status; /* status byte - 8254 only */
- uint8_t lowcount; /* LSB of new counter value for 16-bit writes */
- int rmsb; /* 1 = Next read is MSB of 16-bit value */
- int wmsb; /* 1 = Next write is MSB of 16-bit value */
- int output; /* 0 = low, 1 = high */
-
- int gate; /* gate input (0 = low, 1 = high) */
- int latched_count; /* number of bytes of count latched */
- int latched_status; /* 1 = status latched (8254 only) */
- int null_count; /* 1 = mode control or count written, 0 = count loaded */
- int phase; /* see phase definition tables in simulate2(), below */
- };
-
- void readback(pit8253_timer *timer, int command);
virtual void readback_command(uint8_t data);
- pit8253_timer *get_timer(int which);
- enum
- {
- I8254,
- I8253,
- FE2010
- };
+ double m_clk[3];
+ devcb_write_line m_out_handler[3];
-private:
- double m_clk0;
- double m_clk1;
- double m_clk2;
- devcb_write_line m_out0_handler;
- devcb_write_line m_out1_handler;
- devcb_write_line m_out2_handler;
-
- enum
- {
- PIT8253_MAX_TIMER = 3
- };
-
- pit8253_timer m_timers[PIT8253_MAX_TIMER];
-
- inline uint32_t adjusted_count(int bcd, uint16_t val);
- void decrease_counter_value(pit8253_timer *timer, int64_t cycles);
- void load_counter_value(pit8253_timer *timer);
- void set_output(pit8253_timer *timer, int output);
- void simulate2(pit8253_timer *timer, int64_t elapsed_cycles);
- void simulate(pit8253_timer *timer, int64_t elapsed_cycles);
- void update(pit8253_timer *timer);
- uint16_t masked_value(pit8253_timer *timer);
- void load_count(pit8253_timer *timer, uint16_t newcount);
- void gate_w(int gate, int state);
- void set_clock_signal(int timerno, int state);
-
- int m_type;
+ required_device_array<pit_counter_device, 3> m_counter;
+
+ pit_type m_type;
};
DECLARE_DEVICE_TYPE(PIT8253, pit8253_device)