summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/6850acia.h
blob: 33e7e5325bbfc09b78eaaa550e9be49a8a569fe8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*********************************************************************

    6850acia.h

    6850 ACIA code

*********************************************************************/

#pragma once

#ifndef __ACIA6850_H__
#define __ACIA6850_H__

#include "emu.h"



/***************************************************************************
    EXTERNAL MACROS
***************************************************************************/

#define ACIA6850_STATUS_RDRF	0x01
#define ACIA6850_STATUS_TDRE	0x02
#define ACIA6850_STATUS_DCD		0x04
#define ACIA6850_STATUS_CTS		0x08
#define ACIA6850_STATUS_FE		0x10
#define ACIA6850_STATUS_OVRN	0x20
#define ACIA6850_STATUS_PE		0x40
#define ACIA6850_STATUS_IRQ		0x80



/***************************************************************************
    DEVICE CONFIGURATION MACROS
***************************************************************************/

#define MCFG_ACIA6850_ADD(_tag, _interface) \
	MCFG_DEVICE_ADD(_tag, ACIA6850, 0) \
	acia6850_device::static_set_interface(*device, _interface);

#define ACIA6850_INTERFACE(_name) \
	const acia6850_interface(_name) =


/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/


// ======================> acia6850_interface

struct acia6850_interface
{
	int	m_tx_clock;
	int	m_rx_clock;

	devcb_read_line		m_in_rx_cb;
	devcb_write_line	m_out_tx_cb;

	devcb_read_line		m_in_cts_cb;
	devcb_write_line	m_out_rts_cb;
	devcb_read_line		m_in_dcd_cb;

	devcb_write_line	m_out_irq_cb;
};



// ======================> acia6850_device

class acia6850_device :  public device_t,
                         public acia6850_interface
{
public:
    // construction/destruction
    acia6850_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

	// static configuration helpers
	static void static_set_interface(device_t &device, const acia6850_interface &interface);

	DECLARE_WRITE8_MEMBER( control_write );
	DECLARE_READ8_MEMBER( status_read );
	DECLARE_WRITE8_MEMBER( data_write );
	DECLARE_READ8_MEMBER( data_read );

	void tx_clock_in();
	void rx_clock_in();

	void set_rx_clock(int clock);
	void set_tx_clock(int clock);

	void receive_data(UINT8 data);

protected:
    // 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);

private:
	enum
	{
		TIMER_ID_TRANSMIT,
		TIMER_ID_RECEIVE
	};

	void check_interrupts();

	void tx_tick();
	void transmit_event();

	void rx_tick();
	void receive_event();

	enum serial_state
	{
		START,
		DATA,
		PARITY,
		STOP,
		STOP2,
	};

	enum parity_type
	{
		NONE,
		ODD,
		EVEN
	};

	devcb_resolved_read_line	m_in_rx_func;
	devcb_resolved_write_line	m_out_tx_func;
	devcb_resolved_read_line	m_in_cts_func;
	devcb_resolved_write_line	m_out_rts_func;
	devcb_resolved_read_line	m_in_dcd_func;
	devcb_resolved_write_line	m_out_irq_func;

	UINT8		m_ctrl;
	UINT8		m_status;

	UINT8		m_tdr;
	UINT8		m_rdr;
	UINT8		m_rx_shift;
	UINT8		m_tx_shift;

	UINT8		m_rx_counter;
	UINT8		m_tx_counter;

	int			m_divide;

	// Counters
	int			m_tx_bits;
	int			m_rx_bits;
	int			m_tx_parity;
	int			m_rx_parity;

	// TX/RX state
	int			m_bits;
	parity_type	m_parity;
	int			m_stopbits;
	int			m_tx_int;

	// Signals
	int			m_overrun;
	int			m_reset;
	int			m_rts;
	int			m_brk;
	int			m_first_reset;
	int			m_status_read;
	serial_state m_rx_state;
	serial_state m_tx_state;
	int			m_irq;

	emu_timer	*m_rx_timer;
	emu_timer	*m_tx_timer;

	static const int ACIA6850_DIVIDE[3];
	static const int ACIA6850_WORD[8][3];
};


// device type definition
extern const device_type ACIA6850;



#endif /* __ACIA6850_H__ */