sercp

Sercp [stands for Serial copy] is brand new software for ZX Spectrum and PC intended to send/receive files of any kind between computers. On ZX side Sercp is designed to work as external command of Esxdos. It uses built-in serial port of Spectrum +128K, +2, +2A, +3 connected to internal sound chip’s I/O pins. Main motivation for this project was a need to share files between PC and ZX and sometimes between two ZXs using just standard built-in stock hardware.

News

  • .sercp is included in Esxdos-0.8.7
  • .sercp-v0.3 uses new Esxdos’s syscall utime
  • serial cables for ZX Spectrum 128/+2/+2A/+3 are available – send me e-mail

Main features

  • fastest and most convenient way to send/receive any files to/from Speccy without additional communication hardware
  • works well with USB-serial cables as well as standard COM ports (RS-232 standard)
  • no need to frequently eject/insert card or disk no more carrying physical media from PC to ZX and vice versa
  • transfer is also possible between two Speccys – no need to use PC
  • Serial settings: 38400Bd, 8N1, RTS/CTS flow control*
  • tested with USB-Serial converters on PC side with following chips: FTDI, PL2303, CP2102 and CH340
  • file date/time transfer support**

*) flow control is used only between blocks – see the technical detail
**) latest sercp is ready to date/time handling. It requires latest esxdos

Limitations

  • no re-initiate transfer of bad blocks
  • uses Speccy’s RAM from 0xC000 to 0xFFFF – see technical information
  • works well with files up to 300kB, larger files copy takes too long
  • no LFN support*

*) support will be added after Esxdos gets this feature

Download

sercp for Speccy and ESXDOS
sercp v0.2 sercp-zx-0.2
sercp v0.3 – for esxdos higher than 0.8.6 included in esxdos-0.8.7
sercp for Linux and Mac- source code
sercp v0.2.3 sercp-pc-0.2.3.tar.gz
sercp v0.3 *) sercp-pc-0.3.0.tar.gz
sercp for Windows – exe files 64-bit 32-bit
sercp v0.2 sercp.exe sercp32.exe
sercp v0.3 *) sercp.exe sercp32.exe

*) sercp v0.3 is backward compatible with sercp-zx-v0.2

Public git repository is on https://vym.cz/cgit/sercp-pc

Installation

ESXDOS: copy (by the traditional way*) sercp to /bin folder and use as common external command by .sercp

.sercp -h            ....is good starting point

PC: copy sercp (sercp.exe or sercp32.exe) to path where system finds command. On Linux suggested location is /usr/local/bin. On Windows there is no good place – you can copy sercp.exe to c:\Windows\system\ or similar suitable. Sorry I’m not Windows user.

sercp -h            ....is good starting point

*) traditional way for copying takes many steps: turn off the spectrum, remove CF/SD card, connect card to PC, (auto)mount filesystem, find target folder, find source folder, copy file, unmout card, remove card from pc, connect card to ZX, turn on the Spectrum…

Compiling from sources

make - compile sources to linux executable file
make install - install sercp  to /usr/local/bin
make windows - compile windows exe files - uses mingw

Add user to groupdialout“ – no need to run sercp as root (or sudo).

sudo usermod dialout -a -G "user"

On some Linux systems may be useful to remove modemmanager.

sudo apt-get remove modemmanager

Using sercp

Send file from Spectrum

.sercp filename.ext
.sercp /path/to/filename.ext

Receive file to Spectrum to actual folder/directory

.sercp -r

Send file from PC

  ---Linux---
sercp -d /dev/ttyUSB0 filename.ext
sercp -d /dev/ttyUSB0 /path/to/filename.ext
  ---Windows---
sercp.exe -d com5 filename.ext
sercp.exe -d com5 \path\to\filename.ext

Receive file to PC to actual folder/directory

  ---Linux---
sercp -d /dev/ttyUSB0 -r
  ---Windows---
sercp.exe -d com5 -r

Serial cables

Following schematics show cable connection between ZX and PC. Null modem cable allows to connect two ZXs.

The connector used at Speccy’s serial port is 6-way telephone jack BT631A. ZX Spectrum +128K issue 9G has DB9M connector like ZX Interface 1.

On PC side DB-9F is used to enable easy connection to PC’s serial port / USB-serial converter.

*) ZX Null modem cable for connecting two ZX Spectrums 128. Main difference between standard NULL modem cable and ZX NULL modem cable are connectors DB9M and incomplette wiring. Schema show the solution which is sufficient for serial transfer on ZX.

Standard null modem cable is not usable for ZX<->PC transfer, because it has two DB9F connectors. It is usable for sercp copying files between two PC’s though.


Technical information about sercp on Speccy

  • Transfer is realized on block basis. Each transfer adds a structure called fileinfo which contains filename, length and checksum of each block.
  • Hardware flow control is used between blocks not between bytes
  • Block size is 16kiB. Last block may be shorter.
  • Checksums of blocks is realized as XOR of all bytes and 8-bit SUM of all bytes (both together) – see fileinfo.
  • Filename format is 8.3 DOS format, no LFN for Esxdos v0.8.x.
  • sercp uses Speccy’s RAM from 0xC000 to 0xFFFF as 16kiB buffer for blocks
  • The stack is saved in Esxdos’s RAM and after transfer the stack is recreated to its original place. No need to move RAMTOP.

Technical information about sercp on PC

  • converts long file names to 8.3 format – first 4 character plus last 8 characters (last 4 characters of name and 4 for suffix „.ext“). Example: longfilename.ext
  • works in command line
  • tested on Linux (Fedora, Ubuntu, RPi-Raspbian) and Windows (XP, 7)
  • waits until Speccy saves block on storage – waits about 800 ms and uses hardware flow control for testing when Speccy is ready to receive next block
  • source code is available – see download section

fileinfo – internal structure

Fileinfo structure is sent/received before actual file data. Fileinfo size is 1109 bytes. Fileinfo can hold information relevant for up to 256 blocks. Max. file length is 256 x 16kiB = 4MiB. Four megabytes ought to be enough for anyone…

typedef struct {
	uint16_t block_len;	// legth of block
	uint8_t  block_xor;	// xor of all bytes in block
	uint8_t  block_sum;	// 8-bit sum of all bytes in block
} __attribute__((packed)) fi_sum;// used as fi_blocks in fileinfo

typedef struct {
	uint16_t length;	// length of data in fileinfo
	uint8_t h_xor;		// xor of all bytes of fileinfo
	uint8_t h_sum;		// sum of all bytes of fileinfo
	uint8_t fi_numblocks;	// number of transfered blocks
	uint8_t fi_name[64];	// filename (8.3 format for now)
	uint8_t fi_reserved[12];// reserved
	uint16_t fi_time[1];	// fat file time
	uint16_t fi_date[1];	// fat file date
	fi_sum fi_blocks[256];	// blocks - see fi_sums above
} __attribute__((packed)) FILEINFO;

Development

Bug reports and patches are welcome by email.
Clone sercp from public git repository: https://vym.cz/cgit/sercp-pc


How was sercp born

Sercp is based on the fast serial transfer routines (written by me ;]). Word „fast“ means really fast relatively to using AY-3-8912’s I/O ports. There are some projects using higher speed than 38.4kBd. For example very nice ROM modification RS-232 ROM from Paul Farrow that works at 57600Bd. But it uses hardware flow control for each byte, overall speed is lower than routines in sercp.

Some „benchmarks“ which I’ve done, show that the baud rate isn’t basic precondition for „fast“ transfer. I’m still writing about ZX Spectrum 128 and his processor Z80 at 3.54MHz… I tried to write routines which send data from speccy at 115200Bd. The duration of one bit takes 31 tacts (T) of Z80. It works (see the code snippet bellow), but preparing bits to send takes more time between bytes and resulting overall speed of transfer is low. Many other serial routines written for speccy and AY suffer from this problem. Receiving at 115200Bd is unrealizable in my opinion …

; send bit @115200Bd
	nop		;4T  waiting
	nop		;4T  waiting
	ld a, (hl)	;7T  sending prepared bit
	inc l		;4T  inc pointer to the next bit
	out (c),a	;12T bit out
			;___
			;31T ~ 115200Bd

I decided that most effective baud rate will 38400Bd (~91T per bit). The routines for sending and receiving the data looks similar, but there is some time gap between sending (receiving) bits to rotate accumulator, increase pointer to data and tests for Break key and end of data block. Of course every action is done during actual byte time slot. Byte transfer has precise timing based on start bits. All receiving/sending data manipulation are done at the time of transmission each byte, that allows to use only one stop bit and next byte can folow immediatelly. There is no need (and no time ;]) to flow control between every byte. These facts are the reason what sercp works well with USB-serial cables.

Next step was to write code to read/write files from/to disk using „ultimate“ disk operating system for Speccy – ESXDOS. Doing this was amazingly easy with Esxdos services. Many thanks to Miguel Guerreiro for providing Esxdos programmers documentation.

Scope pictures

Speccy is waiting for startbit. Orange pulses – reading AY
Waiting for startbit – with test Break key. Orange pulses – reading AY, red pulse – writing to AY
Speccy is receiving real data. Orange pulses – reading bits. Red pulses – clear CTS output.
Speccy is sending 0xAA. Red pulses – writing „bits“ to AY.
Speccy is sending 0xAA – timebase 1ms.
Speccy’s one stopbit. One means one…
Speccy is receiving real data.
Three (sometimes two or four) orange pulses close behing each other – waiting for startbit
Cursors points to middle of the receiving bits. You can see that stop bit reading is omitted.
Comparsion of sendig 0xAA byte. White is PC, brown is Speccy.
You can see that PC’s stopbit is more longer – feature of the PL2303 USB-serial chip.
Speccy is sending real data. Stopbit and startbit are lost in bits…

Some multimedia data

AY-3-8912 and osciloscope probes
Detail of probes – RS232-TTL Rx and Tx pins
Sercp in action between two Speccys. Sorry for shaking hand…
Sercp was tested on ZXS 128-rev.6A / 128-rev.9G / +2 / +2A / +3

Benchmark results

; Serial port benchmark - ZX128 toastrack to PC-Linux
; ttyUSB or ttyS selected
; theoretical speed of data 
; flow speed = Bd / number_of_bits (1 startbit + 8 bits + 1 stopbit)
;				sercp		RS232-ROM
; 115200Bd = 11,52 kB/s		2.62 kB/s	n/a
;  57600Bd =  5.76 kB/s		3.36 kB/s	3.29 kB/s
;  38400Bd =  3.84 kB/s		3.65 kB/s	n/a

For comparsion: PC to PC (ttyUSB0 to ttyS4)  3.72 kB/s @38400Bd

Resources

ESXDOS – Papaya Design http://esxdos.org

RS232 ROM by Paul Farrow http://www.fruitcake.plus.com/Sinclair/Interface2/Cartridges/Interface2_RC_New_RS232.htm

Greetings and many thanks to

  • Dusky UB880D for code review and Esxdos support
  • Ikon for text review and moral support
  • Mikezt, Ellvis and Busy for moral support
  • Miguel Guerreiro for his work on ESXDOS