tranZPUter FusionX Technical Guide

Overview

The tranZPUterFusionX is built around two primary silicon devices: a SigmaStar SSD202 System-On-Module (SOM) housing dual Cortex-A7 cores running at 1.2GHz, and an Altera MAX7000AE CPLD (EPM7512) that provides a cycle-accurate Z80 bus interface to the host machine. The fundamental division of responsibility is clean: the CPLD owns the Z80 bus and enforces correct electrical and timing behaviour toward the host, while the SOM handles all emulation work inside a dedicated Linux kernel module running on an isolated CPU core. The two devices communicate over a 50MHz SPI link (SOM → CPLD, write/control path) and a direct GPIO bus (CPLD → SOM, read/address-capture path). This architecture delivers up to ~500MHz-equivalent Z80 throughput — far beyond any real Z80 — while presenting a perfectly orthodox Z80 interface to the host machine. The CPLD's EEPROM-based configuration cells retain the programmed logic indefinitely with no battery or external non-volatile storage required.

Hardware Architecture

Block Diagram

┌────────────────────────────────────────────────────────────────────────┐
│                         tranZPUter FusionX Board                       │
│                                                                        │
│  ┌─────────────────────────────────────────────────┐                  │
│  │             SigmaStar SSD202 SOM (Infinity2M)    │                  │
│  │  ┌─────────┐  ┌─────────┐   128MB DRAM          │                  │
│  │  │ CPU0    │  │ CPU1    │   256MB NAND Flash      │                  │
│  │  │ Linux   │  │ Z80 Emu │   Integrated WiFi       │                  │
│  │  │ 1.2GHz  │  │ 1.2GHz  │   (SSW101B 2.4GHz)     │                  │
│  │  └─────────┘  └─────────┘                        │                  │
│  │   GPIO (read path)  SPI (write path, 50MHz)       │                  │
│  └──────────────┬────────────────┬──────────────────┘                  │
│                 │ GPIO           │ SPI                                  │
│  ┌──────────────▼────────────────▼──────────────────┐                  │
│  │         Altera MAX7000AE CPLD (EPM7512)           │                  │
│  │  Z80 Bus FSM  ◄─────────────────────────────────►│◄──[ 50MHz OSC ] │
│  │  SPI decoder  │                                   │                  │
│  │  Video/Audio  │                                   │                  │
│  └───────────────┬───────────────────────────────────┘                  │
│                  │ DIP-40 Z80 bus                                       │
│  ┌───────────────▼───────────┐  ┌─────────────────────────┐            │
│  │  Z80 DIP-40 host socket   │  │  Video/Audio outputs     │            │
│  │  A0-A15, D0-D7, MREQ,    │  │  GM7123 RGB DAC (30-bit) │            │
│  │  IORQ, RD, WR, HALT,     │  │  TLC5602C Contrast DAC   │            │
│  │  M1, RFSH, NMI, INT,     │  │  TLC5602C Audio DAC      │            │
│  │  WAIT, RESET, CLK, BUSRQ │  └─────────────────────────┘            │
│  └───────────────────────────┘                                          │
│  [ USB-serial CH340E ]──USB──►[ Linux console /dev/ttyUSB0 ]          │
└────────────────────────────────────────────────────────────────────────┘

Key Components

The table below lists the primary components on the tranZPUterFusionX mainboard.
Component Part Specification
SSD202 SOM SigmaStar SSD202 (Infinity2M) Dual Cortex-A7 @ 1.2GHz, 128MB DRAM, 256MB NAND, integrated WiFi
CPLD Altera EPM7512AETC144-10 MAX7000AE, 512 macrocells, 144-pin TQFP, 5V-tolerant inputs
DRAM On-SOM 128MB DDR2
NAND Flash On-SOM 256MB SPI NAND
WiFi SSW101B IEEE 802.11 b/g/n, 2.4GHz, 500m range
Video DAC GM7123 (3.3V) 30-bit RGB DAC (ADV7123 equivalent); 10 bits per colour channel
Contrast DAC TLC5602C 8-bit DAC; drives 4V–5V contrast signal for Sharp MZ monochrome CRT
Audio DAC TLC5602C 8-bit DAC; stereo 48kHz output
Power supply IC On-board regulator 5V → 3.3V for SOM and CPLD rails
USB power switch On-board Switchable USB VBUS for host USB port
USB-serial converter CH340E 115200 baud 8N1; exposes Linux console as /dev/ttyUSB0
50MHz oscillator SMD can oscillator CPLD master clock; used for Z80 bus FSM timing

CPLD Role

The CPLD (EPM7512AETC144-10, 512 macrocells, 144-pin TQFP) is the linchpin of the FusionX design. It serves five distinct functions:
  1. Voltage translation — The SOM GPIO operates at 3.3V; the Z80 host bus operates at 5V. The MAX7000AE CPLD has 5V-tolerant inputs and drives outputs at LVTTL levels (logic '1' = 3.3V), which is above the 2.4V switching threshold of 5V TTL logic on the host side, ensuring correct interfacing in both directions.
  2. Cycle-accurate Z80 bus timing — The CPLD implements full Z80 bus finite state machines (FSMs) for every Z80 cycle type: opcode fetch, memory read, memory write, I/O read, I/O write, interrupt acknowledge, and bus request/grant. All FSMs are clocked by the 50MHz oscillator, giving 20ns resolution against a typical 1MHz–6MHz Z80 host clock.
  3. SOM interface — Two independent communication paths exist: a 50MHz SPI channel for the SOM to send data and control commands to the CPLD (write path), and a direct GPIO path for the CPLD to drive address, data, and status signals onto SOM GPIO pins for fast bus-cycle capture (read path).
  4. Video and audio switching — The CPLD controls the analog multiplexers on daughter boards, selecting between the host's native video/audio and the SOM output. It generates the composite sync signal (VGA_CSYNCn) and the colour carrier frequency (VGA_COLR) for composite video output, and the monochrome blanking signal (MONO.BLANK) for CRT contrast control.
  5. Reset management — The CPLD stretches and synchronises the RESET signal, ensuring that both the SOM and the host machine enter and exit reset in a coordinated manner regardless of the source of the reset event.

CPLD Variants

A separate CPLD build is produced for each supported host machine. Each variant implements the same core Z80 bus FSM but differs in memory map decoding, I/O port assignments, video timing, and bank-switching logic appropriate for the target machine.
Variant Target Machine Key Differences
MZ80A Sharp MZ-80A 40/80-column display timing; MZ-80A memory map; RFS (ROM Filing System) paging
MZ700 Sharp MZ-700 Bank switching of lower 32KB; MZ-700 video and keyboard port decoding
MZ2000 Sharp MZ-2000 Extended memory banking; additional video mode signals
PCW8256 Amstrad PCW-8256 Memory paging (4×16KB banks); PCW I/O port map

Z80 Bus FSM

The CPLD implements a dedicated state machine for each Z80 bus cycle type. The generalised sequence for every cycle is:
  1. Wait for the relevant combination of MREQ/IORQ together with M1/RD/WR to be asserted by the host Z80.
  2. Latch the address from A0–A15.
  3. Send the address to the SOM — via the GPIO read path for read cycles, or via SPI for write cycles.
  4. For read cycles: receive the data byte from the SOM and drive D0–D7 toward the host within the CPLD-enforced T-state window.
  5. For write cycles: capture the data byte from D0–D7 and forward it to the SOM.
  6. Deassert control signals and release the bus with correct T-state timing as specified by the Z80 datasheet.
Cycle Type Bus Signals T-states SOM Notification Method
Opcode fetch (M1) MREQ↓ + M1↓ + RD↓ 4 (min) GPIO address latch → SPI data reply
Memory read MREQ↓ + RD↓ 3 (min) GPIO address latch → SPI data reply
Memory write MREQ↓ + WR↓ 3 (min) GPIO address + data → SPI ack
I/O read IORQ↓ + RD↓ 4 (min) GPIO address latch → SPI data reply
I/O write IORQ↓ + WR↓ 4 (min) GPIO address + data → SPI ack
Interrupt acknowledge IORQ↓ + M1↓ 4 (min) SPI interrupt vector reply
Bus request/grant BUSRQ↓ → BUSAK↓ variable SPI control command

SOM Interface

The SOM communicates with the CPLD over two independent paths optimised for their respective directions:
  • SPI write path (50MHz) — The SOM drives the CPLD over SPI at 50MHz. This path is used for: writing data bytes onto the Z80 bus (for read cycles seen by the host), asserting NMI or INT to the host, controlling video and audio multiplexers on daughter boards, and setting bus direction/tristate control. SPI provides sufficient bandwidth for all control and data-output operations.
  • GPIO read path — The CPLD drives address, data, and status bits directly onto dedicated SOM GPIO pins. The SOM reads these via direct memory-mapped GPIO register access, bypassing the Linux GPIO HAL entirely for minimum latency. This path achieves approximately 2MB/s throughput and is used for address bus capture on each Z80 cycle and data capture from the Z80 for host write cycles. Direct register access is essential because the Linux GPIO subsystem introduces scheduling jitter that would violate Z80 bus timing.

Video Output

The FusionX mainboard provides a 30-bit RGB video output path suitable for all Sharp MZ display modes and additional resolutions up to HD.
  • GM7123 RGB DAC — A 3.3V version of the ADV7123, providing 10 bits per colour channel (30-bit total). The SOM supplies the upper 8 bits per channel; the CPLD provides the lower 2 bits for interpolation and palette fine-tuning.
  • Composite sync — VGA_CSYNCn is generated by the CPLD, synchronised to the Z80 host clock and the selected video mode.
  • Colour carrier — VGA_COLR is generated by the CPLD at the appropriate frequency for composite colour output.
  • Contrast DAC (TLC5602C, 8-bit) — Drives a 4V–5V analogue signal to control the contrast level of the Sharp MZ internal monochrome CRT. The CPLD also generates the MONO.BLANK blanking signal gated to the selected video mode.

Audio

  • Audio DAC (TLC5602C, 8-bit) — Stereo output at 48kHz, driven by the SOM. Delivers CD-quality audio for emulated sound or arbitrary waveform playback.
  • SN76489 PSG emulation — The SN76489 Programmable Sound Generator is emulated entirely in software on the SOM, with generated audio fed to the DAC. All three tone channels and the noise channel are supported.
  • Audio amplifier — Each daughter board includes an audio amplifier stage for routing audio to the host machine's internal speaker.
  • Microphone input — A microphone input is available on the SOM/daughter board for audio recording.

Software Architecture

Dual-Core Design

The SSD202's two Cortex-A7 cores are assigned strictly separate roles. CPU isolation is established at Linux boot time and enforced by the startup script, guaranteeing that the Z80 emulation thread is never preempted by the Linux scheduler.
Core OS Assignment Responsibilities
CPU0 Linux (normal scheduling) All Linux processes, kernel threads, hardware IRQs, memory management, file I/O, network stack, USB subsystem, serial console, web server (future), sharpbiter arbiter daemon, k64fcpu daemon
CPU1 Isolated (taskset / isolcpus) Z80 emulation kernel thread only (z80drv); all other processes and IRQs migrated to CPU0 at startup
CPU isolation is implemented in two layers. First, the kernel is booted with the parameter isolcpus=1, which prevents the Linux scheduler from placing any task on CPU1 unless explicitly requested. Second, the startup script start_FusionX.sh uses taskset to pin the z80drv kernel thread to CPU1 and to migrate all other eligible threads away from it. The result is a dedicated real-time core with deterministic response to CPLD GPIO interrupts, free from Linux scheduling jitter.

Kernel Modules

Two Linux kernel modules form the heart of the FusionX software stack:
  • z80drv.ko — Z80 emulation core
    • Main dispatch loop: polls CPLD GPIO for a pending bus cycle notification.
    • Routes each cycle to the appropriate virtual hardware handler based on the address and cycle type (memory read/write, I/O read/write, opcode fetch).
    • Calls the Zeta Z80 instruction emulator for opcode fetch cycles.
    • Key source files: z80driver.c (main dispatch), z80io.c (hardware abstraction layer), emumz.c (instruction execution wrapper).
  • ttymzdrv.ko — MZ keyboard/display TTY driver
    • Maps the Sharp MZ keyboard matrix to standard Linux key events.
    • Maps Linux console output to Sharp MZ display controller commands.
    • Exposes /dev/ttymz0, allowing a getty login session directly on the host machine's keyboard and display.
    • Supports suspend/resume for clean switching between Z80 emulation mode and Linux console mode.

Virtual Hardware Modules

Each supported host machine has a dedicated virtual hardware module. The z80drv dispatch loop selects the active module at load time based on the configured machine target.
Module Source File Target Function
MZ-80A z80vhw_mz80a.c Sharp MZ-80A Memory map, keyboard matrix, display I/O
MZ-700 z80vhw_mz700.c Sharp MZ-700 Bank switching (lower 32KB), video/keyboard emulation
MZ-2000 z80vhw_mz2000.c Sharp MZ-2000 Extended memory banking, video mode control
PCW-8256 z80vhw_pcw.c Amstrad PCW-8256 Memory paging (4×16KB banks), standard PCW I/O
ROM FS z80vhw_rfs.c MZ-80A (40/80-col) 4 switchable ROM pages; MZF file loading from SD card
TZPU SW z80vhw_tzpu.c tranZPUter SW mode K64F virtual co-processor stub for TZFS behaviour

Z80 Emulation

  • Zeta Z80 library — Instruction execution uses the Zeta Z80 library by Manuel Sainz de Baranda y Goñi (LGPL v3). The library provides a complete, accurate Z80 instruction set implementation including all undocumented opcodes.
  • Emulation loop — Implemented in emumz.c. The loop executes one instruction per iteration and invokes the virtual hardware callback functions for each memory or I/O access generated by that instruction.
  • Memory maps — Each supported machine's memory layout (base addresses, region sizes, RAM/ROM attribute flags) is defined in z80driver.h. The active map is selected at module load time.
  • Performance — The emulator achieves approximately 500MHz Z80-equivalent throughput on the 1.2GHz Cortex-A7 core, with minimal overhead per instruction due to the isolated CPU1 environment.
  • Timing model — Cycle accuracy toward the host is entirely the responsibility of the CPLD hardware. The emulator need only respond within the timing windows that the CPLD enforces; it does not itself implement T-state counting.

User-Space Utilities

  • z80ctrl — Command-line control interface for the z80drv kernel module. Supports the following operations: loadrom (load a ROM image into emulated address space), adddev (register a virtual device), start/stop (start or halt the Z80 emulation thread), dump (display emulated Z80 memory regions), loadmzf (load an MZF program file and optionally auto-run it).
  • k64fcpu — K64F virtual CPU daemon. Emulates the K64F co-processor expected by the TZFS (tranZPUter File System) ROM. Communicates with z80drv via shared kernel memory, responding to co-processor commands issued by the Z80 program.
  • sharpbiter — Arbiter daemon. Coordinates access to the Sharp MZ keyboard and display hardware between ttymzdrv (Linux console) and z80drv (Z80 emulation), preventing register conflicts when both subsystems are active.

Flash and Storage Layout

The SSD202 SOM carries 256MB of SPI NAND Flash, partitioned as follows:
  • U-boot bootloader partition — First-stage and second-stage bootloaders; loads the Linux kernel from NAND.
  • Linux kernel partition — Linux 4.9-rt with PREEMPT_RT patch applied; kernel image with the FusionX defconfig (infinity2m_spinand_fusionx_defconfig).
  • Buildroot root filesystem — Minimal read-only squashfs root filesystem built with Buildroot. Contains only the packages required for FusionX operation.
  • FusionX application partition — Contains: z80drv.ko, ttymzdrv.ko, z80ctrl, k64fcpu, sharpbiter, startup scripts (start_FusionX.sh), and ROM images for all supported machines.
  • Configuration partition — Writable JFFS2 or UBIFS partition. Persists user configuration (machine selection, display mode, etc.) across firmware updates.
An SD card slot on the SOM provides additional user-accessible storage for: user data, additional ROM images, MZF program files, and OTA (over-the-air) firmware update packages. The SOM bootloader auto-detects a suitably prepared SD card on power-up and performs the upgrade before booting Linux.

CPLD Build and Programming

Build Tool

The CPLD HDL is compiled with Quartus II 13.0.1 SP1 Web Edition. This is the last version of Quartus II that supports the MAX7000AE device family and is freely downloadable from Intel/Altera.

Source Files

File Purpose
tzpuFusionX.vhd Main RTL: Z80 bus FSM, SPI decoder, video/audio control logic
tzpuFusionX_Toplevel.vhd Top-level entity: I/O pin assignments, port connections
tzpuFusionX_pkg.vhd Shared VHDL package: type definitions, constants, records
Per-machine Quartus projects are located at:
CPLD/v1.0/MZ80A/
CPLD/v1.0/MZ700/
CPLD/v1.0/MZ2000/
CPLD/v1.0/PCW8256/

Compilation

To compile from the command line using the Quartus shell (example for MZ-80A):
quartus_sh --flow compile tzpuFusionX_MZ80A
The compiled output file is written to:
build/output_files/tzpuFusionX_MZ80A.pof

Programming

The CPLD is programmed via JTAG using an Altera USB-Blaster cable connected to the 10-pin JTAG header on the FusionX board:
quartus_pgm -c "USB-Blaster" -m JTAG -o "p;tzpuFusionX_MZ80A.pof@1"
The MAX7000AE uses EEPROM-based configuration cells, which retain the programmed logic indefinitely without any battery or external non-volatile storage. Programming is required only when the CPLD design is updated.

Linux Firmware Build

Toolchain and SDK

  • Cross-compilerarm-linux-gnueabihf-gcc (ARM hard-float ABI, Linux target)
  • SDK — SigmaStar SDK: U-boot + Linux 4.9-rt + Buildroot
  • Master build scriptBuild_FusionX.sh

Full Firmware Build

cd software/linux/
./Build_FusionX.sh -f nand -p ssd202 -o 2D06 -m 256
The build proceeds through the following stages in order:
  1. U-boot bootloader compilation and configuration for the SSD202 NAND target.
  2. Linux kernel build using defconfig infinity2m_spinand_fusionx_defconfig.
  3. Buildroot root filesystem construction (minimal package set).
  4. FusionX application build: kernel modules, utilities, startup scripts, ROM image packaging.
  5. Partition image assembly and NAND flash image creation.

Kernel Module Only (Rapid Iteration)

During development it is often sufficient to rebuild only the z80drv kernel module. The following builds the MZ-80A variant of z80drv in isolation:
cd software/FusionX/src/z80drv/src.mz80a
make

Flashing

  • Initial programming — Use the SigmaStar ISP tool over USB to write the full NAND image on a bare or factory-reset SOM.
  • OTA update via SD card — Place a prepared firmware package on the SD card. The U-boot bootloader detects the update package on the next power cycle and performs the upgrade automatically before booting Linux.

Debugging

Serial Console

The CH340E USB-serial converter exposes the Linux console on /dev/ttyUSB0 at 115200 baud, 8N1. Connect any terminal emulator (e.g. minicom, picocom, PuTTY) to this port for access to the Linux shell and kernel log output (dmesg). This is the primary debug interface during bring-up and runtime diagnostics.

JTAG

The 10-pin JTAG header on the FusionX mainboard connects to an Altera USB-Blaster for CPLD programming and verification. The same interface supports Quartus SignalTap II, the in-system logic analyser built into Quartus II, which allows real-time capture and display of CPLD internal signals — including the Z80 bus FSM state register, SPI decoder state, and all bus control signals — without any external probes.

Kernel Module Debug Logging

The z80drv kernel module includes a compile-time debug define, DEBUG_PIO. When this define is set, the module emits verbose bus cycle logging to the kernel ring buffer for every Z80 bus transaction. View the output with dmesg -w over the serial console. This is useful for tracing virtual hardware handler calls, verifying memory map decoding, and diagnosing timing issues between the CPLD and the SOM.

z80ctrl --dump

The z80ctrl --dump command queries z80drv and displays the current contents of all emulated Z80 memory regions in hex format. This is useful for verifying ROM loads, inspecting RAM state, and confirming that virtual hardware registers are being written correctly by the running Z80 program.

Quartus SignalTap II

Quartus SignalTap II provides in-system logic analysis of the CPLD without requiring external test equipment. A SignalTap II configuration file can be compiled into the CPLD bitstream, enabling real-time capture of the Z80 bus FSM state machine transitions, SPI frame decoding, address and data bus values, and all control signal edges. Captured data is displayed in the Quartus II waveform viewer over the USB-Blaster JTAG connection.

Reference Sites

Resource URL
tranZPUter FusionX project page eaw.app/tranzputer-fusionx
User Manual eaw.app/tranzputer-fusionx-usermanual
Developer’s Guide eaw.app/tranzputer-fusionx-technicalguide
SigmaStar SSD202 sigmastarmicro.com
Altera MAX7000AE datasheet intel.com — MAX 7000AE Programmable Logic Device Family
Zeta Z80 library github.com/redcode/Zeta
Quartus II 13.0.1 SP1 download intel.com — Quartus II Web Edition
Sharp MZ series reference sharpmz.org
Amstrad PCW reference cpcwiki.eu/index.php/PCW

Wireless Regulatory Notice

This device incorporates an SSW101B 2.4 GHz IEEE 802.11 b/g/n wireless transceiver (integrated within the SigmaStar SSD202 SOM), making it an intentional radiator under radio-frequency regulations worldwide (including FCC Part 15 Subpart C in the United States, and the Radio Equipment Directive 2014/53/EU in the European Union).
Although the SOM module carries pre-existing regulatory certifications, those module-level certifications do not automatically extend to a finished product that incorporates the module. The pre-certified module exemption permits individual hobbyists to build a limited number of devices for personal, experimental, or educational use without obtaining separate equipment authorisation.
Important Limitations
  • Assembled devices must not be sold, offered for sale, gifted, or otherwise distributed to third parties unless the finished product has been independently tested and granted its own equipment authorisation (e.g. FCC ID, CE marking with a Notified Body assessment) in the relevant jurisdiction.
  • Building this project for personal use in limited quantities is generally permitted under hobbyist and experimental-use provisions (e.g. FCC § 15.23), provided the device does not cause harmful interference.
  • Regulatory requirements vary by country. Builders outside the United States should consult their national radio-frequency authority for applicable rules.
Builder’s Responsibility
It is the builder’s sole responsibility to ensure that any device constructed from these designs complies with all applicable radio-frequency regulations in their jurisdiction. The author provides these designs for personal, educational, and hobbyist use and makes no representation that a device built from them satisfies the regulatory requirements for commercial distribution.