Page 3 of 8

External RS-232 Interface, storage, and second screen.

Posted: Thu May 20, 2021 12:12 am
by rje


On 3/3/2021 at 12:06 PM, TomXP411 said:




Part of the intent is to support multiple serial ports simultaneously; one might be used with a level converter for a real RS-232 device, another might be used with an ESP32 for network communication, and another might just connect to another device at TTL levels. 



For example, my use case would be:




  • ESP32 for BBSs and multiplayer games


  • TTL serial port for connecting to Altairduino


  • RS-232 serial port for connecting to Altair 8800 Clone


  • USB for connecting to PC




 



(Question 1) Would this be a card connecting to the User Port, or one of the Expansion Ports?

(Question 2) Would this therefore require different device drivers, one per communication type?  OR..... same API on the X16, implementation on the card itself (ah probably that).

After thinking about it, I suspect this is just patched into the KERNAL I/O routines and redirects for the proper device number.

For example, if Tom and Everyone decided that Device 2 is serial I/O, then his X16 driver would patch to reroute Device 2 commands to his card.

The card would then route the command string to the proper serial connection, and fulfill the work, either making a call or returning response data as requested. 

(Question 3) Would all ports served by this card be handled by ONE device number (e.g. Device 2)?  I think I answered my own question already... maybe.

(Question 4) Can we get a quorum of people supporting the idea of running serial communications off of e.g. Device #2?    I ask this for the sake of application code portability:  the application might expect serial comms to be on a particular Device, and not care which device is actually fulfilling the connection.   OR.... or maybe it doesn't matter?

 


External RS-232 Interface, storage, and second screen.

Posted: Thu May 20, 2021 12:19 am
by rje

  


On 3/3/2021 at 12:06 PM, TomXP411 said:




Part of the intent is to support multiple serial ports simultaneously; one might be used with a level converter for a real RS-232 device, another might be used with an ESP32 for network communication, and another might just connect to another device at TTL levels.



(Question 1)

Would this be a card connecting to the User Port, or one of the Expansion Ports?

 

(Question 2)

Would this therefore require different device drivers, one per communication type?  OR..... same API on the X16, implementation on the card itself (ah probably that).

After thinking about it, I suspect this is just patched into the KERNAL I/O routines and redirects for the proper device number.

For example, if Tom and Everyone decided that Device 2 is serial I/O, then his X16 driver would patch to reroute Device 2 commands to his card.

The card would then route the command string to the proper serial connection, and fulfill the work, either making a call or returning response data as requested. 

 

(Question 3)

Would all ports served by this card be handled by ONE device number (e.g. Device 2)?  I think I answered my own question already... maybe.

 

(Question 4)

Can we get a quorum of people here supporting the idea of running serial communications off of e.g. Device #2?    I ask this for the sake of application code portability:  the application might expect serial comms to be on a particular Device, and not care which device is actually fulfilling the connection.   OR.... or maybe it doesn't matter?

 


External RS-232 Interface, storage, and second screen.

Posted: Thu May 20, 2021 1:28 am
by TomXP411

I think most of those questions are already answered in the design. Did you read the documentation?

 


  1. This plugs into the User port and is accessed by directly manipulating the two data registers. The KERNAL routines are suggested as a convenience, but I’m kind of doubting it will be integrated into the KERNAL at this point, so I would have to supply a machine language driver that would live in Golden RAM or in banked memory. (I’d probably supply several copies of the driver, assembled to different locations.)


  2. The active device is selected via the Secondary address, as stated in the OP. So access to all 4 serial devices would happen on port 2. 


  3. See #2. 


  4. Off topic for this thread. 



External RS-232 Interface, storage, and second screen.

Posted: Thu May 20, 2021 1:45 am
by rje


1 hour ago, TomXP411 said:




I think most of those questions are already answered in the design. Did you read the documentation?



I'd forgotten about it, but I just scanned it again.

It's very nice as far as hardware documentation goes. And, it's great for the stated purposes -- a thing to access the external world from, provided you don't mind banging the bits yourself.

It left me asking, "so where's the API?"  It's in your original post (not in the doc):

OPEN 1,2,3, "9600"
PRINT#1, "http://travellermap.com/data/SPIN/C"

OPEN 2,2,15
INPUT#1, status$, error$, bufferSize$
CLOSE 2

c = val(bufferSize$)
for x (1..c) :rem so sue me, I'm lapsing into pseudocode
{
INPUT#1, byte[x]
}
CLOSE 1

Call the command channel to get the buffer size first, before reading from the input channel.

I think the INPUT# routine could return zeros when there's no more data.  Alternately, it could return strings, and the empty string means "no mas data".

Or something.

 

 


External RS-232 Interface, storage, and second screen.

Posted: Thu May 20, 2021 8:52 pm
by TomXP411

You're adding things that aren't there. There is no http engine, and I have no intention of building one, since there are already IoT http clients out there.

Also, your secondary address is incorrect (the ,3). You have to use SA 10, 11, 12, or 13. These are the Arduino's serial ports 1,2,3, and 4, respectively. SA 14 is reserved for changing settings on the fly (active port, baud rate, parity, data bits, and stop bits). 

INPUT# is also incorrect in this use case. INPUT# works just like INPUT at the console: commas separate input fields, and if you try to INPUT# past the end of the file, you'll get unpredictable results. (I've seen systems lock up, waiting for data, I've seen them return garbage, and I've seen them return the same data as the last call.) In the case of serial communications, INPUT# should wait for a line of input and block the program if there's no data. 

So GET# is what you want for binary or arbitrary text data.

A zero length string ("") should represent "no data waiting". The standard Commodore code returns an empty string when the data is zero: this is an error, as far as I'm concerned, and I would correct that everywhere in the KERNAL. GET# should return "" for "no data" and CHR$(0) when the data is actually a zero byte.

It's also far more likely people will use some sort of AT firmware, so the loop would look more like: 

OPEN 2,2,10

PRINT#2, <command>

INPUT#2, <size>, <status code>  : REM Retrieving HTTP documents with the AT firmware returns an HTTP error code and the length of the document

FOR I=1 TO <size>

GET#2,A$ : IF A$="" THEN <this line>

POKE <buffer>,ASC(A$)

NEXT

CLOSE 2

I'll leave it to you to figure out how to decode the buffer. That is going to be entirely application dependent. 

 

 


External RS-232 Interface, storage, and second screen.

Posted: Fri May 21, 2021 2:39 am
by rje

Those are the sorts of things I don't know about.  Thank you.

 

 

 


External RS-232 Interface, storage, and second screen.

Posted: Wed Jun 09, 2021 5:26 am
by kostrse

Hi, I was also looking for possible options of network connectivity for X16 and stumbled upon this thread.

I read the design doc and very liked it.

I'm not very knowledgeable with hardware, but I would want to share some of my thoughts on the software part of it:

I would make the transport layer between x16 and the external card as abstract and general purpose as possible:

* I would make port numbers purely logical (e.g. 0-255), not bound to any particular physical ports on the external card (e.g. Arduino).

* I would not require to provide parameters like transfer rate from X16, if it's not strictly required for establishing connection between the X16 and the card.

* x16 should not need to know how actual transport between the external card and outside world is implemented (HTTP, USB, COM etc.).

As a programmer I would want:

To have an external card (Arduino or Raspberry) with modern Linux and modern networking stack (Wi-Fi, Ethernet, HTTPS, OpenSSL etc.), and ability to write a server app using any modern programming language (C++, Go, Python etc.) which would listen for incoming connections from the X16, and make requests to outside services using modern protocols (HTTP, SSH, FTP, SMB etc.) with all encryption, authentication, compression etc.

The choice of logical ports between X16 and the server implementation on external card would not be predefined and up to the server implementation, application level protocol also could depend on particular server implementation.

Examples of use cases:

Raspberry Pi with Wi-Fi, connected to internet.

A server application which listens to logical port 100 from X16, as input it accepts URL string, as output it returns binary stream of downloaded file.

On X16, code just opens the port, sends URL strings, reads the incoming byte stream. X16 doesn't know how the actual protocol implemented.

A server application on port 110 provides a lightweight binary protocol for remote file management to X16 (list files, read file, write file, copy file, delete file etc.), and works as a client for SMB or FTP protocols, and makes it possible to access network files from X16.

A server application on port 112 provides primitive telnet protocol to X16 which is being converted to secure SSH connection to outside system.

A server application on port 115 could bridge a game in X16 with the game server in internet.


External RS-232 Interface, storage, and second screen.

Posted: Wed Jun 09, 2021 6:42 pm
by TomXP411

Those are some good notes. I'll address them:


13 hours ago, kostrse said:




I would make the transport layer between x16 and the external card as abstract and general purpose as possible



The connection is currently broken down into an Address and a Data channel. The Address channel is used to select the active port and to control serial parameters. The Data channel is completely transparent, so you can shove through whatever data you want - text, binary data, or even data meant to be UDP or TCP payloads. 


13 hours ago, kostrse said:




* I would make port numbers purely logical (e.g. 0-255), not bound to any particular physical ports on the external card (e.g. Arduino).



Port numbers are entirely at the discretion of the external hardware (ie Arduino). There's nothing in the design or specification that requires port 1 to be the USB port or port 2 to be a serial port or anything like that. If you use an Arduino Mega, there is plenty of room to have several ports of different types, including USB, RS-232, SPI, and TTL serial to a network interface. 

i do NOT plan to directly support a network transceiver, so this should not be used for TCP/UDP data. Instead, you would need to build a smart device externally to handle that. The preferred method at this point would be an ESP32 or ESP8266 running an AT firmware (aka a modem emulator.)


13 hours ago, kostrse said:




* I would not require to provide parameters like transfer rate from X16, if it's not strictly required for establishing connection between the X16 and the card



The purpose of this interface is to connect to RS-232 devices. Other layer 1 protocols, such as I2C or SPI are compatible enough at the data layer, but you should still send the RS-232 initialization sequence, to ensure that if the connection is to an RS-232 device, the UART is configured correctly. Having said that, I expect there to be a default connection speed, which will be 9600,n,8,1 in my reference driver. 

Having said that - SPI connections will simply ignore the parameters that don't make sense for it. SPI does not have a "baud rate", but it does have a maximum speed cap, so I plan to add some basic SPI parameters into the protocol later. I'll probably also work in some way to set the I2C address to allow sub-addressing on an I2C connection. 


13 hours ago, kostrse said:




To have an external card (Arduino or Raspberry) with modern Linux and modern networking stack (Wi-Fi, Ethernet, HTTPS, OpenSSL etc.), and ability to write a server app using any modern programming language (C++, Go, Python etc.) which would listen for incoming connections from the X16, and make requests to outside services using modern protocols (HTTP, SSH, FTP, SMB etc.) with all encryption, authentication, compression etc.



The choice of logical ports between X16 and the server implementation on external card would not be predefined and up to the server implementation, application level protocol also could depend on particular server implementation.



That's a perfectly reasonable use case. In fact, it's one of my expected use cases - using a Pi as an external UART is exactly the kind of this this standard is designed to for.

However, the reference firmware will run on an Arduino Mega, which has 4 serial ports. What you do with it is up to you, but 0-3 should generally be used for RS-232. Use other port numbers as you wish. The important thing is that your software should allow the user to set any port number, and the software should always have the ability to set all of the standard parameters, to allow for any Layer 1 transport to the communication device. (ie: a terminal program needs to set not only baud rate, but should also be able to set SPI speed and I2C channel, in the event someone makes a network modem that runs over SPI.) Never expect that a communication device will run on just the Layer 1 you expect.

If you want to support additional standard protocols and port numbers, it's reasonable to create a list of suggested port numbers for specific purposes. For now, I want to keep that loose, and if you always allow the user to pick a port number and communication parameters, there should be no conflicts with this use case.

 


External RS-232 Interface, storage, and second screen.

Posted: Thu Jun 10, 2021 9:32 am
by TomXP411

As a side note, I'm moving away from the idea of patching the KERNAL to use device 2, and I plan to remove all of that from the documentation (or add it as an addendum.) 

Instead, the reference driver will be accessed via a SYS command, with a jump table at $410. 

$410: Read status from device (updates the buffer counts)

$413: Send a byte 

$416: Read a byte

$419: Send a parameter to the device (parameter in $403, data in $404-40F)

$41C: Read a parameter from the device

$41F: Send a BASIC string

$422: Receive data into a BASIC string

This routine should be fairly small, and I expect to provide binaries assembled for various places in the $400-800 block and at $A000. 

 


External RS-232 Interface, storage, and second screen.

Posted: Thu Jun 10, 2021 10:36 am
by BruceMcF


58 minutes ago, TomXP411 said:




As a side note, I'm moving away from the idea of patching the KERNAL to use device 2, and I plan to remove all of that from the documentation (or add it as an addendum.) 



Instead, the reference driver will be accessed via a SYS command, with a jump table at $410. 



$410: Read status from device (updates the buffer counts)

$413: Send a byte 

$416: Read a byte

$419: Send a parameter to the device (parameter in $403, data in $404-40F)

$41C: Read a parameter from the device

$41F: Send a BASIC string

$422: Receive data into a BASIC string



This routine should be fairly small, and I expect to provide binaries assembled for various places in the $400-800 block and at $A000.



Why $403-$424? Has somebody yelled dibs on $400-$401?