goodoberon / pico-zxspectrum

ZX Spectrum for Raspberry Pico Pi RP2040

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pico-zxspectrum

48k/128k ZX Spectrum for Raspberry Pico Pi RP2040

Features

  • DVI over HDMI (Wren's Amazing PicoDVI)
  • LCD support (ST7789 320x240)
  • VGA video (RGB332, RGB222, RGBY1111)
  • USB keyboard & Joysticks
  • PS/2 keyboard
  • Martix keyboard
  • PWM/I2S DAC audio for 48k buzzer and AY-3-8912
  • Audio input (load from tape)
  • 12 quick save slots
  • Load from .z80 snapshot files
  • Read from .tap & .tzx tape files
  • On screen menu system
  • Kempston and Sinclair joystick emulation

Supported Boards

Interesting projects

Hermit Retro Products

Updates

20/01/24 - Maintenance release of pre-built firmware:

  • All .uf2 files rebuilt (see the uf2 folder)
  • Minor bug fixes
  • Updated libraries (Z80 etc)
  • Misc joystick fixes

I've moved to a new build machine, so let me know if there are any issues. At some point, I will try and organise the spralling README file.

01/01/24 - Added support for bobricius Pico ZX48/128

25/06/23 - Ability to persist volume control and joystick type (Sinclair/Kempston). The settings are persisted to .config file on the SD card and are loaded as the defaults on reset. To save setting goto ''settings->save'' on the menu. I was hoping to save to flash memory but not got that to work as of yet.

04/06/23 - Add MURMULATOR platform, with thanks to Javavi

03/06/23 - Don't freeze on startup if no SD card is present. Release v0.33

29/04/23 - Added new target for Bobricious PICOZX LCD + general release v0.32

  • PICOZX with LCD can now use either the LCD or VGA output
  • Volume control (for target where it makes sense)
  • Some changes to key mappings and menu navigation

To boot into VGA mode hold down the 'fire' button during reset.

The key mapping changes were intended to make navigating the menus with a joystick a bit easier. In particular, now left (usually) goes 'back' and right enters/activates an item. Paging in the file-explorer is now achieved with the Page-Up and Page-Down keys. Not sure it will stay like this; mapping keys and directions in a way that works for the emulator and the menus can be tricky.

19/01/23 - Added new target for ArnoldUK. This target can read from a standard 48k Spectrum keyboard matrix.

25/12/22 - Very basic support for sub-folders in the 'snapshots' and 'tapes' storage areas has been added. Files can be renamed, copied and deleted from the menu system. The quick-saves folder is now under the snapshots folder and behaves just like any other folder. The file 'explorer' has the following commands:

  • <space>/<enter> - enter a folder/load a file
  • ESC - Go up a folder
  • 1=DEL - Delete the file
  • 2=REN - Rename the file
  • 3=CPY - Copy the file
  • 4=PST - Paste the file
  • 5=REF - Reload the list of files in the current folder

The function keys for playing tapes have been removed. The idea is that in the future more useful controls will be added like 'play', 'stop' and 'eject'.

5/12/22 - The emulator can now cope with more files in the snapshots and tapes folders without running out of memory. I've tested up to 400 but it may survive more that this. Directory entries are now written to a file .dcache which can be updated from the menus by 'rescanning' the folder. If you are adding files to the folders on a PC you can just delete the .dcache and it will get regenerated on next power-on.

I've moved to the Redcode Z80 emulator as:

  • It comes with a test suite
  • It is much faster than the previous emulator

TZX support added with some omissions:

  • No CSW support (raise an issue if this is important to you)
  • There are some compatiblity issues

Builds with an RP_AUDIO_IN pin can now load from tape. Preparing the audio signal will require a little extra circuitry and some examples will be added to this page.

The move from Carl's no-OS-FatFS-SD-SPI-RPi-Pico to Pimoroni's FatFS was made as the SD card pins on the Pimoroni Pico DV Demo Base do not match up with the RP2040 SPI harware support. The Pimoroni library has a PIO SPI driver, which gets around the problem.

Screen shots

Audio samples

Firmware targets

Pre-built binary targets can be copied directly to a Pico Pi. They can be downloaded from the links in the table below or found in the uf2 folder.

Before attempting to update the firmware on your Pico make sure power supplies and any USB host devices have been disconnected (hub, keyboard, joysticks, etc.).

Push and hold the BOOTSEL button and plug your Pico into the USB port of your computer. Release the BOOTSEL button after your Pico is connected. It will mount as a Mass Storage Device called RPI-RP2. Drag and drop the UF2 file onto the RPI-RP2 volume.

On hardware with a faceplate the button is usually accessible through a small hole; the PICOZX Lcd board has the Pico facing inwards and you will need to reach a finger inside to press the bootsel button.

Board Binary
HDMI breadboard ZxSpectrumBreadboardHdmi1PinAudio.uf2
HDMI breadboard ZxSpectrumBreadboardHdmi2PinAudio.uf2
HDMI breadboard ZxSpectrumBreadboardHdmi4PinAudio.uf2
VGA breadboard ZxSpectrum4PinAudioVga1111Ps2.uf2
Pico ZX48/128 ZxSpectrumPicomputerVgaAukBob.uf2
PICOZX LCD ZxSpectrumPicomputerZxLcd.uf2
PICOZX LCD with inverse/negative LCD ZxSpectrumPicomputerZxInverseLcd.uf2
PICOZX ZxSpectrumPicomputerVga222Zx.uf2
RetroVGA ZxSpectrumPicocomputerVga.uf2
PicomputerMax ZxSpectrumPicocomputerMax.uf2
PicomputerZX ZxSpectrumPicocomputerZX.uf2
Pimoroni Pico DV ZxSpectrumPicoDv.uf2
Pimoroni Pico VGA ZxSpectrumPicoVga.uf2
HDMI + key matrix ZxSpectrumBreadboardHdmiKbd1PinAudio.ufs
ArnoldUK ZxSpectrumPicomputerVgaAuk.uf2
HDMI MURMULATOR ZX-MURMULATOR_HDMI.uf2
VGA MURMULATOR ZX-MURMULATOR_VGA.uf2

e.g. for the HDMI breadboard wiring show above use:

cp ZxSpectrumBreadboardHdmi4PinAudio.uf2 /media/pi/RPI-RP2/

These targets are discussed in more detail in the following sections.

MURMULATOR platform

ZxSpectrumBreadboardHdmiNPinAudio

This is a series of targets based around my original breadboard prototype:

The targets are:

  • ZxSpectrumBreadboardHdmi4PinAudio
  • ZxSpectrumBreadboardHdmi2PinAudio
  • ZxSpectrumBreadboardHdmi1PinAudio

They support the following:

  • USB keyboard
  • PS/2 keyboard
  • USB joysticks
  • HDMI video
  • PWM sound
  • Audio input (load from tape)
  • SPI SD card
  • Serial port debug

All of these targets share the same pinout but make different use of the 4 audio pins:

image

ZxSpectrum4PinAudioVga1111Ps2

This is a target similar to the HDMI prototype which uses VGA video output.

It supports the following:

  • USB keyboard
  • PS/2 keyboard
  • USB joysticks
  • VGA video (RGBY1111)
  • PWM sound (4 pin)
  • SPI SD card
  • Serial port debug

This target uses 4 audio pins:

image

ZxSpectrumPicomputerVga222Zx

This is a target written for Bobricius' PICOZX

It supports:

  • USB keyboard
  • Keyboard martix
  • USB joysticks
  • VGA video (RGB222)
  • PWM sound (1 pin)
  • SPI SD card

While on the menu...

  • SHIFT-Fire = ESC
  • RELOAD = Backspace
  • SHIFT-RELOAD = Del

Here are the pin assignments:

image

ZxSpectrumPicomputerZxLcd

This is a target written for Bobricius' PICOZX with built in LCD

It supports:

  • USB keyboard
  • Keyboard martix
  • USB joysticks
  • VGA video (RGB222)
  • LCD video (ST7789)
  • PWM sound (1 pin)
  • SPI SD card

By default, the board starts up using the LCD as its display. To boot into VGA mode hold down the 'fire' button during reset. Placing vga.txt on the SD card in the zxspectrum folder changes the default to VGA.

While on the menu...

  • SHIFT-Fire = ESC
  • RELOAD = Backspace
  • SHIFT-RELOAD = Del

Here are the pin assignments:

image

ZxSpectrumPicomputerVga

This is the target for Bobricius' Retro VGA board:

It supports the following:

  • USB keyboard
  • USB joysticks
  • Matrix keyboard (6x6)
  • VGA video (RGB332)
  • PWM sound (1 pin)
  • SPI SD card

Here are the pin assignments:

image

ZxSpectrumPicomputerMax & ZxSpectrumPicomputerZX

These are the targets for Bobricius' Retro PICOmputerMAX and PICOmputerZX. The targets are very similar except the LCD on the PICOmputerZX has rounded corners and needs a different menu layout.

It supports the following:

  • USB keyboard
  • USB joysticks
  • Matrix keyboard (6x6)
  • LCD video (ST7789)
  • PWM sound (1 pin)
  • SPI SD card

Here are the pin assignments:

image

ZxSpectrumPicoDv

This target matches the Pimoroni Pico DV board:

It supports the following:

  • USB keyboard
  • USB joysticks
  • HDMI video
  • I2S sound
  • SPI SD card

Please note that an SD card must be present for this version to start up.

Here are the pin assignments:

image

ZxSpectrumBreadboardHdmiKbd1PinAudio

This is a target similar to the HDMI prototype which can read from an original Spectrum keyboard matrix.

It is a work in progress.

It supports the following:

  • USB keyboard
  • Matrix keyboard (8x8)
  • USB joysticks
  • HDMI video
  • PWM sound (1 pin)
  • SPI SD card

Here are the pin assignments:

image

I don't know how the original keyboard pins were numbered but mine go from left to right with the keyboard oriented as you would type on it.

ZxSpectrumPicomputerVgaAuk

All keys are fully functional and the Emulator Menus can only be accessed via an external button connected to one of the GPIO pins. The Menu can be navigated using the Spectrum's keyboard number keys. There are an extra 8 external buttons that can been used for setting the Spectrum ROM boot mode and a Joystick Keyboard.

Please see the Schematic diagram for more information on GPIO pins used.

Audio pins

There are two techniques for audio output. The first is a mixture of digital sound and PWM output, which comes in three variants. The second is is using a DAC connected to the Pico using I2S.

PWM/Digital Audio

PWM audio output comes in 3 variants 1, 2 and 4 pin:

Label 1 Pin 2 Pin 4 Pin
RP AUDIO1 Buzzer & AY-3-8912 PWM AY-3-8912 PWM AY-3-8912 Channel A PWM
RP AUDIO2 - Buzzer Buzzer
RP AUDIO3 - - AY-3-8912 Channel B PWM
RP AUDIO4 - - AY-3-8912 Channel C PWM

High frequencies need to be filtered out of the PWM audio output and mixed with the Spectrum's digital audio. Here are some sample designs. Please note they are not carefully designed but made from components I found lying around. If you create a particularly nice sounding design please let me know and I will add it to the documentation.

Separating out the Spectrum buzzer from the AY-3-8912 improves the fidelity of the Spectrum beeps.

image

The best audio is achieved by having separate pins for the Spectrum buzzer and AY-3-8912 A,B & C channels.

image

The sound is actually quite good from the 4 pin filter and at some point I will do a stero version.

Designs that only have a single GPIO pin available can have the audio mixed digitally:

image

I2S DAC Audio

The emulation can drive a PCM5100A DAC for line out audio over I2S. It uses the RP_DAC_DATA, RP_DAC_BCLK and RP_DAC_LRCLK pin on the Pico. Currently, only tested on the Pimoroni Pico DV board.

Video output

DVI/HDMI

The following circuit shows roughly how to connect an HDMI socket; I have always used a breakout board...

...but this is what I think it boils down to:

image

So far, there are three supported VGA configurations, which can be found in the various build targets. They have all been designed with a combination of plagiarism and guesswork, so please let me know if you have better versions and I will update this document.

VGA RGBY 1111

Although this is the most complicated, it is my favourite as it only uses 5 pins on the Pico. The display is slightly paler than the other two versions, which is easier on the eyes.

image

See this CMakeLists.txt for an example configuration.

VGA RGB 222

image

See this CMakeLists.txt for an example configuration.

VGA RGB 332

image

See this CMakeLists.txt for an example configuration.

PS/2 Keyboards

The emulator targets can accept input from a PS/2 keyboard wired to RP_PS2_DATA and RP_PS2_CLK. A suggested circuit is shown below:

image

The resistors and Zeners are there in case the keyboard contains a pull-up resistor to 5v on either the data or clock lines; the data and clock lines are, in theory, open-collector with no pull-up.

I'm told most PS/2 keyboards can be run at 3.3v and the the extra components become redundant... but I've not tried with mine. You may find the Pico struggles to deliver enough power at 3.3v for the SD card writes and running a keyboard.

Currently there is no toggling on the lock keys (caps/num lock) and the indicator leds are not used.

Audio Input

Due to a great deal of help from badrianiulian, here is a suggested audio input circuit:

image

Suggestions to improve this circuit are appreciated and please post them here.

Components

RetroVGA and Picomputer keyboard mappings

Trying to squeeze in all the key mappings is tricky but here is an attempt.

These are the nomal key mappings:

These are the mappings with the ALt key down.:

Shifted and numeric mappings are turned on and off using the arrow keys (up, down, left, right). QS1, QS2, ... save the emulator state to the appropriate Quick Save slot.

If there is a save in QS1 it will load after the emulator is powered-on or reset.

The SN keys load snapshots as if they are in a loop. SN loads the current snapshot, SN- load the previous snapshot and SN+ loads the next snapshot.

These are the mappings with the numeric shift on:

Alt+V sets the arrow keys to behave like a Kempston joystick, Alt+C sets the arrow keys to operate the Spectrum cursor keys.

RetroVGA kiosk mode

Kiosk mode disables the menu system and quick-save buttons. Kiosk mode is enabled by placing the following file on the SD-card:

zxspectrum/kiosk.txt

Pico pinout

image

Issues

The Z80 is interrupted at the end of each frame at 60hz. The original Spectrum wrote frames at 50hz, so some code runs more frequently than it used to; there is a 4Mhz CPU setting that kind of balances this up.

There is now preliminary support for Kempston & Sinclair joysticks.

A USB hub can be connected to the RP2040 allowing a keyboard and joysticks to be used with the Spectrum. The code is a bit new and I don't know how many different joysticks will be supported; if you are having trouble raise an issue and attach a HID report descriptor from your device and I will have a look at it.

To get this to work I have done some hacking and slashing in TinyUSB (sorry Ha Thach):

https://github.com/fruit-bat/tinyusb/tree/hid_micro_parser

Build

The version of TinyUSB in the Pico SDK will need to be replaced with a version containing a HID report parser and USB hub support.

Using git protocol:

cd $PICO_SDK_PATH/lib/
mv tinyusb tinyusb.orig
git clone git@github.com:fruit-bat/tinyusb.git
cd tinyusb
git checkout hid_micro_parser

...or using https protocol:

cd $PICO_SDK_PATH/lib/
mv tinyusb tinyusb.orig
git clone https://github.com/fruit-bat/tinyusb.git
cd tinyusb
git checkout hid_micro_parser

Make a folder in which to clone the required projects e.g.

mkdir ~/pico
cd ~/pico

Clone the projects from github:

Using git protocol:

git clone git@github.com:raspberrypi/pico-extras.git
git clone git@github.com:Wren6991/PicoDVI.git
git clone git@github.com:fruit-bat/pico-vga-332.git
git clone git@github.com:fruit-bat/pico-zxspectrum.git
git clone git@github.com:pimoroni/pimoroni-pico.git
git clone git@github.com:fruit-bat/pico-dvi-menu
git clone git@github.com:fruit-bat/pico-emu-utils
git clone git@github.com:redcode/Z80.git
git clone git@github.com:redcode/Zeta.git

...or using https protocol:

git clone https://github.com/raspberrypi/pico-extras.git
git clone https://github.com/Wren6991/PicoDVI.git
git clone https://github.com/fruit-bat/pico-vga-332.git
git clone https://github.com/fruit-bat/pico-zxspectrum.git
git clone https://github.com/pimoroni/pimoroni-pico.git
git clone https://github.com/fruit-bat/pico-dvi-menu
git clone https://github.com/fruit-bat/pico-emu-utils
git clone https://github.com/redcode/Z80.git
git clone https://github.com/redcode/Zeta.git

Edit:

pimoroni-pico/drivers/fatfs/ffconf.h

and set FF_USE_FIND to 1

#define FF_USE_FIND            1

Perform the build:

cd pico-zxspectrum
mkdir build
cd build
cmake -DPICO_COPY_TO_RAM=0 ..
make clean
make -j4

Building for the Pimoroni Pico VGA Demo Base needs a different cmake command:

cd build
cmake -DPICO_COPY_TO_RAM=0 -DPICO_BOARD=vgaboard ..
make -j4 ZxSpectrumPicoVga

Copy the relevant version to your board, which can be located with:

find . -name '*.uf2'

e.g.

cp ./bin/breadboard_hdmi/ZxSpectrumBreadboardHdmi.uf2 /media/pi/RPI-RP2/

Prepare an SD card

The following table shows the folders used by the emulator on the SD card. If not already present, they will be created as the emulator starts up.

Folder Contents
zxspectrum/snapshots Put your .z80 snapshot files in here.
zxspectrum/snapshots/quicksaves Folder for quick saves.
zxspectrum/tapes Folder for .tap and .tzx tape files.

Special keys

Key Action
AltGr Symbol
F1 Toggle on screen menu
F3 Toggle mute
F4 Toggle the Z80 moderator. Cycles through 3.5Mhz, 4.0Mhz and unmoderated
F8 Reload current snap
F9 previous snap
F10 next snap
F11 Reset as 48k Spectrum
F12 Reset as 128k Spectrum
LCtrl + F1-F12 Quick save (LCtrl+F1 = save slot 1, LCtrl+F2 = save slot 2, etc)
LAlt + F1-F12 Quick load (LAlt+F1 = load slot 1, LAlt+F2 = load slot 2, etc)

Debug

Pico pin Pico GPIO Adapter wire
1 GP0 White
2 GP1 Green
3 GND Black
tio -m ODELBS /dev/ttyUSB0

Thanks to

CarlK for the super no OS FAT FS for Pico
Damien G for maintaining and publishing some wonderful 8-bit fonts
Wren for the amazing PicoDVI
hathach for the embeded USB library TinyUSB
Lin Ke-Fong for the Z80 emulator
Pimoroni for lots of useful libraries
badrianiulian for help testing and design work on the audio circuitry
redcode for the Z80 emulator
Javavi for adding support for the MURMULATOR platform

References

Z80 Test suite
Wren's Amazing PicoDVI
Z80 file format documentation
Fonts by DamienG
breakintoprogram - Screen memory layout
breakintoprogram - keyboard layout
breakintoprogram - interrupts
worldofspectrum - 48k ZX Spectrum reference
worldofspectrum - 128k ZX Spectrum reference
worldofspectrum - AY-3-8912 reference
JGH Spectrum ROM
48k ZX Spectrum service manual
GOSH ZX Spectrum ROM
Cassette input circuit design
ZX Spectrum ROM Images
AY-3-8912 - manual
AY-3-8912 - synth
USB HID 1.1
ST7789 LCD driver reference
RGB for 128k ZX Spectrum
PS/2 vs HID keyboard codes
PCM 5100A DAC
RP2040 Datasheet
Z80 Instruction set with XYH
Z80 Instruction set
Site with some WAV files
ZX Modules Software
TZX format
A decoder for ZX format
Circuit diagram editor

About

ZX Spectrum for Raspberry Pico Pi RP2040


Languages

Language:C++ 45.0%Language:C 44.3%Language:Assembly 5.5%Language:CMake 5.2%