trunk/src/emu/machine/6850acia.c
r22550 | r22551 | |
125 | 125 | save_item(NAME(m_rts)); |
126 | 126 | save_item(NAME(m_brk)); |
127 | 127 | save_item(NAME(m_status_read)); |
| 128 | save_item(NAME(m_dcd_triggered)); |
128 | 129 | } |
129 | 130 | |
130 | 131 | |
r22550 | r22551 | |
161 | 162 | |
162 | 163 | m_bits = 0; |
163 | 164 | m_tx_int = 0; |
| 165 | m_dcd_triggered = false; |
164 | 166 | |
165 | 167 | m_out_irq_func(CLEAR_LINE); |
166 | 168 | |
r22550 | r22551 | |
219 | 221 | |
220 | 222 | |
221 | 223 | //------------------------------------------------- |
| 224 | // Handle DCD input changes |
| 225 | //------------------------------------------------- |
| 226 | |
| 227 | void acia6850_device::check_dcd_input() |
| 228 | { |
| 229 | int dcd = m_in_dcd_func(); |
| 230 | |
| 231 | if (dcd) |
| 232 | { |
| 233 | // IRQ from DCD is edge triggered |
| 234 | if ( ! ( m_status & ACIA6850_STATUS_DCD ) ) |
| 235 | { |
| 236 | m_status |= ACIA6850_STATUS_DCD; |
| 237 | m_dcd_triggered = true; |
| 238 | |
| 239 | // Asserting DCD clears RDRF |
| 240 | m_status &= ~ACIA6850_STATUS_RDRF; |
| 241 | |
| 242 | check_interrupts(); |
| 243 | } |
| 244 | } |
| 245 | else if ((m_status & (ACIA6850_STATUS_DCD | ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD) |
| 246 | { |
| 247 | m_status &= ~ACIA6850_STATUS_DCD; |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | |
| 252 | //------------------------------------------------- |
222 | 253 | // control_write - Write Control Register |
223 | 254 | //------------------------------------------------- |
224 | 255 | |
r22550 | r22551 | |
318 | 349 | void acia6850_device::check_interrupts() |
319 | 350 | { |
320 | 351 | int irq = (m_tx_int && (m_status & ACIA6850_STATUS_TDRE) && (~m_status & ACIA6850_STATUS_CTS)) || |
321 | | ((m_ctrl & 0x80) && ((m_status & (ACIA6850_STATUS_RDRF|ACIA6850_STATUS_DCD)) || m_overrun)); |
| 352 | ((m_ctrl & 0x80) && (((m_status & ACIA6850_STATUS_RDRF) || m_dcd_triggered) || m_overrun)); |
322 | 353 | |
323 | 354 | if (irq != m_irq) |
324 | 355 | { |
r22550 | r22551 | |
335 | 366 | m_out_irq_func(CLEAR_LINE); |
336 | 367 | } |
337 | 368 | } |
| 369 | m_dcd_triggered = false; |
338 | 370 | } |
339 | 371 | |
340 | 372 | |
r22550 | r22551 | |
369 | 401 | |
370 | 402 | if (m_status_read) |
371 | 403 | { |
372 | | int dcd = m_in_dcd_func(); |
373 | | |
374 | 404 | m_status_read = 0; |
375 | | m_status &= ~(ACIA6850_STATUS_OVRN | ACIA6850_STATUS_DCD); |
376 | 405 | |
377 | | if (dcd) |
378 | | { |
379 | | m_status |= ACIA6850_STATUS_DCD; |
380 | | } |
| 406 | m_status &= ~ACIA6850_STATUS_OVRN; |
| 407 | |
| 408 | check_dcd_input(); |
381 | 409 | } |
382 | 410 | |
383 | 411 | if (m_overrun == 1) |
r22550 | r22551 | |
542 | 570 | |
543 | 571 | void acia6850_device::rx_tick() |
544 | 572 | { |
545 | | int dcd = m_in_dcd_func(); |
| 573 | check_dcd_input(); |
546 | 574 | |
547 | | if (dcd) |
548 | | { |
549 | | m_status |= ACIA6850_STATUS_DCD; |
550 | | check_interrupts(); |
551 | | } |
552 | | else if ((m_status & (ACIA6850_STATUS_DCD | ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD) |
553 | | { |
554 | | m_status &= ~ACIA6850_STATUS_DCD; |
555 | | } |
556 | | |
557 | 575 | if (m_status & ACIA6850_STATUS_DCD) |
558 | 576 | { |
559 | 577 | m_rx_state = START; |
r22550 | r22551 | |
687 | 705 | |
688 | 706 | void acia6850_device::rx_clock_in() |
689 | 707 | { |
690 | | int dcd = m_in_dcd_func(); |
| 708 | check_dcd_input(); |
691 | 709 | |
692 | | if (dcd) |
693 | | { |
694 | | m_status |= ACIA6850_STATUS_DCD; |
695 | | check_interrupts(); |
696 | | } |
697 | | else if ((m_status & (ACIA6850_STATUS_DCD|ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD) |
698 | | { |
699 | | m_status &= ~ACIA6850_STATUS_DCD; |
700 | | } |
701 | | |
702 | 710 | m_rx_counter ++; |
703 | 711 | |
704 | 712 | if ( m_rx_counter > m_divide - 1) |