void tms9902_device::initiate_transmit() { if (m_BRKON && m_CTSin) /* enter break mode */ send_break(true); else { if (!m_RTSON && (!m_CTSin || (m_XBRE && !m_BRKout))) /* clear RTS output */ set_rts(CLEAR_LINE); else { if (VERBOSE>5) LOG("TMS9902: transferring XBR to XSR; XSRE=false, XBRE=true\n"); m_XSR = m_XBR; m_XSRE = false; m_XBRE = true; field_interrupts(); if (VERBOSE>4) LOG("TMS9902: transmit XSR=%02x, RCL=%02x\n", m_XSR, m_RCL); xmit_callback(0, m_XSR & (0xff >> (3-m_RCL))); // Should store that somewhere (but the CPU is fast enough, can afford to recalc :-) ) double fint = m_clock_rate / ((m_CLK4M) ? 4.0 : 3.0); double baud = fint / (2.0 * ((m_RDV8)? 8:1) * m_RDR); // Time for transmitting 10 bit (8 bit + start + stop) m_sendtimer->adjust(attotime::from_hz(baud/10.0)); } } }
void tms5501_device::timer_decrementer(UINT8 mask) { if ((mask != TMS5501_TIMER_4_INT) || ((mask == TMS5501_TIMER_4_INT) && (!(m_command & TMS5501_INT_7_SELECT)))) m_pending_interrupts |= mask; field_interrupts(); }
void tms9902_device::reset_uart() { logerror("resetting UART\n"); /* disable all interrupts */ m_DSCENB = false; // Data Set Change Interrupt Enable m_TIMENB = false; // Timer Interrupt Enable m_XBIENB = false; // Transmit Buffer Interrupt Enable m_RIENB = false; // Read Buffer Interrupt Enable /* initialize transmitter */ m_XBRE = true; // Transmit Buffer Register Empty m_XSRE = true; // Transmit Shift Register Empty /* initialize receiver */ m_RBRL = false; // Read Buffer Register Loaded /* clear RTS */ m_RTSON = false; // Request-to-send on (flag) m_RTSout = true; // Note we are doing this to ensure the state is sent to the interface set_rts(CLEAR_LINE); m_RTSout = false; // what we actually want /* set all register load flags to 1 */ m_LDCTRL = true; m_LDIR = true; m_LRDR = true; m_LXDR = true; /* clear break condition */ m_BRKON = false; m_BRKout = false; m_DSCH = false; m_TIMELP = false; // m_CTSin = false; // not a good idea - this is the latch of an incoming line m_TMR = 0; m_STOPB = 0; m_RCL = 0; m_XDR = 0; m_RDR = 0; m_RBR = 0; m_XBR = 0; m_XSR = 0; // m_INT will be cleared in field_interrupts; setting to true is required // to trigger the INT line update m_INT = true; field_interrupts(); }
void tms9902_device::reset_uart() { if (VERBOSE>1) LOG("TMS9902: resetting\n"); /* disable all interrupts */ m_DSCENB = false; // Data Set Change Interrupt Enable m_TIMENB = false; // Timer Interrupt Enable m_XBIENB = false; // Transmit Buffer Interrupt Enable m_RIENB = false; // Read Buffer Interrupt Enable /* initialize transmitter */ m_XBRE = true; // Transmit Buffer Register Empty m_XSRE = true; // Transmit Shift Register Empty /* initialize receiver */ m_RBRL = false; // Read Buffer Register Loaded /* clear RTS */ m_RTSON = false; // Request-to-send on (flag) m_RTSout = true; // Note we are doing this to ensure the state is sent to the interface set_rts(CLEAR_LINE); m_RTSout = false; // what we actually want /* set all register load flags to 1 */ m_LDCTRL = true; m_LDIR = true; m_LRDR = true; m_LXDR = true; /* clear break condition */ m_BRKON = false; m_BRKout = false; m_DSCH = false; m_TIMELP = false; m_INT = false; m_CTSin = false; m_TMR = 0; m_STOPB = 0; m_RCL = 0; m_XDR = 0; m_RDR = 0; m_RBR = 0; m_XBR = 0; m_XSR = 0; // m_INT will be cleared in field_interrupts field_interrupts(); }
/* Called whenever the incoming DSR* line changes. This should be called by the device that contains the UART. */ void tms9902_device::rcv_dsr(line_state state) { bool previous = m_DSRin; if (VERBOSE>3) LOG("TMS9902: DSR* = %s\n", (state==ASSERT_LINE)? "asserted" : "cleared"); m_DSRin = (state==ASSERT_LINE); if (m_DSRin != previous) { m_DSCH = true; field_interrupts(); } else { m_DSCH = false; if (VERBOSE>4) LOG("TMS9902: no change in DSR line, no interrupt."); } }
/* Called whenever the incoming DSR* line changes. This should be called by the device that contains the UART. */ void tms9902_device::rcv_dsr(line_state state) { bool previous = m_DSRin; if (TRACE_LINES) logerror("DSR* = %s\n", (state==ASSERT_LINE)? "asserted" : "cleared"); m_DSRin = (state==ASSERT_LINE); if (m_DSRin != previous) { m_DSCH = true; field_interrupts(); } else { m_DSCH = false; if (TRACE_LINES) logerror("no change in DSR line, no interrupt.\n"); } }
/* Called whenever the incoming CTS* line changes. This should be called by the device that contains the UART. */ void tms9902_device::rcv_cts(line_state state) { bool previous = m_CTSin; // CTSin is an internal register of the TMS9902 with positive logic m_CTSin = (state==ASSERT_LINE); if (VERBOSE>3) LOG("TMS9902: CTS* = %s\n", (state==ASSERT_LINE)? "asserted" : "cleared"); if (m_CTSin != previous) { m_DSCH = true; field_interrupts(); // If CTS becomes asserted and we have been sending if (state==ASSERT_LINE && m_RTSout) { // and if the byte buffer is empty if (m_XBRE) { // and we want to have a BRK, send it if (m_BRKON) send_break(true); } else { // Buffer is not empty, we can send it // If the shift register is empty, transfer the data if (m_XSRE && !m_BRKout) { initiate_transmit(); } } } } else { m_DSCH = false; if (VERBOSE>4) LOG("TMS9902: no change in CTS line, no interrupt."); } }
/* Called whenever the incoming RIN line changes. This should be called by the device that contains the UART. Unlike the real thing, we deliver complete bytes in one go. */ void tms9902_device::rcv_data(UINT8 data) { // Put the received byte into the 1-byte receive buffer m_RBR = data; // Clear last errors m_RFER = false; m_RPER = false; if (!m_RBRL) { // Receive buffer was empty m_RBRL = true; m_ROVER = false; if (VERBOSE>3) LOG("TMS9902: Receive buffer loaded with byte %02x\n", data); field_interrupts(); } else { // Receive buffer was full m_ROVER = true; if (VERBOSE>1) LOG("TMS9902: Receive buffer still loaded; overflow error\n"); } }
/* Called whenever the incoming RIN line changes. This should be called by the device that contains the UART. Unlike the real thing, we deliver complete bytes in one go. */ void tms9902_device::rcv_data(UINT8 data) { // Put the received byte into the 1-byte receive buffer m_RBR = data; // Clear last errors m_RFER = false; m_RPER = false; if (!m_RBRL) { // Receive buffer was empty m_RBRL = true; m_ROVER = false; if (TRACE_BUFFER) logerror("Receive buffer loaded with byte %02x; RIENB=%d\n", data, m_RIENB); field_interrupts(); } else { // Receive buffer was full m_ROVER = true; if (TRACE_ERROR) logerror("Receive buffer still loaded; overflow error\n"); } }