#ifndef _N68681_H #define _N68681_H #define MCFG_DUARTN68681_ADD(_tag, _clock, _config) \ MCFG_DEVICE_ADD(_tag, DUARTN68681, _clock) \ MCFG_DEVICE_CONFIG(_config) #define MCFG_DUARTN68681_REPLACE(_tag, _clock, _config) \ MCFG_DEVICE_REPLACE(_tag, DUARTN68681, _clock) \ MCFG_DEVICE_CONFIG(_config) #define MCFG_DUART68681_CHANNEL_ADD(_tag) \ MCFG_DEVICE_ADD(_tag, DUART68681CHANNEL, 0) // forward declaration class duartn68681_device; struct duartn68681_config { devcb_write_line m_out_irq_cb; devcb_write_line m_out_a_tx_cb; devcb_write_line m_out_b_tx_cb; devcb_read8 m_in_port_cb; devcb_write8 m_out_port_cb; /* clocks for external baud rates */ INT32 ip3clk, ip4clk, ip5clk, ip6clk; }; #define MC68681_RX_FIFO_SIZE 3 // forward declaration class duartn68681_device; // n68681 channel class class duart68681_channel : public device_t, public device_serial_interface { public: duart68681_channel(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); // device-level overrides virtual void device_start(); virtual void device_reset(); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); // device_serial overrides virtual void rcv_complete(); // Rx completed receiving byte virtual void tra_complete(); // Tx completed sending byte virtual void tra_callback(); // Tx send bit void input_callback(UINT8 state); UINT8 read_chan_reg(int reg); void write_chan_reg(int reg, UINT8 data); void update_interrupts(); UINT8 read_rx_fifo(); void ACR_updated(); private: /* Registers */ UINT8 CR; /* Command register */ UINT8 CSR; /* Clock select register */ UINT8 MR1; /* Mode register 1 */ UINT8 MR2; /* Mode register 2 */ UINT8 MR_ptr; /* Mode register pointer */ UINT8 SR; /* Status register */ /* State */ int tx_baud_rate, rx_baud_rate; /* Receiver */ UINT8 rx_enabled; UINT8 rx_fifo[MC68681_RX_FIFO_SIZE]; int rx_fifo_read_ptr; int rx_fifo_write_ptr; int rx_fifo_num; int m_ch; /* Transmitter */ UINT8 tx_enabled; UINT8 tx_data; UINT8 tx_ready; duartn68681_device *m_uart; void write_MR(UINT8 data); void write_CR(UINT8 data); void write_TX(UINT8 data); void recalc_framing(); }; class duartn68681_device : public device_t, public duartn68681_config { friend class duart68681_channel; public: duartn68681_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); required_device m_chanA; required_device m_chanB; // API DECLARE_READ8_HANDLER(read); DECLARE_WRITE8_HANDLER(write); UINT8 get_irq_vector() { return IVR; } DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((UINT8)state); } DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((UINT8)state); } protected: // device-level overrides virtual void device_config_complete(); virtual void device_start(); virtual void device_reset(); virtual machine_config_constructor device_mconfig_additions() const; private: TIMER_CALLBACK_MEMBER( duart_timer_callback ); /* registers */ UINT8 ACR; /* Auxiliary Control Register */ UINT8 IMR; /* Interrupt Mask Register */ UINT8 ISR; /* Interrupt Status Register */ UINT8 IVR; /* Interrupt Vector Register */ UINT8 OPCR; /* Output Port Conf. Register */ UINT8 OPR; /* Output Port Register */ PAIR CTR; /* Counter/Timer Preset Value */ /* state */ UINT8 IP_last_state; /* last state of IP bits */ /* timer */ UINT8 half_period; emu_timer *duart_timer; double duart68681_get_ct_rate(); UINT16 duart68681_get_ct_count(); void duart68681_start_ct(int count); int calc_baud(int ch, UINT8 data); int get_ch(duart68681_channel *ch) { return (ch == m_chanA) ? 0 : 1; } void clear_ISR_bits(int mask); void set_ISR_bits(int mask); void update_interrupts(); duart68681_channel *get_channel(int chan); devcb_resolved_write_line m_out_irq_func; devcb_resolved_write_line m_out_a_tx_func; devcb_resolved_write_line m_out_b_tx_func; devcb_resolved_read8 m_in_port_func; devcb_resolved_write8 m_out_port_func; }; extern const device_type DUARTN68681; extern const device_type DUART68681CHANNEL; #endif //_N68681_H