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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
/***************************************************************************
Z80 DART Dual Asynchronous Receiver/Transmitter implementation
Copyright (c) 2008, The MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
****************************************************************************
_____ _____
D1 1 |* \_/ | 40 D0
D3 2 | | 39 D2
D5 3 | | 38 D4
D7 4 | | 37 D6
_INT 5 | | 36 _IORQ
IEI 6 | | 35 _CE
IEO 7 | | 34 B/_A
_M1 8 | | 33 C/_D
Vdd 9 | | 32 _RD
_W/RDYA 10 | Z80-DART | 31 GND
_RIA 11 | | 30 _W/RDYB
RxDA 12 | | 29 _RIB
_RxCA 13 | | 28 RxDB
_TxCA 14 | | 27 _RxTxCB
TxDA 15 | | 26 TxDB
_DTRA 16 | | 25 _DTRB
_RTSA 17 | | 24 _RTSB
_CTSA 18 | | 23 _CTSB
_DCDA 19 | | 22 _DCDB
CLK 20 |_____________| 21 _RESET
_____ _____
D1 1 |* \_/ | 40 D0
D3 2 | | 39 D2
D5 3 | | 38 D4
D7 4 | | 37 D6
_INT 5 | | 36 _IORQ
IEI 6 | | 35 _CE
IEO 7 | | 34 B/_A
_M1 8 | | 33 C/_D
Vdd 9 | | 32 _RD
_W/RDYA 10 | Z80-SIO/0 | 31 GND
_SYNCA 11 | | 30 _W/RDYB
RxDA 12 | | 29 _SYNCB
_RxCA 13 | | 28 RxDB
_TxCA 14 | | 27 _RxTxCB
TxDA 15 | | 26 TxDB
_DTRA 16 | | 25 _DTRB
_RTSA 17 | | 24 _RTSB
_CTSA 18 | | 23 _CTSB
_DCDA 19 | | 22 _DCDB
CLK 20 |_____________| 21 _RESET
_____ _____
D1 1 |* \_/ | 40 D0
D3 2 | | 39 D2
D5 3 | | 38 D4
D7 4 | | 37 D6
_INT 5 | | 36 _IORQ
IEI 6 | | 35 _CE
IEO 7 | | 34 B/_A
_M1 8 | | 33 C/_D
Vdd 9 | | 32 _RD
_W/RDYA 10 | Z80-SIO/1 | 31 GND
_SYNCA 11 | | 30 _W/RDYB
RxDA 12 | | 29 _SYNCB
_RxCA 13 | | 28 RxDB
_TxCA 14 | | 27 _RxCB
TxDA 15 | | 26 _TxCB
_DTRA 16 | | 25 TxDB
_RTSA 17 | | 24 _RTSB
_CTSA 18 | | 23 _CTSB
_DCDA 19 | | 22 _DCDB
CLK 20 |_____________| 21 _RESET
_____ _____
D1 1 |* \_/ | 40 D0
D3 2 | | 39 D2
D5 3 | | 38 D4
D7 4 | | 37 D6
_INT 5 | | 36 _IORQ
IEI 6 | | 35 _CE
IEO 7 | | 34 B/_A
_M1 8 | | 33 C/_D
Vdd 9 | | 32 _RD
_W/RDYA 10 | Z80-SIO/2 | 31 GND
_SYNCA 11 | | 30 _W/RDYB
RxDA 12 | | 29 _RxDB
_RxCA 13 | | 28 _RxCB
_TxCA 14 | | 27 _TxCB
TxDA 15 | | 26 TxDB
_DTRA 16 | | 25 _DTRB
_RTSA 17 | | 24 _RTSB
_CTSA 18 | | 23 _CTSB
_DCDA 19 | | 22 _DCDB
CLK 20 |_____________| 21 _RESET
***************************************************************************/
#ifndef __Z80DART_H__
#define __Z80DART_H__
#include "cpu/z80/z80daisy.h"
//**************************************************************************
// DEVICE CONFIGURATION MACROS
//**************************************************************************
#define MDRV_Z80DART_ADD(_tag, _clock, _config) \
MDRV_DEVICE_ADD(_tag, Z80DART, _clock) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_Z80SIO0_ADD(_tag, _clock, _config) \
MDRV_DEVICE_ADD(_tag, Z80SIO0, _clock) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_Z80SIO1_ADD(_tag, _clock, _config) \
MDRV_DEVICE_ADD(_tag, Z80SIO1, _clock) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_Z80SIO2_ADD(_tag, _clock, _config) \
MDRV_DEVICE_ADD(_tag, Z80SIO2, _clock) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_Z80SIO3_ADD(_tag, _clock, _config) \
MDRV_DEVICE_ADD(_tag, Z80SIO3, _clock) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_Z80SIO4_ADD(_tag, _clock, _config) \
MDRV_DEVICE_ADD(_tag, Z80SIO4, _clock) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_Z80DART_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag)
#define Z80DART_INTERFACE(_name) \
const z80dart_interface (_name) =
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> z80dart_interface
struct z80dart_interface
{
int m_rx_clock_a; // channel A receive clock
int m_tx_clock_a; // channel A transmit clock
int m_rx_clock_b; // channel B receive clock
int m_tx_clock_b; // channel B transmit clock
devcb_read_line m_in_rxda_func;
devcb_write_line m_out_txda_func;
devcb_write_line m_out_dtra_func;
devcb_write_line m_out_rtsa_func;
devcb_write_line m_out_wrdya_func;
devcb_write_line m_out_synca_func;
devcb_read_line m_in_rxdb_func;
devcb_write_line m_out_txdb_func;
devcb_write_line m_out_dtrb_func;
devcb_write_line m_out_rtsb_func;
devcb_write_line m_out_wrdyb_func;
devcb_write_line m_out_syncb_func;
devcb_write_line m_out_int_func;
};
// ======================> z80dart_device_config
class z80dart_device_config : public device_config,
public device_config_z80daisy_interface,
public z80dart_interface
{
friend class z80dart_device;
// construction/destruction
z80dart_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
public:
// allocators
static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock);
virtual device_t *alloc_device(running_machine &machine) const;
protected:
// device_config overrides
virtual void device_config_complete();
};
// ======================> z80dart_device
class z80dart_device : public device_t,
public device_z80daisy_interface
{
friend class z80dart_device_config;
friend class dart_channel;
// construction/destruction
z80dart_device(running_machine &_machine, const z80dart_device_config &_config);
public:
// control register access
UINT8 control_read(int which) { return m_channel[which].control_read(); }
void control_write(int which, UINT8 data) { return m_channel[which].control_write(data); }
// data register access
UINT8 data_read(int which) { return m_channel[which].data_read(); }
void data_write(int which, UINT8 data) { return m_channel[which].data_write(data); }
// put data on the input lines
void receive_data(int which, UINT8 data) { m_channel[which].receive_data(data); }
// control line access
void cts_w(int which, int state) { m_channel[which].cts_w(state); }
void dcd_w(int which, int state) { m_channel[which].dcd_w(state); }
void ri_w(int which, int state) { m_channel[which].ri_w(state); }
void rx_w(int which, int state) { m_channel[which].rx_w(state); }
void tx_w(int which, int state) { m_channel[which].tx_w(state); }
void sync_w(int which, int state) { m_channel[which].sync_w(state); }
private:
// device-level overrides
virtual void device_start();
virtual void device_reset();
// device_z80daisy_interface overrides
virtual int z80daisy_irq_state();
virtual int z80daisy_irq_ack();
virtual void z80daisy_irq_reti();
// internal interrupt management
void check_interrupts();
void take_interrupt(int priority);
// a single channel on the DART
class dart_channel
{
friend class z80dart_device;
public:
dart_channel();
void start(z80dart_device *device, int index, const devcb_read_line &in_rxd, const devcb_write_line &out_txd, const devcb_write_line &out_dtr, const devcb_write_line &out_rts, const devcb_write_line &out_wrdy, const devcb_write_line &out_sync);
void reset();
UINT8 control_read();
void control_write(UINT8 data);
UINT8 data_read();
void data_write(UINT8 data);
void receive_data(UINT8 data);
void cts_w(int state);
void dcd_w(int state);
void ri_w(int state);
void rx_w(int state);
void tx_w(int state);
void sync_w(int state);
private:
void take_interrupt(int level);
int get_clock_mode();
float get_stop_bits();
int get_rx_word_length();
int get_tx_word_length();
int detect_start_bit();
void shift_data_in();
bool character_completed();
void detect_parity_error();
void detect_framing_error();
void receive();
void transmit();
static TIMER_CALLBACK( static_rxc_tick ) { reinterpret_cast<dart_channel *>(ptr)->rx_w(1); }
static TIMER_CALLBACK( static_txc_tick ) { reinterpret_cast<dart_channel *>(ptr)->tx_w(1); }
z80dart_device *m_device;
int m_index;
devcb_resolved_read_line m_in_rxd_func;
devcb_resolved_write_line m_out_txd_func;
devcb_resolved_write_line m_out_dtr_func;
devcb_resolved_write_line m_out_rts_func;
devcb_resolved_write_line m_out_wrdy_func;
devcb_resolved_write_line m_out_sync_func;
// register state
UINT8 m_rr[3]; // read register
UINT8 m_wr[6]; // write register
// receiver state
UINT8 m_rx_data_fifo[3]; // receive data FIFO
UINT8 m_rx_error_fifo[3]; // receive error FIFO
UINT8 m_rx_shift; // 8-bit receive shift register
UINT8 m_rx_error; // current receive error
int m_rx_fifo; // receive FIFO pointer
int m_rx_clock; // receive clock pulse count
int m_rx_state; // receive state
int m_rx_bits; // bits received
int m_rx_first; // first character received
int m_rx_parity; // received data parity
int m_rx_break; // receive break condition
UINT8 m_rx_rr0_latch; // read register 0 latched
int m_ri; // ring indicator latch
int m_cts; // clear to send latch
int m_dcd; // data carrier detect latch
// transmitter state
UINT8 m_tx_data; // transmit data register
UINT8 m_tx_shift; // transmit shift register
int m_tx_clock; // transmit clock pulse count
int m_tx_state; // transmit state
int m_tx_bits; // bits transmitted
int m_tx_parity; // transmitted data parity
int m_dtr; // data terminal ready
int m_rts; // request to send
// synchronous state
UINT16 m_sync; // sync character
};
// internal state
const z80dart_device_config & m_config;
devcb_resolved_write_line m_out_int_func;
dart_channel m_channel[2]; // channels
int m_int_state[8]; // interrupt state
// timers
emu_timer * m_rxca_timer;
emu_timer * m_txca_timer;
emu_timer * m_rxcb_timer;
emu_timer * m_txcb_timer;
};
// device type definition
extern const device_type Z80DART;
extern const device_type Z80SIO0;
extern const device_type Z80SIO1;
extern const device_type Z80SIO2;
extern const device_type Z80SIO3;
extern const device_type Z80SIO4;
//**************************************************************************
// READ/WRITE HANDLERS
//**************************************************************************
// register access
READ8_DEVICE_HANDLER( z80dart_cd_ba_r );
WRITE8_DEVICE_HANDLER( z80dart_cd_ba_w );
READ8_DEVICE_HANDLER( z80dart_ba_cd_r );
WRITE8_DEVICE_HANDLER( z80dart_ba_cd_w );
// control register access
WRITE8_DEVICE_HANDLER( z80dart_c_w );
READ8_DEVICE_HANDLER( z80dart_c_r );
// data register access
WRITE8_DEVICE_HANDLER( z80dart_d_w );
READ8_DEVICE_HANDLER( z80dart_d_r );
// serial clocks
WRITE_LINE_DEVICE_HANDLER( z80dart_rxca_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_txca_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_rxcb_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_txcb_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_rxtxcb_w );
// ring indicator
WRITE_LINE_DEVICE_HANDLER( z80dart_ria_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_rib_w );
// data carrier detected
WRITE_LINE_DEVICE_HANDLER( z80dart_dcda_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_dcdb_w );
// clear to send
WRITE_LINE_DEVICE_HANDLER( z80dart_ctsa_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_ctsb_w );
// sync
WRITE_LINE_DEVICE_HANDLER( z80dart_synca_w );
WRITE_LINE_DEVICE_HANDLER( z80dart_syncb_w );
#endif
|