summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/6850acia.h
blob: 52f323d21648786ccc9fda0d3e5cc6e1a318f149 (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
188
189
190
191
/*********************************************************************

    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);

	UINT8 get_status() { return m_status; }  // returns current status without mangling it

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 check_dcd_input();

	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;
	bool		m_dcd_triggered;

	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__ */