One of the things I often need to do is transfer files to and from my QX-10/16 systems. I had been using the original SysV implementation from 1994 for some time, but it has some issues mostly stemming from the fact it requires stdin/out redirection to function.

To that end I wrote a new modern implementation of the filink protocol in rust. I used the filink.c SysV implementation written by Frank Cringle as a reference for understanding the basic state machine used by the protocol.

This version supports specifying the serial port when running it allowing it to directly setup the serial port parameters and read and write to the serial port itself rather than rely on shell redirection.

You can find the current release on my github/filink-rs page.

Usage

By default filink talks to the serial port at 9600 baud, 8 data bits, no parity and 1 stop bit. These can each be changed with the --baud, --data-bits, --parity and --stop-bits options if your setup needs something different. On the QX side you run the matching filink program from CP/M, I have been using QXFILINK.COM on my QX-16.

Receiving a file

filink --port <port> receive [--output-dir <dir>]

Received files are written to the current directory by default. Use --output-dir to put them somewhere else.

Sending a file

filink --port <port> send <path/to/file>

Since the protocol predates long filenames, names are automatically converted to CP/M’s 8.3 format on the way out, uppercased and space padded. So document.txt arrives as DOCUMENTTXT and archive.tar.gz becomes ARCHIVE TAR.

Larger transfers have a tendency to hang at higher baud rates. The trouble is that if a byte gets dropped the two ends lose sync, and since each side then ends up waiting on data the other is never going to send, the acks stop and the transfer stalls. Adding a small delay between each byte sent with --byte-delay gives the receiving end time to keep up and avoids the problem. I have found a value of 2 gives a stable transfer at 9600 baud:

filink --port <port> --baud 9600 --byte-delay 2 send <path/to/file>

If a transfer is misbehaving the --debug flag will print a trace of the protocol handshake so you can see where things are getting stuck.