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.


  • serial cables for ZX Spectrum 128/+2/+2A/+3 are available – send me e-mail
  • .sercp is included in since Esxdos-0.8.7
  • .sercp-v0.5
    • improved hw data flow
    • path support for receiving
    • proper return to basic
  • .sercp-v0.5EL – for eLeMeNt ZX
    • works with element’s internal USB serial converter
    • uses hw uart 115200Bd with 2048 B fifo

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 details.
**) latest sercp is ready to date/time handling. It requires latest Esxdos.


  • 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


sercp for Speccy and ESXDOS
sercp v0.3 – for esxdos higher than 0.8.6 included in esxdos-0.8.7
sercp v0.5 included in esxdos since v0.8.8
sercp v0.5EL for eLeMeNt ZX sercp-el.tar
sercp source code for Linux Mac and Windows
sercp v0.3.6 sercp-pc-0.3.6.tar.gz
sercp v0.3.7 sercp-pc-0.3.7.tar.gz
sercp for Windows – exe files 64-bit 32-bit
sercp v0.3.6 sercp.exe sercp32.exe
sercp v0.3.7 sercp.exe

Public git repository is on


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

For eLeMeNt ZX is required .sercp-v0.5EL.You need to replace original file /bin/sercp.

.sercp -h   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   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 with optional path to file

.sercp -r
.sercp -r /path/to

Send file from PC

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

Receive file to PC to actual folder/directory

sercp -d /dev/ttyUSB0 -r
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.

Refinement of operation to eLeMeNt ZX

  • Used internal FTDI USB Serial converter
  • Serial settings: 115200Bd, 8N1, none
    • There is no internal wires to control flow via RTS/CTS – requires the use of a pause while writing to the sd card. See the -w and -n switches of sercp on PC.
  • TODO: add switch .sercp to change baudrate to 38400Bd for compatibility with other Speccy.
  • to install on eLeMeNt ZX you have to do:
    • download sercp-el.tar and copy to the sd card to /tmp
    • .cd /tmp
    • .mv /bin/sercp /bin/sercp-zx – backup original .sercp
    • .tar -x sercp-el.tar – extraxct /bin/sercp
    • .sercp

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 -> longname.ext
  • works in command line
  • tested on Linux (Fedora, Ubuntu, RPi-Raspbian) and Windows (7, 10, 11)
  • 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

Refinement of sercp settings for eLeMeNt ZX

  • sercp-pc-0.3.7 or above is required
  • use -n switch to disable RTS/CTS flow control
  • use -b 115200 for change baudrate
  • use waiting -w 1000 or more for writing blocks to the SD card. Time in milliseconds – 1000..1s
  • on some SD cards, especially on gigabytes full filesystem, writing 16k blocks takes a long time – for example 6 seconds, use -w 6000
sercp.exe -d com6 -b 115200 -n -w 2000 file.tap

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;


Bug reports and patches are welcome by email.
Clone sercp from public git repository:

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


ESXDOS – Papaya Design

RS232 ROM by Paul Farrow

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
  • Jan Kučera LMN128 for eLeMeNt ZX and support