Skip to main content

XFS Filesystem

XFS is Spectranext's local filesystem that provides access to RAM-based storage directly from Spectrum programs. It allows you to transfer files from your computer and access them from your Spectrum programs.

Overview

XFS provides:

  • RAM Filesystem Access: Access files stored in Spectranext's RAM filesystem
  • Standard VFS Interface: Uses Spectranet's standard VFS (Virtual File System) API with xfs:// prefix
  • File Operations: Read, write, list, create, delete files and directories with standard Spectranet BASIC commands
  • Development Workflow: Transfer files via USBFS, access from Spectrum programs

Mounting XFS

To use XFS, you must first mount it. XFS uses the protocol name "xfs" and a hostname to specify which filesystem to mount.

Mounting RAM Filesystem

The RAM filesystem is mounted using the protocol "xfs://ram/":

From BASIC:

%mount 0, "xfs://ram/"

Keep in mind, that mounting can be happen automatically upon boot.

Unmounting:

%umount 0

Mount Points

Spectranet supports up to 4 mount points (0-3). Each mount point can have a different filesystem mounted:

  • Mount Point 0: Typically used for primary filesystem
  • Mount Points 1-3: Available for additional filesystems

You can switch between filesystems using:

%fs 0    ; Switch to filesystem 0

Copying Files from Your Computer

Before accessing files from Spectrum, you need to copy them to the RAM filesystem using USBFS tools.

Using XFS Tools

  1. Connect USB-C: Connect Spectranext to your computer with USB-C Cable
  2. Source helper script:
    source tools/xfs.sh
  3. Upload files:
    xfs-put ./program.tap program.tap
    xfs-put ./data.txt data.txt

Accessing Files from Spectrum

Once XFS is mounted, you can access files using standard Spectranet VFS operations.

Opening Files

From BASIC (using streams):

%open #4, "program.tap", "r"    ; Open for reading
%open #5, "output.txt", "w" ; Open for writing

Streams are numbered starting from #4 (streams #0-#3 are reserved for Spectrum system use).

From Assembly:

; Open file for reading
ld hl, filename
ld de, O_RDONLY ; Open flags
call OPEN ; ROM routine at 0x3EB1
; Returns file handle in HL (carry set on error)

File Flags:

  • O_RDONLY (0x01) - Open for reading
  • O_WRONLY (0x02) - Open for writing
  • O_RDWR (0x03) - Open for reading and writing
  • O_CREAT (0x04) - Create file if it doesn't exist
  • O_TRUNC (0x08) - Truncate file to zero length

Reading Files

From BASIC (using streams):

10 %open #4, "program.tap", "r"
20 %oneof 100
30 INPUT #4, a$
40 PRINT a$
50 GO TO 30
100 %close #4

This example opens a file and reads it line by line. The %oneof command catches end-of-file conditions.

Loading entire files:

%load "program.tap"              ; Load BASIC program
%load "image" CODE 16384 ; Load binary data at address
%aload "machinecode" CODE 32768 ; Load arbitrary data (no TAP header)

From Assembly:

ld hl, file_handle
ld de, buffer
ld bc, 256 ; Number of bytes to read
call READ ; ROM routine at 0x3EC9
; Returns bytes read in HL (carry set on error)

Writing Files

From BASIC (using streams):

10 %open #4, "output.txt", "w"
20 PRINT #4; "Hello, world!"
30 PRINT #4; "Line 2"
40 %close #4

Saving files:

%save "program"                  ; Save BASIC program
%save "image" CODE 16384,6912 ; Save binary data
%save "program" LINE 1 ; Save from specific line

From Assembly:

ld hl, file_handle
ld de, buffer
ld bc, 256 ; Number of bytes to write
call WRITE ; ROM routine at 0x3ECC
; Returns bytes written in HL (carry set on error)

Closing Files

From BASIC:

%close #4

Important: Always close files when done to free resources.

From Assembly:

ld hl, file_handle
call VCLOSE ; ROM routine at 0x3ED2

Listing Directories

From BASIC:

%cat                     ; List current directory
%cat "games" ; List subdirectory
%cat "0:/foo/bar" ; List specific path

The %cat command displays directory contents. Paths work like Unix paths with "/" as the separator. Use "." for current directory and ".." for parent directory.

From Assembly:

; Open directory
ld hl, "." ; Current directory
call OPENDIR ; ROM routine at 0x3EAE
; Returns directory handle in HL

; Read directory entry
ld hl, dir_handle
call READDIR ; ROM routine at 0x3ED8
; Returns entry in buffer (carry set on end of directory)

; Close directory
ld hl, dir_handle
call CLOSEDIR ; ROM routine at 0x3EDB

Changing Directory

From BASIC:

%cd "/"                  ; Change to root directory
%cd "games" ; Change to subdirectory
%cd "/programs/basic" ; Change to specific path
%cd ".." ; Change to parent directory

From Assembly:

ld hl, filename
ld de, stat_buffer
call STAT ; ROM routine at 0x3EC3
; Fills stat structure at DE (carry set on error)

The stat structure contains:

  • File mode (permissions)
  • File size
  • Access/modification times
  • User/group IDs

Complete BASIC Example

Here's a complete example that mounts XFS, lists files, loads a program, and reads a file:

10 REM Mount XFS filesystem
20 %mount 0, "xfs://ram/"
30
40 REM List directory contents
50 %cat
60
70 REM Change to a subdirectory
80 %cd "games"
90 %cat
100
110 REM Load a program
120 %load "program.tap"
130
140 REM Read a text file line by line
150 %open #4, "data.txt", "r"
160 %oneof 200
170 INPUT #4, a$
180 PRINT a$
190 GO TO 160
200 %close #4
210
220 REM Unmount when done
230 %umount 0

Complete Assembly Example

Here's a complete assembly example that mounts XFS, lists files, and reads a file:

.include "spectranet.inc"

.data
mount_protocol: defb "xfs",0
mount_hostname: defb "ram",0
mount_source: defb 0
mount_user: defb 0
mount_password: defb 0

mount_struct:
defw mount_protocol
defw mount_hostname
defw mount_source
defw mount_user
defw mount_password

filename: defb "program.tap",0
buffer: defs 256

.text
main:
; Mount XFS
ld ix, mount_struct
ld a, 0
call MOUNT
jr c, mount_error

; Open file
ld hl, filename
ld de, O_RDONLY
call OPEN
jr c, open_error
ld (file_handle), hl

; Read file
ld hl, (file_handle)
ld de, buffer
ld bc, 256
call READ
jr c, read_error

; Close file
ld hl, (file_handle)
call VCLOSE

; Unmount
ld a, 0
call UMOUNT

ret

mount_error:
; Handle mount error
ret

open_error:
; Handle open error
ret

read_error:
; Handle read error
ret

.bss
file_handle: defw 0

Development Workflow

Typical Workflow

  1. Develop on Computer: Write and compile your program
  2. Upload to RAM: Use xfs-put to upload files to RAM filesystem
  3. Mount XFS: Mount XFS filesystem from Spectrum BASIC: %mount 0, "xfs://ram/"
  4. Access Files: Use standard Spectranet BASIC commands (%load, %save, %cat, %open, etc.)
  5. Test: Run your program and test file access
  6. Iterate: Make changes, re-upload, and test again

Example Build Script

#!/bin/bash
# Build and upload script

# Compile program
zcc +zx -o program.tap program.c

# Upload to RAM filesystem
xfs-put program.tap program.tap

# Upload data files
xfs-put data.txt data.txt
xfs-put sprites.bin sprites.bin

Then from Spectrum BASIC:

%mount 0, "xfs://ram/"
%load "program.tap"

File Paths

XFS Tool Paths

When using XFS tools, paths are relative to the RAM filesystem root:

  • program.tap - File in root directory
  • games/game.tap - File in subdirectory
  • data/sprites.bin - File in nested subdirectory

Spectrum Program Paths

When accessing from Spectrum programs after mounting, use standard Spectranet paths:

  • program.tap - File in current directory
  • games/game.tap - File in subdirectory
  • ../other.txt - File in parent directory
  • . - Current directory
  • / - Root directory
  • 0:/path/to/file - Explicit filesystem prefix (optional)

Note: Paths work like Unix paths with "/" as the directory separator. The current directory can be changed with %cd.

XFS Internals

XFS Registers

XFS uses page 0x49 (XFS_SPECTRANET_PAGE) for its registers. When Page A is mapped to 0x49, the XFS registers are accessible at address 0x1000.

The XFS registers structure (xfs_registers_t) includes:

  • Command register: Command to execute (MOUNT, OPEN, READ, etc.)
  • Status register: Current status (IDLE, BUSY, COMPLETE, ERROR)
  • Result register: Error code or success indicator
  • File handle: Handle for file/directory operations
  • Arguments: Command-specific arguments
  • Workspace: Data transfer buffer (1024 bytes)

XFS Commands

  • XFS_CMD_MOUNT (1) - Mount filesystem
  • XFS_CMD_OPEN (2) - Open file
  • XFS_CMD_READ (3) - Read from file
  • XFS_CMD_WRITE (4) - Write to file
  • XFS_CMD_CLOSE (5) - Close file
  • XFS_CMD_OPENDIR (6) - Open directory
  • XFS_CMD_READDIR (7) - Read directory entry
  • XFS_CMD_CLOSEDIR (8) - Close directory
  • XFS_CMD_STAT (9) - Get file information
  • XFS_CMD_UNLINK (10) - Delete file
  • XFS_CMD_MKDIR (11) - Create directory
  • XFS_CMD_RMDIR (12) - Remove directory
  • XFS_CMD_CHDIR (13) - Change directory
  • XFS_CMD_GETCWD (14) - Get current directory
  • XFS_CMD_RENAME (15) - Rename file
  • XFS_CMD_LSEEK (16) - Seek in file

XFS Module

The XFS module is a Spectranet ROM module that implements the VFS interface. It:

  • Intercepts mount requests for "xfs" protocol
  • Communicates with RP2350 via XFS registers
  • Provides standard VFS operations to Spectrum programs

Best Practices

File Management

  1. Mount before use: Always mount XFS before accessing files
  2. Unmount when done: Unmount when finished to free resources
  3. Check errors: Always check return values for errors
  4. Close files: Always close files when done

Performance

  1. Use appropriate buffer sizes: Larger buffers are more efficient
  2. Batch operations: Group file operations together
  3. Cache frequently used data: Copy to Spectrum RAM if needed repeatedly
  4. Avoid small reads: Read in larger chunks when possible

Error Handling

  1. Check mount success: Verify mount succeeded before file operations
  2. Check file operations: Verify open/read/write succeeded
  3. Handle errors gracefully: Provide meaningful error messages
  4. Clean up on error: Close files and unmount even on error

Troubleshooting

Mount Fails

If mounting fails:

  • Verify XFS module is loaded
  • Check hostname is correct ("ram")
  • Verify protocol is "xfs" (case-sensitive)
  • Check console for error messages

File Not Found

If files aren't found:

  • Verify files were uploaded via XFS tools
  • Check file paths are correct (case-sensitive)
  • Use xfs-ls to verify files exist
  • Check current directory with GETCWD

Read/Write Errors

If read/write fails:

  • Verify file is open
  • Check file handle is valid
  • Verify buffer size is correct
  • Check available RAM filesystem space

Limitations

  • RAM Only: Currently only RAM filesystem is supported (hostname "ram")
  • Limited Handles: Maximum 4 open files/directories simultaneously
  • File Size: Limited by available RAM filesystem space
  • Persistence: RAM filesystem is cleared on reboot

Next Steps