IMPORTANT: I stopped working on this project some time ago.
But its legacy continues in the ZX-ESPectrum-IDF project by @EremusOne (to which I also contributed), who is actively maintaining it and adding interesting features.
Please check it out as it incorporates a lot of features and enhancements.
This is an emulator for the Sinclair ZX Spectrum computer running on an Lilygo TTGo VGA32 board.
Just connect an VGA monitor, a PS/2 keyboard, and power via microUSB.
Please watch the project video on YouTube (spanish audio, english subtitles).
Quick start from PlatformIO:
- Clone this repo and Open from VSCode/PlatFormIO
- Copy your SNA files to /data/sna
- Execute task: Upload File System Image
- Execute task: Upload
- Enjoy
This is a fork of the ZX-ESPectrum project, based on it, but with some enhancements.
As of december 2022, I have learned that some boards sold recently (with text "21-2-20" on the board serigraphy) don't handle the 320x240 (4:3) mode correctly. I have set the 16:9 mode as the default. If you have one of these boards and try the 4:3 mode, you will get no picture. There is a flag FIX_320_240_TTGO_21 in hardconfig.h which you can uncomment, which activates some hardcoded values on Bitluni's VGA library and seem to do the trick. Note: this issue is solved in ZX-ESPectrum-IDF.
This branch is for running on a Lilygo TTGo vga32 board. It used to be for a custom devkit contraption I made, you can still find that code in the devkit-custom branch.
Latest updates: Precise timing of 48K machine, supporting multicolor modes. Preliminary realtime .tap file loading support. Use new option in menu to select .tap file and F6,F7 to start/stop tape. (Thanks to EremusOne :-)**
- Spectrum 16/48 architecture emulation without PSRAM.
- Spectrum 128/+2/+3 architecture emulation with PSRAM.
- VGA output, 3 bit, 6 bit (default), 14 bit (untested).
- Accurate Z80 emulation, with enhanced timing and fast video generation.
- Dual Z80 emulators, selectable in compile time using #defines: the precise one (JLS), and the fast one (LKF)
- Contended memory algorithm for very precise timing on 48K, a little less precise on 128K.
- 48K sound: beeper digital output, good PWM sound using JLS CPU core.
- 128K sound: AY-3-8912 sound chip emulation (incomplete but working).
- PS/2 Keyboard used as input for Spectrum keys.
- Wiimote support with per-game key assignments.
- VGA OSD menu: Configuration, architecture, ROM and SNA/Z80 selection.
- Support for two aspect ratios: 16:9 or 4:3 monitors (using 360x200 or 320x240 modes)
- Tape saving and loading (untested).
- SNA snapshot loading.
- Z80 snapshot loading.
- Quick (to memory) and persistent snapshot saving and loading (both 48K and 128K supported).
- Internal SPIFFS support / external SD card support (only one of both, see hardconfig.h).
- Better AY-3-8912 emulation (128K sound is still a little dirty).
Windows, GNU/Linux and MacOS/X. This version has been developed using PlatformIO.
- There is an extension for Atom and VSCode, please check this website.
- Select your board, pico32 which behaves just like the TTGo VGA32.
PlatformIO now autodetects port, so there is no need to specify it (unless autodetection fails).
Change upload_port to whatever you're using.
- Linux:
uploadport = /dev/ttyUSB0
or similar.- Windows:
upload_port = COM1
or similar.- MacOSX: upload_port = /dev/cu.SLAB_USBtoUART
or similar.
Default aspect ratio is 16:9, so if your monitor has this, you don't need to change anything.
If your monitor is 4:3, you should edit hardconfig.h, comment the #define AR_16_9 1
line, and uncomment the #define AR_4_3 1
line.
If using internal flash storage (USE_INT_FLASH #defined in hardconfig.h), you must copy some files to internal storage using this procedure.
PlatformIO > Project Tasks > Upload File System Image
All files under the /data
subdirectory will be copied to the SPIFFS filesystem partition. Run this task whenever you add any file to the data subdirectory (e.g, adding games in .SNA or .Z80 format, into the /data/sna
subdirectory).
NEW: now including my own Spectrum 48K games: Snake and Tetris. NOTE: the games have NO sound.
If using external micro sd card (USE_SD_CARD #defined in hardconfig.h), you must copy files from the /data
subdirectory to the root of the sd card (copy the contents of the folder, NOT the folder itself, so boot.cfg is on the root folder).
The SD card should be formatted in FAT16 / FAT32.
For adding games to the emulator, just turn it off, extract the sd card, copy games in .SNA or .Z80 format to the /sna
folder of the sd card, insert it again, and turn it on.
Important note: once you flash the firmware successfully with USE_SD_CARD defined, you won't be able to flash the firmware again, unless you remove the SD card. This is due to GPIO pin 2/12 used for SD card MISO/MOSI interfering with the boot/flashing process.
What I do: before flashing (PlatformIO > Project Tasks > Upload
), I remove the SD card until flashing starts, then I insert it again. For convenience I use a micro sd card extension strap which features a push to insert / push to remove mechanism, which comes in handy.
PlatformIO > Project Tasks > Build
, then
PlatformIO > Project Tasks > Upload
.
Run these tasks (Upload
also does a Build
) whenever you make any change in the code.
Pin assignment in hardpins.h
is set to match the TTGo VGA32, use it as-is, or change it to your own preference. It is already set for the TTGo version 1.4.
I have used VGA 6 bit driver (so BRIGHT attribute is kept)
To connect, press 1 and 2 buttons in the Wiimote.
All 4 leds will flash during connection phase, and only LED 1 will be ON when connected.
Important note: wiimote suport is NOT enabled by default on the TTGO. I have experienced slowness at least once when developing, but seems to have gone forever. It may happen when the option is enabled, but a Wiimote has never been paired. I'm not completely sure, your mileage may vary.
You can enable wiimote support uncommenting #define WIIMOTE_PRESENT
in hardconfig.h
OSD menu can be opened using the Wiimote's Home key. Navigation is done using the D-Pad, and selection using buttons A, 1 or 2.
From OSD you can load snapshots (from /data/sna
) or change ROMs.
For every .sna / .z80
game in /data/sna
, there should be a corresponding .txt
file in the same dir, with a very simple format. Examples are provided.
The ESPWiimote
library generates the following codes for Wiimote keys:
The .txt
file must have at least 16 characters (only first 16 characters are considered). For example for Manic Miner, ManicMiner.txt
would contain
sZ-h------WQe---
There is a character for each possible 16 bit code of wiimote keys, in order: 0001
, 0002
, 0004
, 0008
, 0010
, 0020
, 0040
, 0080
, 0100
, 0200
, 0400
, 0800
, 1000
, 2000
, 4000
, 8000
; and legal characters are:
1234567890
QWERTYUIOP
ASDFGHJKLe
hZXCVBNMys
With e
for ENTER, h
for CAPS SHIFT, y
for SYMBOL SHIFT and s
for SPACE. Any other character (ex: '``') means not used.
For the Manic Miner example, the correspondences would be:
(2) (0001) -> SPACE (jump)
(1) (0002) -> Z (jump)
(A) (0008) -> SHIFT (jump)
(down) (0400) -> W (right)
(up) (0800) -> Q (left)
(+) (1000) -> ENTER (start)
I have NOT included Manic Miner .sna / .z80
snapshot, but you can download it from worldofspectrum.org and convert it to .sna / .z80
using FUSE, for example.
I have written a detailed story, with photos, of the development process of this emulator and some of the devices I have tested it with.
- Developers of the original project, Rampa and Queru. They provided me with a very good starting point to begin with (a fully working emulator).
- Idea from the work of Charles Peter Debenham Todd: PaseVGA.
- VGA Driver from ESP32Lib by BitLuni.
- PS/2 keyboard support based on ps2kbdlib.
- PS/2 boot for some keyboards from PS2KeyAdvanced.
- Wiimote library from ESP32Wiimote by bigw00d.
- Z80 Emulation (precise) derived from z80cpp, authored by José Luis Sánchez.
- Z80 Emulation (formerly used, but not used anyore) derived from z80emu, authored by Lin Ke-Fong.
- AY sound hardware emulation from AVR-AY.
- Amstrad PLC for the ZX-Spectrum ROM binaries liberated for emulation purposes.
- Nine Tiles Networs Ltd for Sinclair BASIC.
- Gary Lancaster for the +3e ROM.
- Retroleum for the diagnostics ROM.
- Emil Vikström for his ArduinoSort library.
- StormBytes for his code and help for supporting the original ZX Spectrum keyboard.
- Fabrizio di Vittorio for his FabGL library which I use for sound only (but it's a great library).
- Ackerman for his code and ideas for the emulation of the AY-3-8912 sound chip, and for discussing details about this development.
- EremusOne for adding multiple snapshot slots, .TAP support, and other fixes.
- Jean Thomas for his ESP32 APLL calculator, useful for getting a rebel TTGO board to work at 320x240.
- Sir Clive Sinclair.
- Christopher Curry.
- The Sinclair Team.
- Lord Alan Michael Sugar.
- Investrónica team.
- Matthew Smith for Manic Miner.
- Sovietic cloners.
- DCrespo's uncle Pedro for giving him his first computer: a Sinclair ZX81.
- Queru's uncle Roberto for introducing him into the microcomputing world with a Commodore VIC-20.
- Queru's uncle Manolito for introducing him into the ZX-Spectrum world.
- Rampa's mother for the Oric 1 and for inculcate her passion for electronics.
- Microhobby magazine.
- Dr. Ian Logan & Dr. Frank O'Hara for The Complete Spectrum ROM Disassembly book.
- Chris Smith for the The ZX-Spectrum ULA book.
- Users from Abadiaretro and its Telegram group.
- Users from El Mundo del Spectrum and its Telegram group.
- The World of Spectrum.
- GreenWebSevilla for its Fantasy Zone game and others.
- Julián Urbano Muñoz for Speccy Pong.
- Others who have donated distribution rights for this project.