tranZPUter SW-700 (v1) — Technical Guide
tranZPUter SW-700 V1 Technical Guide
Note — V1 Firmware (Original Release)
This guide covers the original V1 firmware for the tranZPUter SW-700, targeting the Sharp MZ-700 only. In V1, the video control registers are mapped at I/O ports
If the board firmware has been updated to the current release (the post I/O port re-assignment build), the video registers will be at
This guide covers the original V1 firmware for the tranZPUter SW-700, targeting the Sharp MZ-700 only. In V1, the video control registers are mapped at I/O ports
0xF8–0xFD and the 0x6B System Command Register does not exist. MZ-2000 emulation is not supported in V1.If the board firmware has been updated to the current release (the post I/O port re-assignment build), the video registers will be at
0xA8–0xAD and the 0x6B System Command Register will be present. In that case, consult the tranZPUter SW-700 Current Technical Guide instead. The register addresses in this document will not match current firmware.
This guide documents the tranZPUter SW-700 V1 hardware architecture, bus-mastering mechanism, memory management subsystem, system register interface, K64F I/O processor service API, CPU switching, V1 video module register interface, FPGA specifications, and the complete build system. It is intended for users who want to understand how the original V1 firmware works at a system level or who need a reference for boards that have not been updated to current firmware.
For day-to-day usage and TZFS monitor command reference see the TZFS User Manual. For Z80 assembly source code walkthroughs see the TZFS Developer's Guide.
Bus Mastering
The core principle of the tranZPUter SW-700 is Z80 bus mastering: the ability to tri-state the original Z80 CPU and take complete control of the Sharp MZ-700 address bus, data bus, and control lines. This mechanism was originally developed for DMA — transferring data between an I/O device and memory much faster than the Z80 running a program loop could manage. The tranZPUter repurposes it as the foundation for all of its extended capabilities.
Bus mastering is used for three distinct purposes in the tranZPUter SW-700 design:
- SD card file I/O — the K64F ARM processor takes the bus and transfers data directly between the SD card and the 512 KB SRAM, without the Z80 being involved in the transfer at all.
- Menu and video overlay presentation — the K64F can write directly into the MZ-700 video RAM to present menus or status information at native video speed.
- Soft CPU execution — when a soft processor (T80, ZPU Evolution) is active in the FPGA, the hard Z80 is held tri-stated permanently and the soft CPU executes in local SRAM, accessing MZ-700 I/O and video RAM only when required, at controlled speed.
Hardware Components
The tranZPUter SW-700 board (PCB versions v1.2 and v1.3) carries the following primary components. The hardware is identical between V1 firmware and current firmware — the differences between firmware versions are entirely in the CPLD logic and K64F software.
| Component | Part | Specification |
|---|---|---|
| Z80 CPU | Z84C0020 (or equivalent) | 20MHz rated; overclocked to 24MHz in testing |
| I/O Processor | Freescale K64F (MK64FN1M0VLL12) | ARM Cortex-M4F, 120MHz, 256KB SRAM, 1MB Flash |
| CPLD | Altera MAX7000A (EPM7512AETC144-10) | 512 macrocells, 144-pin TQFP, 5V-tolerant inputs |
| FPGA | Altera Cyclone III EP3C25 or Cyclone IV EP4CE22/EP4CE75/EP4CE115 | Cyclone IV 75K / 115K is the v1.3 mainstream; Cyclone III used on v1.2 |
| FPGA config Flash | Altera EPCS16 | 16Mbit serial flash for FPGA bitstream |
| SRAM | 512 KB Static RAM | Holds all TZFS firmware, monitor images, and working memory |
| SD card | microSD slot | Connected to K64F SPI; FAT32 filesystem |
| Crystal | Main FPGA timebase | Feeds FPGA PLLs for all internal and video clocks |
- v1.0 / v1.1 — internal prototype designs, not publicly released.
- v1.2 — first publicly released design. Based on the Sharp MZ-80A tranZPUter SW v2.2 and Video Module v2.0, optimised for the MZ-700 platform. Uses a Cyclone III FPGA. Fully functional but lower FPGA resource ceiling.
- v1.3 — mainstream production design. Upgraded to a Cyclone IV (75K or 115K gate count, build-time selectable) which provides higher resolution graphics capability, more soft-CPU headroom, and space for additional video modes. Both v1.2 and v1.3 are proven designs; v1.2 is cheaper to produce.
The MAX7000A CPLD is central to the design for three reasons beyond its logic capacity:
Power Supply
- Voltage translation — The MZ-700 mainboard runs at 5V. The FPGA is 3.3V only. The MAX7000A has 5V-tolerant inputs, so it sits between them and handles level shifting in both directions without the need for separate translation ICs.
- Decode and I/O remapping — The CPLD decodes Z80 I/O addresses, implements the tranZPUter I/O register set, and remaps keyboard I/O so that the soft CPUs can access the MZ-700 keyboard correctly.
- FPGA interface — The CPLD provides the conditioned bus signals that the FPGA needs. Since the FPGA can only tolerate 3.3V on its I/O pins, routing via the CPLD is mandatory.
The CPLD requires 3.3V. The FPGA requires 1.2V for its internal core, 2.5V for PLL and analogue cells, and 3.3V for its I/O banks. Three separate LDO regulators (each rated to 1A) provide these rails from the MZ-700's 5V supply. The K64F uses its own dedicated 3.3V LDO, intentionally isolated from the CPLD/FPGA supply to prevent switching noise coupling. Altera's power analysis tools were used to verify that the LDO ratings are sufficient for the combined CPLD and FPGA load.
Video Interface
The tranZPUter SW-700 does not lift ICs from the MZ-700 mainboard. Instead, the composite video signal is taken from the mainboard modulator connector, routed into the FPGA via the CPLD (the CPLD handles the 5V→3.3V signal conditioning), and the FPGA either passes the original video through or generates its own enhanced video output. Software selects between the two modes by writing to the video control registers (
0xF8–0xFD in V1). When enhanced FPGA video is active, the CPLD tri-states the relevant mainboard signals to prevent conflict.
The colour output uses 4 bits per channel for the analogue RGB path plus a 5th bit per channel for digital RGB monitors and the composite/TV circuitry inside the modulator. The 5th bit ensures that a logic 1 drives the modulator input above 2V (the TTL switching threshold). When driving an analogue RGB monitor the 5th bit must be kept low or high-Z to avoid over-saturating the monitor input; with the 5th bit at 0 it acts as a current sink and slightly reduces the output voltage, providing 32 usable voltage levels per colour channel.
Memory Management Modes
The tranZPUter SW-700 CPLD implements a hardware memory management unit controlled by writing mode codes to I/O port
0x60 (the Memory Management Config register). Each mode selects a different mapping of the tranZPUter's 512 KB SRAM and the MZ-700 mainboard memory into the Z80's 64 KB address space.
In V1 firmware, the following TZMM modes are defined. MZ-2000 specific modes are absent — they were added in the current firmware revision.
| Mode | Code | Description |
|---|---|---|
| TZMM_ORIG | 0x00 | Original Sharp MZ-700 mode. The mainboard ROM and RAM are used directly. The tranZPUter SRAM is not visible. K64F I/O registers remain accessible. |
| TZMM_BOOT | 0x01 | Original mode but 0xE800–0xEFFF maps to tranZPUter SRAM Block 0, allowing the TZFS boot stub to run and issue service requests to the K64F before the full firmware is active. |
| TZMM_TZFS | 0x02 | TZFS main operating mode. All memory in tranZPUter SRAM. Monitor at 0x0000–0x0FFF, user RAM 0x1000–0xCFFF, fixed TZFS window at 0xE800–0xEFFF (Block 0), switchable window at 0xF000–0xFFFF (Block 0 by default). |
| 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, tape speed compensation, CPU switching, MZ model emulation). |
| TZMM_TZFS4 | 0x05 | 0xF000–0xFFFF maps to Block 3 (tzfs_bank4 — Z80 assembler/disassembler). This bank additionally uses 0x1200–0xCFFF for assembler and disassembler tables (up to 52 KB working space). |
| TZMM_CPM | 0x06 | CP/M mode. All SRAM, Block 4 mapped 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. |
| TZMM_MZ700_0 | 0x08 | MZ-700 compatibility: lower 32 KB from SRAM, upper 32 KB from mainboard (I/O mapped region). |
| TZMM_MZ700_1 | 0x09 | MZ-700 compatibility: lower 32 KB from mainboard ROM/RAM, upper from SRAM. |
| TZMM_MZ700_2 | 0x0A | MZ-700 compatibility: full mainboard mapping with SRAM at 0xE000–0xFFFF. |
| TZMM_MZ700_3 | 0x0B | MZ-700 compatibility: full mainboard memory, SRAM overlay at upper bank. |
| TZMM_MZ800_0 | 0x0C | MZ-800 emulation memory map, lower SRAM. |
| TZMM_MZ800_1 | 0x0D | MZ-800 emulation memory map, upper SRAM. |
| TZMM_MZ80A | 0x0E | MZ-80A emulation — full 64 KB SRAM configured as per MZ-80A memory map. |
| TZMM_MZ80B | 0x0F | MZ-80B emulation — full 64 KB SRAM configured as per MZ-80B memory map. |
All active TZMM modes have the
Z80 Address Space in TZMM_TZFS Mode
TZMM_ENIOWAIT bit (0x20) set internally by the CPLD to insert an I/O wait state, ensuring reliable K64F service request communication. The Z80 does not need to set this bit explicitly.
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 Block 0.
Changed by loading a different monitor image via TZFS service
commands; the physical address range stays fixed.
0x1000 256 B MZ-700 system variables / stack
0x1200 ~46 KB User RAM (main program area)
0xCFFF
0xD000 12 KB Video RAM + memory-mapped I/O (Sharp MZ-700 mainboard hardware)
0xE800 2 KB TZFS fixed code window — always mapped to SRAM Block 0.
Contains the primary TZFS entry point, command dispatcher,
external jump table (at 0xE880), and shared variable area.
0xEC80 256 B TZFS variables (within the fixed 0xE800–0xEFFF window)
0xED80 640 B K64F service communication block (TZSVCMEM)
0xEFFF
0xF000 4 KB Switchable code window — SRAM block selected by TZMM mode.
Maps to a different 64 KB SRAM block depending on which
TZFS bank is active (tzfs_bank2 / bank3 / bank4 / CP/M).
0xFFFF
─────────────────────────────────────────────────────────────────────
System Registers (V1)
The tranZPUter SW-700 exposes its control interface to the Z80 as a set of I/O port registers. In V1 firmware, the system registers occupy ports
0x60–0x6F. The 0x6B System Command Register was not present in V1 — it was introduced in the current firmware revision.
All registers are write-only unless otherwise noted. Reading from a write-only register has undefined behaviour.
| Port | Register | Direction | Description |
|---|---|---|---|
| 0x60 | Memory Management Config | W | Write a TZMM mode code to switch the active memory management mode. See the memory modes table above for valid codes. |
| 0x62 | Set CPU Alt Frequency | W | Switches the Z80 clock source to the alternate frequency generated by the K64F. The frequency itself must first be set via port 0x66. |
| 0x64 | Set CPU Base Frequency | W | Switches the Z80 clock source back to the MZ-700 mainboard frequency (3.54 MHz). |
| 0x66 | CPU Frequency Change | W | Writes the desired alternate CPU frequency in Hz (32-bit value). The K64F configures its clock output to match. |
| 0x68 | Service Request | W | Writing any value to this port signals the K64F that a service request has been posted in the TZSVCMEM block at 0xED80. The Z80 then polls TZSVCRESULT for completion. |
| 0x6C | CPU Configuration | W | Selects the active CPU: 0 = hard Z80 (mainboard), 1 = T80 soft-core Z80 (FPGA), 2 = ZPU Evolution soft CPU (FPGA). |
| 0x6D | CPU Information | R | Returns a bitmask of available CPU capabilities for this board. Bit definitions are firmware-version specific; read at startup to discover hardware capabilities. |
| 0x6E | System Configuration | W/R | System feature enable/disable flags. Read to query current configuration; write to change it. |
| 0x6F | System Information | R | Returns board identification code. Read to confirm tranZPUter SW-700 hardware is present and determine PCB revision. |
V1 note: Port
0x6B (System Command Register) is absent in V1 firmware. Any code that writes to 0x6B under V1 firmware will have no effect, or may produce undefined CPLD behaviour. The 0x6B register was added in the current firmware release to provide direct machine-model switching without going through a full K64F service cycle.
K64F / I/O Processor Service API
All SD card file I/O, monitor firmware loading, and CP/M disk access in V1 are performed by the K64F ARM Cortex-M4 I/O processor. The Z80 never accesses the SD card SPI hardware directly — it posts requests through a shared memory block in SRAM and polls for completion. The K64F runs an embedded OS (zOS) and continuously polls the service communication block for pending requests from the Z80.
Service Request Mechanism
- The Z80 fills in the service communication block at 0xED80: writes the command code to
TZSVCCMD, sets any required parameters (filename, load address, size, etc.), and writesTZSVC_STATUS_REQUEST(0xFE) toTZSVCRESULT. - The Z80 writes any value to I/O port
0x68(Service Request) to signal the K64F. - The K64F detects the port write, reads the command block from SRAM, and sets
TZSVCRESULTtoTZSVC_STATUS_PROCESSING(0xFF) while it is working. - 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 placed 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 (Hz) +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 character 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 (V1)
Commands are grouped by function. The Z80 writes the code to
File and Directory Operations
TZSVCCMD before triggering the request via port 0x68.
V1 differences from current firmware: The MZ-2000 IPL loader command (0x26 LOAD2000IPL) and the LOADTZFS command (0x2F) are absent in V1. All other file I/O, CP/M disk, and CPU frequency commands are present.
| 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. |
Note: Command 0x26 (LOAD2000IPL — Load the MZ-2000 IPL) is not present in V1. MZ-2000 emulation was added in the current firmware release. Command 0x2F (LOADTZFS) is also absent in V1.
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. |
| Code | Name | Description |
|---|---|---|
| 0x40 | CPU_BASEFREQ | Switch the Z80 clock to the mainboard base frequency (3.54 MHz). |
| 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. |
| Code | Name | Description |
|---|---|---|
| 0x50 | CPU_SETZ80 | Switch to the hard Z80 CPU on the mainboard. |
| 0x51 | CPU_SETT80 | Load required firmware then signal the FPGA to activate the T80 soft-core Z80. |
| 0x52 | CPU_SETZPUEVO | Load required firmware then signal the FPGA to activate the ZPU Evolution soft CPU. |
| 0x53–0x5C | EMU_SETMZ* | Load the target machine ROM/BIOS from SD then signal the FPGA to activate emulation of that Sharp MZ model. MZ-2000 (0x5D) is not available in V1. |
| Code | Name | Description |
|---|---|---|
| 0x7F | EXIT | Terminate TZFS and restart in TZMM_ORIG mode, handing 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. |
CPU Switching
The tranZPUter SW-700 supports three CPU modes, selectable in software either by writing directly to the CPU Configuration register (port
Available CPUs
0x6C) or by using the K64F service API commands 0x50–0x52.
| Mode | Code (0x6C) | Service Cmd | Description |
|---|---|---|---|
| Hard Z80 | 0x00 | 0x50 CPU_SETZ80 | The original physical Z80 chip on the tranZPUter daughter card runs at the mainboard frequency or the K64F-generated alternate frequency. Default on power-up. |
| T80 soft-core | 0x01 | 0x51 CPU_SETT80 | The T80 open-source Z80 compatible soft-core, instantiated in the CPLD/FPGA, replaces the hard Z80. The K64F loads required firmware before activating the soft-core. |
| ZPU Evolution | 0x02 | 0x52 CPU_SETZPUEVO | The ZPU Evolution soft CPU, instantiated in the FPGA, replaces the hard Z80. Intended for applications that benefit from the ZPU instruction set and its associated toolchain. |
When switching to a soft CPU, the K64F:
CPU Frequency Control
- Tri-states the hard Z80 via the BUSRQ signal.
- Loads any required firmware (boot vectors, ROM images) into the appropriate SRAM region.
- Signals the FPGA via the CPLD to instantiate the requested soft-core and assert bus mastership.
- Returns control to the TZFS service loop.
The Z80 clock source can be switched between the MZ-700 mainboard oscillator (3.54 MHz) and a frequency synthesised by the K64F. The K64F frequency source is continuously variable and has been tested reliably up to 24 MHz (achieved by overclocking a Z84C0020 20 MHz device). Higher frequencies are possible but reliability depends on the specific Z80 part used and the board capacitance.
The recommended sequence for setting an alternate frequency:
# 1. Place desired frequency (Hz) in TZSVC_LOADADDR (32-bit) # Example: 16000000 for 16 MHz LD (TZSVC_LOADADDR), HL ; low word of frequency # 2. Issue CPU_CHGFREQ service command (0x42) LD A, 0x42 LD (TZSVCCMD), A LD A, 0xFE LD (TZSVCRESULT), A OUT (0x68), A ; trigger K64F # 3. Poll TZSVCRESULT for 0x00 (OK) # 4. Switch to the new frequency OUT (0x62), A ; port 0x62 = Set CPU Alt Frequency
To revert to the MZ-700 base frequency, write any value to port
0x64 (Set CPU Base Frequency).
Video Module (V1 — Ports 0xF8–0xFD)
V1 Video Register Address Warning
In V1 firmware the video control registers are at I/O ports
In V1 firmware the video control registers are at I/O ports
0xF8–0xFD. In the current firmware these same registers were moved to 0xA8–0xAD as part of a general I/O port re-assignment. Code written for V1 that accesses 0xF8–0xFD will not work on current firmware, and vice versa.
The tranZPUter SW-700 integrates the Video Module v2.0 functionality directly on the board. The FPGA implements an enhanced video subsystem capable of displaying multiple Sharp MZ machine video modes, VGA output, programmable character generators, and colour graphics with independent colour-attribute control. In V1 firmware, the video subsystem is controlled through six I/O registers at ports 0xF8–0xFD.
Video Register Map (V1)
| Port | Register | Direction | Description |
|---|---|---|---|
| 0xF8 | Control | W | Primary video control register — selects machine model, column width, colour mode, PCG, and VGA scan mode. |
| 0xF9 | Graphics Mode | W | Graphics RAM bank selection, VRAM/GRAM output enable, and pixel blend operator. |
| 0xFA | Colour Writer Red | W | 8-pixel red colour filter — sets which pixels in the current 8-pixel group receive the red component. |
| 0xFB | Colour Writer Green | W | 8-pixel green colour filter — sets which pixels in the current 8-pixel group receive the green component. |
| 0xFC | Colour Writer Blue | W | 8-pixel blue colour filter — sets which pixels in the current 8-pixel group receive the blue component. |
| 0xFD | Memory Page / Status | W/R | Controls GRAM→CPU mapping (bit 0) and CGROM→CPU mapping (bit 7). Read to obtain video status. |
Bit(s) Name Description
────────────────────────────────────────────────────────────────────────────
7:6 VGA Mode 00 = original MZ-700 video timing (15.6 kHz)
01 = VGA 640×200 upscaled output
10 = VGA 640×400 upscaled output
11 = reserved
5 PCG Enable 1 = Programmable Character Generator active
(custom character definitions in GRAM override CGROM)
0 = Standard CGROM characters
4 Colour Enable 1 = Colour attribute RAM active (colour display)
0 = Monochrome display
3 Column Width 1 = 80-column display
0 = 40-column display (MZ-700 default)
2:0 Machine Model 000 = MZ-80K
001 = MZ-80C
010 = MZ-1200
011 = MZ-80A
100 = MZ-700 (default)
101 = MZ-800
110 = MZ-80B
111 = reserved (MZ-2000 NOT supported in V1)
────────────────────────────────────────────────────────────────────────────
Graphics Mode Register (0xF9) Bit Definitions
Bit(s) Name Description
────────────────────────────────────────────────────────────────────────────
7:5 Reserved Must be 0
4:3 GRAM Bank Selects which Graphics RAM bank is addressed when
writing via the Colour Writer registers (0xFA–0xFC)
2 VRAM Output 1 = character VRAM contributes to final video output
0 = VRAM suppressed (GRAM only displayed)
1 GRAM Output 1 = Graphics RAM contributes to final video output
0 = GRAM suppressed (VRAM only displayed)
0 Blend Operator 0 = OR — GRAM and VRAM pixels are OR'd together
1 = XOR — GRAM and VRAM pixels are XOR'd together
────────────────────────────────────────────────────────────────────────────
Colour Writer Registers (0xFA–0xFC)
The Colour Writer provides a fast mechanism for painting colour into the FPGA Graphics RAM without going through individual pixel writes. Each of the three Colour Writer registers holds an 8-bit mask, one bit per pixel in a horizontal group of 8. Writing a mask byte to register 0xFA (Red), 0xFB (Green), or 0xFC (Blue) causes those pixels whose corresponding bit is set to receive that colour component in the Graphics RAM bank currently selected by the Graphics Mode register (0xF9 bits 4:3).
Example — write a solid red horizontal bar covering all 8 pixels in the current group:
LD A, 0xFF OUT (0xFA), A ; all 8 pixels get red XOR A OUT (0xFB), A ; no green OUT (0xFC), A ; no blueMemory Page / Status Register (0xFD) Bit Definitions
Bit Name Description
────────────────────────────────────────────────────────────────────────────
7 CGROM→CPU 1 = Map the Character Generator ROM into the CPU
address space (read-accessible by Z80)
0 = Normal operation; CGROM not mapped to CPU
0 GRAM→CPU 1 = Map Graphics RAM into the CPU address space
(read/write accessible by Z80 in the video RAM
window at 0xD000–0xDFFF)
0 = Normal operation; GRAM not mapped to CPU
────────────────────────────────────────────────────────────────────────────
Reading port 0xFD returns video status information. The exact bit layout of the read-back status is determined by the V1 FPGA bitstream; consult the VHDL source for the definitive definition.
Supported Machine Models (V1)
V1 firmware supports emulation of the following Sharp MZ machine video modes. MZ-2000 is not supported — this was added in the current firmware release.
| Model Code (bits 2:0 of 0xF8) | Machine | Notes |
|---|---|---|
| 000 | MZ-80K | 40-column monochrome, original MZ character set |
| 001 | MZ-80C | 40-column monochrome |
| 010 | MZ-1200 | 40-column monochrome |
| 011 | MZ-80A | 40-column monochrome; compatible with RFS/TZFS MZ-80A monitor |
| 100 | MZ-700 | 40-column colour (default MZ-700 hardware mode) |
| 101 | MZ-800 | 40/80-column, extended colour modes |
| 110 | MZ-80B | 40-column monochrome, MZ-80B character set |
| 111 | (reserved) | MZ-2000 not supported in V1 |
FPGA Specifications
The FPGA is responsible for the video subsystem, all soft-CPU instantiation, and the video output signal generation. The bitstream is stored in the EPCS16 serial flash and loaded automatically on power-up or when the CONFIG button is pressed.
FPGA Device Options
| PCB Revision | FPGA Device | Gate Count | Notes |
|---|---|---|---|
| v1.2 | Altera Cyclone III EP3C25 | 25K LEs | First production design. Sufficient for MZ-700 video emulation and T80/ZPU soft CPUs. |
| v1.3 | Altera Cyclone IV EP4CE22 | 22K LEs | Entry-level Cyclone IV option for v1.3 boards. |
| v1.3 | Altera Cyclone IV EP4CE75 | 75K LEs | Standard v1.3 mainstream. Higher resolution graphics; more soft-CPU headroom. |
| v1.3 | Altera Cyclone IV EP4CE115 | 115K LEs | Maximum capacity option; build-time selectable. |
The main board crystal feeds directly into the Cyclone III/IV FPGA, which uses its four on-chip PLL devices to derive all internal synchronous clocks and video pixel clocks. The following external clock sources are also fed into the FPGA for synchronisation purposes:
FPGA Programming
- SYSCLK — the MZ-700 mainboard system clock (3.54 MHz). Fed into the FPGA to allow synchronised access to mainboard peripherals.
- CTLCLK — the K64F-generated alternate CPU clock. Fed into the FPGA so that soft-CPU execution at alternate frequencies remains properly synchronised with the FPGA internal fabric.
The FPGA is programmed via the JTAG interface. In the recommended daisy-chain configuration, the JTAG chain passes through the CPLD first (higher voltage device), then to the FPGA, as per Altera best practice. The EPCS16 is programmed via the Cyclone III/IV using Altera's built-in EPCS programming IP, which translates standard JTAG commands into EPCS16 SPI programming cycles. Once the EPCS16 is written, the FPGA loads its bitstream from the EPCS16 automatically on every power cycle or CONFIG reset.
V1 vs Current Firmware — Differences Summary
This section summarises all known differences between the V1 firmware (covered by this guide) and the current firmware release. If any register address, command code, or feature listed in another source does not match this guide, check whether that source covers the current firmware.
I/O Port Assignments
| Feature | V1 Address | Current Address |
|---|---|---|
| Video Control register | 0xF8 | 0xA8 |
| Video Graphics Mode register | 0xF9 | 0xA9 |
| Colour Writer Red | 0xFA | 0xAA |
| Colour Writer Green | 0xFB | 0xAB |
| Colour Writer Blue | 0xFC | 0xAC |
| Memory Page / Status | 0xFD | 0xAD |
| System Command Register | Not present | 0x6B |
| Register | V1 | Current |
|---|---|---|
| 0x6B System Command Register | Absent | Present — direct machine model switch without K64F service cycle |
| 0x60–0x6F (all other system registers) | Present, same function | Present, same function |
| Command | V1 | Current |
|---|---|---|
| 0x26 LOAD2000IPL | Absent | Present — loads MZ-2000 IPL firmware |
| 0x2F LOADTZFS | Absent | Present — loads TZFS for machines without onboard monitor |
| 0x5D EMU_SETMZ2000 | Absent | Present — activates MZ-2000 hardware emulation |
| All other commands (0x01–0x5C, 0x7F) | Present | Present, same function |
| Machine | V1 | Current |
|---|---|---|
| MZ-80K | Supported | Supported |
| MZ-80C | Supported | Supported |
| MZ-1200 | Supported | Supported |
| MZ-80A | Supported | Supported |
| MZ-700 | Supported | Supported |
| MZ-800 | Supported | Supported |
| MZ-80B | Supported | Supported |
| MZ-2000 | Not supported | Supported |
V1 firmware and current firmware are not binary-compatible. Updating from V1 to current requires:
- Flashing a new CPLD bitstream (implements the new I/O port map, adds 0x6B).
- Flashing a new FPGA bitstream (implements MZ-2000 video emulation, remaps video registers to 0xA8–0xAD).
- Updating the K64F firmware (adds LOAD2000IPL, LOADTZFS, EMU_SETMZ2000 service commands).
- Updating the TZFS Z80 firmware on the SD card (updated to use new register addresses and new service commands).
Build System
All development is done under Linux (Debian/Ubuntu). The build system is self-contained within the tranZPUter repository. The V1 firmware exists on a separate git branch from the current firmware.
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). |
| Quartus II / Quartus Prime | Required to rebuild CPLD and FPGA bitstreams. Not needed for Z80 firmware-only builds. |
| 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 Quartus installation is required to build the Z80 firmware and SD card image.
Edit
asm/include/tzfs_definitions.asm and set the appropriate target and feature flags. For V1 MZ-700 builds, the standard configuration is:
| Flag | V1 Default | Description |
|---|---|---|
BUILD_MZ700 EQU 1 |
1 | Sharp MZ-700 host machine (only target in V1) |
BUILD_MZ80A EQU 0 |
0 | Sharp MZ-80A host machine |
BUILD_MZ1500 EQU 0 |
0 | Sharp MZ-1500 host machine |
BUILD_MZ2000 EQU 0 |
0 | Not supported in V1 |
ENADEBUG EQU 0 |
0 | Enable assembly-time debug output |
git clone https://git.eaw.app/eaw/tranZPUter.git cd tranZPUter # Check out the V1 firmware branch: git checkout v1 # 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 targeting the V1 I/O register map (0xF8–0xFDvideo registers, no0x6B).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). Built with V1 register addresses. |
tzfs_bank2.bin |
Bank 2 image — message printing, help screen (paged at 0xF000–0xFFFF). |
tzfs_bank3.bin |
Bank 3 image — memory utilities, I/O, CPU 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 for MZ-700. |
monitor_80c_1Z-013A.bin |
1Z-013A 80-column monitor image for MZ-700. |
MZ80B_IPL.bin |
MZ-80B IPL image. |
cbios.bin |
CP/M 2.2 CBIOS SRAM image. |
CPM_DISK_*.img |
CP/M disk images (RAW format). |
Reference Sites
| Resource | Link |
|---|---|
| tranZPUter SW-700 project page | /transzputer-sw-700/ |
| tranZPUter SW-700 V1 README | /transzputer-sw-700-v1/ |
| tranZPUter SW-700 Current Technical Guide | /transzputer-sw-700-technicalguide/ |
| TZFS User Manual | /sharpmz-upgrades-tzfs-usermanual/ |
| TZFS Developer’s Guide | /sharpmz-upgrades-tzfs-developersguide/ |
| TZFS Technical Guide | /sharpmz-upgrades-tzfs-technicalguide/ |
| tranZPUter SW project page | /transzputer-sw/ |
| tranZPUter Fusion project page | /transzputer-fusion/ |
| Video Module Technical Guide | /video-module-technicalguide/ |
| RFS Technical Guide | /sharpmz-upgrades-rfs-technicalguide/ |
| GLASS Z80 Assembler | Bundled in tools/glass.jar |