diff options
Diffstat (limited to 'src/devices/machine/mc68681.h')
-rw-r--r-- | src/devices/machine/mc68681.h | 104 |
1 files changed, 60 insertions, 44 deletions
diff --git a/src/devices/machine/mc68681.h b/src/devices/machine/mc68681.h index ebc29c98fd1..452b67cb64f 100644 --- a/src/devices/machine/mc68681.h +++ b/src/devices/machine/mc68681.h @@ -6,30 +6,24 @@ #pragma once -#define MCFG_MC68681_ADD(_tag, _clock) \ - MCFG_DEVICE_ADD(_tag, MC68681, _clock) - -#define MCFG_MC68681_REPLACE(_tag, _clock) \ - MCFG_DEVICE_REPLACE(_tag, MC68681, _clock) - #define MCFG_MC68681_IRQ_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_irq_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_irq_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_A_TX_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_a_tx_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_a_tx_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_B_TX_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_b_tx_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_b_tx_cb(*device, DEVCB_##_cb); // deprecated: use ipX_w() instead #define MCFG_MC68681_INPORT_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_inport_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_inport_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_OUTPORT_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_outport_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_outport_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_SET_EXTERNAL_CLOCKS(_a, _b, _c, _d) \ - mc68681_base_device::static_set_clocks(*device, _a, _b, _c, _d); + duart_base_device::static_set_clocks(*device, _a, _b, _c, _d); // SC28C94 specific callbacks #define MCFG_SC28C94_ADD(_tag, _clock) \ @@ -48,13 +42,13 @@ #define MC68681_RX_FIFO_SIZE 3 // forward declaration -class mc68681_base_device; +class duart_base_device; -// mc68681_channel class -class mc68681_channel : public device_t, public device_serial_interface +// duart_channel class +class duart_channel : public device_t, public device_serial_interface { public: - mc68681_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + duart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override; @@ -107,7 +101,7 @@ private: uint8_t tx_data; uint8_t tx_ready; - mc68681_base_device *m_uart; + duart_base_device *m_uart; void write_MR(uint8_t data); void write_CR(uint8_t data); @@ -115,15 +109,15 @@ private: void recalc_framing(); }; -class mc68681_base_device : public device_t +class duart_base_device : public device_t { - friend class mc68681_channel; + friend class duart_channel; public: - required_device<mc68681_channel> m_chanA; - required_device<mc68681_channel> m_chanB; - optional_device<mc68681_channel> m_chanC; - optional_device<mc68681_channel> m_chanD; + required_device<duart_channel> m_chanA; + required_device<duart_channel> m_chanB; + optional_device<duart_channel> m_chanC; + optional_device<duart_channel> m_chanD; // inline configuration helpers static void static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6); @@ -131,16 +125,15 @@ public: // API virtual DECLARE_READ8_MEMBER(read); virtual DECLARE_WRITE8_MEMBER(write); - uint8_t get_irq_vector() { m_read_vector = true; return IVR; } DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((uint8_t)state); } DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((uint8_t)state); } - template <class Object> static devcb_base &set_irq_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_irq.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_a_tx_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_a_tx.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_b_tx_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_b_tx.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_inport_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).read_inport.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_outport_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_outport.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_irq_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_irq.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_a_tx_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_a_tx.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_b_tx_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_b_tx.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_inport_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).read_inport.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_outport_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_outport.set_callback(std::forward<Object>(cb)); } // new-style push handlers for input port bits DECLARE_WRITE_LINE_MEMBER( ip0_w ); @@ -149,9 +142,12 @@ public: DECLARE_WRITE_LINE_MEMBER( ip3_w ); DECLARE_WRITE_LINE_MEMBER( ip4_w ); DECLARE_WRITE_LINE_MEMBER( ip5_w ); + DECLARE_WRITE_LINE_MEMBER( ip6_w ); + + bool irq_pending() const { return (ISR & IMR) != 0; } protected: - mc68681_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + duart_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override; @@ -163,6 +159,9 @@ protected: devcb_write8 write_outport; int32_t ip3clk, ip4clk, ip5clk, ip6clk; +protected: + virtual void update_interrupts(); + private: TIMER_CALLBACK_MEMBER( duart_timer_callback ); @@ -170,14 +169,11 @@ private: uint8_t ACR; /* Auxiliary Control Register */ uint8_t IMR; /* Interrupt Mask Register */ uint8_t ISR; /* Interrupt Status Register */ - uint8_t IVR; /* Interrupt Vector Register */ uint8_t OPCR; /* Output Port Conf. Register */ uint8_t OPR; /* Output Port Register */ PAIR CTR; /* Counter/Timer Preset Value */ uint8_t IPCR; /* Input Port Control Register */ - bool m_read_vector; // if this is read and IRQ is active, it counts as pulling IACK - /* state */ uint8_t IP_last_state; /* last state of IP bits */ @@ -185,15 +181,14 @@ private: uint8_t half_period; emu_timer *duart_timer; - double duart68681_get_ct_rate(); - uint16_t duart68681_get_ct_count(); - void duart68681_start_ct(int count); + double get_ct_rate(); + uint16_t get_ct_count(); + void start_ct(int count); int calc_baud(int ch, uint8_t data); void clear_ISR_bits(int mask); void set_ISR_bits(int mask); - void update_interrupts(); - int get_ch(mc68681_channel *ch) + int get_ch(duart_channel *ch) { if (ch == m_chanA) { @@ -211,16 +206,36 @@ private: return 3; } - mc68681_channel *get_channel(int chan); + duart_channel *get_channel(int chan); +}; + +class scn2681_device : public duart_base_device +{ +public: + scn2681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -class mc68681_device : public mc68681_base_device +class mc68681_device : public duart_base_device { public: mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_READ8_MEMBER(read) override; + virtual DECLARE_WRITE8_MEMBER(write) override; + uint8_t get_irq_vector() { m_read_vector = true; return IVR; } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void update_interrupts() override; + +private: + bool m_read_vector; // if this is read and IRQ is active, it counts as pulling IACK + + uint8_t IVR; /* Interrupt Vector Register */ }; -class sc28c94_device : public mc68681_base_device +class sc28c94_device : public duart_base_device { public: sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -240,10 +255,10 @@ protected: private: }; -class mc68340_duart_device : public mc68681_base_device +class mc68340_duart_device : public duart_base_device { public: - mc68340_duart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + mc68340_duart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual DECLARE_READ8_MEMBER(read) override; virtual DECLARE_WRITE8_MEMBER(write) override; @@ -253,9 +268,10 @@ protected: mc68340_duart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); }; +DECLARE_DEVICE_TYPE(SCN2681, scn2681_device) DECLARE_DEVICE_TYPE(MC68681, mc68681_device) DECLARE_DEVICE_TYPE(SC28C94, sc28c94_device) DECLARE_DEVICE_TYPE(MC68340_DUART, mc68340_duart_device) -DECLARE_DEVICE_TYPE(MC68681_CHANNEL, mc68681_channel) +DECLARE_DEVICE_TYPE(DUART_CHANNEL, duart_channel) #endif // MAME_MACHINE_MC68681_H |