diff options
Diffstat (limited to 'trunk/src/emu/machine/z80dart.h')
-rw-r--r-- | trunk/src/emu/machine/z80dart.h | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/z80dart.h b/trunk/src/emu/machine/z80dart.h new file mode 100644 index 00000000000..805c9427f0d --- /dev/null +++ b/trunk/src/emu/machine/z80dart.h @@ -0,0 +1,378 @@ +/*************************************************************************** + + Z80 DART Dual Asynchronous Receiver/Transmitter implementation + + Copyright (c) 2008, The MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**************************************************************************** + _____ _____ + D1 1 |* \_/ | 40 D0 + D3 2 | | 39 D2 + D5 3 | | 38 D4 + D7 4 | | 37 D6 + _INT 5 | | 36 _IORQ + IEI 6 | | 35 _CE + IEO 7 | | 34 B/_A + _M1 8 | | 33 C/_D + Vdd 9 | | 32 _RD + _W/RDYA 10 | Z80-DART | 31 GND + _RIA 11 | | 30 _W/RDYB + RxDA 12 | | 29 _RIB + _RxCA 13 | | 28 RxDB + _TxCA 14 | | 27 _RxTxCB + TxDA 15 | | 26 TxDB + _DTRA 16 | | 25 _DTRB + _RTSA 17 | | 24 _RTSB + _CTSA 18 | | 23 _CTSB + _DCDA 19 | | 22 _DCDB + CLK 20 |_____________| 21 _RESET + + _____ _____ + D1 1 |* \_/ | 40 D0 + D3 2 | | 39 D2 + D5 3 | | 38 D4 + D7 4 | | 37 D6 + _INT 5 | | 36 _IORQ + IEI 6 | | 35 _CE + IEO 7 | | 34 B/_A + _M1 8 | | 33 C/_D + Vdd 9 | | 32 _RD + _W/RDYA 10 | Z80-SIO/0 | 31 GND + _SYNCA 11 | | 30 _W/RDYB + RxDA 12 | | 29 _SYNCB + _RxCA 13 | | 28 RxDB + _TxCA 14 | | 27 _RxTxCB + TxDA 15 | | 26 TxDB + _DTRA 16 | | 25 _DTRB + _RTSA 17 | | 24 _RTSB + _CTSA 18 | | 23 _CTSB + _DCDA 19 | | 22 _DCDB + CLK 20 |_____________| 21 _RESET + + _____ _____ + D1 1 |* \_/ | 40 D0 + D3 2 | | 39 D2 + D5 3 | | 38 D4 + D7 4 | | 37 D6 + _INT 5 | | 36 _IORQ + IEI 6 | | 35 _CE + IEO 7 | | 34 B/_A + _M1 8 | | 33 C/_D + Vdd 9 | | 32 _RD + _W/RDYA 10 | Z80-SIO/1 | 31 GND + _SYNCA 11 | | 30 _W/RDYB + RxDA 12 | | 29 _SYNCB + _RxCA 13 | | 28 RxDB + _TxCA 14 | | 27 _RxCB + TxDA 15 | | 26 _TxCB + _DTRA 16 | | 25 TxDB + _RTSA 17 | | 24 _RTSB + _CTSA 18 | | 23 _CTSB + _DCDA 19 | | 22 _DCDB + CLK 20 |_____________| 21 _RESET + + _____ _____ + D1 1 |* \_/ | 40 D0 + D3 2 | | 39 D2 + D5 3 | | 38 D4 + D7 4 | | 37 D6 + _INT 5 | | 36 _IORQ + IEI 6 | | 35 _CE + IEO 7 | | 34 B/_A + _M1 8 | | 33 C/_D + Vdd 9 | | 32 _RD + _W/RDYA 10 | Z80-SIO/2 | 31 GND + _SYNCA 11 | | 30 _W/RDYB + RxDA 12 | | 29 _RxDB + _RxCA 13 | | 28 _RxCB + _TxCA 14 | | 27 _TxCB + TxDA 15 | | 26 TxDB + _DTRA 16 | | 25 _DTRB + _RTSA 17 | | 24 _RTSB + _CTSA 18 | | 23 _CTSB + _DCDA 19 | | 22 _DCDB + CLK 20 |_____________| 21 _RESET + +***************************************************************************/ + +#ifndef __Z80DART_H__ +#define __Z80DART_H__ + +#include "cpu/z80/z80daisy.h" + + + +//************************************************************************** +// DEVICE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_Z80DART_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, Z80DART, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define MCFG_Z80SIO0_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, Z80SIO0, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define MCFG_Z80SIO1_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, Z80SIO1, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define MCFG_Z80SIO2_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, Z80SIO2, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define MCFG_Z80SIO3_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, Z80SIO3, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define MCFG_Z80SIO4_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, Z80SIO4, _clock) \ + MCFG_DEVICE_CONFIG(_config) + +#define MCFG_Z80DART_REMOVE(_tag) \ + MCFG_DEVICE_REMOVE(_tag) + +#define Z80DART_INTERFACE(_name) \ + const z80dart_interface (_name) = + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + + +// ======================> z80dart_interface + +struct z80dart_interface +{ + int m_rx_clock_a; // channel A receive clock + int m_tx_clock_a; // channel A transmit clock + int m_rx_clock_b; // channel B receive clock + int m_tx_clock_b; // channel B transmit clock + + devcb_read_line m_in_rxda_cb; + devcb_write_line m_out_txda_cb; + devcb_write_line m_out_dtra_cb; + devcb_write_line m_out_rtsa_cb; + devcb_write_line m_out_wrdya_cb; + devcb_write_line m_out_synca_cb; + + devcb_read_line m_in_rxdb_cb; + devcb_write_line m_out_txdb_cb; + devcb_write_line m_out_dtrb_cb; + devcb_write_line m_out_rtsb_cb; + devcb_write_line m_out_wrdyb_cb; + devcb_write_line m_out_syncb_cb; + + devcb_write_line m_out_int_cb; +}; + + + +// ======================> z80dart_device + +class z80dart_device : public device_t, + public device_z80daisy_interface, + public z80dart_interface +{ + friend class dart_channel; + +public: + // construction/destruction + z80dart_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // control register access + UINT8 control_read(int which) { return m_channel[which].control_read(); } + void control_write(int which, UINT8 data) { return m_channel[which].control_write(data); } + + // data register access + UINT8 data_read(int which) { return m_channel[which].data_read(); } + void data_write(int which, UINT8 data) { return m_channel[which].data_write(data); } + + // put data on the input lines + void receive_data(int which, UINT8 data) { m_channel[which].receive_data(data); } + + // control line access + void cts_w(int which, int state) { m_channel[which].cts_w(state); } + void dcd_w(int which, int state) { m_channel[which].dcd_w(state); } + void ri_w(int which, int state) { m_channel[which].ri_w(state); } + void rx_w(int which, int state) { m_channel[which].rx_w(state); } + void tx_w(int which, int state) { m_channel[which].tx_w(state); } + void sync_w(int which, int state) { m_channel[which].sync_w(state); } + +private: + // device-level overrides + virtual void device_config_complete(); + virtual void device_start(); + virtual void device_reset(); + + // device_z80daisy_interface overrides + virtual int z80daisy_irq_state(); + virtual int z80daisy_irq_ack(); + virtual void z80daisy_irq_reti(); + + // internal interrupt management + void check_interrupts(); + void take_interrupt(int priority); + + // a single channel on the DART + class dart_channel + { + friend class z80dart_device; + + public: + dart_channel(); + + void start(z80dart_device *device, int index, const devcb_read_line &in_rxd, const devcb_write_line &out_txd, const devcb_write_line &out_dtr, const devcb_write_line &out_rts, const devcb_write_line &out_wrdy, const devcb_write_line &out_sync); + void reset(); + + UINT8 control_read(); + void control_write(UINT8 data); + + UINT8 data_read(); + void data_write(UINT8 data); + + void receive_data(UINT8 data); + + void cts_w(int state); + void dcd_w(int state); + void ri_w(int state); + void rx_w(int state); + void tx_w(int state); + void sync_w(int state); + + private: + void take_interrupt(int level); + int get_clock_mode(); + float get_stop_bits(); + int get_rx_word_length(); + int get_tx_word_length(); + int detect_start_bit(); + void shift_data_in(); + bool character_completed(); + void detect_parity_error(); + void detect_framing_error(); + void receive(); + void transmit(); + + static TIMER_CALLBACK( static_rxc_tick ) { reinterpret_cast<dart_channel *>(ptr)->rx_w(1); } + static TIMER_CALLBACK( static_txc_tick ) { reinterpret_cast<dart_channel *>(ptr)->tx_w(1); } + + z80dart_device *m_device; + int m_index; + + devcb_resolved_read_line m_in_rxd_func; + devcb_resolved_write_line m_out_txd_func; + devcb_resolved_write_line m_out_dtr_func; + devcb_resolved_write_line m_out_rts_func; + devcb_resolved_write_line m_out_wrdy_func; + devcb_resolved_write_line m_out_sync_func; + + // register state + UINT8 m_rr[3]; // read register + UINT8 m_wr[6]; // write register + + // receiver state + UINT8 m_rx_data_fifo[3]; // receive data FIFO + UINT8 m_rx_error_fifo[3]; // receive error FIFO + UINT8 m_rx_shift; // 8-bit receive shift register + UINT8 m_rx_error; // current receive error + int m_rx_fifo; // receive FIFO pointer + + int m_rx_clock; // receive clock pulse count + int m_rx_state; // receive state + int m_rx_bits; // bits received + int m_rx_first; // first character received + int m_rx_parity; // received data parity + int m_rx_break; // receive break condition + UINT8 m_rx_rr0_latch; // read register 0 latched + + int m_ri; // ring indicator latch + int m_cts; // clear to send latch + int m_dcd; // data carrier detect latch + + // transmitter state + UINT8 m_tx_data; // transmit data register + UINT8 m_tx_shift; // transmit shift register + + int m_tx_clock; // transmit clock pulse count + int m_tx_state; // transmit state + int m_tx_bits; // bits transmitted + int m_tx_parity; // transmitted data parity + + int m_dtr; // data terminal ready + int m_rts; // request to send + + // synchronous state + UINT16 m_sync; // sync character + }; + + // internal state + devcb_resolved_write_line m_out_int_func; + dart_channel m_channel[2]; // channels + int m_int_state[8]; // interrupt state + + // timers + emu_timer * m_rxca_timer; + emu_timer * m_txca_timer; + emu_timer * m_rxcb_timer; + emu_timer * m_txcb_timer; +}; + + +// device type definition +extern const device_type Z80DART; +extern const device_type Z80SIO0; +extern const device_type Z80SIO1; +extern const device_type Z80SIO2; +extern const device_type Z80SIO3; +extern const device_type Z80SIO4; + + + +//************************************************************************** +// READ/WRITE HANDLERS +//************************************************************************** + +// register access +READ8_DEVICE_HANDLER( z80dart_cd_ba_r ); +WRITE8_DEVICE_HANDLER( z80dart_cd_ba_w ); + +READ8_DEVICE_HANDLER( z80dart_ba_cd_r ); +WRITE8_DEVICE_HANDLER( z80dart_ba_cd_w ); + +// control register access +WRITE8_DEVICE_HANDLER( z80dart_c_w ); +READ8_DEVICE_HANDLER( z80dart_c_r ); + +// data register access +WRITE8_DEVICE_HANDLER( z80dart_d_w ); +READ8_DEVICE_HANDLER( z80dart_d_r ); + +// serial clocks +WRITE_LINE_DEVICE_HANDLER( z80dart_rxca_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_txca_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_rxcb_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_txcb_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_rxtxcb_w ); + +// ring indicator +WRITE_LINE_DEVICE_HANDLER( z80dart_ria_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_rib_w ); + +// data carrier detected +WRITE_LINE_DEVICE_HANDLER( z80dart_dcda_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_dcdb_w ); + +// clear to send +WRITE_LINE_DEVICE_HANDLER( z80dart_ctsa_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_ctsb_w ); + +// sync +WRITE_LINE_DEVICE_HANDLER( z80dart_synca_w ); +WRITE_LINE_DEVICE_HANDLER( z80dart_syncb_w ); + +#endif |