1 // license:BSD-3-Clause
2 // copyright-holders:smf, Carl
3 /**********************************************************************
4
5 National Semiconductor 8250 UART interface and emulation
6
7 More information on the different models can be found in
8 section 1.6 at this location:
9 http://www.freebsd.org/doc/en_US.ISO8859-1/articles/serial-uart/
10
11 Model overview (from page above):
12
13 INS8250
14 This part was used in the original IBM PC and IBM PC/XT. The original name
15 for this part was the INS8250 ACE (Asynchronous Communications Element) and
16 it is made from NMOS technology.
17
18 The 8250 uses eight I/O ports and has a one-byte send and a one-byte receive
19 buffer. This original UART has several race conditions and other flaws. The
20 original IBM BIOS includes code to work around these flaws, but this made
21 the BIOS dependent on the flaws being present, so subsequent parts like the
22 8250A, 16450 or 16550 could not be used in the original IBM PC or IBM PC/XT.
23
24 The original 8250 pulses the interrupt line if a higher priority interrupt is
25 cleared but a lower priority one is still active. It also clears the tsre bit
26 for a moment before loading the tsr from the thr. These may be the bugs the
27 PC and XT depend on as the 8250A and up fix them.
28
29 INS8250-B
30 This is the slower speed of the INS8250 made from NMOS technology. It contains
31 the same problems as the original INS8250.
32
33 INS8250A
34 An improved version of the INS8250 using XMOS technology with various functional
35 flaws corrected. The INS8250A was used initially in PC clone computers by vendors
36 who used "clean" BIOS designs. Because of the corrections in the chip, this part
37 could not be used with a BIOS compatible with the INS8250 or INS8250B.
38
39 INS82C50A
40 This is a CMOS version (low power consumption) of the INS8250A and has similar
41 functional characteristics.
42
43 NS16450
44 Same as NS8250A with improvements so it can be used with faster CPU bus designs.
45 IBM used this part in the IBM AT and updated the IBM BIOS to no longer rely on
46 the bugs in the INS8250.
47
48 NS16C450
49 This is a CMOS version (low power consumption) of the NS16450.
50
51 NS16550
52 Same as NS16450 with a 16-byte send and receive buffer but the buffer design
53 was flawed and could not be reliably be used.
54
55 The 16550 sometimes will send more then one character over the bus from the fifo
56 when the rbr is read making the rx fifo useless. It's unlikely anything depends
57 on this behavior.
58
59 NS16550A
60 Same as NS16550 with the buffer flaws corrected. The 16550A and its successors
61 have become the most popular UART design in the PC industry, mainly due to
62 its ability to reliably handle higher data rates on operating systems with
63 sluggish interrupt response times.
64
65 NS16C552
66 This component consists of two NS16C550A CMOS UARTs in a single package.
67
68 PC16550D
69 Same as NS16550A with subtle flaws corrected. This is revision D of the
70 16550 family and is the latest design available from National Semiconductor.
71
72 Intel 82050
73 Essentially a NS16450 squeezed into a 28-pin package with some minor functions
74 eliminated. Can be strapped for either a 18.432 MHz XTAL (divided by 10 to
75 produce the BRG clock) or an externally generated 9.216 or 18.432 MHz clock.
76
77 Intel 82510
78 A functional expansion of the 82050 with dozens of extra registers. Adds 4-byte
79 Tx/Rx FIFOs with programmable thresholds, MCS-51 compatible 9-bit protocol,
80 ASCII/EBCDIC control character recognition, timed interrupts and more.
81
82
83 Known issues:
84 - MESS does currently not handle all these model specific features.
85
86
87 History:
88 KT - 14-Jun-2000 - Improved Interrupt setting/clearing
89 KT - moved into separate file so it can be used in Super I/O emulation and
90 any other system which uses a PC type COM port
91 KT - 24-Jun-2000 - removed pc specific input port tests. More compatible
92 with PCW16 and PCW16 doesn't requre the PC input port definitions
93 which are not required by the PCW16 hardware
94
95 **********************************************************************/
96
97 #include "emu.h"
98 #include "machine/ins8250.h"
99
100 #include <algorithm>
101
102 //#define VERBOSE 1
103 #include "logmacro.h"
104
105 DEFINE_DEVICE_TYPE(INS8250, ins8250_device, "ins8250", "National Semiconductor INS8250 UART")
106 DEFINE_DEVICE_TYPE(NS16450, ns16450_device, "ns16450", "National Semiconductor NS16450 UART")
107 DEFINE_DEVICE_TYPE(NS16550, ns16550_device, "ns16550", "National Semiconductor NS16550 UART")
108 DEFINE_DEVICE_TYPE(PC16552D, pc16552_device, "pc16552d", "National Semiconductor PC16552D UART")
109
ins8250_uart_device(const machine_config & mconfig,device_type type,const char * tag,device_t * owner,u32 clock,dev_type device_type)110 ins8250_uart_device::ins8250_uart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, dev_type device_type)
111 : device_t(mconfig, type, tag, owner, clock)
112 , device_serial_interface(mconfig, *this)
113 , m_device_type(device_type)
114 , m_out_tx_cb(*this)
115 , m_out_dtr_cb(*this)
116 , m_out_rts_cb(*this)
117 , m_out_int_cb(*this)
118 , m_out_out1_cb(*this)
119 , m_out_out2_cb(*this)
120 , m_rxd(1)
121 , m_dcd(1)
122 , m_dsr(1)
123 , m_ri(1)
124 , m_cts(1)
125 {
126 m_regs.ier = 0;
127 }
128
ins8250_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)129 ins8250_device::ins8250_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
130 : ins8250_uart_device(mconfig, INS8250, tag, owner, clock, dev_type::INS8250)
131 {
132 }
133
ns16450_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)134 ns16450_device::ns16450_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
135 : ins8250_uart_device(mconfig, NS16450, tag, owner, clock, dev_type::NS16450)
136 {
137 }
138
ns16550_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)139 ns16550_device::ns16550_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
140 : ins8250_uart_device(mconfig, NS16550, tag, owner, clock, dev_type::NS16550)
141 {
142 }
143
pc16552_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)144 pc16552_device::pc16552_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
145 : device_t(mconfig, PC16552D, tag, owner, clock)
146 {
147 }
148
device_start()149 void pc16552_device::device_start()
150 {
151 m_chan0 = subdevice<ns16550_device>("chan0");
152 m_chan1 = subdevice<ns16550_device>("chan1");
153 }
154
155 /* int's pending */
156 #define COM_INT_PENDING_RECEIVED_DATA_AVAILABLE 0x0001
157 #define COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY 0x0002
158 #define COM_INT_PENDING_RECEIVER_LINE_STATUS 0x0004
159 #define COM_INT_PENDING_MODEM_STATUS_REGISTER 0x0008
160 #define COM_INT_PENDING_CHAR_TIMEOUT 0x0011
161
162 static constexpr u8 INS8250_LSR_TSRE = 0x40;
163 static constexpr u8 INS8250_LSR_THRE = 0x20;
164 static constexpr u8 INS8250_LSR_BI = 0x10;
165 static constexpr u8 INS8250_LSR_FE = 0x08;
166 static constexpr u8 INS8250_LSR_PE = 0x04;
167 static constexpr u8 INS8250_LSR_OE = 0x02;
168 static constexpr u8 INS8250_LSR_DR = 0x01;
169
170 static constexpr u8 INS8250_MCR_DTR = 0x01;
171 static constexpr u8 INS8250_MCR_RTS = 0x02;
172 static constexpr u8 INS8250_MCR_OUT1 = 0x04;
173 static constexpr u8 INS8250_MCR_OUT2 = 0x08;
174 static constexpr u8 INS8250_MCR_LOOPBACK = 0x10;
175
176 static constexpr u8 INS8250_LCR_BITCOUNT_MASK= 0x03;
177 static constexpr u8 INS8250_LCR_2STOP_BITS = 0x04;
178 //static constexpr u8 INS8250_LCR_PEN = 0x08;
179 //static constexpr u8 INS8250_LCR_EVEN_PAR = 0x10;
180 //static constexpr u8 INS8250_LCR_PARITY = 0x20;
181 //static constexpr u8 INS8250_LCR_BREAK = 0x40;
182 static constexpr u8 INS8250_LCR_DLAB = 0x80;
183
184 /* ints will continue to be set for as long as there are ints pending */
update_interrupt()185 void ins8250_uart_device::update_interrupt()
186 {
187 int state;
188
189 /* if any bits are set and are enabled */
190 if (((m_int_pending & m_regs.ier) & 0x0f) != 0)
191 {
192 /* trigger next highest priority int */
193
194 /* set int */
195 state = 1;
196 m_regs.iir &= ~(0x08|0x04|0x02);
197
198 /* highest to lowest */
199 if (m_regs.ier & m_int_pending & COM_INT_PENDING_RECEIVER_LINE_STATUS)
200 m_regs.iir |=0x04|0x02;
201 else if (m_regs.ier & m_int_pending & COM_INT_PENDING_RECEIVED_DATA_AVAILABLE)
202 {
203 m_regs.iir |=0x04;
204 if ((m_int_pending & COM_INT_PENDING_CHAR_TIMEOUT) == 0x11)
205 m_regs.iir |= 0x08;
206 }
207 else if (m_regs.ier & m_int_pending & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY)
208 m_regs.iir |=0x02;
209
210 /* int pending */
211 m_regs.iir &= ~0x01;
212 }
213 else
214 {
215 /* clear int */
216 state = 0;
217
218 /* no ints pending */
219 m_regs.iir |= 0x01;
220 /* priority level */
221 m_regs.iir &= ~(0x08|0x04|0x02);
222 }
223
224 /* set or clear the int */
225 m_out_int_cb(state);
226 }
227
228 /* set pending bit and trigger int */
trigger_int(int flag)229 void ins8250_uart_device::trigger_int(int flag)
230 {
231 m_int_pending |= flag;
232 update_interrupt();
233 }
234
235 /* clear pending bit, if any ints are pending, then int will be triggered, otherwise it
236 will be cleared */
clear_int(int flag)237 void ins8250_uart_device::clear_int(int flag)
238 {
239 m_int_pending &= ~flag;
240 update_interrupt();
241 }
242
READ_LINE_MEMBER(ins8250_uart_device::intrpt_r)243 READ_LINE_MEMBER(ins8250_uart_device::intrpt_r)
244 {
245 return !BIT(m_regs.iir, 0);
246 }
247
248 // Baud rate generator is reset after writing to either byte of divisor latch
update_baud_rate()249 void ins8250_uart_device::update_baud_rate()
250 {
251 LOG("%.1f baud selected (divisor = %d)\n", double(clock()) / (m_regs.dl * 16), m_regs.dl);
252 set_rate(clock(), m_regs.dl * 16);
253
254 // FIXME: Baud rate generator should not affect transmitter or receiver, but device_serial_interface resets them regardless.
255 // If the transmitter is still running at this time and we don't flush it, the shift register will never be emptied!
256 if (!(m_regs.lsr & INS8250_LSR_TSRE))
257 tra_complete();
258 }
259
ins8250_w(offs_t offset,u8 data)260 void ins8250_uart_device::ins8250_w(offs_t offset, u8 data)
261 {
262 int tmp;
263
264 switch (offset)
265 {
266 case 0:
267 if (m_regs.lcr & INS8250_LCR_DLAB)
268 {
269 m_regs.dl = (m_regs.dl & 0xff00) | data;
270 update_baud_rate();
271 }
272 else
273 {
274 m_regs.thr = data;
275 m_regs.lsr &= ~INS8250_LSR_THRE;
276 if((m_device_type >= dev_type::NS16550) && (m_regs.fcr & 1))
277 push_tx(data);
278 clear_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
279 if(m_regs.lsr & INS8250_LSR_TSRE)
280 tra_complete();
281 }
282 break;
283 case 1:
284 if (m_regs.lcr & INS8250_LCR_DLAB)
285 {
286 m_regs.dl = (m_regs.dl & 0xff) | (data << 8);
287 update_baud_rate();
288 }
289 else
290 {
291 if ((m_regs.lsr & INS8250_LSR_THRE) && (data & COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY))
292 trigger_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
293 m_regs.ier = data;
294 update_interrupt();
295 }
296 break;
297 case 2:
298 set_fcr(data);
299 break;
300 case 3:
301 m_regs.lcr = data;
302
303 {
304 int data_bit_count = (m_regs.lcr & INS8250_LCR_BITCOUNT_MASK) + 5;
305 parity_t parity;
306 stop_bits_t stop_bits;
307
308 switch ((m_regs.lcr>>3) & 7)
309 {
310 case 1:
311 parity = PARITY_ODD;
312 break;
313
314 case 3:
315 parity = PARITY_EVEN;
316 break;
317
318 case 5:
319 parity = PARITY_MARK;
320 break;
321
322 case 7:
323 parity = PARITY_SPACE;
324 break;
325
326 default:
327 parity = PARITY_NONE;
328 break;
329 }
330
331 if (!(m_regs.lcr & INS8250_LCR_2STOP_BITS))
332 stop_bits = STOP_BITS_1;
333 else if (data_bit_count == 5)
334 stop_bits = STOP_BITS_1_5;
335 else
336 stop_bits = STOP_BITS_2;
337
338 set_data_frame(1, data_bit_count, parity, stop_bits);
339 }
340 break;
341 case 4:
342 if ( ( m_regs.mcr & 0x1f ) != ( data & 0x1f ) )
343 {
344 m_regs.mcr = data & 0x1f;
345
346 update_msr();
347
348 if (m_regs.mcr & INS8250_MCR_LOOPBACK)
349 {
350 m_out_tx_cb(1);
351 device_serial_interface::rx_w(m_txd);
352 m_out_dtr_cb(1);
353 m_out_rts_cb(1);
354 m_out_out1_cb(1);
355 m_out_out2_cb(1);
356 }
357 else
358 {
359 m_out_tx_cb(m_txd);
360 device_serial_interface::rx_w(m_rxd);
361 m_out_dtr_cb((m_regs.mcr & INS8250_MCR_DTR) ? 0 : 1);
362 m_out_rts_cb((m_regs.mcr & INS8250_MCR_RTS) ? 0 : 1);
363 m_out_out1_cb((m_regs.mcr & INS8250_MCR_OUT1) ? 0 : 1);
364 m_out_out2_cb((m_regs.mcr & INS8250_MCR_OUT2) ? 0 : 1);
365 }
366 }
367 break;
368 case 5:
369 /*
370 This register can be written, but if you write a 1 bit into any of
371 bits 5 - 0, you could cause an interrupt if the appropriate IER bit
372 is set.
373 */
374 m_regs.lsr = (m_regs.lsr & (INS8250_LSR_TSRE|INS8250_LSR_THRE)) | (data & ~(INS8250_LSR_TSRE|INS8250_LSR_THRE));
375
376 tmp = 0;
377 tmp |= ( m_regs.lsr & INS8250_LSR_DR ) ? COM_INT_PENDING_RECEIVED_DATA_AVAILABLE : 0;
378 tmp |= ( m_regs.lsr & 0x1e ) ? COM_INT_PENDING_RECEIVER_LINE_STATUS : 0;
379 tmp |= ( m_regs.lsr & INS8250_LSR_THRE ) ? COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY : 0;
380 trigger_int(tmp);
381
382 break;
383 case 6:
384 /*
385 This register can be written, but if you write a 1 bit into any of
386 bits 3 - 0, you could cause an interrupt if the appropriate IER bit
387 is set.
388 Bits 7 - 4 are read-only.
389 */
390 m_regs.msr = (m_regs.msr & 0xf0) | (data & 0x0f);
391
392 if ( m_regs.msr & 0x0f )
393 trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
394 else
395 clear_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
396 break;
397 case 7:
398 m_regs.scr = data;
399 break;
400 }
401 }
402
ins8250_r(offs_t offset)403 u8 ins8250_uart_device::ins8250_r(offs_t offset)
404 {
405 int data = 0x0ff;
406
407 switch (offset)
408 {
409 case 0:
410 if (m_regs.lcr & INS8250_LCR_DLAB)
411 data = (m_regs.dl & 0xff);
412 else
413 {
414 if (!machine().side_effects_disabled())
415 {
416 if ((m_device_type >= dev_type::NS16550) && (m_regs.fcr & 1))
417 m_regs.rbr = pop_rx();
418 else
419 {
420 clear_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
421 if (m_regs.lsr & INS8250_LSR_DR)
422 m_regs.lsr &= ~INS8250_LSR_DR;
423 }
424 }
425 data = m_regs.rbr;
426 }
427 break;
428 case 1:
429 if (m_regs.lcr & INS8250_LCR_DLAB)
430 data = (m_regs.dl >> 8);
431 else
432 data = m_regs.ier & 0x0f;
433 break;
434 case 2:
435 data = m_regs.iir;
436 /* The documentation says that reading this register will
437 clear the int if this is the source of the int */
438 if (!machine().side_effects_disabled())
439 {
440 if ((m_regs.iir & 0x0f) == 0x02)
441 clear_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
442 }
443 break;
444 case 3:
445 data = m_regs.lcr;
446 break;
447 case 4:
448 data = m_regs.mcr;
449 break;
450 case 5:
451 data = m_regs.lsr;
452 if (!machine().side_effects_disabled() && (m_regs.lsr & (INS8250_LSR_BI | INS8250_LSR_FE | INS8250_LSR_PE | INS8250_LSR_OE)) != 0)
453 {
454 m_regs.lsr &= 0xe1; /* clear FE, PE and OE and BREAK bits */
455
456 /* reading line status register clears int */
457 clear_int(COM_INT_PENDING_RECEIVER_LINE_STATUS);
458 }
459 break;
460 case 6:
461 data = m_regs.msr;
462 if (!machine().side_effects_disabled())
463 {
464 m_regs.msr &= 0xf0; /* reset delta values */
465
466 /* reading msr clears int */
467 clear_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
468 }
469 break;
470 case 7:
471 data = m_regs.scr;
472 break;
473 }
474 return data;
475 }
476
rcv_complete()477 void ns16550_device::rcv_complete()
478 {
479 if(!(m_regs.fcr & 1))
480 return ins8250_uart_device::rcv_complete();
481
482 receive_register_extract();
483
484 if(m_rnum == 16)
485 {
486 m_regs.lsr |= INS8250_LSR_OE; //overrun
487 trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS);
488 return;
489 }
490
491 u8 errors = 0;
492 if (is_receive_framing_error())
493 errors |= INS8250_LSR_FE;
494 if (is_receive_parity_error())
495 errors |= INS8250_LSR_PE;
496 if (m_rnum == 0 && errors != 0)
497 {
498 m_regs.lsr |= errors;
499 trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS);
500 }
501
502 m_regs.lsr |= INS8250_LSR_DR;
503 m_rfifo[m_rhead] = get_received_char();
504 m_efifo[m_rhead] = errors;
505 ++m_rhead &= 0x0f;
506 m_rnum++;
507 if(m_rnum >= m_rintlvl)
508 trigger_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
509 set_timer();
510 }
511
tra_complete()512 void ns16550_device::tra_complete()
513 {
514 if(!(m_regs.fcr & 1))
515 return ins8250_uart_device::tra_complete();
516
517 if(m_ttail != m_thead)
518 {
519 transmit_register_setup(m_tfifo[m_ttail]);
520 ++m_ttail &= 0x0f;
521 m_regs.lsr &= ~INS8250_LSR_TSRE;
522 if(m_ttail == m_thead)
523 {
524 m_regs.lsr |= INS8250_LSR_THRE;
525 trigger_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
526 }
527 }
528 else
529 m_regs.lsr |= 0x40;
530 }
531
rcv_complete()532 void ins8250_uart_device::rcv_complete()
533 {
534 // According to datasheet (and HP82939 self-test) the received character is always
535 // extracted and stored in RBR even in case of overrun
536 receive_register_extract();
537 if(m_regs.lsr & INS8250_LSR_DR)
538 {
539 m_regs.lsr |= INS8250_LSR_OE; //overrun
540 }
541 m_regs.lsr |= INS8250_LSR_DR;
542
543 if (is_receive_framing_error())
544 m_regs.lsr |= INS8250_LSR_FE;
545 if (is_receive_parity_error())
546 m_regs.lsr |= INS8250_LSR_PE;
547 if ((m_regs.lsr & (INS8250_LSR_BI | INS8250_LSR_PE | INS8250_LSR_FE | INS8250_LSR_OE)) != 0)
548 trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS);
549
550 m_regs.rbr = get_received_char();
551 trigger_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
552 }
553
tra_complete()554 void ins8250_uart_device::tra_complete()
555 {
556 if(!(m_regs.lsr & INS8250_LSR_THRE))
557 {
558 transmit_register_setup(m_regs.thr);
559 m_regs.lsr &= ~INS8250_LSR_TSRE;
560 m_regs.lsr |= INS8250_LSR_THRE;
561 trigger_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
562 }
563 else
564 m_regs.lsr |= INS8250_LSR_TSRE;
565 }
566
tra_callback()567 void ins8250_uart_device::tra_callback()
568 {
569 m_txd = transmit_register_get_data_bit();
570 if (m_regs.mcr & INS8250_MCR_LOOPBACK)
571 {
572 device_serial_interface::rx_w(m_txd);
573 }
574 else
575 {
576 m_out_tx_cb(m_txd);
577 }
578 }
579
update_msr()580 void ins8250_uart_device::update_msr()
581 {
582 u8 data;
583 int change;
584
585 if (m_regs.mcr & INS8250_MCR_LOOPBACK)
586 {
587 data = (((m_regs.mcr & (INS8250_MCR_OUT1|INS8250_MCR_OUT2)) << 4) | \
588 ((m_regs.mcr & INS8250_MCR_DTR) << 5) | ((m_regs.mcr & INS8250_MCR_RTS) << 3));
589 change = (m_regs.msr ^ data) >> 4;
590 if(!(m_regs.msr & 0x40) && (data & 0x40))
591 change &= ~4;
592 }
593 else
594 {
595 data = (!m_dcd << 7) | (!m_ri << 6) | (!m_dsr << 5) | (!m_cts << 4);
596 change = (m_regs.msr ^ data) >> 4;
597 }
598
599 m_regs.msr = data | change;
600
601 if(change)
602 trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER);
603 }
604
WRITE_LINE_MEMBER(ins8250_uart_device::dcd_w)605 WRITE_LINE_MEMBER(ins8250_uart_device::dcd_w)
606 {
607 m_dcd = state;
608 update_msr();
609 }
610
WRITE_LINE_MEMBER(ins8250_uart_device::dsr_w)611 WRITE_LINE_MEMBER(ins8250_uart_device::dsr_w)
612 {
613 m_dsr = state;
614 update_msr();
615 }
616
WRITE_LINE_MEMBER(ins8250_uart_device::ri_w)617 WRITE_LINE_MEMBER(ins8250_uart_device::ri_w)
618 {
619 m_ri = state;
620 update_msr();
621 }
622
WRITE_LINE_MEMBER(ins8250_uart_device::cts_w)623 WRITE_LINE_MEMBER(ins8250_uart_device::cts_w)
624 {
625 m_cts = state;
626 update_msr();
627 }
628
WRITE_LINE_MEMBER(ins8250_uart_device::rx_w)629 WRITE_LINE_MEMBER(ins8250_uart_device::rx_w)
630 {
631 m_rxd = state;
632
633 if (!(m_regs.mcr & INS8250_MCR_LOOPBACK))
634 device_serial_interface::rx_w(m_rxd);
635 }
636
device_start()637 void ins8250_uart_device::device_start()
638 {
639 m_out_tx_cb.resolve_safe();
640 m_out_dtr_cb.resolve_safe();
641 m_out_rts_cb.resolve_safe();
642 m_out_int_cb.resolve_safe();
643 m_out_out1_cb.resolve_safe();
644 m_out_out2_cb.resolve_safe();
645 set_tra_rate(0);
646 set_rcv_rate(0);
647
648 save_item(NAME(m_regs.thr));
649 save_item(NAME(m_regs.rbr));
650 save_item(NAME(m_regs.ier));
651 save_item(NAME(m_regs.dl));
652 save_item(NAME(m_regs.iir));
653 save_item(NAME(m_regs.fcr));
654 save_item(NAME(m_regs.lcr));
655 save_item(NAME(m_regs.mcr));
656 save_item(NAME(m_regs.lsr));
657 save_item(NAME(m_regs.msr));
658 save_item(NAME(m_regs.scr));
659 save_item(NAME(m_int_pending));
660 save_item(NAME(m_txd));
661 save_item(NAME(m_rxd));
662 save_item(NAME(m_dcd));
663 save_item(NAME(m_dsr));
664 save_item(NAME(m_ri));
665 save_item(NAME(m_cts));
666 }
667
device_reset()668 void ins8250_uart_device::device_reset()
669 {
670 m_regs.ier = 0;
671 m_regs.iir = 1;
672 m_regs.lcr = 0;
673 m_regs.mcr = 0;
674 m_regs.lsr = INS8250_LSR_THRE | INS8250_LSR_TSRE;
675 update_msr();
676 m_regs.msr &= 0xf0;
677 m_int_pending = 0;
678 update_interrupt();
679 receive_register_reset();
680 transmit_register_reset();
681 m_txd = 1;
682 m_out_tx_cb(1);
683 m_out_rts_cb(1);
684 m_out_dtr_cb(1);
685 m_out_out1_cb(1);
686 m_out_out2_cb(1);
687 }
688
device_start()689 void ns16550_device::device_start()
690 {
691 m_timeout = timer_alloc();
692 ins8250_uart_device::device_start();
693 save_item(NAME(m_rintlvl));
694 save_item(NAME(m_rfifo));
695 save_item(NAME(m_efifo));
696 save_item(NAME(m_tfifo));
697 save_item(NAME(m_rhead));
698 save_item(NAME(m_rtail));
699 save_item(NAME(m_rnum));
700 save_item(NAME(m_thead));
701 save_item(NAME(m_ttail));
702 }
703
device_reset()704 void ns16550_device::device_reset()
705 {
706 std::fill(std::begin(m_rfifo), std::end(m_rfifo), 0);
707 std::fill(std::begin(m_efifo), std::end(m_efifo), 0);
708 std::fill(std::begin(m_tfifo), std::end(m_tfifo), 0);
709 m_rhead = m_rtail = m_rnum = 0;
710 m_thead = m_ttail = 0;
711 m_timeout->adjust(attotime::never);
712 ins8250_uart_device::device_reset();
713 }
714
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)715 void ns16550_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
716 {
717 if(!id)
718 {
719 trigger_int(COM_INT_PENDING_CHAR_TIMEOUT);
720 m_timeout->adjust(attotime::never);
721 }
722 }
723
push_tx(u8 data)724 void ns16550_device::push_tx(u8 data)
725 {
726 m_tfifo[m_thead] = data;
727 ++m_thead &= 0x0f;
728 }
729
pop_rx()730 u8 ns16550_device::pop_rx()
731 {
732 u8 data = m_rfifo[m_rtail];
733 clear_int(COM_INT_PENDING_CHAR_TIMEOUT & ~1); // don't clear bit 1 yet
734
735 if(m_rnum)
736 {
737 ++m_rtail &= 0x0f;
738 m_rnum--;
739 if (m_rnum > 0 && m_efifo[m_rtail] != 0)
740 {
741 m_regs.lsr |= m_efifo[m_rtail];
742 trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS);
743 }
744 }
745 else
746 data = 0;
747
748 if(m_rnum < m_rintlvl)
749 clear_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
750
751 if(m_rnum)
752 set_timer();
753 else
754 {
755 m_timeout->adjust(attotime::never);
756 m_regs.lsr &= ~INS8250_LSR_DR;
757 }
758
759 return data;
760 }
761
set_fcr(u8 data)762 void ns16550_device::set_fcr(u8 data)
763 {
764 const int bytes_per_int[] = {1, 4, 8, 14};
765 if(!(data & 1))
766 {
767 m_regs.fcr = 0;
768 m_regs.iir &= ~0xc8;
769 return;
770 }
771 if(!(m_regs.fcr & 1) && (data & 1))
772 data |= 0x06;
773 if(data & 2)
774 {
775 std::fill(std::begin(m_rfifo), std::end(m_rfifo), 0);
776 std::fill(std::begin(m_efifo), std::end(m_efifo), 0);
777 m_rhead = m_rtail = m_rnum = 0;
778 clear_int(COM_INT_PENDING_CHAR_TIMEOUT | COM_INT_PENDING_RECEIVED_DATA_AVAILABLE);
779 m_timeout->adjust(attotime::never);
780 }
781 if(data & 4)
782 {
783 std::fill(std::begin(m_tfifo), std::end(m_tfifo), 0);
784 m_thead = m_ttail = 0;
785 m_regs.lsr |= INS8250_LSR_THRE;
786 trigger_int(COM_INT_PENDING_TRANSMITTER_HOLDING_REGISTER_EMPTY);
787 }
788 m_rintlvl = bytes_per_int[(data>>6)&3];
789 m_regs.iir |= 0xc0;
790 m_regs.fcr = data & 0xc9;
791 }
792