#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();
UINT8 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__ */