summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author arbee <rb6502@users.noreply.github.com>2018-07-01 17:39:57 -0400
committer arbee <rb6502@users.noreply.github.com>2018-07-01 17:39:57 -0400
commit44bc4d6bc32cffe6c4bea8b5f148b7663b62c781 (patch)
tree7794e071960954a3ad6fc814d642f8f3a70fce59
parent0a9765dcc29a81607e99650c15b3343bde1a2858 (diff)
z80scc: fix transmit interrupt behavior that was locking up the Apple IIgs [R. Belmont]
-rw-r--r--src/devices/machine/z80scc.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp
index 94833cbf5e8..dcc3597c2cf 100644
--- a/src/devices/machine/z80scc.cpp
+++ b/src/devices/machine/z80scc.cpp
@@ -90,7 +90,7 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC
#define LOG_DCD (1U << 8)
#define LOG_SYNC (1U << 9)
-//#define VERBOSE (LOG_TX)
+//#define VERBOSE (LOG_GENERAL|LOG_SETUP|LOG_READ|LOG_INT|LOG_CMD|LOG_TX|LOG_RCV|LOG_CTS|LOG_DCD|LOG_SYNC)
//#define LOG_OUTPUT_STREAM std::cout
#include "logmacro.h"
@@ -2647,10 +2647,31 @@ void z80scc_channel::data_write(uint8_t data)
{
m_uart->trigger_interrupt(m_index, INT_TRANSMIT); // Set TXIP bit
}
+ /*
+ RB July 1, 2018: This breaks the Apple IIgs SCC MIDI driver. The driver does this with interrupts off:
+
+ sta SCCdata,x ; send the byte
+ lda SCCcommand,x ; try to do another character
+ bit #$04 ; transmitter empty?
+ beq done ; if not, don't do this
+ jsl getNextByte ; get the next byte to send
+ bcs nochar ; there isn't one?
+ sta SCCdata,x ; send a second byte
+
+ The first byte write with this behavior raises a TX_BUFFER_EMPTY interrupt, but interrupts are off here.
+ Because TX_BUFFER_EMPTY is asserted at the "try to do another character" it sends a second byte. The second
+ byte turns OFF the TX_BUFFER_EMPTY flag, so when interrupts are re-enabled and the interrupt fires, the
+ code has no idea why it fired and the system locks up.
+
+ Also, this behavior contradicted the comment above: we are an NMOS/CMOS part and on the first write
+ the transmit buffer is not full, so this interrupt should not be raised here.
+ */
+ #if 0
else if(m_rr0 & RR0_TX_BUFFER_EMPTY) // Check TBE bit and interrupt if one or more FIFO slots available
{
m_uart->trigger_interrupt(m_index, INT_TRANSMIT); // Set TXIP bit
}
+ #endif
}
}