1
votes

I recently got hold of a ZX Spectrum +3 and am trying to get RS232 working with the spectrum. I’ve built a cable (‘BT’ style connector <-> DB9 serial) following the pin out of the cable (Spectrum 128 RS232 data cable) here. The other end of the cable is connected to the PC using a USB-Serial adapter. I'm using Moserial on Linux to communicate with the Spectrum.

The cable works and I can use LLIST to print BASIC programs over the serial port, but I'm unable to get the Spectrum to read from the serial port reliably - even when enabling hardware handshaking (DTR/CTS) in Moserial.

I wrote a simple program in +3 BASIC to print received characters to the screen. It seems the first character is received OK, but the remaining characters are dropped or become corrupted.

Here is an example of what the Spectrum outputs when attempting to send 'zx spectrum' at 300 baud:

z[dot/box character]. VAL$ [box character]MOVE VAL$ VAL$ ?)

(it seems VAL$ and MOVE$ are each a single character in the Spectrum's ROM)

screenshot: https://i.stack.imgur.com/D0TMW.jpg

And the BASIC program which opens the serial port, and prints received characters to the screen:

10  FORMAT LINE 300
20  FORMAT LPRINT "r"
30  FORMAT LPRINT "e"
40  OPEN #4,"p"
50  PRINT INKEY$#4;
60  GO TO 50

I discovered that if I send characters one-by-one from the PC with a long enough delay between them, I can get a much more reliable output from the Spectrum. I tested this with different delays, and 80ms worked the best. I don't really want to use this approach as a solution - it's awfully slow and occasionally some characters are dropped.

Could this be an issue with the Spectrum itself? Or am I missing something in my setup? Something just doesn't seem right, I know there is a program loader for the spectrum over serial - so surely the spectrum must be able to accept serial input without a 80ms delay per character?

3
If I was doing this, I would focus first on transmitting by the Spectrum and receiving by the PC. Use a 'scope to measure the actual baud rate to confirm the accuracy of the old hardware crystal/oscillator. Then compare the baudrate sent by the PC. "Here is an example of what the Spectrum outputs when attempting to send 'zx spectrum' at 300 baud" -- Don't you mean what the Spectrum displays after receiving ...? IOW keep your perspective of input/output consistent. - sawdust
What USB-RS232 adaptor are you using? Have you verified it works at slow speeds with other devices? - Marcos G.
At 300 baud the transfer speed is about 30 characters per second, so 80ms are still quite slow, but not by big factors. Can you look up the hex/binary values of the characters received? Then compare the binary values to those of the sent characters - you might have wrong parameters (number of data bits, parity, number of stop bits) and received characters are "shifted". And yes, those "MOVE" and such are printed because the received character is a byte-coded "token" in the Spectrum. Better output hex values. - the busybee
@sawdust yeah that’s what I meant, sorry that could have been worded better - cobbm
Are you aware of Retrocomputing resource? There are lots of Spectrum gurus there. - tum_

3 Answers

2
votes

The ZX Spectrum Interface 1 works by bit-sampling, in a software loop, with delays, so that it can look for the start bit and then look for the other bits. There is no shift register. It's all done in software.They don't even use interrupts or some other kind of fixed external timer to generate baud rate delays.

As a result, it doesn't even start looking for a start bit until it knows you're looking for input... Now that you have an idea what's going on I'm pretty sure you've already seen the problem there? If you're sending data too fast, then your basic program doesn't even have time to go back to the receive routine to look for start bits, and start bits are going to be lost, or more likely, you're going to pick up a bit transition mid-byte and receive gibberish... So you need to make sure that there's a delay between bytes and your Spectrum is ready to receive the next byte before you start transmitting.

Hope this helps even though it's a while ago, but others will find this so...

0
votes

In zx spectrum 48k, with interface 1, i must choose how the rs232 will work. Mode t : text ->rx and tx only character in 7bit Mode b: byte -> rx and tx full byte (8 bit)

Maybe you must chek that.

On 48k with interface 1 FORMAT "b";9600 Then , the spectrum works in 8bit data at 9600 bauds.

In your code, i dont see how will works.

My best regards.

0
votes

I came across your problem as I was trying to do the same!

You need to enable RTS/CTS handshaking in your linux (PC) application, not DTR/RTS.

This works for me on my Spectrum+2:

 100 REM ** Receive Test **
 110 REM ** Use RTS/CTS **
 120 CLS
 130 FORMAT "p";9600
 140 OPEN #4,"p"
 150 PRINT INKEY$#4;
 160 GO TO 150