Z80 SIO RTS Problem

688 views
Skip to first unread message

Bill Wuttke

unread,
Aug 28, 2017, 9:38:08 PM8/28/17
to RC2014-Z80
All,

I recently designed a Z80 SIO-based serial board for the RC2014 and had it built at OSH Park. I needed extra ports for my VT510, Decwriter LA100, and Model 33 Teletypes. Being stuck at 115200 baud would not hack it. This was my first attempt at PC board design and Kicad. It turned out very nicely, but not without problems.


The board has an onboard MC14411 bit rate generator providing selectable 9600, 2400, 1200, 300, and 110 baud rates as well as using the system clock for 115200 baud. The I/O port is selectable from 16 I/O port addresses and uses 8 bytes of I/O space. CTS is brought out to the serial port header to allow higher baud rate connections to the VT510 and LA100, which rely on hardware handshaking for reliable connections (when the SIO is programmed for “Autos”, transmit handshaking/flow control is automatically taken care of by CTS). CTS can also be jumpered to ground to disable this flow control. The board can also be configured to use either an SIO/0 or an SIO/2 through jumpers. (I ordered SIO/2’s from eBay, but got SIO/0’s.)


During performance testing I noted that performance at 115200 baud was abysmal. Numerous people on the RC2014 board said to add a delay after each character. That seemed to solve the problem, but inserting a 1 millisecond delay after each character drops the effective baud rate to something close to 9200 baud, which is slower than a 9600 baud connection. I wanted to find out why the performance was so poor and to fix the problem. So I acquired a logic analyzer and started testing.


I discovered that when the SIO dropped RTS (RTS High), two characters were dropped. RTS was dropped in the middle of a received character which was dropped. (See SIO_RTS_Anomaly below.) Note no IRQ or IORQ activity for the two characters received after RTS was dropped. I couldn’t believe this was happening, since both the Monitor ROM code and the CPM22 code (from Grant Searle) appeared to rely on dropping RTS to stop the data flow to prevent buffer overflow - as it should. Since the buffer high watermark is designed to allow any characters received after the RTS is dropped to be received and placed in the buffer, you would expect that it works that way. Nope!


A second test was run with the original RC2014 68B50 serial board. Everything worked as expected. The two characters that were received after RTS was dropped were processed as expected. Note the IRQ and IORQ activity for the two characters indicating that they were processed. (See ACIA_RTS_Test below.)


How could I fix this problem? Was the SIO I received a (mostly functional) clone? Is this behavior normal? Is anyone else having this problem?


My fix to the problem was to use the SIO DTR instead of RTS. This involved a minor board modification and a software change to toggle DTR instead of RTS. Results are shown in SIO_RTS_DTR_Fix below. I now have completely reliable communications at 115200 baud without inserting a delay after each character. 

 

Cheers,

Bill
SIO_RTS_Anomaly.png
ACIA_RTS_Test.png
SIO_RTS_DTR_Fix.png

Tom Szolyga

unread,
Aug 29, 2017, 3:37:06 PM8/29/17
to RC2014-Z80
Perhaps there is a misunderstanding.  The SIO RTS signal has nothing to do with receiving characters.  Instead, it is linked to transmitting characters.  (See clip from SIO Datasheet.)  The RTS signal is software controlled.  It is set High or Low by writing to Reg 5 in the SIO.  When RTS is reset in Asynch mode, it goes High after the transmitter is empty.  If RTS is used to control receiving characters, it must be manipulated by software.  Therefore, if received characters are lost, it must be a software error.  

Also, remember that the SIO Rx data registers are quadruply buffered and the Tx registers are doubly bufferes.  To determine if the SIO has dropped characters on receive, the "Rx Overrun Error" bit in Register 1 should be checked.

Best regards,
Tom 
SIO_RTS.jpg

Bill Wuttke

unread,
Aug 29, 2017, 5:51:49 PM8/29/17
to RC2014-Z80
Hi Tom,

If you are talking DTE to DCE communications, I'd agree with you. However, other than modems, how many DCE devices can you find nowadays?

The problem is that when you connect two DTE's together (e.g., terminal to SIO - SIO expects to be DTE), RTS on one end becomes CTS on the other end. Hence, you are controlling character reception. The receive interrupt service routines in both Grant Searle's monitor and cbios rely on resetting RTS to prevent receive buffer overflow.

Regards,
Bill

Bill Wuttke

unread,
Sep 1, 2017, 4:38:30 PM9/1/17
to RC2014-Z80
All,

I knew something else had to be wrong. No matter how many times you check and double-check your work, you always seem to miss something. My RTS problem was actually caused by floating DCD input pins. It seems that just making RTS go high would cause the DCD pin to go high, which, due to "Autos" being enabled, would turn the receiver off. I grounded the DCD pins and RTS now works as it should.

Cheers,

Bill


Peter Willard

unread,
Sep 2, 2017, 9:56:10 AM9/2/17
to RC2014-Z80
This makes a lot of sense.

StephenA

unread,
Jul 19, 2018, 10:52:45 PM7/19/18
to RC2014-Z80
Hi All,

Sorry to resurrect an old thread but I think this one is important.

On Tuesday, August 29, 2017 at 11:38:08 AM UTC+10, Bill Wuttke wrote:

My fix to the problem was to use the SIO DTR instead of RTS. This involved a minor board modification and a software change to toggle DTR instead of RTS. Results are shown in SIO_RTS_DTR_Fix below. I now have completely reliable communications at 115200 baud without inserting a delay after each character. 



I believe that the modification Bill outlines above is probably essential for reliable high-speed serial comms.

>Tom Szolyga  8/30/17

>Perhaps there is a misunderstanding.  The SIO RTS signal has nothing to do with receiving characters.
>Instead, it is linked to transmitting characters.  (See clip from SIO Datasheet.)

What Tom says is correct - in context.

As designed the original use for CTS RTS was not symmetrical. The host computer/terminal would raise RTS to a modem. The modem would reply with CTS when it was all clear to send. Note that while the modem can use CTS to signal ready to the host, the reverse is not true.

This original schema was changed some time in the late 1980's (according to Wikipedia) and we got the updated RS232-E (TIA-232-E). Now the name of the RTS (Request To Send) is changed to RTR (Ready To Receive) and the usage of the signals is now symmetrical. Confusingly everybody kept calling the new RTR signal RTS.

So why is this an issue for the RC2014?

I believe that the original older method for RTS/CTS usage is "baked' into the Zilog SIO/x chip silicon. It says so clearly in the data sheet extract that Tom posted:-

SIO Data sheet quote: "When the RTS bit is reset in the Asynchronous mode, the output goes high *after* the transmitter is empty."

The Zilog engineers assumed that RTS would be a "Request To Send" to a DCE (modem) and as such the request is only dropped when there is no more data in transmit buffer to send.

So if you attempt to control the SIO RTS manually using the more modern context it is likely to lead to unexpected results. Your receive buffer is reaching the "high tide" water mark. Your serial ring buffer driver turns off RTS in an attempt to halt the inflow of new data, and... nothing happens! Data keeps coming, Your buffer overflows. Why? Because you still had data in the outward bound transmit buffer of the SIO/x chip at the time you wanted to turn RTS off.

The solution?

Do exactly what Bill did. Use the SIO DTR signal as the CTS (RTR) signal. The SIO DTR has no such hangups when it comes to data in the TX buffer. You can toggle it on and off at will. Zilog declare it to be a "general purpose" signal in the data sheet. So we'll just change the name to RTR (aka RTS).

Granted, if your RX ring buffer is large enough you may never see the problem (and I note some have experimented with increasing this). Also noted that on the RC2014 the transmit of data cannot be suspended by the receiver. Because the RC2014 CTS input is hard wired to ground. So the handshake here is disabled, the transmitter is always enabled. So it's more likely that the TX buffer will be empty. However this creates another problem in need of fixing that has been noted elsewhere:-


Cheers Steve.




Jay Cotton

unread,
Aug 19, 2019, 1:47:19 PM8/19/19
to RC2014-Z80
I have a similar problem with the KIO chip.  The RTS bit is high, and nothing I do will change it to low.  If I monitor the bit with a scope and just transmit a text string I can see
some activity, but it seems that a high state is blocking the FTDI cable from sending data into the chip.  A short to ground of RTS will get things moving but this is not  a solution
I want to use.  I have tried to follow the code for sio from RomWBW, but that seems to want interrupts running.... I am attempting polled i/o at this time.  

I'd like to ignore the RTS signal, but that is not an option see FTDI above.  

I should point out that setting RTS to one or zero makes no difference at the connector.  

Wondering if pushing a null out the transmitter is required to get the receive side working ?  That would be clumsy 

Jay Cotton

unread,
Aug 19, 2019, 6:56:47 PM8/19/19
to RC2014-Z80
Based on what I can find on the INET, looks like we abandon RTS and use DTR as the h/w handshake bit.  ....  I will hack the board and see what happens.
Message has been deleted

Peter Willard

unread,
Feb 21, 2023, 6:42:40 PM2/21/23
to RC2014-Z80

Speaking of the MC14411, I am always bugged by the poor quality of the ancient databook/datasheet scans so I thought I would have a go at making a replacement from scratch
 (I like doing this sort of thing for 'practice').  

 
mc14411.pdf
Reply all
Reply to author
Forward
0 new messages