void acia6850_device::device_reset() { int cts = m_in_cts_func(); int dcd = m_in_dcd_func(); m_status = (cts << 3) | (dcd << 2) | ACIA6850_STATUS_TDRE; m_tdr = 0; m_rdr = 0; m_tx_shift = 0; m_rx_shift = 0; m_tx_counter = 0; m_rx_counter = 0; TXD(1); m_overrun = 0; m_status_read = 0; m_brk = 0; m_rx_state = START; m_tx_state = START; m_irq = 0; m_out_irq_func(1); if (m_first_reset) { m_first_reset = 0; RTS(1); } else { RTS(m_rts); } }
void acia6850_device::rx_clock_in() { int dcd = m_in_dcd_func(); if (dcd) { m_status |= ACIA6850_STATUS_DCD; check_interrupts(); } else if ((m_status & (ACIA6850_STATUS_DCD|ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD) { m_status &= ~ACIA6850_STATUS_DCD; } m_rx_counter ++; if ( m_rx_counter > m_divide - 1) { rx_tick(); m_rx_counter = 0; } }
void acia6850_device::check_dcd_input() { int dcd = m_in_dcd_func(); if (dcd) { // IRQ from DCD is edge triggered if ( ! ( m_status & ACIA6850_STATUS_DCD ) ) { m_status |= ACIA6850_STATUS_DCD; m_dcd_triggered = true; // Asserting DCD clears RDRF m_status &= ~ACIA6850_STATUS_RDRF; check_interrupts(); } } else if ((m_status & (ACIA6850_STATUS_DCD | ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD) { m_status &= ~ACIA6850_STATUS_DCD; } }
void acia6850_device::rx_tick() { int dcd = m_in_dcd_func(); if (dcd) { m_status |= ACIA6850_STATUS_DCD; check_interrupts(); } else if ((m_status & (ACIA6850_STATUS_DCD | ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD) { m_status &= ~ACIA6850_STATUS_DCD; } if (m_status & ACIA6850_STATUS_DCD) { m_rx_state = START; } else { int rxd = m_in_rx_func(); switch (m_rx_state) { case START: { if (rxd == 0) { if (LOG) logerror("MC6850 '%s': RX START BIT\n", tag()); m_rx_shift = 0; m_rx_parity = 0; m_rx_bits = m_bits; m_rx_state = DATA; } break; } case DATA: { if (LOG) logerror("MC6850 '%s': RX DATA BIT %x\n", tag(), rxd); m_rx_shift |= rxd ? 0x80 : 0; m_rx_parity ^= rxd; if (--m_rx_bits == 0) { if (m_status & ACIA6850_STATUS_RDRF) { m_overrun = 1; check_interrupts(); } m_rx_state = m_parity == NONE ? STOP : PARITY; } else { m_rx_shift >>= 1; } break; } case PARITY: { if (LOG) logerror("MC6850 '%s': RX PARITY BIT %x\n", tag(), rxd); m_rx_parity ^= rxd; if (m_parity == EVEN) { if (m_rx_parity) { m_status |= ACIA6850_STATUS_PE; } } else { if (!m_rx_parity) { m_status |= ACIA6850_STATUS_PE; } } m_rx_state = STOP; break; } case STOP: { if (rxd == 1) { if (LOG) logerror("MC6850 '%s': RX STOP BIT\n", tag()); if (m_stopbits == 1) { m_status &= ~ACIA6850_STATUS_FE; if (!(m_status & ACIA6850_STATUS_RDRF)) { if (LOG) logerror("MC6850 '%s': RX DATA %x\n", tag(), m_rx_shift); m_rdr = m_rx_shift; m_status |= ACIA6850_STATUS_RDRF; check_interrupts(); } m_rx_state = START; } else { m_rx_state = STOP2; } } else { m_status |= ACIA6850_STATUS_FE; m_rx_state = START; } break; } case STOP2: { if (rxd == 1) { if (LOG) logerror("MC6850 '%s': RX STOP BIT\n", tag()); m_status &= ~ACIA6850_STATUS_FE; if (!(m_status & ACIA6850_STATUS_RDRF)) { if (LOG) logerror("MC6850 '%s': RX DATA %x\n", tag(), m_rx_shift); m_rdr = m_rx_shift; m_status |= ACIA6850_STATUS_RDRF; check_interrupts(); } m_rx_state = START; } else { m_status |= ACIA6850_STATUS_FE; m_rx_state = START; } break; } } } }