mirror of
https://github.com/holub/mame
synced 2025-10-06 09:00:04 +03:00
WIP: Intergraph driver support: Enabled more Rx interrupts and fixed error fifo
This commit is contained in:
parent
7d401c1ad9
commit
86ca7dcf60
@ -81,14 +81,15 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC
|
||||
#define VERBOSE 0
|
||||
#define LOGPRINT(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
#define LOG(x) {} LOGPRINT(x)
|
||||
#define LOGR(x) {} LOGPRINT(x)
|
||||
#define LOGR(x) {}
|
||||
#define LOGSETUP(x) {} LOGPRINT(x)
|
||||
#define LOGINT(x) {} LOGPRINT(x)
|
||||
#define LOGTX(x) {} LOGPRINT(x)
|
||||
#define LOGRCV(x) {} LOGPRINT(x)
|
||||
#define LOGCTS(x) {} LOGPRINT(x)
|
||||
#define LOGDCD(x) {} LOGPRINT(x)
|
||||
#define LOGSYNC(x) {} LOGPRINT(x)
|
||||
#define LOGINT(x) {}
|
||||
#define LOGCMD(x) {}
|
||||
#define LOGTX(x) {}
|
||||
#define LOGRCV(x) {}
|
||||
#define LOGCTS(x) {}
|
||||
#define LOGDCD(x) {}
|
||||
#define LOGSYNC(x) {}
|
||||
#if VERBOSE == 2
|
||||
#define logerror printf
|
||||
#endif
|
||||
@ -1321,7 +1322,7 @@ uint8_t z80scc_channel::do_sccreg_rr0()
|
||||
{
|
||||
uint8_t rr0 = m_rr0;
|
||||
|
||||
LOGINT(("%s %c %s <- %02x\n",tag(), 'A' + m_index, FUNCNAME, m_rr0));
|
||||
LOG(("%s %c %s <- %02x\n",tag(), 'A' + m_index, FUNCNAME, m_rr0));
|
||||
if (m_extint_latch == 1)
|
||||
{
|
||||
rr0 &= ((~m_wr15) | WR15_WR7PRIME | WR15_STATUS_FIFO); // clear enabled bits, saving 2 unrelated bits
|
||||
@ -1330,7 +1331,7 @@ uint8_t z80scc_channel::do_sccreg_rr0()
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGINT(("- %c returning unlatched value: %02x\n", 'A' + m_index, rr0));
|
||||
LOG(("- %c returning unlatched value: %02x\n", 'A' + m_index, rr0));
|
||||
}
|
||||
|
||||
return rr0;
|
||||
@ -1626,30 +1627,6 @@ uint8_t z80scc_channel::control_read()
|
||||
return data;
|
||||
}
|
||||
|
||||
/* CRC Initialization Code handling - candidate for breaking out in a z80sio_base class
|
||||
Handle the WR0 CRC Reset/Init bits separatelly, needed by derived devices separatelly from the commands */
|
||||
void z80scc_channel::do_sccreg_wr0_resets(uint8_t data)
|
||||
{
|
||||
LOG(("%s(%02x) %s",FUNCNAME, data, tag()));
|
||||
switch (data & WR0_CRC_RESET_CODE_MASK)
|
||||
{
|
||||
case WR0_CRC_RESET_NULL:
|
||||
LOG((" CRC_RESET_NULL\n"));
|
||||
break;
|
||||
case WR0_CRC_RESET_RX: /* In Synchronous mode: all Os (zeros) (CCITT-O CRC-16) */
|
||||
LOGSYNC((" CRC_RESET_RX - not implemented\n"));
|
||||
break;
|
||||
case WR0_CRC_RESET_TX: /* In HDLC mode: all 1s (ones) (CCITT-1) */
|
||||
LOGSYNC((" CRC_RESET_TX - not implemented\n"));
|
||||
break;
|
||||
case WR0_CRC_RESET_TX_UNDERRUN: /* Resets Tx underrun/EOM bit (D6 of the RRO register) */
|
||||
LOGSYNC((" CRC_RESET_TX_UNDERRUN - not implemented\n"));
|
||||
break;
|
||||
default: /* Will not happen unless someone messes with the mask */
|
||||
logerror(" Wrong CRC reset/init command:%02x\n", data & WR0_CRC_RESET_CODE_MASK);
|
||||
}
|
||||
}
|
||||
|
||||
/**/
|
||||
void z80scc_channel::do_sccreg_wr0(uint8_t data)
|
||||
{
|
||||
@ -1688,7 +1665,7 @@ void z80scc_channel::do_sccreg_wr0(uint8_t data)
|
||||
(there are two transitions), another interrupt is not generated. Exceptions to this
|
||||
rule are detailed in the RR0 description.*/
|
||||
|
||||
LOGINT(("%s %s %c - Reset External/Status Interrupt, latch %s\n", m_owner->tag(), FUNCNAME, 'A' + m_index,
|
||||
LOGCMD(("%s %c - Reset External/Status Interrupt, latch %s\n", m_owner->tag(), 'A' + m_index,
|
||||
m_extint_latch == 1? "is released" : "was already released"));
|
||||
// Release latch if no other external or status sources are active
|
||||
if ((m_extint_latch = m_uart->update_extint(m_index)) == 0)
|
||||
@ -1702,18 +1679,18 @@ void z80scc_channel::do_sccreg_wr0(uint8_t data)
|
||||
if (m_uart->m_variant & (SET_NMOS))
|
||||
{
|
||||
logerror("WR0 SWI ack command not supported on NMOS\n");
|
||||
LOGINT(("\"%s\" %s: %c : Reset Highest IUS command not available on NMOS!\n", m_owner->tag(), FUNCNAME, 'A' + m_index));
|
||||
LOGCMD(("%s: %c : WR0_RESET_HIGHEST_IUS command not available on NMOS!\n", m_owner->tag(), 'A' + m_index));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGINT(("\"%s\" %s: %c : Reset Highest IUS\n", m_owner->tag(), FUNCNAME, 'A' + m_index));
|
||||
LOGCMD(("%s: %c : Reset Highest IUS\n", m_owner->tag(), 'A' + m_index));
|
||||
// loop over all interrupt sources
|
||||
for (auto & elem : m_uart->m_int_state)
|
||||
{
|
||||
// find the first channel with an interrupt requested
|
||||
if (elem & Z80_DAISY_INT)
|
||||
{
|
||||
LOGINT(("- %c found IUS bit to clear\n", 'A' + m_index));
|
||||
LOGCMD(("- %c found IUS bit to clear\n", 'A' + m_index));
|
||||
elem = 0; // Clear IUS bit (called IEO in z80 daisy lingo)
|
||||
m_uart->check_interrupts();
|
||||
break;
|
||||
@ -1727,30 +1704,44 @@ void z80scc_channel::do_sccreg_wr0(uint8_t data)
|
||||
data with the special condition is held in the Receive FIFO until this command is issued. If either
|
||||
of these modes is selected and this command is issued before the data has been read from the
|
||||
Receive FIFO, the data is lost */
|
||||
LOG(("\"%s\" %s: %c : WR0_ERROR_RESET\n", m_owner->tag(), FUNCNAME, 'A' + m_index));
|
||||
//do_sccreg_wr0(data); // reset status registers
|
||||
LOGCMD(("%s: %c : WR0_ERROR_RESET - not implemented\n", m_owner->tag(), 'A' + m_index));
|
||||
m_rx_fifo_rp_step(); // Reset error state in fifo and unlock it. unlock == step to next slot in fifo.
|
||||
break;
|
||||
case WR0_SEND_ABORT:
|
||||
data &= 0xef; // convert SCC SEND_ABORT command to a SIO SEND_ABORT command and fall through
|
||||
/* The following commands relies on the SIO default behviour */
|
||||
case WR0_NULL:
|
||||
LOG(("\"%s\" Channel %c : Null\n", m_owner->tag(), 'A' + m_index));
|
||||
case WR0_SEND_ABORT: // Flush transmitter and Send 8-13 bits of '1's, used with SDLC
|
||||
LOGCMD(("%s: %c : WR0_SEND_ABORT - not implemented\n", m_owner->tag(), 'A' + m_index));
|
||||
break;
|
||||
case WR0_ENABLE_INT_NEXT_RX:
|
||||
// enable interrupt on next receive character
|
||||
LOG(("\"%s\" Channel %c : Enable Interrupt on Next Received Character\n", m_owner->tag(), 'A' + m_index));
|
||||
case WR0_NULL: // Do nothing
|
||||
LOGCMD(("%s: %c : WR0_NULL\n", m_owner->tag(), 'A' + m_index));
|
||||
break;
|
||||
case WR0_ENABLE_INT_NEXT_RX: // enable interrupt on next receive character
|
||||
LOGCMD(("%s: %c : WR0_ENABLE_INT_NEXT\n", m_owner->tag(), 'A' + m_index));
|
||||
m_rx_first = 1;
|
||||
break;
|
||||
case WR0_RESET_TX_INT:
|
||||
// reset transmitter interrupt pending
|
||||
LOG(("\"%s\" Channel %c : Reset Transmitter Interrupt Pending\n", m_owner->tag(), 'A' + m_index));
|
||||
logerror("\"%s\" Channel %c : unsupported command: Reset Transmitter Interrupt Pending\n", m_owner->tag(), 'A' + m_index);
|
||||
case WR0_RESET_TX_INT: // reset transmitter interrupt pending
|
||||
LOGCMD(("%s: %c : WR0_RESET_TX_INT - not implemented\n", m_owner->tag(), 'A' + m_index));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
do_sccreg_wr0_resets(data);
|
||||
|
||||
/* CRC Initialization Code handling */
|
||||
switch (data & WR0_CRC_RESET_CODE_MASK)
|
||||
{
|
||||
case WR0_CRC_RESET_NULL:
|
||||
LOGCMD((" CRC_RESET_NULL\n"));
|
||||
break;
|
||||
case WR0_CRC_RESET_RX: /* In Synchronous mode: all Os (zeros) (CCITT-O CRC-16) */
|
||||
LOGCMD((" CRC_RESET_RX - not implemented\n"));
|
||||
break;
|
||||
case WR0_CRC_RESET_TX: /* In HDLC mode: all 1s (ones) (CCITT-1) */
|
||||
LOGCMD((" CRC_RESET_TX - not implemented\n"));
|
||||
break;
|
||||
case WR0_CRC_RESET_TX_UNDERRUN: /* Resets Tx underrun/EOM bit (D6 of the RRO register) */
|
||||
LOGCMD((" CRC_RESET_TX_UNDERRUN - not implemented\n"));
|
||||
break;
|
||||
default: /* Will not happen unless someone messes with the mask */
|
||||
logerror(" Wrong CRC reset/init command:%02x\n", data & WR0_CRC_RESET_CODE_MASK);
|
||||
}
|
||||
|
||||
if ( m_uart->m_variant & SET_Z85X3X)
|
||||
{
|
||||
@ -2278,26 +2269,13 @@ uint8_t z80scc_channel::data_read()
|
||||
data = m_rx_fifo_rp_data();
|
||||
|
||||
// load error status from the FIFO
|
||||
m_rr1 = (m_rr1 & ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR)) | m_rx_error_fifo[m_rx_fifo_rp]; // TODO: Status FIFO needs to be fixed
|
||||
m_rr1 = (m_rr1 & ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR)) | m_rx_error_fifo[m_rx_fifo_rp];
|
||||
|
||||
// trigger interrup and lock the fifo if an error is present
|
||||
// trigger interrupt and lock the fifo if an error is present
|
||||
if (m_rr1 & (RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR))
|
||||
{
|
||||
logerror("Rx Error %02x\n", m_rr1 & (RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR));
|
||||
switch (m_wr1 & WR1_RX_INT_MODE_MASK)
|
||||
{
|
||||
case WR1_RX_INT_FIRST:
|
||||
if (!m_rx_first)
|
||||
{
|
||||
m_uart->trigger_interrupt(m_index, INT_SPECIAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case WR1_RX_INT_ALL_PARITY:
|
||||
case WR1_RX_INT_ALL:
|
||||
m_uart->trigger_interrupt(m_index, INT_SPECIAL);
|
||||
break;
|
||||
}
|
||||
m_uart->trigger_interrupt(m_index, INT_SPECIAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2446,22 +2424,30 @@ void z80scc_channel::data_write(uint8_t data)
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// receive_data - receive data word into fifo
|
||||
// receive_data - put received data word into fifo
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80scc_channel::receive_data(uint8_t data)
|
||||
{
|
||||
LOG(("\"%s\": %c : Receive Data Byte '%02x'\n", m_owner->tag(), 'A' + m_index, data));
|
||||
LOG(("\"%s\": %c : Received Data Byte '%c'/%02x put into FIFO\n", m_owner->tag(), 'A' + m_index, isprint(data) ? data : ' ', data));
|
||||
|
||||
if (m_rx_fifo_wp + 1 == m_rx_fifo_rp || ( (m_rx_fifo_wp + 1 == m_rx_fifo_sz) && (m_rx_fifo_rp == 0) ))
|
||||
{
|
||||
// receive overrun error detected
|
||||
m_rx_error_fifo[m_rx_fifo_wp] |= RR1_RX_OVERRUN_ERROR; // = m_rx_error; TODO: Status FIFO needs to be fixed
|
||||
m_rx_error_fifo[m_rx_fifo_wp] |= RR1_RX_OVERRUN_ERROR;
|
||||
|
||||
// store received character but do not step the fifo
|
||||
m_rx_data_fifo[m_rx_fifo_wp] = data;
|
||||
|
||||
logerror("Receive_data() Error %02x\n", m_rx_error_fifo[m_rx_fifo_wp] & (RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rx_error_fifo[m_rx_fifo_wp] &= ~RR1_RX_OVERRUN_ERROR; // = m_rx_error; TODO: Status FIFO needs to be fixed
|
||||
m_rx_error_fifo[m_rx_fifo_wp] &= ~RR1_RX_OVERRUN_ERROR;
|
||||
|
||||
// store received character
|
||||
m_rx_data_fifo[m_rx_fifo_wp] = data;
|
||||
|
||||
m_rx_fifo_wp++;
|
||||
if (m_rx_fifo_wp >= m_rx_fifo_sz)
|
||||
{
|
||||
@ -2469,13 +2455,9 @@ void z80scc_channel::receive_data(uint8_t data)
|
||||
}
|
||||
}
|
||||
|
||||
// store received character
|
||||
m_rx_data_fifo[m_rx_fifo_wp] = data;
|
||||
|
||||
m_rr0 |= RR0_RX_CHAR_AVAILABLE;
|
||||
|
||||
#if 0 // interrupt on exit from fifo
|
||||
// receive interrupt
|
||||
// receive interrupt on FIRST and ALL character
|
||||
switch (m_wr1 & WR1_RX_INT_MODE_MASK)
|
||||
{
|
||||
case WR1_RX_INT_FIRST:
|
||||
@ -2487,12 +2469,10 @@ void z80scc_channel::receive_data(uint8_t data)
|
||||
}
|
||||
break;
|
||||
|
||||
case WR1_RX_INT_ALL_PARITY:
|
||||
case WR1_RX_INT_ALL:
|
||||
m_uart->trigger_interrupt(m_index, INT_RECEIVE);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user