surl-server – a serial proxy for 8bit computers

surl-server is a serial-to-network proxy designed for 8bit computers, and especially for the Apple II series. It is based on libraries like CURL, jq, ffmpeg, CUPS, and more, and provides a way for these old computers to :

  • Fetch and send data over the internet, using any protocol CURL supports
  • Parse JSON responses
  • Convert text from UTF-8 to the native charset and vice-versa
  • Convert modern image formats to native graphics representation
  • Stream video
  • Stream audio
  • Pretend to be an ImageWriter II and print files sent to it
  • Provide two virtual volumes to ProDOS

Installing surl-server

The easiest way to install the proxy is to get the pre-built Raspberry image from my github’s Releases page.

Download the latest surl-server-bullseye-YYYY-MM-DD-lite.img.gz.

Uncompress it and copy it to a micro-SD card. You can do it using command-line on most platforms, or use a tool like Balena Etcher to do it interactively. Here is how to do it via command-line (substitute YYYY-MM-DD for the file you downloaded, and /dev/mmcblk0 for your microSD’s device file):

gunzip surl-server-RELEASE-YYYY-MM-DD-lite.img.gz
sudo dd if=surl-server-RELEASE-YYYY-MM-DD-lite.img of=/dev/mmcblk0

You can now insert the microSD card in a Raspberry, plug it into your Ethernet network, and boot it.

By default, the booted OS will present itself on the local network as surl-server.local. You can ssh to it using the default Raspberry login and password: pi/raspberry.

Serial configuration

The main surl-server configuration file is located in either /usr/local/etc/a2tools/tty.conf or /etc/a2tools/tty.conf, depending on whether you built it yourself, or used the Raspberry image.

If this file is absent, running surl-server will provide you with an example configuration file:

tty: /dev/ttyUSB0
baudrate: 115200
hw_handshake: off
aux_tty: /dev/ttyUSB1
aux_baudrate: 9600

The only parameter you should need to change is the tty: adapt it to the device name of your USB-serial adapter. The aux_tty: parameter is optional and only used by Wozamp, Woztubes and Mastodon video players, or for the virtual printer feature.

If you want to use the dual-port setup, the hardest part is to make sure the USB-serial adapters are recognized correctly each time. In order to achieve that, the easiest is to have two different models of USB adapters, and configure tty.conf in this way: plug in one USB adapter and do

root@surl-server:~# ls -l /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 11 avril 03:17 usb-Prolific_Technology_Inc._USB-
Serial_Controller-if00-port0 -> ../../ttyUSB0

Plug the second one and re-do the same command:

root@surl-server:~# ls -l /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 11 avril 03:17 usb-FTDI_FT232R_USB_UART_AB0PXCGI-
if00-port0 -> ../../ttyUSB1
lrwxrwxrwx 1 root root 13 11 avril 03:17 usb-Prolific_Technology_Inc._USB-
Serial_Controller-if00-port0 -> ../../ttyUSB0

You now know which is which and you can set these paths into tty.conf:

root@surl-server:~# cat /etc/a2tools/tty.conf
tty: /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-
Serial_Controller-if00-port0
baudrate: 115200
hw_handshake: on
aux_tty: /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AB0PXCGI-if00-port0
aux_baudrate: 9600

If you change the baudrate, the client programs will need reconfiguration too. They will suggest you do so when they fail connecting to the proxy. Audio and audio-video streaming requires 115.200bps on the main tty. Virtual printing requires 9600 bps on aux_tty. There is no reason that you would need to change the baudrates.

Setting up virtual ImageWriter II printing

As you now know, surl-server can stream video using a second serial port. The rest of the time, this port is unused, but surl-server listens on it for any data from the connected computer. If it receives some, it will consider that the computer is printing to an ImageWriter II, and prepare a Postscript file with the print result, or send it to a real printer.

Getting Postscript files

If you’re running the proxy from the provided Raspberry image, each print result will be made available by default in the prints directory of the FTP server at ftp://surl-server.local/.

If you want to have these directly sent to a printer, you can configure it as you would configure any CUPS server. By default, surl-server will try to send each Postscript file to the default printer, if it exists. You can set a default printer on the proxy quite easily, for example:

ssh pi@surl-server.local

# List available printers
$ sudo lpstat -v

# Set printer "HP-M281" as default
$ sudo lpadmin -d HP-M281

If your setup is more complicated, you can forward the CUPS administration port to your computer:

ssh -L 6311:localhost:631 pi@surl-server.local

then use a browser to get to http://localhost:6311/

Configuring printing options

The virtual printer options are defined in either /usr/local/etc/a2tools/printer.conf or /etc/a2tools/printer.conf, depending on whether you built surl-server yourself, or used the Raspberry image.

The file is commented and the settings should be self-explanatory.

Using surl-server as only a printer emulator

If you want to print from your Apple II, but are not interested in my programs that make use of the proxy, you can use it as a printer emulator only, with a single USB-serial emulator. For this, set the tty parameter of tty.conf to a non-existent file, and aux_tty to your only USB-serial adapter.

Configuring VSDrives – Virtual serial drives

Surl-server implements VSDrive, a virtual drive protocol as provided by ADTPro or veserver.py. This allows ProDOS to access up to two remote volume images of up to 32MB. Some of the programs that use surl-server make use of storage and have the corresponding client (Mastodon, STP, and the image viewer).

The configuration file defining which images to server is /usr/local/etc/a2tools/vsdrive.conf or /etc/a2tools/vsdrive.conf, depending on whether you built surl-server yourself, or used the Raspberry image. The Raspberry image ships preconfigured to serve a single 32MB blank volume.

Upgrading surl-server

It is quite often that the programs I develop for my Apple II require modifications to the proxy. It is often new features, but sometimes reworking of existing features; this means that the client program and the proxy have to agree on a protocol to talk to each other. To make sure mismatches don’t happen, a protocol version number is exchanged between the client and the proxy. If you get “surl-server Protocol X required”, this means you either have a too old, or too recent, surl-server. To upgrade it, you can either download a new image from my Releases page, or ssh to the surl-server proxy and issue the following commands:

sudo apt update
sudo apt install --reinstall surl-server

Minimal requirements

The surl-server proxy is relatively lightweight, and will function with a good level of performance on a Raspberry Pi 3. Some features are more CPU intensive, for example video streaming. You would wait a shorter time to watch streamed videos with a Raspberry Pi 4.

Deploying on other hardware

A Rapsberry Pi is not a requirement. surl-server will happily run on a normal computer. No pre-built binaries are provided for this, but you can compile it yourself easily under Linux:

git clone https://github.com/colinleroy/a2tools.git
cd a2tools

#install build dependancies (you can check the uptodate
#list in src/debian/control, Build-Depends section)

sudo apt install libcurl4-gnutls-dev libgumbo-dev libpng-dev \
  libjq-dev libsdl-image1.2-dev libavcodec-dev libavformat-dev \
  libavfilter-dev libavutil-dev libswresample-dev libmagic-dev \
  libcups2-dev libfreetype-dev

cd src/surl-server
make clean all install