GDB Remote Serial Protocol (RSP)
Spectranext cartridges support the GDB Remote Serial Protocol (RSP), enabling external tools to automate file operations, device control, and debugging tasks. This protocol allows you to build custom tools that interact with the cartridge's onboard XFS filesystem without requiring a web browser or manual file transfers.
Overview
The GDB RSP implementation in Spectranext provides:
- File operations via
vFileprotocol extension - Device-specific operations via
vSpectranextprotocol extension - Standard GDB debugging capabilities (register access, memory read/write, breakpoints)
- Connection via USB CDC or TCP socket (port 1337, for emulators)
Protocol Basics
Packet Format
GDB RSP uses a simple packet-based protocol:
$<data>#<checksum>
Where:
$- Packet start delimiter<data>- Packet payload (can contain any bytes, including null bytes)#- Checksum delimiter<checksum>- Two hex digits representing the 8-bit checksum of all bytes in<data>
Checksum Calculation
The checksum is the sum of all bytes in the data payload, modulo 256:
checksum = sum(ord(byte) for byte in data) & 0xFF
Acknowledgments
- ACK (
+): Sent when a packet is received correctly - NAK (
-): Sent when a packet checksum is invalid or packet is malformed
Interrupt Character
The interrupt character (\x03, Ctrl+C) can be sent at any time to halt execution. It is only processed when the deframer is in idle state (not receiving a packet).
Connection Methods
USB CDC (Serial)
The device appears as a USB CDC serial port (e.g., /dev/ttyACM0 on Linux, COM28 on Windows).
TCP Socket (Emulators)
Connect via TCP socket:
- Host:
localhost(or remote host if GDB server is running remotely) - Port:
1337(default)
The TCP connection is useful when using the Fuse emulator's GDB server.
Protocol Detection
To detect if a device supports Spectranext extensions, send a qSupported query:
$qSupported#<checksum>
The response will include vSpectranext+ if supported:
$PacketSize=4000;qXfer:features:read+;qXfer:auxv:read+;vSpectranext+#<checksum>
vFile Protocol
The vFile protocol extension provides file operations on the cartridge's RAM filesystem. All paths and data are encoded as ASCII-hex (two hex characters per byte).
Packet Format
$vFile:<subcommand>:<args>#<checksum>
Commands
vFile:open
Open a file for reading or writing.
Request:
$vFile:open:<fd>,<flags>,<mode>,<path>#<checksum>
<fd>: File descriptor (hex, ignored, use1)<flags>: Open flags (hex):0x0000= O_RDONLY (read-only)0x0001= O_WRONLY (write-only)0x0002= O_RDWR (read-write)0x0008= O_APPEND (append mode)0x0100= O_CREAT (create if not exists)0x0200= O_CREAT | O_TRUNC (create and truncate)
<mode>: File mode (hex, ignored)<path>: File path (ASCII-hex encoded)
Response:
- Success:
F<fd>where<fd>is the file descriptor (hex, typically1) - Error:
F-1,<errno>where<errno>is the error number (hex)
Example:
Request: $vFile:open:1,2,0,2f746573742e747874#<checksum>
(opens "/test.txt" for read-write)
Response: F1
vFile:close
Close an open file.
Request:
$vFile:close:<fd>#<checksum>
<fd>: File descriptor (hex)
Response:
- Success:
F0 - Error:
F-1,<errno>
Example:
Request: $vFile:close:1#<checksum>
Response: F0
vFile:pread
Read data from an open file (sequential read from current position).
Request:
$vFile:pread:<fd>,<count>#<checksum>
<fd>: File descriptor (hex)<count>: Number of bytes to read (hex)
Response:
- Success:
<hex-data>(hex-encoded binary data, no prefix) - Error:
F-1,<errno>
Example:
Request: $vFile:pread:1,100#<checksum>
(read 256 bytes)
Response: 48656c6c6f20576f726c64...
(hex-encoded "Hello World...")
vFile:pwrite
Write data to an open file (sequential write at current position).
Request:
$vFile:pwrite:<fd>,<hex-data>#<checksum>
<fd>: File descriptor (hex)<hex-data>: Binary data encoded as ASCII-hex (two hex chars per byte)
Response:
- Success:
F<bytes-written>where<bytes-written>is the number of bytes written (hex) - Error:
F-1,<errno>
Example:
Request: $vFile:pwrite:1,48656c6c6f#<checksum>
(write "Hello" = 0x48 0x65 0x6c 0x6c 0x6f)
Response: F5
(5 bytes written)
vFile:size
Get the size of a file.
Request:
$vFile:size:<path>#<checksum>
<path>: File path (ASCII-hex encoded)
Response:
- Success:
F<size>where<size>is the file size in bytes (hex) - Error:
F-1,<errno>
Example:
Request: $vFile:size:2f746573742e747874#<checksum>
(get size of "/test.txt")
Response: F1000
(file is 4096 bytes)
vFile:exists
Check if a file exists.
Request:
$vFile:exists:<path>#<checksum>
<path>: File path (ASCII-hex encoded)
Response:
- Exists:
F,1 - Not exists:
F,0 - Error:
F-1,<errno>
Example:
Request: $vFile:exists:2f746573742e747874#<checksum>
Response: F,1
vFile:unlink
Delete a file.
Request:
$vFile:unlink:<path>#<checksum>
<path>: File path (ASCII-hex encoded)
Response:
- Success:
F0 - Error:
F-1,<errno>
Example:
Request: $vFile:unlink:2f746573742e747874#<checksum>
Response: F0
vSpectranext Protocol
The vSpectranext protocol extension provides Spectranext-specific operations for device control and directory operations.
Packet Format
$vSpectranext:<subcommand>:<args>#<checksum>
Commands
vSpectranext:reboot
Trigger a ZX Spectrum reboot.
Request:
$vSpectranext:reboot#<checksum>
Response:
- Success:
OK(sent before reboot)
Example:
Request: $vSpectranext:reboot#<checksum>
Response: OK
(device reboots immediately after)
vSpectranext:autoboot
Configure autoboot from xfs://ram/ and reboot the device.
Request:
$vSpectranext:autoboot#<checksum>
Response:
- Success:
OK(sent before reboot) - Error:
E<errno>
Example:
Request: $vSpectranext:autoboot#<checksum>
Response: OK
(device configures autoboot and reboots)
vSpectranext:opendir
Open a directory for reading.
Request:
$vSpectranext:opendir:<path>#<checksum>
<path>: Directory path (ASCII-hex encoded)
Response:
- Success:
OK - Error:
E<errno>
Example:
Request: $vSpectranext:opendir:2f#<checksum>
(open root directory "/")
Response: OK
vSpectranext:readdir
Read the next directory entry.
Request:
$vSpectranext:readdir#<checksum>
Response:
- Success:
FOK,<name>,<type>,<size>where:<name>: File/directory name (ASCII-hex encoded)<type>:Ffor file,Dfor directory<size>: File size in bytes (hex, ignored for directories)
- End of directory: `` (empty string)
- Error:
E<errno>
Example:
Request: $vSpectranext:readdir#<checksum>
Response: FOK,746573742e747874,46,1000
(file "test.txt", type file, size 4096 bytes)
Request: $vSpectranext:readdir#<checksum>
Response:
(end of directory)
vSpectranext:closedir
Close an open directory.
Request:
$vSpectranext:closedir#<checksum>
Response:
- Success:
OK - Error:
E<errno>
Example:
Request: $vSpectranext:closedir#<checksum>
Response: OK
vSpectranext:mv
Move/rename a file or directory.
Request:
$vSpectranext:mv:<old-path>,<new-path>#<checksum>
<old-path>: Current path (ASCII-hex encoded)<new-path>: New path (ASCII-hex encoded)
Response:
- Success:
OK - Error:
E<errno>
Example:
Request: $vSpectranext:mv:2f6f6c64,2f6e6577#<checksum>
(rename "/old" to "/new")
Response: OK
vSpectranext:mkdir
Create a directory.
Request:
$vSpectranext:mkdir:<path>#<checksum>
<path>: Directory path (ASCII-hex encoded)
Response:
- Success:
OK - Error:
E<errno>
Example:
Request: $vSpectranext:mkdir:2f6d79646972#<checksum>
(create "/mydir")
Response: OK
vSpectranext:rmdir
Remove an empty directory.
Request:
$vSpectranext:rmdir:<path>#<checksum>
<path>: Directory path (ASCII-hex encoded)
Response:
- Success:
OK - Error:
E<errno>
Example:
Request: $vSpectranext:rmdir:2f6d79646972#<checksum>
Response: OK
Error Codes
Error responses use standard errno values:
0= Success (no error)2= ENOENT (No such file or directory)5= EIO (Input/output error)9= EBADF (Bad file descriptor)12= ENOMEM (Out of memory)17= EEXIST (File exists)20= ENOTDIR (Not a directory)21= EISDIR (Is a directory)22= EINVAL (Invalid argument)27= EFBIG (File too large)28= ENOSPC (No space left on device)39= ENOTEMPTY (Directory not empty)
Implementation Notes
Sequential I/O
vFile:pread and vFile:pwrite perform sequential I/O from the current file position. The position advances automatically after each read or write operation.
Path Encoding
All paths must be encoded as ASCII-hex (two hex characters per byte). For example:
/→2f/test.txt→2f746573742e747874/my dir/file.bin→2f6d79206469722f66696c652e62696e
Binary Data Encoding
Binary data in vFile:pwrite requests must be hex-encoded. Binary data in vFile:pread responses is returned as hex-encoded.
Packet Size Limits
The maximum packet size is as advertised in qSupported.
For large file transfers, split data into multiple vFile:pwrite operations.
Reference Implementation
The spx command-line tool (sdk/bin/spx.py) provides a complete reference implementation of the GDB RSP protocol for Spectranext. You can use it as a reference for building your own tools.
See Also
- Syncing with Computer - Using the
spxtool for file operations - XFS Filesystem - Understanding the onboard filesystem
- GDB Remote Serial Protocol Specification - Official GDB RSP documentation