diff options
author | Joakim Larsson Edström <joakimlarsson42@gmail.com> | 2019-11-15 10:41:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-15 10:41:46 +0100 |
commit | e94984babf59e3c8c30465227d4b7d7fc2478421 (patch) | |
tree | 76b6d85dec9ab6dc2570773aae14feb4f3f85d8c /src/devices/machine | |
parent | b3c47a4639b4669ae2e20d4fbdeccd1c960119d7 (diff) |
ins8250 support for BAUDOUT pin (#5858) and
* ins8250: improved support for BAUDOUT pin and added rclk_w to allow special receiver clock circuit required for descrete BRG of the epc driver
* epc: Added 8087 support
* epc: Added S21 jumper supporting secondary keyboard connector interface and completed the descrete BRG
Diffstat (limited to 'src/devices/machine')
-rw-r--r-- | src/devices/machine/ins8250.cpp | 43 | ||||
-rw-r--r-- | src/devices/machine/ins8250.h | 7 |
2 files changed, 44 insertions, 6 deletions
diff --git a/src/devices/machine/ins8250.cpp b/src/devices/machine/ins8250.cpp index ec5d8e041d7..25c80d0147d 100644 --- a/src/devices/machine/ins8250.cpp +++ b/src/devices/machine/ins8250.cpp @@ -100,6 +100,8 @@ History: #include <algorithm> //#define VERBOSE 1 +//#define LOG_OUTPUT_STREAM std::cout + #include "logmacro.h" DEFINE_DEVICE_TYPE(INS8250, ins8250_device, "ins8250", "National Semiconductor INS8250 UART") @@ -117,6 +119,9 @@ ins8250_uart_device::ins8250_uart_device(const machine_config &mconfig, device_t , m_out_int_cb(*this) , m_out_out1_cb(*this) , m_out_out2_cb(*this) + , m_out_baudout_cb(*this) + , m_brg_clock(true) + , m_txd(1) , m_rxd(1) , m_dcd(1) , m_dsr(1) @@ -245,16 +250,33 @@ READ_LINE_MEMBER(ins8250_uart_device::intrpt_r) return !BIT(m_regs.iir, 0); } +TIMER_CALLBACK_MEMBER(ins8250_uart_device::brg_clock) +{ + if (!is_transmit_register_empty()) + { + tx_clock_w(m_brg_clock); + } + if (is_receive_register_synchronized()) + { + if (m_out_baudout_cb.isnull()) + { + device_serial_interface::rx_clock_w(m_brg_clock); + } + else + { + m_out_baudout_cb(m_brg_clock); + } + } + m_brg_clock = !m_brg_clock; + m_brg->adjust(((clock() && (m_regs.dl) ? (attotime::from_hz(clock()) * m_regs.dl * 16) : attotime::never) / 2)); +} + // Baud rate generator is reset after writing to either byte of divisor latch void ins8250_uart_device::update_baud_rate() { LOG("%.1f baud selected (divisor = %d)\n", double(clock()) / (m_regs.dl * 16), m_regs.dl); - 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(); + m_brg->adjust(((clock() && (m_regs.dl) ? (attotime::from_hz(clock()) * m_regs.dl * 16) : attotime::never) / 2)); } void ins8250_uart_device::ins8250_w(offs_t offset, u8 data) @@ -604,6 +626,11 @@ void ins8250_uart_device::update_msr() trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER); } +WRITE_LINE_MEMBER(ins8250_uart_device::rclk_w) +{ + device_serial_interface::rx_clock_w(state); +} + WRITE_LINE_MEMBER(ins8250_uart_device::dcd_w) { m_dcd = state; @@ -644,9 +671,10 @@ void ins8250_uart_device::device_start() m_out_int_cb.resolve_safe(); m_out_out1_cb.resolve_safe(); m_out_out2_cb.resolve_safe(); + m_out_baudout_cb.resolve_safe(); set_tra_rate(0); set_rcv_rate(0); - + m_brg = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ins8250_uart_device::brg_clock), this)); save_item(NAME(m_regs.thr)); save_item(NAME(m_regs.rbr)); save_item(NAME(m_regs.ier)); @@ -659,6 +687,7 @@ void ins8250_uart_device::device_start() save_item(NAME(m_regs.msr)); save_item(NAME(m_regs.scr)); save_item(NAME(m_int_pending)); + save_item(NAME(m_brg_clock)); save_item(NAME(m_txd)); save_item(NAME(m_rxd)); save_item(NAME(m_dcd)); @@ -680,12 +709,14 @@ void ins8250_uart_device::device_reset() update_interrupt(); receive_register_reset(); transmit_register_reset(); + m_brg_clock = true; m_txd = 1; m_out_tx_cb(1); m_out_rts_cb(1); m_out_dtr_cb(1); m_out_out1_cb(1); m_out_out2_cb(1); + m_out_baudout_cb(1); } void ns16550_device::device_start() diff --git a/src/devices/machine/ins8250.h b/src/devices/machine/ins8250.h index 5f9a6bd1793..2ad59e05389 100644 --- a/src/devices/machine/ins8250.h +++ b/src/devices/machine/ins8250.h @@ -26,10 +26,12 @@ public: auto out_int_callback() { return m_out_int_cb.bind(); } auto out_out1_callback() { return m_out_out1_cb.bind(); } auto out_out2_callback() { return m_out_out2_cb.bind(); } + auto out_baudout_callback() { return m_out_baudout_cb.bind(); } void ins8250_w(offs_t offset, u8 data); u8 ins8250_r(offs_t offset); + DECLARE_WRITE_LINE_MEMBER(rclk_w); DECLARE_WRITE_LINE_MEMBER(dcd_w); DECLARE_WRITE_LINE_MEMBER(dsr_w); DECLARE_WRITE_LINE_MEMBER(ri_w); @@ -86,6 +88,11 @@ private: devcb_write_line m_out_int_cb; devcb_write_line m_out_out1_cb; devcb_write_line m_out_out2_cb; + devcb_write_line m_out_baudout_cb; + + emu_timer *m_brg; + TIMER_CALLBACK_MEMBER(brg_clock); + bool m_brg_clock; void update_interrupt(); void update_msr(); |