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
tranZPUter SW
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.
The first production tranZPUter board. It plugs into the Sharp MZ-80A, MZ-700, MZ-1500, or MZ-2000 expansion bus and provides:
tranZPUter SW-700 v1.3
- 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.
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
tranZPUter FusionX
BUILD_VIDEOMODULE flag.
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
picoZ80
BUILD_FUSIONX flag.
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
Z80 Address Space Layout
tzfs_bank4.asm uses the full 52 KB user RAM range for the assembler and disassembler tables.
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
- 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 writesTZSVC_STATUS_REQUEST(0xFE) toTZSVCRESULT. - The Z80 writes to I/O port
SVCREQ(0x68) to signal the K64F. - The K64F detects the port write, reads the command block, and sets
TZSVCRESULTtoTZSVC_STATUS_PROCESSING(0xFF) while it works. - The Z80 polls
TZSVCRESULTin a tight loop until the value is neither 0xFF (processing) nor 0xFE (request not yet seen). Any other value indicates completion. - On success
TZSVCRESULTisTZSVC_STATUS_OK(0x00). On error it holds a non-zero error code. Any result data (directory entries, file blocks, etc.) is in theTZSVCSECTORbuffer within the block.
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
File and Directory Operations
TZSVCCMD before triggering the request:
| 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. |
| 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). |
| 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. |
| 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. |
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. |
| Code | Name | Description |
|---|---|---|
| 0x7F | EXIT | Terminate TZFS and restart in original TZMM_ORIG mode (hands the machine back to its native firmware). |
| 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
Build Flags
tools/glass.jar — no separate installation is required.
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. |
git clone https://github.com/pdsmart/tranZPUter.git cd tranZPUter # Full build: ./build.sh
build.sh runs the following steps in order:
- Compiles
cpmtoolsfrom source (first run only) and adds it toPATH. tools/assemble_tzfs.sh— assemblestzfs.asmand all bank files (tzfs_bank2.asm,tzfs_bank3.asm,tzfs_bank4.asm) into binary images.tools/assemble_cpm.sh— assembles the CP/M 2.2 CBIOS into its SRAM image.tools/assemble_roms.sh— assembles all monitor firmware variants (SA-1510 40/80col, 1Z-013A 40/80col, MZ-80B IPL) and MZF application images.tools/make_cpmdisks.sh— builds CP/M disk images (RAW format for the K64F to serve via READSDDRIVE / WRITESDDRIVE).
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 |