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