From a8d7ce5fc65038c628df7ca2146ee2223dca30ad Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 11 Mar 2018 22:07:55 -0400 Subject: [PATCH] ins8250: Add hack to reset transmitter when baud rate is changed (nw) This is needed to make the VT102 printer loopback test pass because ins8250_uart_device does not fully emulate the baud rate generator as the independent block it really is, but relies on the all-purpose, somewhat faulty device_serial_interface implementation. --- src/devices/machine/ins8250.cpp | 15 +++++++++++++-- src/devices/machine/ins8250.h | 2 ++ src/mame/drivers/vt100.cpp | 19 +++++++++++++++---- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/devices/machine/ins8250.cpp b/src/devices/machine/ins8250.cpp index 6a872cf9366..1aff3d30ed0 100644 --- a/src/devices/machine/ins8250.cpp +++ b/src/devices/machine/ins8250.cpp @@ -225,6 +225,17 @@ void ins8250_uart_device::clear_int(int flag) update_interrupt(); } +// Baud rate generator is reset after writing to either byte of divisor latch +void ins8250_uart_device::update_baud_rate() +{ + set_rate(clock(), m_regs.dl * 16); + + // FIXME: Baud rate generator should not affect transmitter or receiver, but device_serial_interface resets them regardless. + // If the transmitter is still running at this time and we don't flush it, the shift register will never be emptied! + if (!(m_regs.lsr & INS8250_LSR_TSRE)) + tra_complete(); +} + WRITE8_MEMBER( ins8250_uart_device::ins8250_w ) { int tmp; @@ -235,7 +246,7 @@ WRITE8_MEMBER( ins8250_uart_device::ins8250_w ) if (m_regs.lcr & INS8250_LCR_DLAB) { m_regs.dl = (m_regs.dl & 0xff00) | data; - set_rate(clock(), m_regs.dl*16); + update_baud_rate(); } else { @@ -252,7 +263,7 @@ WRITE8_MEMBER( ins8250_uart_device::ins8250_w ) if (m_regs.lcr & INS8250_LCR_DLAB) { m_regs.dl = (m_regs.dl & 0xff) | (data << 8); - set_rate(clock(), m_regs.dl*16); + update_baud_rate(); } else { diff --git a/src/devices/machine/ins8250.h b/src/devices/machine/ins8250.h index 997b7090654..fcd52f2ba89 100644 --- a/src/devices/machine/ins8250.h +++ b/src/devices/machine/ins8250.h @@ -59,6 +59,8 @@ protected: void trigger_int(int flag); void clear_int(int flag); + void update_baud_rate(); + const dev_type m_device_type; struct { uint8_t thr; /* 0 -W transmitter holding register */ diff --git a/src/mame/drivers/vt100.cpp b/src/mame/drivers/vt100.cpp index 9e11cb0f32f..968eddf86ee 100644 --- a/src/mame/drivers/vt100.cpp +++ b/src/mame/drivers/vt100.cpp @@ -53,7 +53,7 @@ public: m_nvr(*this, "nvr"), m_rstbuf(*this, "rstbuf"), m_rs232(*this, RS232_TAG), - m_printer_uart(*this, "printer_uart"), + m_printer_uart(*this, "printuart"), m_p_ram(*this, "p_ram") { } @@ -246,6 +246,17 @@ void vt100_state::machine_start() m_kbduart->write_swe(0); m_pusart->write_cts(0); + + if (m_printer_uart.found()) + { + auto *printer_port = subdevice("printer"); + printer_port->write_dtr(0); + printer_port->write_rts(0); + + m_printer_uart->cts_w(0); + m_printer_uart->dcd_w(0); + m_printer_uart->ri_w(0); + } } void vt100_state::machine_reset() @@ -422,13 +433,13 @@ MACHINE_CONFIG_START(vt100_state::vt102) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_IO_MAP(vt102_io) - MCFG_DEVICE_ADD("printer_uart", INS8250, XTAL(24'073'400) / 16) + MCFG_DEVICE_ADD("printuart", INS8250, XTAL(24'073'400) / 16) MCFG_INS8250_OUT_TX_CB(DEVWRITELINE("printer", rs232_port_device, write_txd)) MCFG_INS8250_OUT_INT_CB(INPUTLINE("maincpu", I8085_RST75_LINE)) // 8085 pin 7, mislabeled RST 5.5 on schematics MCFG_RS232_PORT_ADD("printer", default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("printer_uart", ins8250_device, rx_w)) - MCFG_RS232_DSR_HANDLER(DEVWRITELINE("printer_uart", ins8250_device, dsr_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("printuart", ins8250_device, rx_w)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("printuart", ins8250_device, dsr_w)) MACHINE_CONFIG_END /* VT1xx models: