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) |