tranZPUter Filing System — Technical Guide

TZFS Technical Guide

This guide documents the tranZPUter Filing System (TZFS) hardware integration, memory architecture, software module layout, K64F I/O processor service API, CP/M implementation, and the complete build system. It is intended for users who want to understand how TZFS works at a system level, port TZFS to new hardware, or perform a full build from source.
TZFS is a port of RFS adapted for the tranZPUter family of boards. Unlike RFS, which programs physical Flash ROM chips, TZFS runs entirely in the tranZPUter's 512 KB RAM — the K64F (or equivalent) I/O processor loads the entire firmware from SD card into SRAM at boot, before handing control to the Z80. All SD card access goes through the K64F service API; the Z80 never touches SPI hardware directly.
For day-to-day usage and monitor command reference see the User Manual. For Z80 assembly source code walkthroughs see the Developer's Guide.

Hardware Platforms

TZFS targets five hardware platforms. Each is selected at compile time via flags in tzfs_definitions.asm. The resulting firmware differs in feature availability and which TZFS monitor commands are exposed, though file, tape, and memory commands work identically across all platforms.

tranZPUter SW
The first production tranZPUter board. It plugs into the Sharp MZ-80A, MZ-700, MZ-1500, or MZ-2000 expansion bus and provides:
  • K64F ARM Cortex-M4 I/O processor — manages SD card access, loads TZFS and monitor firmware into SRAM at boot, and executes all Z80 service requests via shared memory.
  • 512 KB SRAM — holds all TZFS code, monitor firmware, and CP/M images. The Z80 sees this as its normal address space; no physical ROM chips are present.
  • FPGA — implements the T80 soft-core Z80 CPU, ZPU Evolution soft CPU, hardware emulation of all Sharp MZ models (MZ-80A, MZ-700, MZ-800, MZ-1500, MZ-2000, MZ-80B), and VGA video output.

tranZPUter SW-700 v1.3
A refined version of the tranZPUter SW with improved PCB layout and reliability. It carries the same K64F, 512 KB SRAM, FPGA (with T80, ZPU Evolution, hardware emulation, and VGA output) as the SW. This is the current shipping version of the tranZPUter board. The TZFS firmware is identical to the SW build.

tranZPUter Fusion
The tranZPUter SW-700 combined with a 40/80 colour video module on the same board. In addition to all SW-700 capabilities, the Fusion adds hardware-accelerated colour graphics. The colour video commands are exposed in TZFS on this platform. Selected at build time with the BUILD_VIDEOMODULE flag.

tranZPUter FusionX
An FPGA-based virtual tranZPUter. All hardware emulation of Sharp MZ models, CPU switching between hard and soft cores, and VGA output are handled natively by the FPGA — TZFS does not expose these as monitor commands on this platform since there is nothing to switch at the firmware level. File, tape, and memory commands work identically to the SW-700 build. Selected at build time with the BUILD_FUSIONX flag.

picoZ80
An RP2350-based Z80 replacement that emulates the entire MZ-80A memory map in PSRAM. The K64F I/O processor role is taken by the RP2350's second core, which loads TZFS from SD card and handles all K64F service requests using the same shared memory protocol. TZFS does not expose CPU switching or hardware emulation commands on this platform (the RP2350 handles all of that transparently). File, tape, and memory commands are fully functional. Selected at build time with the BUILD_PICOZ80 flag.

Memory Architecture

TZFS uses the tranZPUter's memory management unit to divide the 512 KB SRAM into several 64 KB blocks, then map different blocks into the Z80's address space using hardware-controlled TZMM modes. This is fundamentally different from RFS, which bank-switches 2 KB windows into physical Flash ROM. TZFS can switch entire 64 KB RAM blocks, allowing much larger code regions — in particular tzfs_bank4.asm uses the full 52 KB user RAM range for the assembler and disassembler tables.

Z80 Address Space Layout
Address     Size    Contents
─────────────────────────────────────────────────────────────────────
0x0000      4 KB    Monitor ROM area — SA-1510 (or 1Z-013A, MZ-80B IPL etc.)
                    loaded from SD card by K64F at boot, resident in SRAM.
                    Switched by loading a different monitor image via TZFS
                    service commands; the physical address range stays the same.
0x1000      256 B   MZ system variables / stack
0x1200    ~46 KB    User RAM (main program area)
0xCFFF
0xD000      12 KB   Video RAM + memory-mapped I/O (Sharp MZ mainboard hardware)
0xE800       2 KB   TZFS fixed code window — always mapped to the TZMM_TZFS
                    bank (64 KB Block 0). Contains the primary TZFS entry point,
                    command dispatcher, jump table, and shared variable area.
0xEC80      256 B   TZFS variables (within the fixed E800–EFFF window)
0xED80      640 B   K64F service communication block (TZSVCMEM)
0xEFFF
0xF000       4 KB   Switchable code window — bank selected by TZMM mode.
                    Maps to a different 64 KB SRAM block depending on which
                    TZFS module is active (tzfs_bank2 / bank3 / bank4 / CP/M).
0xFFFF
─────────────────────────────────────────────────────────────────────

Memory Management Modes (TZMM)
The tranZPUter CPLD implements hardware memory management controlled by writing to I/O port registers. Each mode selects a different mapping of the 512 KB SRAM blocks into the Z80 address space. All TZMM modes in active use have the TZMM_ENIOWAIT bit (0x20) set to insert an I/O wait state for reliable K64F communication.
Mode Code Description
TZMM_ORIG 0x00 Original Sharp MZ mode — the mainboard ROM and RAM are used directly. No tranZPUter SRAM is visible. The K64F I/O control registers remain accessible.
TZMM_BOOT 0x01 Original mode but 0xE800–0xEFFF is mapped to tranZPUter SRAM Block 0 so that the TZFS boot stub can run and issue service requests to the K64F.
TZMM_TZFS 0x02 TZFS main mode — all memory in tranZPUter SRAM. Monitor at 0x0000–0x0FFF, user RAM 0x1000–0xCFFF, fixed TZFS code at 0xE800–0xEFFF, switchable window at 0xF000–0xFFFF. Block 0 selected for 0xF000–0xFFFF.
TZMM_TZFS2 0x03 Same as TZMM_TZFS but 0xF000–0xFFFF maps to Block 1 (tzfs_bank2 — message printing, ASCII conversion, help screen).
TZMM_TZFS3 0x04 0xF000–0xFFFF maps to Block 2 (tzfs_bank3 — memory utilities, I/O read/write, tape compensation, CPU/hardware emulation).
TZMM_TZFS4 0x05 0xF000–0xFFFF maps to Block 3 (tzfs_bank4 — Z80 assembler/disassembler). This bank also uses 0x1200–0xCFFF for assembler/disassembler tables, giving up to 52 KB of working space.
TZMM_CPM 0x06 CP/M mode — all SRAM, Block 4 selected across the full address space.
TZMM_CPM2 0x07 CP/M mode 2 — 0xF000–0xFFFF in Block 4, 0x0040–0xCFFF and 0xE800–0xEFFF in Block 5.
Additional TZMM modes for MZ-700 and MZ-800 compatibility emulation also exist, allowing TZFS to present the correct memory map when emulating those machines.

Comparison with RFS Bank Switching
RFS switches 2 KB windows into physical Flash ROM using a hardware bank latch register — only the 0xE800–0xEFFF User ROM window changes between banks. TZFS instead switches the entire 64 KB SRAM block mapped at 0xF000–0xFFFF by writing a new TZMM mode code. Because the switched window is 4 KB (0xF000–0xFFFF) and is backed by a full 64 KB block, TZFS bank code can be much larger: tzfs_bank4 spreads across 52 KB when it additionally claims the user RAM range 0x1200–0xCFFF for its tables. The fixed TZFS window at 0xE800–0xEFFF never changes, so the command dispatcher and jump table are always reachable regardless of which bank is active.

Software Architecture

The complete module table — every source file, its memory range, TZMM mode, and function:
Module Memory Range Size TZMM Mode Description
tzfs.asm 0xE800–0xEFFF 2 KB fixed TZMM_TZFS Primary TZFS entry point, command dispatcher, bank-switch infrastructure, external jump table at 0xE880, shared variable area. Always mapped — never paged out.
tzfs_bank2.asm 0xF000–0xFFFF 4 KB paged TZMM_TZFS2 Message printing, formatted output, ASCII↔Sharp character set conversion, help screen.
tzfs_bank3.asm 0xF000–0xFFFF 4 KB paged TZMM_TZFS3 Memory utilities (D, M, CP, FILL), I/O port read/write, tape speed compensation, CPU frequency switching, hardware emulation of Sharp MZ models.
tzfs_bank4.asm 0x1200–0xCFFF + 0xF000–0xFFFF 52 KB paged TZMM_TZFS4 Full interactive Z80 assembler and Z80 disassembler. Claims 52 KB by using both the user RAM range and the paged window simultaneously.
monitor_SA1510.asm 0x0000–0x0FFF 4 KB TZMM_TZFS SA-1510 monitor ROM for MZ-80A (40-column). Loaded from SD by K64F at boot.
monitor_80c_SA1510.asm 0x0000–0x0FFF 4 KB TZMM_TZFS SA-1510 patched for 80-column display.
monitor_1Z-013A.asm 0x0000–0x0FFF 4 KB TZMM_TZFS 1Z-013A monitor ROM for MZ-700 / MZ-1200.
monitor_80c_1Z-013A.asm 0x0000–0x0FFF 4 KB TZMM_TZFS 1Z-013A patched for 80-column display.
MZ80B_IPL.asm 0x0000–0x0FFF 4 KB TZMM_TZFS MZ-80B IPL firmware.
At most one monitor image occupies 0x0000–0x0FFF at any given time. The active monitor is selected at boot (or changed via TZFS service commands) by having the K64F copy the appropriate image into SRAM Block 0 before the Z80 starts. The monitor firmware has no knowledge of TZFS internals — it calls back into TZFS exclusively through the fixed external jump table at 0xE880.
External Jump Table (TZFSJMPTABLE at 0xE880)
The jump table provides stable fixed addresses that monitor firmware uses to call TZFS functions. Because the table sits in the fixed 0xE800–0xEFFF window, these addresses never change regardless of which TZMM mode is active:
Address Name Description
0xE880 CMT_RDINF Read tape/SD header (MZF attribute block)
0xE883 CMT_RDDATA Read tape/SD data block
0xE886 CMT_WRINF Write tape/SD header
0xE889 CMT_WRDATA Write tape/SD data block
0xE88C CMT_VERIFY Verify tape/SD write
0xE88F CMT_DIR SD card directory listing
0xE892 CMT_CD SD card change directory
0xE895 SET_FREQ Set CPU clock frequency

K64F / I/O Processor Service API

All SD card file I/O, monitor loading, and CP/M disk access are performed by the K64F I/O processor (or the RP2350 second core on picoZ80). The Z80 never accesses storage hardware directly — it submits requests through a shared memory block and polls for completion. For CPU switching and hardware emulation, the K64F's role is to load the required firmware or ROM images before signalling the FPGA to activate the requested core or emulation mode; the T80, ZPU Evolution, and all Sharp MZ hardware emulation are implemented in the FPGA itself.

Service Request Mechanism
  1. The Z80 fills in the service communication block at 0xED80: writes the command code to TZSVCCMD, sets any required parameters (filename, address, size, etc.), and writes TZSVC_STATUS_REQUEST (0xFE) to TZSVCRESULT.
  2. The Z80 writes to I/O port SVCREQ (0x68) to signal the K64F.
  3. The K64F detects the port write, reads the command block, and sets TZSVCRESULT to TZSVC_STATUS_PROCESSING (0xFF) while it works.
  4. The Z80 polls TZSVCRESULT in a tight loop until the value is neither 0xFF (processing) nor 0xFE (request not yet seen). Any other value indicates completion.
  5. On success TZSVCRESULT is TZSVC_STATUS_OK (0x00). On error it holds a non-zero error code. Any result data (directory entries, file blocks, etc.) is in the TZSVCSECTOR buffer within the block.

Service Communication Block (0xED80, 640 bytes)
Offset  Size    Field            Description
────────────────────────────────────────────────────────────────────────────
+0x00   1 B     TZSVCCMD         Service command code (see command table below)
+0x01   1 B     TZSVCRESULT      Result/status byte (0x00=OK, 0xFE=request, 0xFF=busy)
+0x02   1 B     TZSVCDIRSEC      Directory sector number for multi-block dir reads
+0x03   2 B     TZSVC_TRACK_NO   Virtual drive track number / 32-bit LBA sector address
+0x05   2 B     TZSVC_SECTOR_NO  Virtual drive sector number
+0x07   1 B     TZSVC_FILE_NO    File number within directory
+0x08   1 B     TZSVC_FILE_TYPE  File type: 0=MZF, 1=MZF header only, 2=CAS, 3=BAS, 10=ALL
+0x09   2 B     TZSVC_LOADADDR   Dynamic load address / save address / CPU frequency
+0x0B   2 B     TZSVC_LOADSIZE   Image size in bytes to load or save
+0x0D  20 B     TZSVC_DIRNAME    Directory name (for CHANGEDIR and READDIR)
+0x21  17 B     TZSVC_FILENAME   Sharp MZ filename (17-character, Sharp encoding)
+0x32  20 B     TZSVCWILDC       Directory wildcard filter string
+0x46 512 B     TZSVCSECTOR      Data sector buffer — file blocks, directory entries, etc.
────────────────────────────────────────────────────────────────────────────
Total: 640 bytes (0xED80–0xEFFF, within the fixed TZFS window)

Service Commands
Commands are grouped by function. The Z80 writes the code to TZSVCCMD before triggering the request:
File and Directory Operations
Code Name Description
0x01 READDIR Open the directory specified in TZSVC_DIRNAME and return the first block of entries in TZSVCSECTOR.
0x02 NEXTDIR Return the next block of entries from the currently open directory.
0x03 READFILE Open the file specified by TZSVC_FILENAME and return the first 512-byte block in TZSVCSECTOR.
0x04 NEXTREADFILE Return the next 512-byte block of the open file.
0x05 WRITEFILE Create a new file and write the first 512-byte block from TZSVCSECTOR.
0x06 NEXTWRITEFILE Write the next 512-byte block to the open file.
0x07 CLOSE Close any currently open file or directory handle.
0x08 LOADFILE Load a complete file directly from SD into tranZPUter SRAM at TZSVC_LOADADDR.
0x09 SAVEFILE Save a region of tranZPUter SRAM (TZSVC_LOADSIZE bytes from TZSVC_LOADADDR) as a file.
0x0A ERASEFILE Delete the file specified by TZSVC_FILENAME from the SD card.
0x0B CHANGEDIR Change the active SD card directory to TZSVC_DIRNAME.
Monitor / BIOS Loading
Code Name Description
0x20 LOAD40ABIOS Load the 40-column SA-1510 monitor into SRAM at 0x0000.
0x21 LOAD80ABIOS Load the 80-column SA-1510 monitor into SRAM at 0x0000.
0x22 LOAD700BIOS40 Load the MZ-700 1Z-013A 40-column monitor.
0x23 LOAD700BIOS80 Load the MZ-700 1Z-013A 80-column monitor.
0x24 LOAD80BIPL Load the MZ-80B IPL firmware.
0x25 LOAD800BIOS Load the MZ-800 9Z-504M BIOS.
0x26 LOAD2000IPL Load the MZ-2000 IPL.
0x2F LOADTZFS Load TZFS itself (used for machines such as MZ-80B and MZ-2000 that have no onboard monitor BIOS to bootstrap TZFS).
CP/M Disk Operations
Code Name Description
0x30 LOADBDOS Reload the CP/M BDOS+CCP into RAM (warm boot support).
0x31 ADDSDDRIVE Attach an SD card disk image to a CP/M drive letter.
0x32 READSDDRIVE Read a 128-byte CP/M sector from an SD card disk image.
0x33 WRITESDDRIVE Write a 128-byte CP/M sector to an SD card disk image.
CPU Frequency Control
Code Name Description
0x40 CPU_BASEFREQ Switch the Z80 clock to the mainboard base frequency.
0x41 CPU_ALTFREQ Switch to the alternate frequency provided by the K64F.
0x42 CPU_CHGFREQ Set the alternate frequency to the value (in Hz) in TZSVC_LOADADDR.
CPU and Hardware Emulation Switching
These commands are only effective on the tranZPUter SW, SW-700, and Fusion. On FusionX and picoZ80 the FPGA or RP2350 handles CPU selection natively and TZFS does not expose these commands.
Code Name Description
0x50 CPU_SETZ80 Switch to the hard Z80 CPU on the mainboard.
0x51 CPU_SETT80 Load any required firmware then signal the FPGA to activate the T80 soft-core Z80 (implemented in the FPGA).
0x52 CPU_SETZPUEVO Load any required firmware then signal the FPGA to activate the ZPU Evolution soft CPU (implemented in the FPGA).
0x53–0x5D EMU_SETMZ* Load the target machine’s ROM/BIOS from SD then signal the FPGA to activate hardware emulation of that Sharp MZ model. All emulation logic is implemented in the FPGA.
Control
Code Name Description
0x7F EXIT Terminate TZFS and restart in original TZMM_ORIG mode (hands the machine back to its native firmware).

Status Codes
Value Name Description
0x00 TZSVC_STATUS_OK Command completed successfully. Any result data is in TZSVCSECTOR.
0xFE TZSVC_STATUS_REQUEST The Z80 has posted a request and is waiting for the K64F to acknowledge it.
0xFF TZSVC_STATUS_PROCESSING The K64F is currently executing the command. The Z80 must continue polling.

CP/M 2.2 Implementation

CP/M 2.2 is available on all TZFS platforms via the CPM monitor command. The implementation uses TZMM_CPM / TZMM_CPM2 modes to give CP/M access to 64 KB SRAM blocks independent of the TZFS working area. The Custom BIOS (CBIOS) uses K64F service calls for all disk I/O — there is no direct SPI driver in TZFS, and the Z80 never accesses SD card hardware. CP/M drives A:–G: are SD card disk images stored on the SD card in the standard SDCFS filesystem layout.
Unlike RFS, where the CBIOS is split across four User ROM banks, the TZFS CBIOS is assembled as part of the CP/M SRAM image. The CP/M disk driver issues ADDSDDRIVE, READSDDRIVE, and WRITESDDRIVE service commands for all disk reads and writes. The K64F maps each drive letter to a disk image file on the SD card, so the Z80 never needs to know the FAT32 layout of the SD card.
CP/M 2.2 delivers 47 KB of usable program RAM. The CCP and BDOS reside in RAM and can be overwritten by large applications; they are reloaded on warm boot via the LOADBDOS service command.

Build System

All development is done under Linux (Debian/Ubuntu). The build system is almost entirely self-contained within the repository.

Prerequisites
Tool Purpose
Java JRE 8+ Runs the GLASS Z80 assembler (tools/glass.jar). java must be on PATH.
bash All build scripts are bash shell scripts.
perl Required by tools/mzftool.pl for MZF file manipulation.
gcc / make Compiles cpmtools from source on first build (automatic).
dd, cat, stat Standard Linux utilities used by the packaging scripts.
The GLASS Z80 assembler is bundled in tools/glass.jar — no separate installation is required.

Build Flags
Edit asm/include/tzfs_definitions.asm and set the appropriate target and feature flags. Platform flags (set exactly one to 1):
Flag Target
BUILD_MZ80A EQU 1 Sharp MZ-80A host machine
BUILD_MZ700 EQU 1 Sharp MZ-700 / MZ-1200 host machine (default)
BUILD_MZ1500 EQU 1 Sharp MZ-1500 host machine
BUILD_MZ2000 EQU 1 Sharp MZ-2000 / MZ-80B host machine
Additional optional feature flags:
Flag Default Description
BUILD_FUSIONX 0 Set to 1 when targeting the tranZPUter FusionX. Disables CPU/emulation switch commands.
BUILD_PICOZ80 0 Set to 1 when targeting the picoZ80. Disables CPU/emulation switch commands.
ENADEBUG 0 Enable assembly-time debug output.

Build Steps
git clone https://github.com/pdsmart/tranZPUter.git
cd tranZPUter

# Full build:
./build.sh
build.sh runs the following steps in order:
  1. Compiles cpmtools from source (first run only) and adds it to PATH.
  2. tools/assemble_tzfs.sh — assembles tzfs.asm and all bank files (tzfs_bank2.asm, tzfs_bank3.asm, tzfs_bank4.asm) into binary images.
  3. tools/assemble_cpm.sh — assembles the CP/M 2.2 CBIOS into its SRAM image.
  4. tools/assemble_roms.sh — assembles all monitor firmware variants (SA-1510 40/80col, 1Z-013A 40/80col, MZ-80B IPL) and MZF application images.
  5. tools/make_cpmdisks.sh — builds CP/M disk images (RAW format for the K64F to serve via READSDDRIVE / WRITESDDRIVE).
The K64F firmware (compiled separately) is responsible for loading TZFS and monitor images into SRAM at boot. The build outputs must be copied to the SD card so the K64F can find them. Refer to the K64F firmware documentation for the expected directory layout on the SD card.

Output Files
After a successful build the roms/ directory contains:
File Description
tzfs.bin Primary TZFS image — fixed window code (0xE800–0xEFFF, Block 0).
tzfs_bank2.bin Bank 2 image — message printing, help screen (paged at 0xF000–0xFFFF).
tzfs_bank3.bin Bank 3 image — memory utilities, I/O, emulation switching (paged at 0xF000–0xFFFF).
tzfs_bank4.bin Bank 4 image — Z80 assembler and disassembler (paged, uses 52 KB).
monitor_SA1510.bin SA-1510 40-column monitor image (0x0000–0x0FFF).
monitor_80c_SA1510.bin SA-1510 80-column monitor image.
monitor_1Z-013A.bin 1Z-013A 40-column monitor image.
monitor_80c_1Z-013A.bin 1Z-013A 80-column monitor image.
MZ80B_IPL.bin MZ-80B IPL image.
cbios.bin CP/M 2.2 CBIOS SRAM image (loaded into TZMM_CPM blocks by K64F).
CPM_DISK_*.img CP/M disk images (RAW format, served by K64F via READSDDRIVE / WRITESDDRIVE).

Reference Sites

Resource Link
TZFS project page /sharpmz-upgrades-tzfs/
TZFS User Manual /sharpmz-upgrades-tzfs-usermanual/
TZFS Developer’s Guide /sharpmz-upgrades-tzfs-developersguide/
tranZPUter project page /transzputer-sw/
tranZPUter Fusion project page /transzputer-fusion/
RFS Technical Guide /sharpmz-upgrades-rfs-technicalguide/
picoZ80 Technical Guide /picoz80-technicalguide/
GLASS Z80 Assembler Bundled in tools/glass.jar