From 2d318f541a7986fd980e7aa880ca75bfe492f8c3 Mon Sep 17 00:00:00 2001 From: Mark Garlanger Date: Sun, 29 Oct 2023 11:20:52 -0500 Subject: machine/ins8250.cpp: Implement transmit Break functionality. (#11665) --- src/devices/machine/ins8250.cpp | 36 ++++++++++++++++++++++++++++++++---- src/mame/heathkit/tlb.cpp | 2 -- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/devices/machine/ins8250.cpp b/src/devices/machine/ins8250.cpp index a967713bce9..c1b60c6b60a 100644 --- a/src/devices/machine/ins8250.cpp +++ b/src/devices/machine/ins8250.cpp @@ -179,7 +179,7 @@ static constexpr u8 INS8250_LCR_2STOP_BITS = 0x04; //static constexpr u8 INS8250_LCR_PEN = 0x08; //static constexpr u8 INS8250_LCR_EVEN_PAR = 0x10; //static constexpr u8 INS8250_LCR_PARITY = 0x20; -//static constexpr u8 INS8250_LCR_BREAK = 0x40; +static constexpr u8 INS8250_LCR_BREAK = 0x40; static constexpr u8 INS8250_LCR_DLAB = 0x80; /* ints will continue to be set for as long as there are ints pending */ @@ -299,9 +299,11 @@ void ins8250_uart_device::ins8250_w(offs_t offset, u8 data) set_fcr(data); break; case 3: + { + bool break_state_changed = bool((m_regs.lcr ^ data) & INS8250_LCR_BREAK); + m_regs.lcr = data; - { int data_bit_count = (m_regs.lcr & INS8250_LCR_BITCOUNT_MASK) + 5; parity_t parity; stop_bits_t stop_bits; @@ -336,6 +338,19 @@ void ins8250_uart_device::ins8250_w(offs_t offset, u8 data) else stop_bits = STOP_BITS_2; + if (break_state_changed) + { + int new_out_val = (m_regs.lcr & INS8250_LCR_BREAK) ? 0 : m_txd; + + if (m_regs.mcr & INS8250_MCR_LOOPBACK) + { + device_serial_interface::rx_w(new_out_val); + } + else + { + m_out_tx_cb(new_out_val); + } + } set_data_frame(1, data_bit_count, parity, stop_bits); } break; @@ -349,7 +364,10 @@ void ins8250_uart_device::ins8250_w(offs_t offset, u8 data) if (m_regs.mcr & INS8250_MCR_LOOPBACK) { m_out_tx_cb(1); - device_serial_interface::rx_w(m_txd); + if ((m_regs.lcr & INS8250_LCR_BREAK) == 0) + { + device_serial_interface::rx_w(m_txd); + } m_out_dtr_cb(1); m_out_rts_cb(1); m_out_out1_cb(1); @@ -357,7 +375,10 @@ void ins8250_uart_device::ins8250_w(offs_t offset, u8 data) } else { - m_out_tx_cb(m_txd); + if ((m_regs.lcr & INS8250_LCR_BREAK) == 0) + { + m_out_tx_cb(m_txd); + } device_serial_interface::rx_w(m_rxd); m_out_dtr_cb((m_regs.mcr & INS8250_MCR_DTR) ? 0 : 1); m_out_rts_cb((m_regs.mcr & INS8250_MCR_RTS) ? 0 : 1); @@ -568,6 +589,13 @@ void ins8250_uart_device::tra_complete() void ins8250_uart_device::tra_callback() { m_txd = transmit_register_get_data_bit(); + + if (m_regs.lcr & INS8250_LCR_BREAK) + { + // in break mode, don't change transmitted bit + return; + } + if (m_regs.mcr & INS8250_MCR_LOOPBACK) { device_serial_interface::rx_w(m_txd); diff --git a/src/mame/heathkit/tlb.cpp b/src/mame/heathkit/tlb.cpp index c049b3cf2cd..0736f533bbe 100644 --- a/src/mame/heathkit/tlb.cpp +++ b/src/mame/heathkit/tlb.cpp @@ -15,8 +15,6 @@ Input can also come from the serial port. TODO: - - INS8250 needs to implement "Set Break" (LCR, bit 6) before Break key - will function as expected. - 49/50 row mode does not work when DOT clocks are programmed as documented in the manual. It does work when DOT clock is fixed at the 20.282 MHz rate. -- cgit v1.2.3