What's the state of play with serial port support?

Chat about anything CX16 related that doesn't fit elsewhere
BruceMcF
Posts: 1336
Joined: Fri Jul 03, 2020 4:27 am

What's the state of play with serial port support?

Post by BruceMcF »



4 hours ago, Andre said:




Not only that. It is also using the NMI, that is, in general, incompatible with precise IEC bus timing.



One of the reasons I am cautious whether we could just multiply by eight to get the maximum throughput of either a pure bit-banged or a serial shift register based CX16 port, given that the CX16 has the PS/2 keyboard and mouse to support. Times 4 seems a bit safer, which would make 9600bps a safe assumption for a bit banged User Port serial port.

Even 4x for a CX16 port of the UP9600 approach is pretty appealing ... 19.2kbps is a common default serial port setting, and 38.4Mbps would still be not far off from landline max.

TomXP411
Posts: 1781
Joined: Tue May 19, 2020 8:49 pm

What's the state of play with serial port support?

Post by TomXP411 »


So looking at the diagram Kevin posted on FB, here are the pins:

104290272_10158477834379913_4299460036948540974_n.jpg?_nc_cat=108&_nc_sid=b9115d&_nc_ht=scontent-lax3-1.xx&oh=f8b956fcdb5abc2bad9750da3e73dd84&oe=5F366DF9

Note that the text description at the top is wrong. The correct procedure for writing to the printer is:


  1. Set PB0 (Strobe) High


  2. Apply data to PA0-PA7


  3. Wait for CA2 (Busy) to go low


  4. Set PB0 Low. 


  5. Wait 1ms


  6. Set PB0 High.


So.... if we extend this functionality a little bit, we can add flow control and receive data on the PB lines:

Key:


  • Set by computer


  • Set by modem 


  • Asserted when low





  • PB0 - Strobe: Idle when HIGH, when LOW a byte is on PA0-PA7.


  • PB1 - Clear To Send: HIGH when the transmit buffer is not full. 


  • PB2 - Data Waiting: HIGH when data is in the read buffer. (The computer should read from the modem)


  • PB3 - Data Direction: LOW when sending a byte to the modem/UART. HIGH when reading from the modem/UART


  • PB4 - DTR: Pass through to RS232 pin 20 (DB25) or Pin 4 (DE9)


  • PB5 - Read Status/Select Port: High for data transfer. Low for status pins/Port Select


  • PA0-PA7 - transmit or receive byte when PB5 is high.


  • When PB5 is LOW:


    • PA0: DCD


    • PA1: DTR


    • PA2: DSR


    • PA3: RTS


    • PA4: CTS


    • PA5: RI




So the process of exchanging data with a modem or UART would look like this:


  1. Read from the modem


    1. Computer reads PB2. Skip if LOW, proceed if HIGH


    2. Set PB3 HIGH (read)


    3. Set PB0 LOW 


    4. Read PA0-PA7


    5. Set PB0 HIGH




  2. Write to the modem


    1. Computer reads PB1. Skip if LOW, proceed if HIGH:


    2. Set PB3 LOW (write)


    3. Write PA0-PA7


    4. Set PB0 LOW


    5. Wait 8 clock cycles (4 NOPs should do it. This could probably be shortened, with the speed of an Arduino Uno as a baseline)


    6. Set PB0 HIGH




  3. Read modem status pins


    1. Set PB5 Low (Status)


    2. Set PB3 High (Read)


    3. Set PB0 Low (Strobe)


    4. Read PA0-PA5


    5. Set PB0 High


    6. Set PB5 High




  4. Change UART port and speed:


    1. Set PB5 Low (Status/Port Select)


    2. Set PB3 Low (Write)


    3. Set port number in PA0-PA3


    4. Set speed in PA4-7


    5. Set PB0 Low (Strobe)


    6. Set PB0 High


    7. Set PB3 High


    8. Set PB5 High




I'd probably use an Arduino Mega or Due, since they have plenty of pins and are fast enough to keep up with the Commander's data transfer. (The Mega runs at 16MHz, and the Due runs at 84Mhz).  Which one would depend on whether the User port is 5v or 3.3v. The Due is a 3.3v device, and the Mega is 5V. 


  • UART RX/TX: D19-D14 and USB (Port 0)


  • PA0-PA8: Pins 2-10


  • PB0-PB5: Pins A0-A5


  • RS-232


    • CTS: D62


    • RTS: D63


    • DTR: D64


    • DSR: D65


    • RI: D66


    • CD: D67




  • In total, there are 4 UARTS available on the Due board. The USB port is Port 0, with Port 1-3 on D14-19. There is also an SPI port and an ICSP port, which could be selected as ports 3-4. 


  • RS-232 Speeds are: 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200. SPI speeds would be application specific and determined by the Arduino sketch. 


  • When SPI and ICSP ports are selected, computer will need to hold PB0 low long enough to read or send a full byte. With faster SPI modes, this will not be a problem, as they will likely be faster than the CX16's system clock. 


In all, you could set up a high speed, 4-port serial interface for around $50. 

 

BruceMcF
Posts: 1336
Joined: Fri Jul 03, 2020 4:27 am

What's the state of play with serial port support?

Post by BruceMcF »



3 hours ago, TomXP411 said:




So.... if we extend this functionality a little bit, we can add flow control and receive data on the PB lines:



Key:




  • Set by computer


  • Set by modem 


  • Asserted when low





  • PB0 - Strobe: Idle when HIGH, when LOW a byte is on PA0-PA7.


  • PB1 - Clear To Send: HIGH when the transmit buffer is not full. 


  • PB2 - Data Waiting: HIGH when data is in the read buffer. (The computer should read from the modem)


  • PB3 - Data Direction: LOW when sending a byte to the modem/UART. HIGH when reading from the modem/UART


  • PB4 - DTR: Pass through to RS232 pin 20 (DB25) or Pin 4 (DE9)


  • PB5 - Read Status/Select Port: High for data transfer. Low for status pins/Port Select


  • PA0-PA7 - transmit or receive byte when PB5 is high.


  • When PB5 is LOW:


    • PA0: DCD


    • PA1: DTR


    • PA2: DSR


    • PA3: RTS


    • PA4: CTS


    • PA5: RI






 



The difference between that and EPP is:

In EPP, Pin 1 is Read/Write, that is, Low implies PA0-PA7 are output, High implies PA0-PA7 are input.

CA1 is the Interrupt or Alert input from the connected device. It is specified as interrupt on a rising transition.

CA2. is Wait/Ready input from the device, when low, a data or address read/write may be performed.

EPP does not use PB1, PB2, or PB4.

PB3 is the Data strobe: when low, Data is being read or written

PB5 is the Address Strobe: when low, the Register Address is being Written or Status is being Read.

Whatever is connected to RESB is connected through an inverter to the Reset line, which resets the devices that is connected to the Serial Port ... that seems like a bit of an issue since it is not clear that we always want to reset the computer in order to reset the device that is attached to the parallel port.

Using the EPP protocol might be parsimonious in the sense that support for what are now retro legacy EPP devices (though for most of the 80s they were largely in the future) and support for new devices can use the same protocol.

Andre
Posts: 21
Joined: Wed Jul 15, 2020 9:37 pm

What's the state of play with serial port support?

Post by Andre »


You know that the VIA has "handshake mode" on the PA? This is allowing to automatically bump the CA2 line when reading or writing PA, to signal the transfer to an external device. See the VIA datasheet for more details. This is very handy in such situations.

Edit: also, PA and PB can be "latched" on input on positive or negative edge of CA1/CB1 respectively.

BruceMcF
Posts: 1336
Joined: Fri Jul 03, 2020 4:27 am

What's the state of play with serial port support?

Post by BruceMcF »



20 hours ago, Andre said:




You know that the VIA has "handshake mode" on the PA? This is allowing to automatically bump the CA2 line when reading or writing PA, to signal the transfer to an external device. See the VIA datasheet for more details. This is very handy in such situations.



Edit: also, PA and PB can be "latched" on input on positive or negative edge of CA1/CB1 respectively.



The latter is what an EPP interface would rely on ... as far as I can tell, CA1 set to 0 and CA2 set to 001 so both are independent negative edge detects would be fine for an EPP protocol ... especially since what connects to EPP are typically ISA bus speed devices, so being unable to keep up with the CX16 would rarely be a problem.

Whether CA1 should trigger an IRQ or not depends on whether you want an interrupt driven routine or want to poll.

However, as the User Port is most recently specified, would require a little rewiring of the standard block header to parallel port connector so that /Reset is on a spare GPIO. WIth a jumper setting, the same cable could be used for a standard parallel port and for an EPP.

A custom parallel port protocol could indeed be faster by relying on the hardware handshake to allow you to read or write a packet with very little delay.

 

TomXP411
Posts: 1781
Joined: Tue May 19, 2020 8:49 pm

What's the state of play with serial port support?

Post by TomXP411 »



5 hours ago, BruceMcF said:




The latter is what an EPP interface would rely on ... as far as I can tell, CA1 set to 0 and CA2 set to 001 so both are independent negative edge detects would be fine for an EPP protocol ... especially since what connects to EPP are typically ISA bus speed devices, so being unable to keep up with the CX16 would rarely be a problem.



Whether CA1 should trigger an IRQ or not depends on whether you want an interrupt driven routine or want to poll.



However, as the User Port is most recently specified, would require a little rewiring of the standard block header to parallel port connector so that /Reset is on a spare GPIO. WIth a jumper setting, the same cable could be used for a standard parallel port and for an EPP.



A custom parallel port protocol could indeed be faster by relying on the hardware handshake to allow you to read or write a packet with very little delay.

 



The question was about serial ports, not EPP, and I am proposing a very specific standard for polled UART connections, not an EPP device connection standard. Can we keep EPP talk to the EPP thread and focus here on hooking up a hardware UART to the user port? 

BruceMcF
Posts: 1336
Joined: Fri Jul 03, 2020 4:27 am

What's the state of play with serial port support?

Post by BruceMcF »



1 hour ago, TomXP411 said:




The question was about serial ports, not EPP, and I am proposing a very specific standard for polled UART connections, not an EPP device connection standard. Can we keep EPP talk to the EPP thread and focus here on hooking up a hardware UART to the user port? 



You are solving essentially the same problem that the EPP was addressing, with exactly two additions. Why make it different from an already existing standard for no functional improvement?

There IS a functional advantage to moving your Data Waiting to CA1, because then if you wish it can trigger an interrupt.

Having data direction on PB0 or PB3 is the same effect. Having PB3 strobe Data and PB5 strobe Status versus having PA0 strobe both and have PB5 select which is the same effect. Having them use the same pins the same way means they can share that part of their driver code.

The only distinctive feature is that you know you are talking to queues connected to an asynchronous bi directional interface, so it is more efficient to have CTS and DTR directly available. There is no particular reason they couldn't be on PB1 and PB2, which are free in the EPP specification.

Finally, having CA2 as a handshake line allows confirming that your UART manager has received the strobe and is ready to exchange the byte. Even if the UART box will normally not need a delay in normal operation, allowing for that capability will be valuable when debugging the system. And that should be an edge detect rather than latching the state of /DevAck.

 

 

TomXP411
Posts: 1781
Joined: Tue May 19, 2020 8:49 pm

What's the state of play with serial port support?

Post by TomXP411 »



16 hours ago, BruceMcF said:




You are solving essentially the same problem that the EPP was addressing, with exactly two additions. Why make it different from an already existing standard for no functional improvement?



Because I don't care about the EPP standard, and I'm not trying to implement it.

While that was a 3 AM "back of the napkin" idea, I still don't want to get tied down trying to support a protocol meant for Zip drives, scanners, and LapLink. 

 

don’t get me wrong... if there are trivial changes to make, such as switching which pins do what, that’s not a big deal. Right now, I’m going for “working” more than following a specific standard. After all, this is just intended to be a serial bridge, not a general protocol for parallel device attachment. 

TomXP411
Posts: 1781
Joined: Tue May 19, 2020 8:49 pm

What's the state of play with serial port support?

Post by TomXP411 »



On 7/16/2020 at 7:42 AM, Andre said:




You know that the VIA has "handshake mode" on the PA? This is allowing to automatically bump the CA2 line when reading or writing PA, to signal the transfer to an external device. See the VIA datasheet for more details. This is very handy in such situations.



Edit: also, PA and PB can be "latched" on input on positive or negative edge of CA1/CB1 respectively.



Thanks. I haven't dug into VIA programming much, yet. For a first attempt, I just want to see something work. Once I've proven the concept, then we can refine it and implement interrupt handling. But I want to always have the option of polling the port. 

Regardless, since I don't have a Commander - or any 6502 computer with 14 VIA lines free, I can't actually do anything about this except design. I could design a bridge using two Arduinos as a proof of concept, which I may try to do.  God knows I have enough of them floating around here....

BruceMcF
Posts: 1336
Joined: Fri Jul 03, 2020 4:27 am

What's the state of play with serial port support?

Post by BruceMcF »



1 hour ago, TomXP411 said:




Because I don't care about the EPP standard, and I'm not trying to implement it.



While that was a 3 AM "back of the napkin" idea, I still don't want to get tied down trying to support a protocol meant for Zip drives, scanners, and LapLink.



Just saying if you start from the EPP version of the interface instead of the SPP version of the interface like you did, there's less modification required. Customize the general EPP setup to fit the device, add the CTS/DTR lines, job done.

Where a bespoke interface gains the upper hand is when you make use of the CA2 pulse output. If the device you are talking to is fast enough to keep up, you can just set up the port, then write a packet to the port in a loop, or read a packet from the port in a loop, and each read or write gets a pulse output on the CA2 line to tell the external device "store this byte in the FIFO queue" or "fetch the next byte from the FIFO queue", so throughput goes up substantially compared to the EPP approach, you have to strobe each byte with bit banging.



Using the VIA hardware handshaking, you've got a bit of overhead per packet, but for the packet itself, transfer can be as fast as an memory to memory block move.

For that, you want a single strobe and a status/data select bit like you have sketched it, instead of the separate data/address strobes.

But move the strobe from PB0 to CA2, so it can be automatic when reading or writing in a loop, and move Data Waiting to CA1. That gives you the option to have "Data Waiting" trigger an interrupt, and then you can poll Data Waiting in your loop to load as many bytes as have arrived before the interrupt service routine started.

 

Post Reply