diff options
Diffstat (limited to 'trunk/src/emu/diserial.h')
-rw-r--r-- | trunk/src/emu/diserial.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/trunk/src/emu/diserial.h b/trunk/src/emu/diserial.h new file mode 100644 index 00000000000..4e604f4ba0f --- /dev/null +++ b/trunk/src/emu/diserial.h @@ -0,0 +1,194 @@ +#pragma once + +#ifndef __EMU_H__ +#error Dont include this file directly; include emu.h instead. +#endif + +#ifndef __DISERIAL_H__ +#define __DISERIAL_H__ + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** +/* parity selections */ +/* if all the bits are added in a byte, if the result is: + even -> parity is even + odd -> parity is odd +*/ +enum +{ + SERIAL_PARITY_NONE, /* no parity. a parity bit will not be in the transmitted/received data */ + SERIAL_PARITY_ODD, /* odd parity */ + SERIAL_PARITY_EVEN, /* even parity */ + SERIAL_PARITY_MARK, /* one parity */ + SERIAL_PARITY_SPACE /* zero parity */ +}; + +/* + CTS = Clear to Send. (INPUT) + Other end of connection is ready to accept data + + + NOTE: + + This output is active low on serial chips (e.g. 0 is CTS is set), + but here it is active high! +*/ +#define SERIAL_STATE_CTS 0x0001 + +/* + RTS = Request to Send. (OUTPUT) + This end is ready to send data, and requests if the other + end is ready to accept it + + NOTE: + + This output is active low on serial chips (e.g. 0 is RTS is set), + but here it is active high! +*/ +#define SERIAL_STATE_RTS 0x0002 + +/* + DSR = Data Set ready. (INPUT) + Other end of connection has data + + + NOTE: + + This output is active low on serial chips (e.g. 0 is DSR is set), + but here it is active high! +*/ +#define SERIAL_STATE_DSR 0x0004 + +/* + DTR = Data terminal Ready. (OUTPUT) + TX contains new data. + + NOTE: + + This output is active low on serial chips (e.g. 0 is DTR is set), + but here it is active high! +*/ +#define SERIAL_STATE_DTR 0x0008 +/* RX = Recieve data. (INPUT) */ +#define SERIAL_STATE_RX_DATA 0x00010 +/* TX = Transmit data. (OUTPUT) */ +#define SERIAL_STATE_TX_DATA 0x00020 + +// ======================> device_serial_interface +class device_serial_interface : public device_interface +{ +public: + // construction/destruction + device_serial_interface(const machine_config &mconfig, device_t &device); + virtual ~device_serial_interface(); + + virtual void input_callback(UINT8 state) = 0; + + void set_data_frame(int num_data_bits, int stop_bit_count, int parity_code); + + void receive_register_reset(); + void receive_register_update_bit(int bit); + void receive_register_extract(); + + void set_rcv_rate(int baud); + void set_tra_rate(int baud); + + void transmit_register_reset(); + void transmit_register_add_bit(int bit); + void transmit_register_setup(UINT8 data_byte); + UINT8 transmit_register_get_data_bit(); + void transmit_register_send_bit(); + + UINT8 serial_helper_get_parity(UINT8 data) { return m_serial_parity_table[data]; } + + UINT8 get_in_data_bit() { return ((m_input_state & SERIAL_STATE_RX_DATA)>>4) & 1; } + void set_out_data_bit(UINT8 data) { m_connection_state &=~SERIAL_STATE_TX_DATA; m_connection_state |=(data<<5); } + + void serial_connection_out(); + + bool is_receive_register_full(); + bool is_transmit_register_empty(); + + UINT8 get_received_char() { return m_rcv_byte_received; } + + void set_other_connection(device_serial_interface *other_connection); + + void connect(device_serial_interface *other_connection); + UINT8 check_for_start(UINT8 bit); +protected: + UINT8 m_input_state; + UINT8 m_connection_state; + virtual void tra_callback() { } + virtual void rcv_callback() { receive_register_update_bit(m_rcv_line); } + virtual void tra_complete() { } + virtual void rcv_complete() { } + + // interface-level overrides + virtual void interface_pre_start(); +private: + void tra_timer(void *ptr, int param); + void rcv_timer(void *ptr, int param); + + UINT8 m_serial_parity_table[256]; + + // Data frame + // length of word in bits + UINT8 m_df_word_length; + // parity state + UINT8 m_df_parity; + // number of stop bits + UINT8 m_df_stop_bit_count; + + // Receive register + /* data */ + UINT16 m_rcv_register_data; + /* flags */ + UINT8 m_rcv_flags; + /* bit count received */ + UINT8 m_rcv_bit_count_received; + /* length of data to receive - includes data bits, parity bit and stop bit */ + UINT8 m_rcv_bit_count; + /* the byte of data received */ + UINT8 m_rcv_byte_received; + + // Transmit register + /* data */ + UINT16 m_tra_register_data; + /* flags */ + UINT8 m_tra_flags; + /* number of bits transmitted */ + UINT8 m_tra_bit_count_transmitted; + /* length of data to send */ + UINT8 m_tra_bit_count; + + emu_timer *m_rcv_clock; + emu_timer *m_tra_clock; + int m_rcv_baud; + int m_tra_baud; + UINT8 m_rcv_line; + + device_serial_interface *m_other_connection; +}; + + +class serial_source_device : public device_t, + public device_serial_interface +{ +public: + // construction/destruction + serial_source_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual void input_callback(UINT8 state); + void send_bit(UINT8 data); +protected: + // device-level overrides + virtual void device_start(); +}; + +extern const device_type SERIAL_SOURCE; + +#define MCFG_SERIAL_SOURCE_ADD(_tag) \ + MCFG_DEVICE_ADD((_tag), SERIAL_SOURCE, 0) + +#endif /* __DISERIAL_H__ */ |