Files
pico/README.md
Philip Smart e19a22fce6 Added README
2026-03-29 23:59:43 +01:00

14 KiB
Vendored

picoZ80 / pico6502

RP2350-based drop-in CPU replacements with cycle-accurate PIO bus interface, WiFi management, and virtual device framework.

Copyright (c) 2019-2026 Philip Smart — eaw.app


Overview

The picoZ80 is a custom PCB designed to drop directly into the Z80 DIP-40 CPU socket of any legacy Z80-based computer. Rather than using a discrete Z80 processor, the board hosts an RP2350B microcontroller — a dual-core 150 MHz Cortex-M33 (up to 300 MHz) — whose programmable I/O (PIO) state machines take full, cycle-accurate control of the Z80 address, data, and control buses.

The pico6502 applies the same architecture to the MOS 6502, replacing the 6502 DIP-40 CPU in any compatible host.

Every bus transaction is handled in real time by the RP2350's PIO engines, giving the host system exactly the same bus timing it would see from a real CPU. The RP2350's second core, 512 KB on-chip SRAM, 8 MB external PSRAM, and 16 MB Flash allow an almost unlimited range of capabilities: accelerated execution, virtualised memory, ROM banking, virtual disk drives, and full machine-persona emulation.

An ESP32 co-processor provides WiFi, Bluetooth, SD-card mass storage, and a browser-based management interface. All configuration is driven from a single config.json file on the SD card — no recompilation is required to reconfigure the memory map, ROM images, or driver selection.

Key Features

  • Drop-in Z80/6502 replacement — installs in any DIP-40 CPU socket; the host sees normal bus timing throughout
  • Cycle-accurate PIO bus interface — three RP2350 PIO blocks handle address, data, and control signals at full bus speed
  • 8 MB PSRAM — 64 banks x 64 KB of banked address space, configurable in 512-byte granularity
  • ROM/RAM banking — blocks can be mapped as ROM, RAM, physical host memory, or virtual function handlers
  • Virtual device framework — any memory block or I/O port range can be backed by a C function
  • Machine personas — JSON-driven configuration for any Z80/6502 host; Sharp MZ personas included
  • Floppy and QuickDisk emulation — WD1773 FDC and Sharp QuickDisk drive emulation from SD card images
  • WiFi web management — seven-page Bootstrap web interface for configuration, file management, OTA updates, and persona selection
  • Dual firmware partitions — two independent 5 MB firmware slots for safe OTA upgrades
  • USB firmware update — bootloader exposes a USB bridge for initial flashing without a hardware debugger

Hardware

The picoZ80 PCB (revision 2.5) is a compact, 6-layer board designed to fit within the physical footprint of the Z80 DIP-40 package. All logic operates at 3.3 V with level shifting for the 5 V host bus.

Key Components

Component Description
RP2350B Dual-core Cortex-M33 @ up to 300 MHz, 512 KB SRAM, 48 GPIO (QFN-80)
16 MB SPI Flash Bootloader, two firmware slots, two config slots, partition table
8 MB PSRAM External pseudo-static RAM — 64 banks x 64 KB
ESP32-S3-PICO-1 WiFi/BT co-processor, SD card, web server
SD card slot FAT32 — stores config.json, ROM images, disk images
USB hub CH334F — host connectivity and firmware update bridging
Power supply TLV62590BV 5 V-to-3.3 V buck converter from Z80 socket VCC

Schematic Sheets

The KiCad design (kicad/PICOZ80/) is divided into five sheets:

  1. RP2350B Processor — GPIO assignments, crystal, Flash, PSRAM
  2. ESP32 Co-processor — WiFi module, SD card, FSPI/UART inter-processor communication
  3. Z80 Bus Interface — DIP-40 socket, series resistor network for all bus signals
  4. Power Supply — 5 V-to-3.3 V synchronous buck converter
  5. USB Hub Controller — CH334F with Mini-B connector

Architecture

Dual-Core Design

  • Core 0 — non-real-time tasks: USB bridge, file I/O (relayed to ESP32), firmware update coordination, watchdog supervision, fault diagnostics
  • Core 1 — CPU emulation hot loop exclusively: services PIO FIFOs, resolves addresses against the memory map, dispatches to physical host, PSRAM, or virtual device handlers

PIO Bus Interface

The Z80 bus interface is implemented entirely in RP2350 PIO assembly (z80.pio). All three PIO blocks are used:

PIO Programs Function
0 z80_addr, z80_data, z80_cycle, z80_fetch Address/data bus, cycle sequencing, opcode fetch
1 z80_mem_read/write, z80_io_read/write, z80_busrq, z80_nmi, z80_clk_sync, z80_int_ack Memory/IO cycles, bus control, interrupts
2 z80_reset, z80_refresh, z80_wait, z80_sync Host timing, DRAM refresh, wait states, T1 synchronisation

Three-Tier Memory Model

Tier Storage Description
1 RP2350 SRAM (512 KB) O(1) block-type lookup table — 128 entries for 512-byte blocks
2 PSRAM (8 MB, SPI) 64 banks x 64 KB RAM/ROM images, pointer arrays, function-pointer arrays
3 Flash (16 MB, SPI) Firmware, ROM images (copied to PSRAM at boot), config JSON

Memory block types: PHYSICAL, PHYSICAL_VRAM, PHYSICAL_HW, RAM, ROM, VRAM, FUNC, PTR

Flash Memory Layout

Partition Address Range Size Contents
Bootloader 0x10000000-0x1001FFFF 128 KB USB bridge, firmware update, partition selector
App Slot 1 0x10020000-0x1051FFFF 5 MB Z80 firmware (partition 1)
App Slot 2 0x10520000-0x10A1FFFF 5 MB Z80 firmware (partition 2)
App Config 1 0x10A20000-0x10C9FFFF 2.5 MB ROM images + config JSON (slot 1)
App Config 2 0x10CA0000-0x10F1FFFF 2.5 MB ROM images + config JSON (slot 2)
General Config 0x10F20000-0x10FFEFFF 892 KB Core settings
Partition Table 0x10FFF000-0x11000000 4 KB Active slot, checksums, metadata

Machine Personas

The firmware supports multiple machine personas, each associated with a different PSRAM bank. Switching persona changes the active memory map and loaded ROM images without rebooting.

Peripheral and Filing-System Drivers

Driver Description
MZ700.c Sharp MZ-700 peripheral set — bank-switching, video, keyboard I/O
WD1773.c WD1773 floppy disk controller — 80-track DSK/RAW images from SD card
QDDrive.c Sharp QuickDisk drive — full SIO/2 emulation with QD image files
RFS.c ROM Filing System — MZF loading from SD, CP/M v2.23, SA-1510 BASIC, MS-BASIC v4.7
TZFS.c TranZPUter Filing System (work in progress)
MZ-1E05.c Sharp MZ-1E05 floppy disk interface unit
MZ-1E14.c QuickDisk controller with BIOS ROM (MZ-700/MZ-800)
MZ-1E19.c QuickDisk controller without BIOS ROM (MZ-800/MZ-2000/MZ-2200/MZ-2500)
MZ-1R12.c 32 KB battery-backed RAM board (persisted to SD card)
MZ-1R18.c 64 KB RAM expansion / RAMFILE

Build Instructions

Prerequisites

  • CMake 3.20+
  • ARM GCC toolchainarm-none-eabi-gcc
  • Docker — for ESP32 firmware build (Espressif IDF container espressif/idf:release-v5.4)
  • Python 3 — required by Pico SDK build tools
  • Perl — used for automatic version incrementing

Directory Structure

<root>/
├── get_and_build_sdk.sh      # clones and builds pico-sdk
├── build_tzpuPico.sh         # builds RP2350 firmware (+ optionally ESP32)
├── picoZ80.h.tmpl            # board definition, copied into SDK at build time
├── pico-sdk/                 # cloned by get_and_build_sdk.sh
├── pico-extras/              # cloned by get_and_build_sdk.sh
└── projects/
    ├── Z80/                  # Z80 emulator library (clone separately)
    └── tzpuPico/             # this project

Step 1 — Clone the Projects

mkdir -p <root>/projects
cd <root>/projects

# Clone the main project
git clone https://git.eaw.app/eaw/pico.git tzpuPico

# Clone the Z80 emulator library
git clone https://github.com/redcode/Z80.git Z80

Step 2 — Set PICO_PATH

Edit the PICO_PATH variable at the top of get_and_build_sdk.sh and build_tzpuPico.sh:

export PICO_PATH=/your/chosen/root/

Step 3 — Get and Build the Pico SDK

cd <root>
./get_and_build_sdk.sh

Step 4 — Build the RP2350 Firmware

cd <root>

# Standard release build (RP2350 only)
./build_tzpuPico.sh

# Debug build
./build_tzpuPico.sh DEBUG

# Full build — RP2350 + ESP32 firmware via Docker
./build_tzpuPico.sh ALL

Output files:

  • projects/tzpuPico/fw/uf2/ — Bootloader UF2 images (for initial USB flashing)
  • projects/tzpuPico/fw/bin/ — Application partition binaries (for OTA updates)

Build ESP32 Firmware Separately

alias idf54='docker run --rm --privileged \
  --volume /dev:/dev --volume /sys:/sys:ro \
  --volume /dev/bus/usb:/dev/bus/usb \
  -v $PWD:/project -w /project \
  -it espressif/idf:release-v5.4 idf.py "$@"'

cd <root>/projects/tzpuPico/esp32
idf54 build

Flashing

Initial RP2350 Flash

The 6-pin debug header pinout:

Pin 1 Pin 2 Pin 3 Pin 4 Pin 5 Pin 6
SWCLK SWDIO Reset RP2350 Reset ESP32 GND BOOTSEL
  1. Hold Pin 6 (BOOTSEL) low
  2. Apply power or assert Pin 3 (Reset) low then release
  3. Release BOOTSEL promptly after boot begins
  4. Connect USB — the RP2350 enumerates as a mass-storage device
  5. Copy Bootloader_<version>.uf2 to the mounted drive

Initial ESP32 Flash

python3 -m venv ./venv/ && source ./venv/bin/activate
cd $HOME/esptool

PORT=/dev/ttyUSB0          # adjust to your system
BINPATH=/path/to/build

python3 ./esptool.py -p ${PORT} -b 115200 \
  --before default_reset --after hard_reset --chip esp32s3 \
  write_flash --flash_mode dio --flash_size 4MB --flash_freq 80m \
  0x0     ${BINPATH}/bootloader.bin \
  0x8000  ${BINPATH}/partition-table.bin \
  0x9000  ${BINPATH}/ota_data_initial.bin \
  0x10000 ${BINPATH}/sd_card.bin

OTA Updates (after initial flash)

  • RP2350 — navigate to http://<device-ip>/ota-rp2350.htm, upload the .bin file
  • ESP32 — navigate to http://<device-ip>/ota-esp32.htm, upload the firmware binary or FilePack archive

SD Card Preparation

Format as FAT32. Place config.json in the root directory. Create subdirectories for ROM images and disk images as referenced in your configuration. The SD card can also be managed via the web File Manager page.


Web Interface

The ESP32 serves a seven-page Bootstrap web interface over WiFi:

Page Function
Status System overview — RP2350 and ESP32 firmware versions, partition info, uptime
Personality Select and switch machine personas
Configuration Edit config.json with syntax highlighting
File Manager Browse, upload, download, delete files on the SD card
OTA RP2350 Upload RP2350 firmware binary for over-the-air update
OTA ESP32 Upload ESP32 firmware or FilePack archive
WiFi Settings Configure AP/client mode, SSID, password

Documentation

Full documentation is available at eaw.app:


Credits

  • Manuel Sainz de Baranda y GoniZ80 C-language Z80 CPU emulator library (GPL v3)
  • Raspberry Pi Ltd — Pico SDK and RP2350 hardware
  • Espressif Systems — ESP-IDF framework and ESP32 hardware
  • Philip Smart — Hardware design, RP2350 PIO firmware, ESP32 web application, JSON configuration system, Sharp MZ persona drivers, documentation

Commercial Use Restriction

No commercial use permitted without express written permission.

The picoZ80/pico6502 hardware designs, firmware, and all associated software are made available for personal, educational, and non-commercial use only. No part of this design may be used, reproduced, manufactured, sold, or incorporated into any commercial product without the express written permission of the author.

To request a commercial licence, contact: info@eaw.app


Licences

Component Licence
picoZ80/pico6502 RP2350 firmware (PIO, C sources) GNU General Public License v3
picoZ80/pico6502 ESP32 firmware and web interface GNU General Public License v3
Z80 CPU emulator library (Manuel Sainz de Baranda y Goni) GNU General Public License v3
KiCad hardware design files (schematics, PCB, Gerbers) Creative Commons BY-NC-SA 4.0
Documentation and user guides Creative Commons BY-NC-SA 4.0
Raspberry Pi Pico SDK BSD 3-Clause
ESP-IDF framework Apache License 2.0
Bootstrap 4 (web interface) MIT License

The firmware and software are open-source under the GPL v3. The hardware designs and documentation are licensed under CC BY-NC-SA 4.0 (non-commercial use only — commercial licensing available on request). Third-party libraries retain their own licences.

The names picoZ80, pico6502, and engineers@work are trademarks of Philip Smart. See the NOTICE file for full attribution, trademark, and anti-passing-off terms.

Full licence texts: LICENSE | LICENSE-HARDWARE.txt | LICENSE-SOFTWARE.txt