//------------------------------------------------- // update_serial - //------------------------------------------------- void z80sio_channel::update_serial() { int data_bit_count = get_rx_word_length(); stop_bits_t stop_bits = get_stop_bits(); parity_t parity; LOG(("Z80SIO update_serial\n")); if (m_wr4 & WR4_PARITY_ENABLE) { if (m_wr4 & WR4_PARITY_EVEN) parity = PARITY_EVEN; else parity = PARITY_ODD; } else parity = PARITY_NONE; set_data_frame(1, data_bit_count, parity, stop_bits); int clocks = get_clock_mode(); if (m_rxc > 0) { set_rcv_rate(m_rxc / clocks); } if (m_txc > 0) { set_tra_rate(m_txc / clocks); } receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset }
void z80dart_channel::update_serial() { int data_bit_count = get_rx_word_length(); stop_bits_t stop_bits = get_stop_bits(); parity_t parity; if (m_wr[4] & WR4_PARITY_ENABLE) { if (m_wr[4] & WR4_PARITY_EVEN) parity = PARITY_EVEN; else parity = PARITY_ODD; } else parity = PARITY_NONE; set_data_frame(1, data_bit_count, parity, stop_bits); int clocks = get_clock_mode(); if (m_rxc > 0) { set_rcv_rate(m_rxc / clocks); } if (m_txc > 0) { set_tra_rate(m_txc / clocks); } }
void z80dart_channel::update_serial() { int clocks = get_clock_mode(); if (m_rxc > 0) { set_rcv_rate(m_rxc / clocks); } if (m_txc > 0) { set_tra_rate(m_txc / clocks); } int num_data_bits = get_rx_word_length(); int stop_bit_count = get_stop_bits(); int parity_code = SERIAL_PARITY_NONE; if (m_wr[1] & WR4_PARITY_ENABLE) { if (m_wr[1] & WR4_PARITY_EVEN) parity_code = SERIAL_PARITY_EVEN; else parity_code = SERIAL_PARITY_ODD; } set_data_frame(num_data_bits, stop_bit_count, parity_code); }
void z80dart_channel::update_serial() { int data_bit_count = get_rx_word_length(); stop_bits_t stop_bits = get_stop_bits(); parity_t parity; if (m_wr[4] & WR4_PARITY_ENABLE) { if (m_wr[4] & WR4_PARITY_EVEN) parity = PARITY_EVEN; else parity = PARITY_ODD; } else parity = PARITY_NONE; set_data_frame(1, data_bit_count, parity, stop_bits); int clocks = get_clock_mode(); if (m_rxc > 0) { set_rcv_rate(m_rxc / clocks); } if (m_txc > 0) { set_tra_rate(m_txc / clocks); } receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset (FIXME: doing this without checking is stupid) }
//TODO: implement sanity checks. hal_uart_port hal_uart_open(hal_uart_port port, hal_uart_baudrate baudrate, hal_uart_parity parity, hal_uart_stop_bits stop_bits, hal_uart_on_data_received_callback data_received){ on_data_received[port] = data_received; assert(port >= HAL_UART_PORT_1 && port <= HAL_UART_NUMBER_OF_PORTS ); /* Configure uart */ UART_MODULE uart = logic_uart2phy_uart(port); SetRxTxPins(uart); UARTConfigure(uart, UART_ENABLE_PINS_TX_RX_ONLY); UARTSetFifoMode(uart, UART_INTERRUPT_ON_TX_DONE | UART_INTERRUPT_ON_RX_NOT_EMPTY); UARTSetLineControl(uart, UART_DATA_SIZE_8_BITS | get_parity(parity) | get_stop_bits(stop_bits)); UARTSetDataRate(uart, PIC32_PERIPHERALBUS_FREQ, get_baudrate(baudrate)); UARTEnable(uart, UART_ENABLE_FLAGS(UART_PERIPHERAL | UART_TX | UART_RX)); INTClearFlag(INT_SOURCE_UART_RX(uart)); INTEnable(INT_SOURCE_UART_RX(uart),INT_ENABLED); return port; }
//------------------------------------------------- // update_serial - //------------------------------------------------- void z80sio_channel::update_serial() { int data_bit_count = get_rx_word_length(); stop_bits_t stop_bits = get_stop_bits(); parity_t parity; LOG("%s\n", FUNCNAME); if (m_wr4 & WR4_PARITY_ENABLE) { LOG("- Parity enabled\n"); if (m_wr4 & WR4_PARITY_EVEN) parity = PARITY_EVEN; else parity = PARITY_ODD; } else parity = PARITY_NONE; set_data_frame(1, data_bit_count, parity, stop_bits); int clocks = get_clock_mode(); if (m_rxc > 0) { LOG("- RxC:%d/%d = %d\n", m_rxc, clocks, m_rxc / clocks); set_rcv_rate(m_rxc / clocks); } if (m_txc > 0) { LOG("- TxC:%d/%d = %d\n", m_txc, clocks, m_txc / clocks); set_tra_rate(m_txc / clocks); } receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset }
void z80sio_channel::do_sioreg_wr4(uint8_t data) { m_wr4 = data; LOG("Z80SIO \"%s\" Channel %c : Parity Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0); LOG("Z80SIO \"%s\" Channel %c : Parity %s\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd"); LOG("Z80SIO \"%s\" Channel %c : Stop Bits %s\n", m_owner->tag(), 'A' + m_index, stop_bits_tostring(get_stop_bits())); LOG("Z80SIO \"%s\" Channel %c : Clock Mode %uX\n", m_owner->tag(), 'A' + m_index, get_clock_mode()); }
void z80dart_channel::control_write(UINT8 data) { int reg = m_wr[0] & WR0_REGISTER_MASK; LOG(("Z80DART \"%s\" Channel %c : Control Register Write '%02x'\n", m_owner->tag(), 'A' + m_index, data)); // write data to selected register if (reg < 6) m_wr[reg] = data; if (reg != 0) { // mask out register index m_wr[0] &= ~WR0_REGISTER_MASK; } switch (reg) { case 0: switch (data & WR0_COMMAND_MASK) { case WR0_NULL: LOG(("Z80DART \"%s\" Channel %c : Null\n", m_owner->tag(), 'A' + m_index)); break; case WR0_SEND_ABORT: LOG(("Z80DART \"%s\" Channel %c : Send Abort\n", m_owner->tag(), 'A' + m_index)); logerror("Z80DART \"%s\" Channel %c : unsupported command: Send Abort\n", m_owner->tag(), 'A' + m_index); break; case WR0_RESET_EXT_STATUS: // reset external/status interrupt m_rr[0] &= ~(RR0_DCD | RR0_RI | RR0_CTS | RR0_BREAK_ABORT); if (!m_dcd) m_rr[0] |= RR0_DCD; if (m_ri) m_rr[0] |= RR0_RI; if (m_cts) m_rr[0] |= RR0_CTS; m_rx_rr0_latch = 0; LOG(("Z80DART \"%s\" Channel %c : Reset External/Status Interrupt\n", m_owner->tag(), 'A' + m_index)); break; case WR0_CHANNEL_RESET: // channel reset LOG(("Z80DART \"%s\" Channel %c : Channel Reset\n", m_owner->tag(), 'A' + m_index)); device_reset(); break; case WR0_ENABLE_INT_NEXT_RX: // enable interrupt on next receive character LOG(("Z80DART \"%s\" Channel %c : Enable Interrupt on Next Received Character\n", m_owner->tag(), 'A' + m_index)); m_rx_first = 1; break; case WR0_RESET_TX_INT: // reset transmitter interrupt pending LOG(("Z80DART \"%s\" Channel %c : Reset Transmitter Interrupt Pending\n", m_owner->tag(), 'A' + m_index)); logerror("Z80DART \"%s\" Channel %c : unsupported command: Reset Transmitter Interrupt Pending\n", m_owner->tag(), 'A' + m_index); break; case WR0_ERROR_RESET: // error reset LOG(("Z80DART \"%s\" Channel %c : Error Reset\n", m_owner->tag(), 'A' + m_index)); m_rr[1] &= ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR); break; case WR0_RETURN_FROM_INT: // return from interrupt LOG(("Z80DART \"%s\" Channel %c : Return from Interrupt\n", m_owner->tag(), 'A' + m_index)); m_uart->z80daisy_irq_reti(); break; } break; case 1: LOG(("Z80DART \"%s\" Channel %c : External Interrupt Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_EXT_INT_ENABLE) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Transmit Interrupt Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_TX_INT_ENABLE) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Status Affects Vector %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_STATUS_VECTOR) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Wait/Ready Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR1_WRDY_ENABLE) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Wait/Ready Function %s\n", m_owner->tag(), 'A' + m_index, (data & WR1_WRDY_FUNCTION) ? "Ready" : "Wait")); LOG(("Z80DART \"%s\" Channel %c : Wait/Ready on %s\n", m_owner->tag(), 'A' + m_index, (data & WR1_WRDY_ON_RX_TX) ? "Receive" : "Transmit")); switch (data & WR1_RX_INT_MODE_MASK) { case WR1_RX_INT_DISABLE: LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt Disabled\n", m_owner->tag(), 'A' + m_index)); break; case WR1_RX_INT_FIRST: LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on First Character\n", m_owner->tag(), 'A' + m_index)); break; case WR1_RX_INT_ALL_PARITY: LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters, Parity Affects Vector\n", m_owner->tag(), 'A' + m_index)); break; case WR1_RX_INT_ALL: LOG(("Z80DART \"%s\" Channel %c : Receiver Interrupt on All Characters\n", m_owner->tag(), 'A' + m_index)); break; } m_uart->check_interrupts(); break; case 2: // interrupt vector if (m_index == z80dart_device::CHANNEL_B) m_rr[2] = ( m_rr[2] & 0x0e ) | ( m_wr[2] & 0xF1);; m_uart->check_interrupts(); LOG(("Z80DART \"%s\" Channel %c : Interrupt Vector %02x\n", m_owner->tag(), 'A' + m_index, data)); break; case 3: LOG(("Z80DART \"%s\" Channel %c : Receiver Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR3_RX_ENABLE) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Auto Enables %u\n", m_owner->tag(), 'A' + m_index, (data & WR3_AUTO_ENABLES) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Receiver Bits/Character %u\n", m_owner->tag(), 'A' + m_index, get_rx_word_length())); update_serial(); break; case 4: LOG(("Z80DART \"%s\" Channel %c : Parity Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Parity %s\n", m_owner->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd")); LOG(("Z80DART \"%s\" Channel %c : Stop Bits %s\n", m_owner->tag(), 'A' + m_index, stop_bits_tostring(get_stop_bits()))); LOG(("Z80DART \"%s\" Channel %c : Clock Mode %uX\n", m_owner->tag(), 'A' + m_index, get_clock_mode())); update_serial(); break; case 5: LOG(("Z80DART \"%s\" Channel %c : Transmitter Enable %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_TX_ENABLE) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Transmitter Bits/Character %u\n", m_owner->tag(), 'A' + m_index, get_tx_word_length())); LOG(("Z80DART \"%s\" Channel %c : Send Break %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_SEND_BREAK) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Request to Send %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_RTS) ? 1 : 0)); LOG(("Z80DART \"%s\" Channel %c : Data Terminal Ready %u\n", m_owner->tag(), 'A' + m_index, (data & WR5_DTR) ? 1 : 0)); update_serial(); if (data & WR5_RTS) { // when the RTS bit is set, the _RTS output goes low set_rts(0); m_rts = 1; } else { // when the RTS bit is reset, the _RTS output goes high after the transmitter empties m_rts = 0; } // data terminal ready output follows the state programmed into the DTR bit*/ set_dtr((data & WR5_DTR) ? 0 : 1); break; case 6: LOG(("Z80DART \"%s\" Channel %c : Transmit Sync %02x\n", m_owner->tag(), 'A' + m_index, data)); m_sync = (m_sync & 0xff00) | data; break; case 7: LOG(("Z80DART \"%s\" Channel %c : Receive Sync %02x\n", m_owner->tag(), 'A' + m_index, data)); m_sync = (data << 8) | (m_sync & 0xff); break; } }