diff options
author | 2022-07-07 01:40:34 -0700 | |
---|---|---|
committer | 2022-07-07 18:40:34 +1000 | |
commit | f079cbf8dc162dcf7a2ddb79baae8a65e12933b6 (patch) | |
tree | 935f006297659a9bb56744c2bb80b6b253aafabf /src | |
parent | 55f6fc8843794c0eaa5314d73c8581053755a03b (diff) |
machine/z80scc.cpp: Implemented /W//REQ and /DTR//REQ DMA request features. (#9952)
Adds support for using /W//REQ as the RX DMA pin, as well as the /DTR//REQ pin as the TX DMA pin, allowing software that uses both directions simultaneously to function.
Diffstat (limited to 'src')
-rw-r--r-- | src/devices/machine/z80scc.cpp | 55 | ||||
-rw-r--r-- | src/devices/machine/z80scc.h | 2 |
2 files changed, 36 insertions, 21 deletions
diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index 746bc7ee757..848f95c8c23 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -1260,7 +1260,7 @@ void z80scc_channel::tra_complete() set_rts(1); } - check_waitrequest(); + check_dma_request(); if (m_wr1 & WR1_TX_INT_ENABLE && m_tx_int_disarm == 0) { @@ -1380,8 +1380,12 @@ void z80scc_channel::update_rts() set_rts(!m_rts); } - // data terminal ready output follows the state programmed into the DTR bit*/ - set_dtr((m_wr5 & WR5_DTR) ? 0 : 1); + // data terminal ready output follows the state programmed into the DTR bit + // unless configured to use the DTR pin as the transmit REQ pin for DMA + if (!(m_wr14 & WR14_DTR_REQ_FUNC)) + { + set_dtr((m_wr5 & WR5_DTR) ? 0 : 1); + } } //------------------------------------------------- @@ -1893,7 +1897,7 @@ void z80scc_channel::do_sccreg_wr1(uint8_t data) LOG("- Wait/DMA Request Function %s\n", (data & WR1_WREQ_FUNCTION) ? "Request" : "Wait"); LOG("- Wait/DMA Request on %s\n", (data & WR1_WREQ_ON_RX_TX) ? "Receive" : "Transmit"); - check_waitrequest(); + check_dma_request(); switch (data & WR1_RX_INT_MODE_MASK) { @@ -1997,7 +2001,7 @@ void z80scc_channel::do_sccreg_wr5(uint8_t data) safe_transmit_register_reset(); update_rts(); // Will also update DTR accordingly - check_waitrequest(); + check_dma_request(); } } @@ -2417,6 +2421,8 @@ uint8_t z80scc_channel::data_read() m_uart->check_interrupts(); } } + + check_dma_request(); } else { @@ -2515,7 +2521,7 @@ void z80scc_channel::data_write(uint8_t data) } } - check_waitrequest(); + check_dma_request(); /* Transmitter enabled? */ if (m_wr5 & WR5_TX_ENABLE) @@ -2594,6 +2600,7 @@ void z80scc_channel::receive_data(uint8_t data) } m_rr0 |= RR0_RX_CHAR_AVAILABLE; + check_dma_request(); // receive interrupt on FIRST and ALL character switch (m_wr1 & WR1_RX_INT_MODE_MASK) @@ -2960,28 +2967,36 @@ void z80scc_channel::write_rx(int state) } /* - * This is a partial implementation of the "wait/dma request" functionality of the SCC controlled by + * This is a partial implementation of the "wait/dma request" and "dtr request" DMA functionality of the SCC controlled by * bits D7, D6 and D5 in WR1. This implementation is sufficient to support DMA request on transmit - * used by the InterPro driver. + * used by the InterPro driver and DMA request on receive by the NWS-5000X driver. * * TODO: * - wait function (D6=0) * - wait/request function on receive (D5=1) + * - Synchronous mode timing differences + * - Configuration of WREQ and DTR/REQ timing (see datasheet) + * - Interaction with locked fifo on error condition */ -void z80scc_channel::check_waitrequest() +void z80scc_channel::check_dma_request() { - // don't do anything if wait/request function is not enabled - if ((m_wr1 & WR1_WREQ_ENABLE) == 0) - return; - - // wait/request function for receive not implemented - if (m_wr1 & WR1_WREQ_ON_RX_TX) - return; + if (m_wr14 & WR14_DTR_REQ_FUNC) + { + // assert /DTR//REQ if transmit buffer is empty + set_dtr((m_rr0 & RR0_TX_BUFFER_EMPTY) ? 0 : 1); + } - // if dma request function is enabled - if (m_wr1 & WR1_WREQ_FUNCTION) + if ((m_wr1 & WR1_WREQ_ENABLE) && (m_wr1 & WR1_WREQ_FUNCTION)) { - // assert /W//REQ if transmit buffer is empty and transmitter is enabled - m_uart->m_out_wreq_cb[m_index](((m_rr0 & RR0_TX_BUFFER_EMPTY) && (m_wr5 & WR5_TX_ENABLE)) ? 0 : 1); + if (m_wr1 & WR1_WREQ_ON_RX_TX) + { + // assert /W//REQ if receive buffer has a character avaliable + m_uart->m_out_wreq_cb[m_index]((m_rr0 & RR0_RX_CHAR_AVAILABLE) ? 0 : 1); + } + else + { + // assert /W//REQ if transmit buffer is empty and transmitter is enabled + m_uart->m_out_wreq_cb[m_index](((m_rr0 & RR0_TX_BUFFER_EMPTY) && (m_wr5 & WR5_TX_ENABLE)) ? 0 : 1); + } } } diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h index a993d831ce0..4ef274aba92 100644 --- a/src/devices/machine/z80scc.h +++ b/src/devices/machine/z80scc.h @@ -251,7 +251,7 @@ protected: int get_rx_word_length(); int get_tx_word_length(); void safe_transmit_register_reset(); - void check_waitrequest(); + void check_dma_request(); // receiver state uint8_t m_rx_data_fifo[8]; // receive data FIFO |