-
Notifications
You must be signed in to change notification settings - Fork 3
EN Boards
Reference page · Boards: MURM2, PICO_PC, PICO_DV, ZERO, ZERO2, MURM · Source of truth: the GPIO Map section of CLAUDE.md
pico-spec runs on six Murmulator-family carrier boards built around a Raspberry Pi Pico-class module. Two MCU families are supported:
- RP2350 (newer): MURM2 (RP2350A), PICO_PC (RP2350A), PICO_DV (RP2350), ZERO2 (RP2350B). More RAM, more GPIO and PSRAM, so they get the heavy features.
- RP2040 (original): ZERO, MURM. Tighter on RAM, so several features are compiled out.
About the Murmulator project. The Murmulator (Мурмулятор) is an open-source "board for developing and murmulating retro platforms" created by Alex Ekb (Алекс Екб), who designed the hardware and the first ZX Spectrum emulation firmware. The boards use common, inexpensive parts with open Gerbers and open firmware sources, so they are easy to self-assemble. The wider community supports 10+ platforms (ZX Spectrum, БК 0010, Game Boy, Sega Game Gear / Mega Drive / Master System, NES/Dendy/Famicom, …); pico-spec is the ZX-Spectrum firmware. See murmulator.ru, the Telegram group @ZX_MURMULATOR and the file archive.
| Capability | RP2040 (ZERO, MURM) | RP2350 (the other four) |
|---|---|---|
| SRAM | 256 KB (≈148 KB free heap at boot, ≈5 KB after the framebuffer) | larger; PSRAM on most boards |
| Networking (Network) | not supported | ESP-01S over UART (ZiFi, WiFi, FTP, archives) |
| MIDI out | not supported (PICO_RP2040=1) |
yes, on a UART-TX pin |
| esxDOS / MB-02+ / Z-Controller / IDE-HDD (Storage) | not supported | yes |
| RTC / Mr Gluk TimeKeeper | not supported | yes |
| Profi machine, ULA+, Gigascreen | disabled / limited | yes |
RP2040 memory is tight. Of 256 KB SRAM, only ≈5 KB of heap is left after the 240×320 framebuffer is allocated. Large static arrays and heap-heavy menu code can break these boards — which is why the SD-disk interfaces, networking and RTC are RP2350-only.
The build selects one of two Pico-SDK board header profiles under src/boards/ — these
are the silicon definitions, not extra user-facing boards:
-
picospec_rp2350b.h— used by the RP2350A/RP2350B carriers (MURM2, PICO_PC, PICO_DV, MURM1_P2). A copy of the SDKpico2header with the RP2350B (48-GPIO) variant forced on, so GPIO 30–47 are valid. -
waveshare_rp2350_pizero.h— used by ZERO2 (Waveshare RP2350-PiZero).
All functional pins are set explicitly in CMakeLists.txt per board, so the header
defaults are inert.
| Board | MCU | GPIO range | FIXED / REASSIGN / FREE | MIDI | NESPAD |
|---|---|---|---|---|---|
| MURM2 | RP2350A | 0–29 | 15 / 9 / 5 | OK (GPIO 22) | conflict with PSRAM (CLK=20, LAT=21) |
| PICO_PC | RP2350A | 0–29 | 13 / 10 / 6 | OK (GPIO 26) | OK |
| PICO_DV | RP2350 | 0–29, 47 | 14 / 8 / 9 | BUG (GPIO 21 = RX!) | conflict with display (8, 9) |
| ZERO | RP2040 | 0–28 | 16 / 8 / 5 | N/A (RP2040) | OK |
| ZERO2 | RP2350B | 0–47 | 14 / 12 / 22 | OK (GPIO 22) | disabled |
| MURM | RP2040 | 0–28 | 18 / 10 / 0 | N/A (RP2040) | OK |
- FIXED — hardwired on the PCB, cannot change (display, SD card, onboard PSRAM, LED).
- REASSIGNABLE — currently used but can be remapped/disabled in software (NESPAD, keyboard, MIDI, audio, WAV-input, ZiFi UART).
- FREE — not used by any peripheral.
FIXED = 15 · REASSIGNABLE = 9 · FREE = 5
| GPIO | Function | Cat | Notes |
|---|---|---|---|
| 0 | — | FREE | |
| 1 | — | FREE | |
| 2 | KBD_CLOCK | REASSIGN | PS/2 keyboard |
| 3 | KBD_DATA | REASSIGN | PS/2 keyboard |
| 4 | SD MISO | FIXED | SPI0 PCB |
| 5 | SD CS | FIXED | SPI0 PCB |
| 6 | SD SCK | FIXED | SPI0 PCB |
| 7 | SD MOSI | FIXED | SPI0 PCB |
| 8 | BUTTER_PSRAM | FIXED | RP2350 onboard PSRAM XIP CS1 |
| 9 | Audio DATA / BEEPER / LATCH_595 | REASSIGN | Triple-alias (I2S / PWM / 595) |
| 10 | Audio BCK / PWM0 / CLK_595 | REASSIGN | Triple-alias |
| 11 | Audio LCK / PWM1 / DATA_595 | REASSIGN | Triple-alias |
| 12–19 | VGA / HDMI (8 pins) | FIXED | Display base = 12; also PSRAM SPI on 18–19 |
| 20 | PSRAM_MOSI / NES_CLK | FIXED | PSRAM priority; NESPAD conflict! |
| 21 | PSRAM_MISO / NES_LAT | FIXED | PSRAM priority; NESPAD conflict! |
| 22 | MIDI_TX / LOAD_WAV_PIO | REASSIGN | Mutually exclusive. UART1 TX funcsel 11 — works |
| 23 | — | FREE | |
| 24 | — | FREE | |
| 25 | LED | FIXED | |
| 26 | NES_DATA | REASSIGN | NESPAD joy1 |
| 27 | NES_DATA+1 (implicit) | REASSIGN | NESPAD joy2 (PIO reads DATA+1) |
| 28 | — | FREE | |
| 29 | CLK_AY_PIN2 | REASSIGN | AY clock out |
FIXED = 13 · REASSIGNABLE = 10 · FREE = 6
| GPIO | Function | Cat | Notes |
|---|---|---|---|
| 0 | KBD_CLOCK | REASSIGN | |
| 1 | KBD_DATA | REASSIGN | |
| 2 | — | FREE | QWST1 connector |
| 3 | — | FREE | |
| 4 | SD MISO | FIXED | SPI0 PCB |
| 5 | NES_CLK / LOAD_WAV_PIO | REASSIGN | Shared |
| 6 | SD SCK | FIXED | SPI0 PCB |
| 7 | SD MOSI | FIXED | SPI0 PCB |
| 8 | BUTTER_PSRAM | FIXED | RP2350 onboard PSRAM XIP CS1 |
| 9 | NES_LAT | REASSIGN | |
| 10 | — | FREE | |
| 11 | — | FREE | |
| 12–19 | VGA / HDMI (8 pins) | FIXED | Display base = 12 |
| 20 | NES_DATA | REASSIGN | UXT1-3 |
| 21 | NES_DATA2 | REASSIGN | UXT1-4 |
| 22 | SD CS | FIXED | SPI0 PCB |
| 23 | — | FREE | |
| 24 | — | FREE | |
| 25 | LED | FIXED | |
| 26 | BEEPER / LATCH_595 / MIDI_TX | REASSIGN | UART1 TX funcsel 11 — works |
| 27 | PWM0 / CLK_595 | REASSIGN | Audio PWM right |
| 28 | PWM1 / DATA_595 | REASSIGN | Audio PWM left |
| 29 | CLK_AY_PIN2 | REASSIGN | AY clock out |
FIXED = 14 · REASSIGNABLE = 8 · FREE = 9
| GPIO | Function | Cat | Notes |
|---|---|---|---|
| 0 | ZiFi UART0 TX | REASSIGN | freed from KBD; UART0 TX funcsel 2 |
| 1 | ZiFi UART0 RX | REASSIGN | freed from KBD; UART0 RX funcsel 2 |
| 2 | — | FREE | |
| 3 | — | FREE | |
| 4 | — | FREE | |
| 5 | SD SCK | FIXED | SPI1 PCB |
| 6–13 | VGA / HDMI (8 pins) | FIXED | Display base = 6; NES_CLK=8, NES_LAT=9 conflict! |
| 14 | KBD_CLOCK | REASSIGN | moved from GP0 for ZiFi |
| 15 | KBD_DATA | REASSIGN | moved from GP1 for ZiFi |
| 16 | — | FREE | |
| 17 | — | FREE | |
| 18 | SD MOSI | FIXED | SPI1 PCB |
| 19 | SD MISO | FIXED | SPI1 PCB |
| 20 | LOAD_WAV_PIO / NES_DATA | REASSIGN | No USE_NESPAD |
| 21 | MIDI_TX / NES_DATA2 | REASSIGN | BUG: GPIO 21 odd = UART RX, not TX! MIDI broken |
| 22 | SD CS | FIXED | SPI1 PCB |
| 23 | — | FREE | |
| 24 | — | FREE | |
| 25 | LED | FIXED | |
| 26 | Audio DATA / PWM0 / LATCH_595 | REASSIGN | |
| 27 | Audio BCK / PWM1 / CLK_595 | REASSIGN | |
| 28 | Audio LCK / BEEPER / DATA_595 | REASSIGN | |
| 29 | CLK_AY_PIN2 | REASSIGN | |
| 47 | BUTTER_PSRAM | FIXED | RP2350B onboard PSRAM |
FIXED = 16 · REASSIGNABLE = 8 · FREE = 5
| GPIO | Function | Cat | Notes |
|---|---|---|---|
| 0 | KBD_CLOCK | REASSIGN | |
| 1 | KBD_DATA | REASSIGN | |
| 2–5 | PSRAM SPI (CS / SCK / MOSI / MISO) | FIXED | Onboard PSRAM |
| 6 | — | FREE | |
| 7 | CLK_AY_PIN2 / NES_CLK | REASSIGN | AY + NESPAD share (conflict) |
| 8 | NES_LAT | REASSIGN | |
| 9 | NES_DATA (DATA2 = 9) | REASSIGN | Single joystick |
| 10 | Audio DATA / PWM0 / LATCH_595 | REASSIGN | |
| 11 | Audio BCK / PWM1 / CLK_595 | REASSIGN | |
| 12 | Audio LCK / BEEPER / DATA_595 | REASSIGN | |
| 13 | — | FREE | |
| 14 | — | FREE | |
| 15 | — | FREE | |
| 16 | — | FREE | |
| 17 | LOAD_WAV_PIO | REASSIGN | No MIDI (RP2040) |
| 18–21 | SD SPI (SCK / MOSI / MISO / CS) | FIXED | SPI0 PCB |
| 22–28 | VGA / HDMI (8 pins from 22) | FIXED | Includes LED=25, SMPS=23, VBUS=24 |
FIXED = 14 · REASSIGNABLE = 12 · FREE = 22
| GPIO | Function | Cat | Notes |
|---|---|---|---|
| 0–1 | — | FREE | PSRAM disabled |
| 2 | PCM5122_I2C_SDA | REASSIGN | DAC control (if attached) |
| 3 | PCM5122_I2C_SCL | REASSIGN | |
| 4–6 | — | FREE | NESPAD disabled |
| 7 | CLK_AY_PIN2 | REASSIGN | AY clock out |
| 8–9 | — | FREE | |
| 10 | Audio DATA / PWM0 / LATCH_595 | REASSIGN | |
| 11 | Audio BCK / PWM1 / CLK_595 | REASSIGN | |
| 12 | Audio LCK / BEEPER / DATA_595 | REASSIGN | |
| 13 | — | FREE | |
| 14 | KBD_CLOCK | REASSIGN | Moved from 2/3 for PCM5122 I2C |
| 15 | KBD_DATA | REASSIGN | |
| 16 | — | FREE | |
| 17 | LOAD_WAV_PIO | REASSIGN | WAV loader |
| 18 | PCM5122_I2S_BCK | REASSIGN | DAC bit clock |
| 19 | PCM5122_I2S_LCK | REASSIGN | DAC LR clock |
| 20 | — | FREE | Good MIDI candidate (UART1 TX) |
| 21 | PCM5122_I2S_DATA | REASSIGN | DAC data |
| 22 | MIDI_TX | REASSIGN | UART1 TX funcsel 11 — works |
| 23–29 | — | FREE | |
| 30 | SD SCK | FIXED | SPI1 Waveshare board |
| 31 | SD MOSI | FIXED | |
| 32–39 | VGA / HDMI (8 pins) | FIXED | Display base = 32 |
| 40 | SD MISO | FIXED | |
| 41–42 | — | FREE | |
| 43 | SD CS | FIXED | |
| 44–46 | — | FREE | |
| 47 | BUTTER_PSRAM | FIXED | RP2350B onboard PSRAM |
FIXED = 18 · REASSIGNABLE = 10 · FREE = 0
| GPIO | Function | Cat | Notes |
|---|---|---|---|
| 0 | KBD_CLOCK / DBG_UART0_TX | REASSIGN | DBG_UART=ON → UART0_TX (J6 header), KBD moves to GP16/17 |
| 1 | KBD_DATA / DBG_UART0_RX | REASSIGN | DBG_UART=ON → UART0_RX |
| 2–5 | SD SPI (SCK / MOSI / MISO / CS) | FIXED | SPI0 PCB |
| 6–13 | VGA / HDMI (8 pins) | FIXED | Display base = 6 |
| 14 | NES_CLK | REASSIGN | DBG_UART=ON → NESPAD disabled |
| 15 | NES_LAT | REASSIGN | DBG_UART=ON → NESPAD disabled |
| 16 | NES_DATA / KBD_CLOCK (DBG_UART=ON) | REASSIGN | when DBG_UART=ON: KBD moves here |
| 17 | NES_DATA+1 / KBD_DATA (DBG_UART=ON) | REASSIGN | when DBG_UART=ON: KBD moves here |
| 18–21 | PSRAM SPI (CS / SCK / MOSI / MISO) | FIXED | Onboard PSRAM; BUTTER = 19 |
| 22 | MIDI_TX / LOAD_WAV_PIO | REASSIGN | RP2040: WAV only. RP2350 (MURM_P2): UART1 TX works |
| 23 | — | FIXED (RP2040) | SMPS power on standard Pico |
| 24 | — | FIXED (RP2040) | VBUS sense on standard Pico |
| 25 | LED | FIXED | |
| 26 | Audio DATA / PWM0 / LATCH_595 | REASSIGN | |
| 27 | Audio BCK / PWM1 / CLK_595 | REASSIGN | |
| 28 | Audio LCK / BEEPER / DATA_595 | REASSIGN | |
| 29 | CLK_AY_PIN2 | REASSIGN | RP2040: GPIO29 = ADC3 / VSYS |
- PICO_DV MIDI_TX = GPIO 21 — odd GPIO, so the hardware UART1 gives RX, not TX. MIDI is broken on this board. Fix: move it to GPIO 20.
- MURM2 NESPAD vs PSRAM — NES_CLK=20, NES_LAT=21 overlap PSRAM_MOSI=20, PSRAM_MISO=21. They cannot coexist.
-
PICO_DV NESPAD vs display — NES_CLK=8, NES_LAT=9 fall inside the display range
(6–13).
USE_NESPADis correctly not set on this board. -
MURM2 / MURM MIDI_TX = LOAD_WAV_PIO = 22 — two features share one pin (mutually
exclusive). Handled in code (a warning in
messages.h).
MIDI out uses a single UART-TX pin. On RP2350 UART TX is available via two funcsels,
and only even GPIOs can be TX — an odd GPIO gives RX. The code auto-selects the UART
instance and funcsel; the authoritative pinmux comes from
rp2350[ab]_interface_pins.json (the old (pin/4)%2 heuristic was wrong for GPIO
8/10/24/26). RP2040 boards (ZERO, MURM) have no MIDI (PICO_RP2040=1).
Working MIDI pins: MURM2 GPIO 22, PICO_PC GPIO 26, ZERO2 GPIO 22. PICO_DV is broken (GPIO 21 — see bug 1 above).
The NESPAD interface uses a 3-wire shift-register read (CLK / LATCH / DATA, with joy2 on DATA+1). It is OK on PICO_PC, ZERO and MURM, disabled on ZERO2, and conflicts on MURM2 (with PSRAM) and PICO_DV (with the display) — see the bug list above.
The ESP-01S networking UART has no compile-time pin define — it is chosen at runtime
(Config::zifi_tx_pin / zifi_rx_pin, resolved by BoardPins::resolveZifiPins()).
When a chosen pair shares pins with another peripheral, ZiFi has priority at boot and
the displaced peripheral skips its own init. Per-board default TX/RX pairs:
| Board | TX / RX (default) | UART | Note |
|---|---|---|---|
| PICO_DV | 0 / 1 | UART0 | dedicated ZiFi header |
| MURM2 | 20 / 21 | UART1 | takes NESPAD pins |
| PICO_PC | 20 / 21 | UART1 | takes NESPAD pins; alt 2/3 (QWST1), 10/11 |
| ZERO2 | 24 / 25 | UART1 | free |
| MURM-1 (RP2350) | 16 / 17 | UART0 | takes NESPAD pins |
Full wiring and the pin picker are on the Network page.
- Storage — SD card (SPI) usage per board
- Network — ESP-01S wiring and the ZiFi UART pin picker
- Murmulator project (hardware, Gerbers, how to build/buy/flash): murmulator.ru · Telegram @ZX_MURMULATOR · file archive
- Developer reference (full GPIO map, kept up to date): CLAUDE.md
Меню (RU)
Сквозные темы
Для разработчиков