1 // license:BSD-3-Clause
2 // copyright-holders:Joakim Larsson Edstrom
3 /***************************************************************************
4
5 Philips DUSCC - Dual Serial Communications Controller emulation
6
7 ****************************************************************************
8
9 Chan B Chan A Chan B Chan A
10 ======= _____ _____ ======== ======= _____ _____ ========
11 IACKN 1|* \_/ |48 VCC IACKN 1|* \_/ |48 VDD
12 A3 2| |47 A4 A3 2| |47 A4
13 A2 3| |46 A5 A2 3| |46 A5
14 A1 4| |45 A6 A1 4| |45 A6
15 RTxDAK/GPI1 5| |44 RTxDAK/GPI1 5| |44 RTxDAK/GP1
16 IRQN 6| |43 X1/CLK IRQN 6| |43 X1/CLK
17 RDYN 7| |42 X2 RESETN 7| |42 X2
18 RTS/SYNOUT 8| |41 RTS/SYNOUT 8| |41 RTS/SYNOUT
19 TRxC 9| |40 TRxC TRxC 9| |40 TRxC
20 RTxC 10| |39 RTxC RTxC 10| |39 RTxC
21 DCD/SYNI 11| |38 DCD/SYNI 11| |38 DCD/SYNI
22 RxD 12| |37 RxD RxD 12| |37 RxD
23 TxD 13| SCN26562 |36 TxD TxD 13| SCN68562 |36 TxD
24 TxDAK/GPI2 14| SCN26C562 |35 TxDAK/GPI2 14| SCN68C562 |35 TxDAK/GPI2
25 RTxDRQ/GPO1 15| |34 RTxDRQ/GPO1 15| |34 RTxDRQ/GPO1
26 TxDRQ/RTS/GPO2 16| |33 TxDRQ/RTS/GPO2 16| |33 TxDRQ/RTS/GPO2
27 CTS/LC 17| |32 CTS/LC CTS/LC 17| |32 CTS/LC
28 D7 18| |31 D0 D7 18| |31 D0
29 D6 19| |30 D1 D6 19| |30 D1
30 D5 20| |29 D2 D5 20| |29 D2
31 D4 21| |28 D3 D4 21| |28 D3
32 RDN 22| |27 EOPN DTACKN 22| |27 DONEN
33 RESETN 23| |26 WRN DTCN 23| |26 R/WN
34 GND 24|_____________|25 CEN CND 24|_____________|25 CSN
35 Intel Bus Motorola Bus
36
37 ***************************************************************************/
38
39 #ifndef MAME_MACHINE_SCNXX562_H
40 #define MAME_MACHINE_SCNXX562_H
41
42 #pragma once
43
44 #include "machine/z80daisy.h"
45 #include "diserial.h"
46
47
48 //**************************************************************************
49 // TYPE DEFINITIONS
50 //**************************************************************************
51
52 // ======================> duscc_channel
53
54 class duscc_device;
55
56 class duscc_channel : public device_t, public device_serial_interface
57 {
58 friend class duscc_device;
59
60 public:
61 duscc_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
62
63 // read register handlers
64 uint8_t do_dusccreg_cmr1_r();
65 uint8_t do_dusccreg_cmr2_r();
66 uint8_t do_dusccreg_s1r_r();
67 uint8_t do_dusccreg_s2r_r();
68 uint8_t do_dusccreg_tpr_r();
69 uint8_t do_dusccreg_ttr_r();
70 uint8_t do_dusccreg_rpr_r();
71 uint8_t do_dusccreg_rtr_r();
72 uint8_t do_dusccreg_ctprh_r();
73 uint8_t do_dusccreg_ctprl_r();
74 uint8_t do_dusccreg_ctcr_r();
75 uint8_t do_dusccreg_omr_r();
76 uint8_t do_dusccreg_cth_r();
77 uint8_t do_dusccreg_ctl_r();
78 uint8_t do_dusccreg_pcr_r();
79 uint8_t do_dusccreg_ccr_r();
80 uint8_t do_dusccreg_rxfifo_r();
81 uint8_t do_dusccreg_rsr_r();
82 uint8_t do_dusccreg_trsr_r();
83 uint8_t do_dusccreg_ictsr_r();
84 uint8_t do_dusccreg_gsr_r();
85 uint8_t do_dusccreg_ier_r();
86 uint8_t do_dusccreg_cid_r();
87 uint8_t do_dusccreg_ivr_ivrm_r();
88 uint8_t do_dusccreg_icr_r();
89 uint8_t do_dusccreg_mrr_r();
90 uint8_t do_dusccreg_ier1_r();
91 uint8_t do_dusccreg_ier2_r();
92 uint8_t do_dusccreg_ier3_r();
93 uint8_t do_dusccreg_trcr_r();
94 uint8_t do_dusccreg_rflr_r();
95 uint8_t do_dusccreg_ftlr_r();
96 uint8_t do_dusccreg_trmsr_r();
97 uint8_t do_dusccreg_telr_r();
98
99 // write register handlers
100 void do_dusccreg_cmr1_w(uint8_t data);
101 void do_dusccreg_cmr2_w(uint8_t data);
102 void do_dusccreg_s1r_w(uint8_t data);
103 void do_dusccreg_s2r_w(uint8_t data);
104 void do_dusccreg_tpr_w(uint8_t data);
105 void do_dusccreg_ttr_w(uint8_t data);
106 void do_dusccreg_rpr_w(uint8_t data);
107 void do_dusccreg_rtr_w(uint8_t data);
108 void do_dusccreg_ctprh_w(uint8_t data);
109 void do_dusccreg_ctprl_w(uint8_t data);
110 void do_dusccreg_ctcr_w(uint8_t data);
111 void do_dusccreg_omr_w(uint8_t data);
112 void do_dusccreg_pcr_w(uint8_t data);
113 void do_dusccreg_ccr_w(uint8_t data);
114 void do_dusccreg_txfifo_w(uint8_t data);
115 void do_dusccreg_rsr_w(uint8_t data);
116 void do_dusccreg_trsr_w(uint8_t data);
117 void do_dusccreg_ictsr_w(uint8_t data);
118 void do_dusccreg_gsr_w(uint8_t data);
119 void do_dusccreg_ier_w(uint8_t data);
120 // void do_dusccreg_rea_w(uint8_t data); // Short cutted non complex feature
121 void do_dusccreg_ivr_w(uint8_t data);
122 void do_dusccreg_icr_w(uint8_t data);
123 void do_dusccreg_sea_rea_w(uint8_t data); // Short cutted non complex feature
124 void do_dusccreg_mrr_w(uint8_t data);
125 void do_dusccreg_ier1_w(uint8_t data);
126 void do_dusccreg_ier2_w(uint8_t data);
127 void do_dusccreg_ier3_w(uint8_t data);
128 void do_dusccreg_trcr_w(uint8_t data);
129 void do_dusccreg_ftlr_w(uint8_t data);
130 void do_dusccreg_trmsr_w(uint8_t data);
131
132 uint8_t read(offs_t &offset);
133 void write(uint8_t data, offs_t &offset);
134
135 // uint8_t data_read();
136 // void data_write(uint8_t data);
137
138 void receive_data(uint8_t data);
139 void m_tx_fifo_rp_step();
140 void m_rx_fifo_rp_step();
141 uint8_t m_rx_fifo_rp_data();
142
143 void write_rx(int state);
144 void cts_w(int state);
145 void dcd_w(int state);
146 void ri_w(int state);
147 void rxc_w(int state);
148 void txc_w(int state);
149 void sync_w(int state);
150
151 protected:
152 // device-level overrides
153 virtual void device_start() override;
154 virtual void device_reset() override;
155 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
156
157 // device_serial_interface overrides
158 virtual void tra_callback() override;
159 virtual void tra_complete() override;
160 virtual void rcv_callback() override;
161 virtual void rcv_complete() override;
162
163 int m_rxc;
164 int m_txc;
165 int m_tra;
166 int m_rcv;
167
168 // Register state
169 uint8_t m_cmr1;
170 uint8_t m_cmr2;
171 uint8_t m_s1r;
172 uint8_t m_s2r;
173 uint8_t m_tpr;
174 uint8_t m_ttr;
175 uint8_t m_rpr;
176 uint8_t m_rtr;
177 // uint8_t m_ctprh;
178 // uint8_t m_ctprl;
179 unsigned int m_ctpr;
180 uint8_t m_ctcr;
181 uint8_t m_omr;
182 // uint8_t m_cth;
183 // uint8_t m_ctl;
184 unsigned int m_ct;
185 uint8_t m_pcr;
186 uint8_t m_ccr;
187 uint8_t m_txfifo[4];
188 uint8_t m_rxfifo[4];
189 uint8_t m_rsr;
190 uint8_t m_trsr;
191 uint8_t m_ictsr;
192 // uint8_t m_gsr; // moved to the device since it is global
193 uint8_t m_ier;
194 // uint8_t m_rea;
195 uint8_t m_cid;
196 //uint8_t m_ivr;
197 //uint8_t m_icr;
198 // uint8_t m_sea;
199 //uint8_t m_ivrm;
200 uint8_t m_mrr;
201 uint8_t m_ier1;
202 uint8_t m_ier2;
203 uint8_t m_ier3;
204 uint8_t m_trcr;
205 uint8_t m_rflr;
206 uint8_t m_ftlr;
207 uint8_t m_trmsr;
208 uint8_t m_telr;
209
210 enum // Needs to be 0-3 in unmodified prio level
211 {
212 INT_RXREADY = 0,
213 INT_TXREADY = 1,
214 INT_RXTXSTAT = 2,
215 INT_EXTCTSTAT = 3
216 };
217
218 enum
219 {
220 REG_CCR_RESET_TX = 0x00,
221 REG_CCR_ENABLE_TX = 0x02,
222 REG_CCR_DISABLE_TX = 0x03,
223 REG_CCR_RESET_RX = 0x40,
224 REG_CCR_ENABLE_RX = 0x42,
225 REG_CCR_DISABLE_RX = 0x43,
226 REG_CCR_START_TIMER = 0x80,
227 REG_CCR_STOP_TIMER = 0x81,
228 REG_CCR_PRST_FFFF = 0x82,
229 REG_CCR_PRST_CTPR = 0x83,
230 };
231
232 enum
233 {
234 REG_CMR1_PARITY = 0x20,
235 REG_CMR1_PMMODE_MASK = 0x18,
236 REG_CMR1_PMMODE_NONE = 0x00,
237 REG_CMR1_PMMODE_RES = 0x01,
238 REG_CMR1_PMMODE_PARITY = 0x10,
239 REG_CMR1_PMMODE_FORCED = 0x11,
240 REG_CMR1_CPMODE_MASK = 0x07,
241 REG_CMR1_CPMODE_ASYNC = 0x07
242 };
243
244 enum
245 {
246 REG_CMR2_DTI_MASK = 0x38,
247 REG_CMR2_DTI_NODMA = 0x38
248 };
249
250 enum
251 {
252 REG_RPR_DATA_BITS_MASK = 0x03,
253 REG_RPR_DATA_BITS_5BIT = 0x00,
254 REG_RPR_DATA_BITS_6BIT = 0x01,
255 REG_RPR_DATA_BITS_7BIT = 0x02,
256 REG_RPR_DATA_BITS_8BIT = 0x03,
257 REG_RPR_DCD = 0x04,
258 REG_RPR_STRIP_PARITY = 0x08,
259 REG_RPR_RTS = 0x10
260 };
261
262 enum
263 {
264 REG_TPR_DATA_BITS_MASK = 0x03,
265 REG_TPR_DATA_BITS_5BIT = 0x00,
266 REG_TPR_DATA_BITS_6BIT = 0x01,
267 REG_TPR_DATA_BITS_7BIT = 0x02,
268 REG_TPR_DATA_BITS_8BIT = 0x03,
269 REG_TPR_CTS = 0x04,
270 REG_TPR_RTS = 0x08,
271 REG_TPR_STOP_BITS_MASK = 0xf0
272 };
273
274 enum
275 {
276 REG_TTR_EXT = 0x80,
277 REG_TTR_TXCLK_MASK = 0x70,
278 REG_TTR_TXCLK_1XEXT = 0x00,
279 REG_TTR_TXCLK_16XEXT = 0x10,
280 REG_TTR_TXCLK_DPLL = 0x20,
281 REG_TTR_TXCLK_BRG = 0x30,
282 REG_TTR_TXCLK_2X_OTHER = 0x40,
283 REG_TTR_TXCLK_32X_OTHER = 0x50,
284 REG_TTR_TXCLK_2X_OWN = 0x60,
285 REG_TTR_TXCLK_32X_OWN = 0x70,
286 REG_TTR_BRG_RATE_MASK = 0x0f,
287 };
288
289 enum
290 {
291 REG_RTR_EXT = 0x80,
292 REG_RTR_RXCLK_MASK = 0x70,
293 REG_RTR_RXCLK_1XEXT = 0x00,
294 REG_RTR_RXCLK_16XEXT = 0x10,
295 REG_RTR_RXCLK_BRG = 0x20,
296 REG_RTR_RXCLK_CT = 0x30,
297 REG_RTR_RXCLK_DPLL_64X_X1 = 0x40,
298 REG_RTR_RXCLK_DPLL_32X_EXT = 0x50,
299 REG_RTR_RXCLK_DPLL_32X_BRG = 0x60,
300 REG_RTR_RXCLK_DPLL_32X_CT = 0x70,
301 REG_RTR_BRG_RATE_MASK = 0x0f,
302 };
303
304 enum
305 {
306 REG_PCR_X2_IDC = 0x80,
307 REG_PCR_GP02_RTS = 0x40,
308 REG_PCR_SYNOUT_RTS = 0x20,
309 REG_PCR_RTXC_MASK = 0x18,
310 REG_PCR_RTXC_INPUT = 0x00,
311 REG_PCR_RTXC_CNTR_OUT = 0x08,
312 REG_PCR_RTXC_TXCLK_OUT = 0x10,
313 REG_PCR_RTXC_RXCLK_OUT = 0x18,
314 REG_PCR_TRXC_MASK = 0x07,
315 REG_PCR_TRXC_INPUT = 0x00,
316 REG_PCR_TRXC_CRYST_OUT = 0x01,
317 REG_PCR_TRXC_DPLL_OUT = 0x02,
318 REG_PCR_TRXC_CNTR_OUT = 0x03,
319 REG_PCR_TRXC_TXBRG_OUT = 0x04,
320 REG_PCR_TRXC_RXBRG_OUT = 0x05,
321 REG_PCR_TRXC_TXCLK_OUT = 0x06,
322 REG_PCR_TRXC_RXCLK_OUT = 0x07,
323 };
324
325 enum
326 {
327 REG_OMR_TXRCL_MASK = 0xe0,
328 REG_OMR_TXRCL_8BIT = 0xe0,
329 REG_OMR_TXRDY_ACTIVATED = 0x10,
330 REG_OMR_RXRDY_ACTIVATED = 0x08,
331 REG_OMR_GP02 = 0x04,
332 REG_OMR_GP01 = 0x02,
333 REG_OMR_RTS = 0x01,
334 };
335
336 enum
337 {
338 REG_RSR_CHAR_COMPARE = 0x80,
339 REG_RSR_OVERRUN_ERROR = 0x20,
340 REG_RSR_FRAMING_ERROR = 0x02,
341 REG_RSR_PARITY_ERROR = 0x01,
342 };
343
344 enum
345 {
346 REG_GSR_CHAN_A_RXREADY = 0x01,
347 REG_GSR_CHAN_B_RXREADY = 0x10,
348 REG_GSR_CHAN_A_TXREADY = 0x02,
349 REG_GSR_CHAN_B_TXREADY = 0x20,
350 REG_GSR_XXREADY_MASK = 0x33
351 };
352
353 enum
354 {
355 REG_ICTSR_ZERO_DET = 0x40,
356 REG_ICTSR_DELTA_CTS = 0x10,
357 REG_ICTSR_DCD = 0x08,
358 REG_ICTSR_CTS = 0x04,
359 };
360
361 enum
362 {
363 REG_IER_DCD_CTS = 0x80,
364 REG_IER_TXRDY = 0x40,
365 REG_IER_TRSR73 = 0x20,
366 REG_IER_RXRDY = 0x10,
367 REG_IER_RSR76 = 0x08,
368 REG_IER_RSR54 = 0x04,
369 REG_IER_RSR32 = 0x02,
370 REG_IER_RSR10 = 0x01,
371 };
372
373 // Register offsets, stripped from channel bit 0x20 but including A7 bit
374 enum
375 {
376 REG_CMR1 = 0x00,
377 REG_CMR2 = 0x01,
378 REG_S1R = 0x02,
379 REG_S2R = 0x03,
380 REG_TPR = 0x04,
381 REG_TTR = 0x05,
382 REG_RPR = 0x06,
383 REG_RTR = 0x07,
384 REG_CTPRH = 0x08,
385 REG_CTPRL = 0x09,
386 REG_CTCR = 0x0a,
387 REG_OMR = 0x0b,
388 REG_CTH = 0x0c,
389 REG_CTL = 0x0d,
390 REG_PCR = 0x0e,
391 REG_CCR = 0x0f,
392 REG_TXFIFO_0= 0x10,
393 REG_TXFIFO_1= 0x11,
394 REG_TXFIFO_2= 0x12,
395 REG_TXFIFO_3= 0x13,
396 REG_RXFIFO_0= 0x14,
397 REG_RXFIFO_1= 0x15,
398 REG_RXFIFO_2= 0x16,
399 REG_RXFIFO_3= 0x17,
400 REG_RSR = 0x18,
401 REG_TRSR = 0x19,
402 REG_ICTSR = 0x1a,
403 REG_GSR = 0x1b,
404 REG_IER = 0x1c,
405 REG_REA = 0x1d,
406 REG_CID = 0x1d,
407 REG_IVR = 0x1e,
408 REG_ICR = 0x1f,
409 REG_SEA = 0x1d,
410 REG_IVRM = 0x1e,
411 REG_MRR = 0x1f,
412 REG_IER1 = 0x42,
413 REG_IER2 = 0x43,
414 REG_IER3 = 0x45,
415 REG_TRCR = 0x47,
416 REG_RFLR = 0x4e,
417 REG_FTLR = 0x5c,
418 REG_TRMSR = 0x5e,
419 REG_TELR = 0x5f,
420 };
421
422 // Timers
423 emu_timer *duscc_timer;
424 emu_timer *rtxc_timer;
425 emu_timer *trxc_timer;
426
427 uint8_t m_rtxc;
428 uint8_t m_trxc;
429
430
431 enum
432 {
433 REG_CTCR_ZERO_DET_INT = 0x80,
434 REG_CTCR_ZERO_DET_CTL = 0x40,
435 REG_CTCR_TIM_OC = 0x20,
436 };
437
438 enum
439 {
440 TIMER_ID,
441 TIMER_ID_RTXC,
442 TIMER_ID_TRXC
443 };
444
445 uint16_t m_brg_rx_rate;
446 uint16_t m_brg_tx_rate;
447 uint16_t m_brg_const;
448
449 // TODO: Implement the 14.4K, 56K and 64K bauds available on the CDUSCC
get_baudrate(unsigned int br)450 static unsigned int get_baudrate(unsigned int br)
451 {
452 switch (br)
453 {
454 case 0x00: return 50; break;
455 case 0x01: return 75; break;
456 case 0x02: return 110; break;
457 case 0x03: return 134; break;
458 case 0x04: return 150; break;
459 case 0x05: return 200; break;
460 case 0x06: return 300; break;
461 case 0x07: return 600; break;
462 case 0x08: return 1050; break;
463 case 0x09: return 1200; break;
464 case 0x0a: return 2000; break;
465 case 0x0b: return 2400; break;
466 case 0x0c: return 4800; break;
467 case 0x0d: return 9600; break;
468 case 0x0e: return 19200; break;
469 case 0x0f: return 38400; break;
470 };
471 return 0;
472 }
473
474 void update_serial();
475 void set_dtr(int state);
476 void set_rts(int state);
477
478 int get_tx_clock_mode();
479 int get_rx_clock_mode();
480 stop_bits_t get_stop_bits();
481 int get_rx_word_length();
482 int get_tx_word_length();
483
484 /* FIFOs and rx/tx status */
485 /* Receiver */
486 uint8_t m_rx_data_fifo[16]; // data FIFO
487 uint8_t m_rx_error_fifo[16]; // error FIFO
488 int m_rx_fifo_rp; // FIFO read pointer
489 int m_rx_fifo_wp; // FIFO write pointer
490 int m_rx_fifo_sz; // FIFO size
491 uint8_t m_rx_error; // current error
492
493 /* Transmitter */
494 uint8_t m_tx_data_fifo[16]; // data FIFO
495 uint8_t m_tx_error_fifo[16]; // error FIFO
496 int m_tx_fifo_rp; // FIFO read pointer
497 int m_tx_fifo_wp; // FIFO write pointer
498 int m_tx_fifo_sz; // FIFO size
499 uint8_t m_tx_error; // current error
500
501 int m_rx_clock; // receive clock pulse count
502 int m_rx_first; // first character received
503 int m_rx_break; // receive break condition
504
505 int m_rxd;
506 int m_ri; // ring indicator latch
507 int m_cts; // clear to send latch
508 int m_dcd; // data carrier detect latch
509
510 // transmitter state
511 uint8_t m_tx_data; // transmit data register
512 int m_tx_clock; // transmit clock pulse count
513
514 int m_dtr; // data terminal ready
515 int m_rts; // request to send
516
517 // synchronous state
518 uint16_t m_sync; // sync character
519
520 int m_rcv_mode;
521 int m_index;
522 duscc_device *m_uart;
523
524 // CDUSCC specifics
525 int m_a7; // Access additional registers
526 };
527
528
529 // ======================> duscc_device
530
531 class duscc_device : public device_t, public device_z80daisy_interface
532 {
533 friend class duscc_channel;
534
535 public:
536 // construction/destruction
537 duscc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
538
out_txda_callback()539 auto out_txda_callback() { return m_out_txda_cb.bind(); }
out_dtra_callback()540 auto out_dtra_callback() { return m_out_dtra_cb.bind(); }
out_rtsa_callback()541 auto out_rtsa_callback() { return m_out_rtsa_cb.bind(); }
out_synca_callback()542 auto out_synca_callback() { return m_out_synca_cb.bind(); }
out_rtxca_callback()543 auto out_rtxca_callback() { return m_out_rtxca_cb.bind(); }
out_trxca_callback()544 auto out_trxca_callback() { return m_out_trxca_cb.bind(); }
545
out_txdb_callback()546 auto out_txdb_callback() { return m_out_txdb_cb.bind(); }
out_dtrb_callback()547 auto out_dtrb_callback() { return m_out_dtrb_cb.bind(); }
out_rtsb_callback()548 auto out_rtsb_callback() { return m_out_rtsb_cb.bind(); }
out_syncb_callback()549 auto out_syncb_callback() { return m_out_syncb_cb.bind(); }
out_rtxcb_callback()550 auto out_rtxcb_callback() { return m_out_rtxcb_cb.bind(); }
out_trxcb_callback()551 auto out_trxcb_callback() { return m_out_trxcb_cb.bind(); }
out_int_callback()552 auto out_int_callback() { return m_out_int_cb.bind(); }
553
configure_channels(int rxa,int txa,int rxb,int txb)554 void configure_channels(int rxa, int txa, int rxb, int txb)
555 {
556 #if 0 // TODO: Fix this, need a way to set external rx/tx clocks for the channels
557 m_chanA->m_rxc = rxa;
558 m_chanA->m_txc = txa;
559 m_chanB->m_rxc = rxb;
560 m_chanB->m_txc = txb;
561 #endif
562 }
563
564 uint8_t read(offs_t offset);
565 void write(offs_t offset, uint8_t data);
566
567 // interrupt acknowledge
568 uint8_t iack();
569
570 // device_z80daisy_interface overrides
571 virtual int z80daisy_irq_state() override;
572 virtual int z80daisy_irq_ack() override;
573 virtual void z80daisy_irq_reti() override;
574
rxa_w(int state)575 void rxa_w(int state) { m_chanA->write_rx(state); }
rxb_w(int state)576 void rxb_w(int state) { m_chanB->write_rx(state); }
ctsa_w(int state)577 void ctsa_w(int state) { m_chanA->cts_w(state); }
ctsb_w(int state)578 void ctsb_w(int state) { m_chanB->cts_w(state); }
dcda_w(int state)579 void dcda_w(int state) { m_chanA->dcd_w(state); }
dcdb_w(int state)580 void dcdb_w(int state) { m_chanB->dcd_w(state); }
ria_w(int state)581 void ria_w(int state) { m_chanA->ri_w(state); }
rib_w(int state)582 void rib_w(int state) { m_chanB->ri_w(state); }
583 #if 0
584 void rxca_w(int state) { m_chanA->rxc_w(state); }
585 void rxcb_w(int state) { m_chanB->rxc_w(state); }
586 void txca_w(int state) { m_chanA->txc_w(state); }
587 void txcb_w(int state) { m_chanB->txc_w(state); }
588 void rxtxcb_w(int state) { m_chanB->rxc_w(state); m_chanB->txc_w(state); }
589 #endif
synca_w(int state)590 void synca_w(int state) { m_chanA->sync_w(state); }
syncb_w(int state)591 void syncb_w(int state) { m_chanB->sync_w(state); }
592
593 protected:
594 duscc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant);
595
596 // device-level overrides
597 virtual void device_start() override;
598 virtual void device_reset() override;
599 virtual void device_add_mconfig(machine_config &config) override;
600
601 // internal interrupt management
602 void check_interrupts();
603 void reset_interrupts();
604 uint8_t modify_vector(uint8_t vect, int i, uint8_t src);
605 void trigger_interrupt(int index, int state);
get_channel_index(duscc_channel * ch)606 int get_channel_index(duscc_channel *ch) const { return (ch == m_chanA) ? 0 : 1; }
607
608 // Variants in the DUSCC family
609 enum
610 {
611 TYPE_DUSCC = 0x001,
612 TYPE_DUSCC26562 = 0x002,
613 TYPE_DUSCC26C562 = 0x004,
614 TYPE_DUSCC68562 = 0x008,
615 TYPE_DUSCC68C562 = 0x010,
616
617 SET_NMOS = TYPE_DUSCC26562 | TYPE_DUSCC68562,
618 SET_CMOS = TYPE_DUSCC26C562 | TYPE_DUSCC68C562
619 };
620
621 enum
622 {
623 CHANNEL_A = 0,
624 CHANNEL_B
625 };
626
627 required_device<duscc_channel> m_chanA;
628 required_device<duscc_channel> m_chanB;
629
630 // internal state
631 #if 0
632 int m_rxca;
633 int m_txca;
634 int m_rxcb;
635 int m_txcb;
636 #endif
637
638 devcb_write_line m_out_txda_cb;
639 devcb_write_line m_out_dtra_cb;
640 devcb_write_line m_out_rtsa_cb;
641 devcb_write_line m_out_synca_cb;
642 devcb_write_line m_out_rtxca_cb;
643 devcb_write_line m_out_trxca_cb;
644
645 devcb_write_line m_out_txdb_cb;
646 devcb_write_line m_out_dtrb_cb;
647 devcb_write_line m_out_rtsb_cb;
648 devcb_write_line m_out_syncb_cb;
649 devcb_write_line m_out_rtxcb_cb;
650 devcb_write_line m_out_trxcb_cb;
651
652 devcb_write_line m_out_int_cb;
653
654 int m_int_state[8]; // interrupt state
655
656 int m_variant;
657 uint8_t m_gsr;
658 uint8_t m_ivr;
659 uint8_t m_ivrm;
660 uint8_t m_icr;
661
662 enum
663 {
664 REG_ICR_CHB = 0x01,
665 REG_ICR_CHA = 0x02,
666 REG_ICR_VEC_MOD = 0x04,
667 REG_ICR_V2V4_MOD = 0x08,
668 REG_ICR_VEC_MODE_MASK = 0x30,
669 REG_ICR_VEC_MODE_NONE = 0x30,
670 REG_ICR_PRIO_MASK = 0xC0,
671 REG_ICR_PRIO_AHI = 0x00,
672 REG_ICR_PRIO_BHI = 0x40,
673 REG_ICR_PRIO_AINT = 0x80,
674 REG_ICR_PRIO_BINT = 0xC0,
675 };
676 };
677
678 // device type definition
DECLARE_DEVICE_TYPE(DUSCC,duscc_device)679 DECLARE_DEVICE_TYPE(DUSCC, duscc_device)
680 DECLARE_DEVICE_TYPE(DUSCC_CHANNEL, duscc_channel)
681 DECLARE_DEVICE_TYPE(DUSCC26562, duscc26562_device)
682 DECLARE_DEVICE_TYPE(DUSCC26C562, duscc26c562_device)
683 DECLARE_DEVICE_TYPE(DUSCC68562, duscc68562_device)
684 DECLARE_DEVICE_TYPE(DUSCC68C562, duscc68c562_device)
685
686 class duscc26562_device : public duscc_device
687 {
688 public :
689 duscc26562_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
690 };
691
692 class duscc26c562_device : public duscc_device
693 {
694 public :
695 duscc26c562_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
696 };
697
698 class duscc68562_device : public duscc_device
699 {
700 public :
701 duscc68562_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
702 };
703
704 class duscc68c562_device : public duscc_device
705 {
706 public :
707 duscc68c562_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
708 };
709
710 #endif // MAME_MACHINE_SCNXX562_H
711