cc65 and RS232 User Port Serial

Basic and Machine Language

Moderator: Moderators

Bobbi
Vic 20 Afficionado
Posts: 355
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Post by Bobbi »

I have had the opportunity to do a pile more testing. RS-232 seems very solid now at 1200 baud using v3 of srowe's wedge! Excellent work!!

On a related question, does anyone know a way to write to a disk file via the IEC serial port while also downloading data from user port RS-232? The kernal routines interact with one another with the result that the data obtained from RS232 is completely garbled. How do terminal programs get around this for XModem downloads for example, or just logging of the session to disk file? I need a way to do this for another project I am working on.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: cc65 and RS232 User Port Serial

Post by Mike »

srowe wrote:Here's v3 of the wedge. The ISR now disables all further interrupts and processes all pending ones before re-enabling. This should cope with any combination of Tx and Rx states, as well as you pounding on the RESTORE key.

I've run it for a while receiving data at 1200 baud, I've not seen a dropped or corrupt character.
I have another question:

As stated in Denial Wiki, hardware handshake is broken with the original RS232 routines in the KERNAL. Does your wedge fix this issue?
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: cc65 and RS232 User Port Serial

Post by srowe »

Mike wrote: As stated in Denial Wiki, hardware handshake is broken with the original RS232 routines in the KERNAL. Does your wedge fix this issue?
Short answer, yes. Long answer: sort of.

Yes, the wedge reads from the correct VIA registers. However the behaviour implemented is still the original use of RTS and CTS for use with half-duplex modems, this is not the same as the current usage of those lines for flow control. See https://en.wikipedia.org/wiki/RS-232#RTS,_CTS,_and_RTR
It is not possible to fix READST in the wedge as the routine is not vectored. There is a routine in the code, RSREADST, that correctly implements it.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: cc65 and RS232 User Port Serial

Post by Mike »

srowe wrote:Short answer, yes. Long answer: sort of.
Thank you!

The reason I've been asking is a WIP, that in one of its implementations would sport two VIC-20s connected with a nullmodem cable.

So it's sensible for me to make a fully wired nullmodem cable (not just 3-wire, i.e. RxD <-> TxD vs GND, and RTS/CTS bridged in the connector), in fact: both sides would have the same understanding how the hardware handshake is supposed to work. :)

Cheers,

Michael
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: cc65 and RS232 User Port Serial

Post by srowe »

No, the original definition of CTS/RTS is not symmetrical. The VIC routines are coded as a DTE device, from what I can determine the flow is as follows for a full-duplex session:
  • When the RS-232 device is open DTR and RTS are set high, if the DSR line is low an error is flagged
  • If during Tx the DSR or CTS line goes low an error is flagged
  • When the device is closed DTR and RTS are set high again
A half-duplex session is more complex:
  • When a channel is opened for output the DSR is checked and if low an error is flagged
  • - if RTS is low it is because an input channel was opened (see below), loop while CTS is high then raise RTS
  • When a channel is opened for input the DSR is checked and if low an error is flagged
  • - if RTS is high then loop while timer T1 is running then lower RTS
For added confusion all the control lines (both in and out) go through an extra inverter on the VIC-1011A board.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: cc65 and RS232 User Port Serial

Post by Mike »

O.K., then I'll have to look deeper into it. The goal for me remains to directly couple two VIC-20s over the user port RS232, without any level shifting - and preferably without any signal inversion necessary. And, if possible, with functioning hardware handshake.

Think of a 'talk' application with two terminals, except one of the two terminals is supposed to do something else. :wink:
srowe wrote:The VIC routines are coded as a DTE device
That should be perfectly in line with my plans. A nullmodem cable actually lets a DTE device appear as DCE device for the DTE device on the other side (and vice versa): https://en.wikipedia.org/wiki/Null_modem
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: cc65 and RS232 User Port Serial

Post by srowe »

I can look into changing the wedge to use the modern form of RTS/CTS handshaking. It should be just a matter of checking in the Tx interrupt routine before scheduling a new byte and having some form of watermark in the Rx routine.
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: cc65 and RS232 User Port Serial

Post by srowe »

Mike wrote: That should be perfectly in line with my plans. A nullmodem cable actually lets a DTE device appear as DCE device for the DTE device on the other side (and vice versa)
That only works when the protocol is symmetric.
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: cc65 and RS232 User Port Serial

Post by srowe »

I am working on this when I have time. I've decided to rip out support for 2 stop bits, parity checking and anything other than 8 bits. This reduces the number of cycles spent in an interrupt and may mean it can support higher baud rates.
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: cc65 and RS232 User Port Serial

Post by srowe »

I've finally finished working on this RS-232 wedge. It took a lot longer than I'd hoped as the decisions of which VIA pins are used for what caused the flow control checking in the Tx path to be rather complicated. I've tested simultaneous send and receive at 1200 baud, which works without problems. At 2400 just send or just receive are fine, doing both results in frequent Rx corruptions. I think this is down to the fact that there are only tens of cycles between the timer intervals at that baud rate, handling both is just beyond the capability of a 1MHz processor.

Available at https://eden.mose.org.uk/download/rs-232-rewrite.zip, source included.
Bobbi
Vic 20 Afficionado
Posts: 355
Joined: Thu Oct 13, 2016 11:35 am
Location: Toronto
Occupation: Programmer

Re: cc65 and RS232 User Port Serial

Post by Bobbi »

I am going to have to give this new version a try with my RSS Reader! Thanks for all your RS-232 efforts!
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: cc65 and RS232 User Port Serial

Post by Mike »

There's a small issue with the RSVECT routine. It briefly resets the NMI vector to its original value from the table in the KERNAL, and then applies the new value to call the NMI wedge.

In real h/w, the RESTORE key bounces, and sometimes, this will lead to another NMI being issued just when the NMI vector had been restored to the KERNAL defaults (or is half-way through the change!), will can then result in either inadvertent disabling of the wedge or in a crash.

tokra actually experienced these issues with the overscan screen editors he wrote some time ago. He solved the issue by only ever writing to the NMI vector once during (re-)init, with the intended value: http://sleepingelephant.com/ipw-web/bul ... php?t=8375
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: cc65 and RS232 User Port Serial

Post by srowe »

When RSVECT is called from RSNMI all interrupt sources on VIA1 are disabled, they only get re-enabled once INITVIA is called.

When RSVECT is called from RSCOLD at system power on the initial state of the IER register prevents any NMIs until INITVIA is again called. The risk of the NMI vector being in an invalid state when an interrupt happens does occur if RSCOLD or RSVECT are called directly after the system has booted. For safety I'll explicitly clear the IER before calling FRESTOR.

The reason tokra was bitten by this is because the KERNAL NMI routine leaves interrupts enabled while it's processing. I think that risks another problem, if another interrupt condition occurs while the NMI routine is running it may get accidently cleared by register interactions. By clearing the IER the VIA keeps the interrupt in a pending state.

A different scenario is an external device that generates NMIs. There's nothing that can be done to protect against jumping through the vector to nowhere if an interrupt occurs before the vector is set up.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: cc65 and RS232 User Port Serial

Post by Mike »

srowe wrote:When RSVECT is called from RSNMI all interrupt sources on VIA1 are disabled, they only get re-enabled once INITVIA is called. [...]
Ah, okay. Didn't see that. So you're actually do what's normally done for "normal" IRQs, "bracketing" the vector (re-)init with SEI/CLI - just in this case you block the interrupt source itself. As you wrote, that only applies to the VIA NMI line - not much that can be done with NMIs from a cartridge.

Still, writing the NMI vector only once is probably a cleaner, even if slightly more complicated way to handle this.

In a WIP where I also change the BRK vector and want to re-init both the BRK and NMI vectors from STOP/RESTORE, here's what I'm doing:

Code: Select all

.Vectors
 LDY #&03
.Vectors_00
 LDA Vectors_01,Y
 STA &0316,Y
 DEY
 BPL Vectors_00
 RTS
.Vectors_01
 EQUW Break
 EQUW NMI

.Vectors2
 LDY #&1F
.Vectors2_00
 CPY #&02
 BCC Vectors2_01
 CPY #&06
 BCC Vectors2_02
.Vectors2_01
 LDA &FD6D,Y
 STA &0314,Y
.Vectors2_02
 DEY
 BPL Vectors2_00
 RTS
... where the tool startup routine just does JSR Vectors, and my copy of the NMI routine does JSR Vectors and JSR Vectors2. The CMPs between Vectors2_00 and Vectors2_01 exclude the BRK and NMI vectors from being written to in Vectors2. The rationale behind this: the tool is supposed to keep the other KERNAL vectors during init (changed by yet another tool perhaps), but reinit to the KERNAL defaults (except BRK and NMI) with STOP/RESTORE still takes place.


Edit: @srowe: PM sent
doug_in_nc
Vic 20 Enthusiast
Posts: 156
Joined: Wed Feb 24, 2021 11:32 am
Location: NC, USA
Occupation: Engineer

Re: cc65 and RS232 User Port Serial

Post by doug_in_nc »

Sorry for the necro-post but I was looking through this thread and tried to download the final RS232 fix from srowe, but unfortunately the link is now broken. Does anyone have a copy of the file that they could post here for posterity and idiots like me?

I'm looking at the possibility of building as RC2014 which is a Z80 based computer kit that can run CP/M and is built from modern components. It normally works with a PC, Mac or Raspberry PI as a terminal via an RS232 to USB cable rather than having its own display hardware, and I had the (stupid) idea that using a VIC with an 80 column card (Protecto 80) and its built-in terminal emulation software would be a suitably retro, not to mention very slow, alternative at least just to see if it would work
Post Reply