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:
- 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.
- 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.
- 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).
- 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.
- 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:
- Wait for the relevant combination of MREQ/IORQ together with M1/RD/WR to be asserted by the host Z80.
- Latch the address from A0–A15.
- Send the address to the SOM — via the GPIO read path for read cycles, or via SPI for write cycles.
- For read cycles: receive the data byte from the SOM and drive D0–D7 toward the host within the CPLD-enforced T-state window.
- For write cycles: capture the data byte from D0–D7 and forward it to the SOM.
- 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-compiler —
arm-linux-gnueabihf-gcc(ARM hard-float ABI, Linux target) - SDK — SigmaStar SDK: U-boot + Linux 4.9-rt + Buildroot
- Master build script —
Build_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:
- U-boot bootloader compilation and configuration for the SSD202 NAND target.
- Linux kernel build using defconfig
infinity2m_spinand_fusionx_defconfig. - Buildroot root filesystem construction (minimal package set).
- FusionX application build: kernel modules, utilities, startup scripts, ROM image packaging.
- 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
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.
- 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.
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.