mirror of
https://github.com/holub/mame
synced 2025-10-08 09:30:17 +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 VERBOSE 0
|
||||||
#define LOGPRINT(x) do { if (VERBOSE) logerror x; } while (0)
|
#define LOGPRINT(x) do { if (VERBOSE) logerror x; } while (0)
|
||||||
#define LOG(x) {} LOGPRINT(x)
|
#define LOG(x) {} LOGPRINT(x)
|
||||||
#define LOGR(x) {} LOGPRINT(x)
|
#define LOGR(x) {}
|
||||||
#define LOGSETUP(x) {} LOGPRINT(x)
|
#define LOGSETUP(x) {} LOGPRINT(x)
|
||||||
#define LOGINT(x) {} LOGPRINT(x)
|
#define LOGINT(x) {}
|
||||||
#define LOGTX(x) {} LOGPRINT(x)
|
#define LOGCMD(x) {}
|
||||||
#define LOGRCV(x) {} LOGPRINT(x)
|
#define LOGTX(x) {}
|
||||||
#define LOGCTS(x) {} LOGPRINT(x)
|
#define LOGRCV(x) {}
|
||||||
#define LOGDCD(x) {} LOGPRINT(x)
|
#define LOGCTS(x) {}
|
||||||
#define LOGSYNC(x) {} LOGPRINT(x)
|
#define LOGDCD(x) {}
|
||||||
|
#define LOGSYNC(x) {}
|
||||||
#if VERBOSE == 2
|
#if VERBOSE == 2
|
||||||
#define logerror printf
|
#define logerror printf
|
||||||
#endif
|
#endif
|
||||||
@ -1321,7 +1322,7 @@ uint8_t z80scc_channel::do_sccreg_rr0()
|
|||||||
{
|
{
|
||||||
uint8_t rr0 = m_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)
|
if (m_extint_latch == 1)
|
||||||
{
|
{
|
||||||
rr0 &= ((~m_wr15) | WR15_WR7PRIME | WR15_STATUS_FIFO); // clear enabled bits, saving 2 unrelated bits
|
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
|
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;
|
return rr0;
|
||||||
@ -1626,30 +1627,6 @@ uint8_t z80scc_channel::control_read()
|
|||||||
return data;
|
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)
|
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
|
(there are two transitions), another interrupt is not generated. Exceptions to this
|
||||||
rule are detailed in the RR0 description.*/
|
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"));
|
m_extint_latch == 1? "is released" : "was already released"));
|
||||||
// Release latch if no other external or status sources are active
|
// Release latch if no other external or status sources are active
|
||||||
if ((m_extint_latch = m_uart->update_extint(m_index)) == 0)
|
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))
|
if (m_uart->m_variant & (SET_NMOS))
|
||||||
{
|
{
|
||||||
logerror("WR0 SWI ack command not supported on NMOS\n");
|
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
|
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
|
// loop over all interrupt sources
|
||||||
for (auto & elem : m_uart->m_int_state)
|
for (auto & elem : m_uart->m_int_state)
|
||||||
{
|
{
|
||||||
// find the first channel with an interrupt requested
|
// find the first channel with an interrupt requested
|
||||||
if (elem & Z80_DAISY_INT)
|
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)
|
elem = 0; // Clear IUS bit (called IEO in z80 daisy lingo)
|
||||||
m_uart->check_interrupts();
|
m_uart->check_interrupts();
|
||||||
break;
|
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
|
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
|
of these modes is selected and this command is issued before the data has been read from the
|
||||||
Receive FIFO, the data is lost */
|
Receive FIFO, the data is lost */
|
||||||
LOG(("\"%s\" %s: %c : WR0_ERROR_RESET\n", m_owner->tag(), FUNCNAME, 'A' + m_index));
|
LOGCMD(("%s: %c : WR0_ERROR_RESET - not implemented\n", m_owner->tag(), 'A' + m_index));
|
||||||
//do_sccreg_wr0(data); // reset status registers
|
|
||||||
m_rx_fifo_rp_step(); // Reset error state in fifo and unlock it. unlock == step to next slot in fifo.
|
m_rx_fifo_rp_step(); // Reset error state in fifo and unlock it. unlock == step to next slot in fifo.
|
||||||
break;
|
break;
|
||||||
case WR0_SEND_ABORT:
|
case WR0_SEND_ABORT: // Flush transmitter and Send 8-13 bits of '1's, used with SDLC
|
||||||
data &= 0xef; // convert SCC SEND_ABORT command to a SIO SEND_ABORT command and fall through
|
LOGCMD(("%s: %c : WR0_SEND_ABORT - not implemented\n", m_owner->tag(), 'A' + m_index));
|
||||||
/* The following commands relies on the SIO default behviour */
|
|
||||||
case WR0_NULL:
|
|
||||||
LOG(("\"%s\" Channel %c : Null\n", m_owner->tag(), 'A' + m_index));
|
|
||||||
break;
|
break;
|
||||||
case WR0_ENABLE_INT_NEXT_RX:
|
case WR0_NULL: // Do nothing
|
||||||
// enable interrupt on next receive character
|
LOGCMD(("%s: %c : WR0_NULL\n", m_owner->tag(), 'A' + m_index));
|
||||||
LOG(("\"%s\" Channel %c : Enable Interrupt on Next Received Character\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;
|
m_rx_first = 1;
|
||||||
break;
|
break;
|
||||||
case WR0_RESET_TX_INT:
|
case WR0_RESET_TX_INT: // reset transmitter interrupt pending
|
||||||
// reset transmitter interrupt pending
|
LOGCMD(("%s: %c : WR0_RESET_TX_INT - not implemented\n", m_owner->tag(), 'A' + m_index));
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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)
|
if ( m_uart->m_variant & SET_Z85X3X)
|
||||||
{
|
{
|
||||||
@ -2278,26 +2269,13 @@ uint8_t z80scc_channel::data_read()
|
|||||||
data = m_rx_fifo_rp_data();
|
data = m_rx_fifo_rp_data();
|
||||||
|
|
||||||
// load error status from the FIFO
|
// 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))
|
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));
|
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)
|
m_uart->trigger_interrupt(m_index, INT_SPECIAL);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
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)
|
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) ))
|
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
|
// 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));
|
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
|
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++;
|
m_rx_fifo_wp++;
|
||||||
if (m_rx_fifo_wp >= m_rx_fifo_sz)
|
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;
|
m_rr0 |= RR0_RX_CHAR_AVAILABLE;
|
||||||
|
|
||||||
#if 0 // interrupt on exit from fifo
|
// receive interrupt on FIRST and ALL character
|
||||||
// receive interrupt
|
|
||||||
switch (m_wr1 & WR1_RX_INT_MODE_MASK)
|
switch (m_wr1 & WR1_RX_INT_MODE_MASK)
|
||||||
{
|
{
|
||||||
case WR1_RX_INT_FIRST:
|
case WR1_RX_INT_FIRST:
|
||||||
@ -2487,12 +2469,10 @@ void z80scc_channel::receive_data(uint8_t data)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WR1_RX_INT_ALL_PARITY:
|
|
||||||
case WR1_RX_INT_ALL:
|
case WR1_RX_INT_ALL:
|
||||||
m_uart->trigger_interrupt(m_index, INT_RECEIVE);
|
m_uart->trigger_interrupt(m_index, INT_RECEIVE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user