- Supports VGA, HDMI, DVI and LCD displays
- Supports sound over HDMI, onboard DAC or PWM when available in hardware
- Provides an immersive full screen experience, with a very fast boot time and no operating system
- Simultaneous USB keyboard and joystick support (using a powered USB hub)
- Can be fully controlled from a ZX81 style 40 key keyboard
- 1980s style 9-pin Atari joysticks can be connected to some board types
- The small form factor makes the board easy to mount in period or reproduction cases. The low cost, relatively low performance and software generated display of the Pico is a 21st century analogue for the ZX80 and ZX81
- Emulates pseudo and Hi-res graphics
- Emulates ZX81 and ZX80 (with either 4K or 8K ROM) hardware
- Emulates ZonX, Quicksilva and TV (sync) sound
- Emulates user defined graphics, including CHR$128 and QS User Defined Graphics
- Emulates the Chroma 80 and Chroma 81 interfaces to allow a colour display. Also supports the enhanced TV sound provided by Chroma
- Emulation runs at accurate speed of a 3.25MHz ZX81
- Optionally emulates real-time ZX81/80 program load and save with realistic sound and graphics
- Emulates European and US configuration (i.e. emulates 50Hz and 60Hz ZX81)
- Supports larger ZX81 generated displays of over 320 by 240 pixels (40 character width and 30 character height)
- Load
.p
,.81
,.o
,.80
and.p81
files from micro SD Card. Save.p
and.o
files - Can display at 640x480 or 720x576 (for an authentic display on a UK TV)
- 720x576 can be configured to run at a frame rate to match the "real" ZX81 (~50.65 Hz).
- An interlaced mode can be selected to display interlaced images with minimal flicker
- Supports loading and saving of memory blocks using ZXpand like syntax
- Set-up of emulator (computer type, RAM, Hi-Res graphics, sound, joystick control etc) configurable on a per program basis, using config files
- Optionally displays graphic of keyboard (taken from sz81). Can type in code with keyboard visible
- Can be extended for other board types. Code support included for a custom VGA RGB 332 board similar to that supported by MCUME and for a RGB 222 board with CSYNC similar to PICOZX
- Pimoroni Pico VGA demo board
- Pimoroni Pico DVI demo board (HDMI)
- PicoMiteVGA board
- Olimex RP2040-PICO-PC (HDMI)
- Waveshare RP2040-PiZero (HDMI)
- Waveshare Pico-ResTouch-LCD-2.8
- Cytron Maker Pi Pico with 320 by 240 LCD and RGB222 VGA displays
- PICOZX All in one board with VGA output, built in keyboard and 9-pin joystick port
- PICOZX with LCD All in one board with VGA and LCD output, built in keyboard and 9-pin joystick port
- PICOZX for ZX-Spectrum case All in one board with VGA output, designed to be put in a ZX-Spectrum case with keyboard and 9-pin joystick port
Both the RP2040 and RP2350A is supported
The following images are taken with permission from a thread on SinclairZXWorld and show how user computergui
has used picozx81 together with a case created by user Spinnetti
to create a replica ZX80
The left image shows a system with a 3d printed ZX81 case being used as a USB keyboard. A usb hub allows control via the keyboard and a joystick. The high resolution version of Galaxians is displayed on screen
The right image shows the emulator running MaxDemo, which generates a 320 by 240 display, exactly filling the 2.8 inch Waveshare LCD
To the left SplinterGU SInvaders can be seen on a TV connected over HDMI. Sound can also be played over HDMI
To the right can be seen a status page, illustrating some of the configurable options for the emulator
Cytron Maker Pi Pico with Waveshare 2.0" LCD (ST7789V controller) displaying the 25thanni full screen demo
Cytron Maker Pi Pico with Generic 3.2" LCD (ILI9341 controller) displaying the 25thanni full screen demo
PICOZX with VGA and LCD output running 3D Monster Maze
Pictures supplied by zzapmort
A ZX81 disguised as a Spectrum!
ColourAttrModeTest and HiRes ZX-Galaxians
The fastest way to get started is to:
- Write data onto a Micro SD Card
- Install the pre-built binary onto your Pico
- Connect your board to a keyboard and start exploring
- Click here to download a zip file containing files and directories to copy to an empty micro SD card
- unzip the file into the root directory of an empty micro SD Card
- Insert the micro SD Card into your boards micro SD card slot
Click on the uf2 name corresponding to your board in the table below to download the latest version
Board | uf2 name |
---|---|
Pimoroni DVI | picozx81_dvi_rp2040.uf2 |
Pimoroni VGA | picozx81_vga_rp2040.uf2 |
Olimex PICO DVI | picozx81_olimexpc_rp2040.uf2 |
PicoMiteVGA | picozx81_picomitevga_rp2040.uf2 |
Olimex PICO DVI with HDMI Sound | picozx81_olimexpc_hdmi_sound_rp2040.uf2 |
Pimoroni DVI with HDMI Sound | picozx81_dvi_hdmi_sound_rp2040.uf2 |
Waveshare PiZero with HDMI Sound | picozx81_wspizero_hdmi_sound_rp2040.uf2 |
Waveshare 2.8 LCD | picozx81_lcdws28_rp2040.uf2 |
Cytron Maker + 320x240 LCD | picozx81_lcdmaker_rp2040.uf2 |
Cytron Maker + VGA 222 CSYNC | picozx81_vgamaker222c_rp2040.uf2 |
PICOZX | picozx81_picozx_rp2040.uf2 |
PICOZX with LCD | picozx81_picozx_lcd_rp2040.uf2 |
PICOZX for ZX-Spectrum case | picozx81_picozxreal_rp2040.uf2 |
Board | uf2 name |
---|---|
Pimoroni DVI | picozx81_dvi_rp2350.uf2 |
Pimoroni VGA | picozx81_vga_rp2350.uf2 |
Olimex PICO DVI | picozx81_olimexpc_rp2350.uf2 |
PicoMiteVGA | picozx81_picomitevga_rp2350.uf2 |
Olimex PICO DVI with HDMI Sound | picozx81_olimexpc_hdmi_sound_rp2350.uf2 |
Pimoroni DVI with HDMI Sound | picozx81_dvi_hdmi_sound_rp2350.uf2 |
Waveshare 2.8 LCD | picozx81_lcdws28_rp2350.uf2 |
- Connect your Board to your display using a VGA or HDMI cable, as appropriate for your board
- Connect the Pico to your PC using a USB cable, whilst pressing the BOOTSEL button on the Pico. Use the micro USB connector on the Pico, not the micro USB cable on your board
- The Pico should appear on the PC as a USB drive
- Drag the uf2 file that you downloaded onto the USB drive
- The file will be loaded onto the Pico, which will then reboot. You should see the familiar
K
prompt appear on your display
- Remove the USB cable from the Pico. Plug a USB keyboard into the Pico. You will need an OTG adaptor cable to do this
- Plug a micro USB power supply into the USB connector on your board. You can also power your board directly from your PC using a micro USB cable
- You now have an emulated ZX81 with a working keyboard and display
Read on for more information. The Applications Tested section contains links to free downloads of some of the most iconic ZX80 and ZX81 software
- If the emulator is started with no SD Card, or with an empty SD Card, then it will emulate a 16K ZX81
- To switch to always starting emulating a ZX80, a populated SD Card is required. If it is present, the machine that is emulated is specified by the
config.ini
file in the root directory, see configuring the emulator - If the contents of the examples directory have been copied to the SD Card, then the included programs can be loaded. Press
F2
to see files in the current directory that can be loaded - To make picozx81 emulate a an original 4K ZX80, without changing
config.ini
, either a ZX80 program can be loaded, or the computer typeZX80-4K
can be selected from the Modify menu. Press F6 to bring up the Modify menu. To emulate a ZX80 upgraded with a 8K ROM , selectZX80-8K
from the modify menu - The current settings used by the emulator can be viewed by pressing
F3
- The following sections describe how to configure the emulator and provide links to programs that can be downloaded, copied to the SD Card and then run using the emulator
The capabilities of the emulator are set using configuration files stored on the SD Card
Configuration attributes (described in the following sections) are set via config.ini
files. When a program is loaded the emulation configuration is read, and set for the program before it is run.
The order for configuring an item for a given program (e.g. prog.p
) is as follows:
- Search for
config.ini
in the directory that containsprog.p
- If it exists, configure items specified in a
[prog.p]
section - If it exists, configure items not yet specified, that exist in a
[default]
section - Search for
config.ini
in the root directory - If it exists, configure items not yet specified, that exist in a
[default]
section - Configure any items not yet specified with the default values given above
Note: All entries in a config.ini
file are case insensitive
The following can be configured:
Item | Description | Default Value | Notes |
---|---|---|---|
Computer | Selects ZX81, ZX81x2, ZX80-4K or ZX80-8K | ZX81 | ZX80-4K selects ZX80 with the original 4kB ROM. ZX80-8K selects a ZX80 that has been upgraded with an 8K ROM. ZX81x2 selects a ZX81 with the "Big Bang" ROM for faster BASIC |
Memory | In kB. Starting at 0x4000 | 16 | 1, 2, 3, 4, 16, 32 and 48 allowed |
WRX | Selects if RAM supports Hi-res graphics | Off | Automatically set to on if Memory is 2kB or less |
LowRAM | Selects if RAM populated between 0x2000 and 0x3fff | Off | Typically used in conjunction with WRX to create a hires display file in low memory, can also be used for UDG graphics emulation if WRX off |
M1NOT | Allows machine code to be executed between 0x8000 and 0xbfff | Off | Memory must be set to 32 or 48 |
ExtendFile | Enables the loading and saving of memory blocks for the ZX81, using ZXpand+ syntax | On | See Loading and Saving Memory Blocks |
Centre | When enabled the usual 32 by 24 character display is centred on screen | On | When in 640 by 480 mode, set to Off for some programs that require the full 320 by 240 pixel display (e.g. QS Defenda or MaxDemo) |
FrameSync | Synchronises screen updates to the start of the display frame. Option to synchronise frame pairs for programs that display interlaced images | Off | On reduces "tearing" in programs with horizontal scrolling, at the expense of a possible small lag. Interlaced reduces flickering in programs that display interlaced images |
CHR128 | Enables emulation of a 128 character user defined graphics board (CHR$128) in Low memory. | Off | When enabled LowRAM is forced to On, WRX and QSUDG are forced to off |
QSUDG | Enables emulation of the QS user defined graphics board | Off | Memory automatically limited to 16 when selected |
Sound | Selects sound card type (if any) | None | Valid options are QUICKSILVA , ZONX , TV , CHROMA and NONE or OFF |
ACB | Enables ACB stereo if sound card enabled | Off | |
NTSC | Enables emulation of NTSC (60Hz display refresh) | Off | As for the "real" ZX81, SLOW mode is slower when NTSC is selected |
VTOL | Specifies the tolerance in lines of the emulated TV display detecting vertical sync | 25 | See notes below |
Notes:
- The "real" QS UDG board had a manual switch to enable / disable. In the emulator, if
QSUDG
is selected, it is assumed to be switched on after the first write to the memory mapped address range (0x8400 to 0x87ff) - To emulate other standard UDG graphics cards that reside between 0x2000 and 0x3fff set
LowRAM
toOn
andWRX
toOff
. This setting is needed to run e.g. Galaxians with user defined graphics. If emulation of CHR128 UDG graphics is required setCHR128
toOn
. This setting is needed to run e.g. zedgragon - If
NTSC
is set toOn
andCentre
is set toOff
then a black vsync bar will be seen at the bottom of the display for programs that generate a typical 192 line display - A higher tolerance value set for
VTOL
results in faster screen stabilisation. As for a real TV, a low tolerance level results in vertical sync being lost for some programs, such as QS Defenda and Nova2005. Set the value to 15 to emulate a TV that struggles to maintain vertical lock. Run the Flicker program to see the effects of PAUSE on lock - The "Big Bang" ROM can double the speed of BASIC programs
- The Waveshare LCD 2.8 board has no sound capabilities
- The
TV
sound option emulates the sound generated through the TV speaker by VSYNC pulses. TheCHROMA
sound option emulates the sound generated through the TV speaker by the Chroma interface when VSYNC pulses are not frame synchronised
In addition a USB joystick,and on some boards a 9-pin joystick, can be configured to generated key presses
Item | Description | Default Value |
---|---|---|
Left | Keypress when joystick moved left | 5 |
Right | Keypress when joystick moved right | 8 |
Up | Keypress when joystick moved up | 7 |
Down | Keypress when joystick moved down | 6 |
Button | Keypress when joystick button pressed | 0 |
Notes: ENTER and SPACE can be used to represent the New Line and Space keys, respectively
Eight extra options apply across all programs and can only be set in the [default]
section of the config.ini
file in the root directory of the SD Card
Item | Description | Default Value |
---|---|---|
FiveSevenSix | Enables the generation of a 720x576p display @ 50Hz On , or 720x576p display @ 50.65Hz Match . If set to Off a 640x480 display @ 60Hz is produced |
Off |
Dir | Sets the initial default directory to load and save programs | / |
Load | Specifies the name of a program to load automatically on boot in the directory given by Dir |
"" |
DoubleShift | Enables the generation of function key presses on a 40 key ZX80 or ZX81 keyboard. See here | On |
AllFiles | When set, all files are initially displayed when the Load Menu is selected. When off only files with extensions .p , .o , .81 , .80 and .p81 are initially displayed |
Off |
MenuBorder | Enables a border area (in characters) for the Load and Pause menus, useful when using a display with overscan. Range 0 to 2 | 1 |
LoadUsingROM | Runs the Sinclair ROM routines to load a file in real-time. Authentic loading visual and audio effects are emulated | OFF |
SaveUsingROM | Runs the Sinclair ROM routines to save a file in real-time. Authentic saving visual and audio effects are emulated | OFF |
NinePinJoystick | When set to on Enables reading a 9 pin joystick, if supported in hardware |
Off |
VGA | When set to on enables VGA output for the PICOZX + LCD board |
off |
Notes:
- By default the European ZX81 generates frames slightly faster than 50Hz (50.65 Hz). Setting
FiveSevenSix
toMatch
enables a display mode slightly faster than the 50Hz TV standard, so that better synchronisation between the frame generates by the emulator and frames sent to the monitor can be achieved. If there are issues with a TV or monitor locking to 50.65 Hz, thenFiveSevenSix
can be set toOn
to generate an exact 50 Hz frame rate - The LCD supported displays all have a fixed 320 by 240 resolution.
FiveSevenSix
therefore only sets the framerate for these displays (50 Hz, 50.65 Hz or 60 Hz) - Due to the low speed of the ZX8x cassette interface, files can take many minutes to load and save when
LoadUsingROM
andSaveUsingROM
is enabled
Examples of the config.ini
files used to test the programs listed in this section can be found here
The config.ini
file cannot be edited within the emulator. Modify the config.ini
file using another computer.
After replacing the SD Card into the emulator, the Pico must be restarted, either via a Power cycle, or by pressing the run / reset button on the board, before any edits will be visible to the emulator
The emulated machine is always reset if any of the following options are changed:
Computer
Memory
LowRAM
M1NOT
QSUDG
CHR128
LoadUsingROM
SaveUsingROM
Note: Changing the virtual sound card, or the FrameSync
or NTSC
settings, does not trigger a reset
Program and configuration files are stored on a micro SD-Card. Directories are supported. File and directory names should only contain characters that exist in the ZX81 character set. File and directory names can be a mixture of upper and lower case, but are used case insensitive. Therefore, all file and child directory names in a given directory must differ by more than just case
The emulator has several menus that can be selected through function key presses. To keep the look and feel of the ZX8x computers the menus are in black and white and, dependent on the computer type being emulated, use either the ZX81 or ZX80 font
The original ZX80/ZX81 40 key keyboard does not have function keys. A "double shift" mechanism can be used instead. The mechanism is as follows:
- Shift is pressed without another key
- Shift is released, without another key being pressed
- Within one second shift is pressed again
- Shift is released, without another key being pressed
- To generate a function key, within one second, a numeric key in the range
1
to8
is pressed without shift being pressed. If0
is pressedEscape
is generated
This mechanism is enabled by default. To disable it set DoubleShift
to Off
in the configuration file
Hard resets the emulator. It is equivalent to removing and reconnecting the power
A menu displaying directories and files that can be loaded is displayed, using the ZX81 font. Any sound that is playing is paused. Directory names are prepended by <
and appended by >
e.g. <NAME>
If the name of a file or directory is too long to display in full it is truncated with the last characters as +
(file) and +>
(directory)
- The display can be navigated using the
up
,down
andenter
keys. The7
key also generatesup
and the6
key also generatesdown
- For directories with a large number of files it is possible to move to the next page of files by using the
right
,Page Down
or8
key. To move to the previous page of files use theleft
,Page Up
or5
key - Press
A
to display all files in the directory. PressP
to only display files with extensions.p
,.o
,.81
,.80
and .p81
- Press
enter
whilst a directory entry is selected to move to that directory - Press
enter
when a file is selected to load that file - Press
Escape
,space
,Q
or0
to return to the emulation without changing directory or loading a new program
Displays the current emulator status. Any sound that is playing is paused. Note that this display is read only, no changes to the configuration can be made. Press Escape
, space
, Q
or 0
to exit back to the running emulator
Pauses the emulation. Handy if the phone rings during a gaming session! P
is XORed into the 4 corners of the display to indicate that the emulator is paused. Press Escape
, space
, Q
or 0
to end the pause and return to the running emulator
The ZX80 and ZX81 use single key press BASIC entry. Pressing F5
displays a 4 colour image (VGA) or a grey scale image (DVI / HDMI) representing the keyboard of the computer being emulated, so that the correct key presses can be determined. The image was taken from sz81. It is possible to enter commands whilst the keyboard is displayed
Press Escape
to remove the keyboard display. The keyboard is also removed if another menu is selected
If a ZX8x 40 key keyboard is being used and DoubleShift
is enabled, the menu can be removed by pressing and releasing shift twice and then pressing 0
within one second of releasing shift
Allows some values to be modified "on the fly" to see the impact of the changes without having to edit the config files. Select the item to modify using the up
and down
keys. The 7
key also generates up
and the 6
key also generates down
. Change the value of an item using the left
and right
keys. The 5
key also generates left
and the 8
key also generates right
The changes are not written back to the config files, so will be lost when the emulator is rebooted. Exit by pressing Enter
to see the effect of the changes. Press Escape
to exit without changes
Allows some values to be modified to see the impact of the changes without having to edit the config files. Changing these values will result in the emulated machine being reset and returning to the K
prompt. Select the item to modify using the up
and down
keys. The 7
key also generates up
and the 6
key also generates down
. Change the value of an item using the left
and right
keys. The 5
key also generates left
and the 8
key also generates right
The changes are not written back to the config files, so will be lost when the emulator is rebooted. Exit by pressing Enter
to action the changes. Press Escape
to exit without changes
Allows the impact of changes to display resolution and frequency to be seen without editing config files. If a change is made and the menu is then exited by pressing Enter
the Pico will reboot and use the new display mode. The changes are not written back to the main config files, so any changes will be lost on subsequent reboots.
On the LCD builds the display resolution is fixed and only the frequency can be changed
The emulator supports loading .p
, .81
, .o
, .80
and .p81
files from micro SD Card. It can save in .p
and .o
format.
Files to be loaded should only contain characters that are in the ZX81 or ZX80 character set
There are 3 ways to load files:
The user can navigate the SD card directory and select a file to load. The emulator is configured to the settings specified for the file in the config.ini
files, reset and the new file loaded
If the user enters the LOAD
command without specifying a file name the SD Card directory menu is displayed and a file to load can be selected. The emulator is configured to the settings specified for the file in the config.ini
files. Unlike for option 1, the emulator is only reset if the configuration differs. This, for example, allows for RAMTOP to be manually set before loading a program
If a file name is specified, then .p
is appended and an attempt is made to load the file from the current directory. The configuration for the file is read. A reset is performed only if required by a configuration change. This allows for multiple parts of an application to be loaded e.g. HiRes Chess or QS games that include character definitions.
If the supplied filename, with .p
appended, does not exist, then the LOAD
fails with error D
. This is similar to a "real" ZX81, where if a named file is not on a tape, the computer will attempt to load until the user aborts by pressing BREAK
, generating error D
To save a program the SAVE "Filename"
command is used. If "Filename"
has no extension then .p
is appended to the supplied file name. The file is saved in the current directory. If a file of the specified name already exists, it is overwritten
To save a program the SAVE
command is used. SAVE
does not take a file name, so mechanisms are provided to supply a file name. When SAVE
is executed the emulator scans the program for a REM
statement of the form:
REM SAVE "filename"
If such a REM
is found the file is saved with the name filename
with .o
appended if not supplied
Note: The SAVE
in the REM
is the keyword. Enter it first then use the cursor keys to insert the REM in front of it
If no REM
statement of the required format is found, then a save screen will be displayed to allow a filename to be entered.
The ZX80 keyboard image is automatically displayed to make it easier to enter non alphanumeric characters. The cursor keys (SHIFT 5
and SHIFT 8
) and Rubout
(SHIFT 0
) can be used.
Press ENTER
to exit the screen and use the filename, .o
is appended if not supplied. Press Esc
or SHIFT 1
to leave the screen without setting a filename
The program is saved to the current directory. If no valid file name is supplied a default filename of "zx80prog.o"
is used. Any existing file with the same name is overwritten
When emulating a ZX81, extensions are provided to LOAD
and SAVE
to support the loading and saving of memory blocks. The syntax is similar to that used by ZXpand
Note: There are differences in failure modes and error reporting compared to the ZXpand. Also .p
is not appended when loading and saving memory blocks
The extensions are enabled by default. Set the ExtendFile
config option to Off
to disable the extensions
LOAD "filename;nnnnn"
where nnnnn
represents a decimal number specifying the target address
- Error inverse
1
: The target address is not a number, or is outside of the range 0 to 65535 - Error inverse
3
: No data would be written into existent RAM. Checks are made to ensure that data is not written to ROM, or non existing RAM addresses - Error
D
: The specified filename does not exist (no.p
extension is added)
Note:
- The string passed to
LOAD
is parsed for target address if and only if it contains at least 1;
the target address is assumed to be after the last;
in the string. If the string does not contain a;
it is treated as a single filename and a program file is loaded with the name of the supplied string (with.p
appended if there is no.
in the supplied string)
SAVE "filename;sssss,lllll"
where:
sssss
represents a decimal number specifying the start address of memory to be savedlllll
specifies the number of bytes of memory to be saved
- Error inverse
1
: The start address is not a number, or is outside of the range 0 to 65535 - Error inverse
2
: The length address is not a number, or is outside of the range 1 to 65536 - Error inverse
3
: The sum of the start address and the length is greater than 65536 Notes: - If a file with the specified name exists on the SD Card, it is overwritten
- The string passed to
SAVE
is parsed for start and length if and only if it contains at least 1;
and a,
exists in the string after the last;
. Otherwise the string is treated as a single filename and a program file is saved with the name of the supplied string (with.p
appended if there is no.
in the supplied string)
The original ZX81 used tape as a storage media, with no concept of a directory structure. The emulator uses an SD Card, and does support the basic use of directories.
LOAD "../HIGHER"
will attempt to load the fileHIGHER.P
from the parent directory of the current directoryLOAD "ABC/LOWER"
will attempt to load the fileLOWER.P
from the child directory with the nameABC
The LoadUsingROM
and SaveUsingROM
configuration options allow the ROM code to be executed. This emulates the loading and saving of program files (but not data blocks) in the same time that it would take on a real ZX80/ZX81
Picozx81 generates realistic load and save sounds and graphics for the 8K ROM. The 4K ROM generates sounds and graphics when saving, which picozx81 emulates. The 4K ROM does not generate a load screen. Picozx81 will show a black screen when the 4K ROM is loading a program
The save sounds generated for both the 4K and 8K ROMs have been recorded as wav files and then successfully loaded into the EightyOne emulator
The ROM is used for program loading if either the filename is specified on the command line, e.g. LOAD "FILENAME.P"
or (for the ZX81) an empty filename is supplied e.g. LOAD ""
. If a file extension exists (.p
, .o
etc) then it must be supplied. Directories can be specified as part of the filename e.g. LOAD "SUBDIR/FILENAME.P"
The config file is read prior to loading. If the configuration file requires the emulator to be reconfigured so that it requires a reboot (e.g. the computer type or memory size changes) then the ROM will not be used for loading, and the file will be loaded immediately, as if LoadUsingROM
was set to OFF
. The ROM is also not used for loading if the file to be loaded is selected by pressing F2
When loading, picozx81 will read a .p
, .o
or .p81
file and generate values which the ROM reads through IN statements
Note: A program cannot be loaded directly from a wav file
Testing the emulator has been a great way to experience some classic ZX81 games and demos, including many that stretch the ZX81 and ZX80 well beyond what Sinclair may have originally expected. The following have been successfully tested:
- clkfreq / clckfreq
- Runs in the right number of frames (1863) when NTSC not selected
- Artic Galaxians
- The one lo-res game that had to work correctly!
- 3D Monster Maze
- An iconic ZX81 game
- ZXTEST2
- This creates an image that periodically moves up and down by 1 pixel on a real ZX81. The emulator replicates this behaviour
- Maxtxt
- Creates a 40 by 30 character display
- Celebration and Lightning Display Driver
- Set LowRAM on, and Memory to 48kB to view a colour version of celebration
- Z-Xtricator
- For the bomb (aka "Super Zapper") effects to render correctly
WRX
must be set to Off (see here)
- For the bomb (aka "Super Zapper") effects to render correctly
- Rocket Man
- War Web
- ZX81 Hires Invaders
- High Resolution Invaders
- Against The Elements
- Set LowRAM on, and Memory to 48kB to view a colour version of celebration
- Dr Beep's amazing collection of 81 1K games
- A sub-set have been tested. More will be test tested, but it is very easy to become distracted as they are very addictive! So far all appear to be displayed correctly
- SplinterGU SInvaders
- A very faithful clone of the arcade Space Invaders
- MaxDemo
- Hi-res 320x240 and 40 by 30 characters. Set
Centre
to off to see the full image in 640 by 480 mode - The display routine is the most CPU intensive part of the emulator, so this is the best test that the emulator can run at 100% of the speed of "real" hardware
- Hi-res 320x240 and 40 by 30 characters. Set
- HRDEMO3
- HiRes Chess
- All 26 lines are shown
- Bi-Plot Demo
- Othello
- WRX1K1
- The assembler routine runs in 1K, but the BASIC demo program that draws concentric circles does not, as it requires more than 1K of RAM. This can be verified by using the BASIC listing tool in EightyOne to check the memory address of each line of BASIC. It will run in 2K
- zedit
Set WRX
to Off
and CHR128
to on
- ARX_Demo Demonstrates ARX graphics
- ARX Hangman Replicates the "off by 1 error" seen on real hardware and discussed here
- Pink Panther Demo
- Bigg Oil
- QS Programs
- Galaxians
- SInvaders
- Dancing Demon
- PT3 player and STC Player
- Use
config.ini
insounds
- Note: The
config.ini
file must be in the same directory as the.p
file, therefore to run thesplash.p
files supplied with the PT3 players, move them to the same directory as the player and ensure that a copy of theconfig.ini
file is in that directory - The ZXpand configuration line in the PT3 player, which appears as a
LLIST
command at line 9992, should be deleted
- Use
- Nova2005
- This is written for a 60Hz ZX81. For the second count to be accurate the
NTSC
option must be enabled. IfNTSC
is not selected the clock will run at 50/60 speed. Nova generates up to 26 rows of 34 characters. These are displayed correctly - To see the clock when
NTSC
is not enabled,Centre
must be set toOff
. In this case a vsync bar will be seen at the bottom of the display
- This is written for a 60Hz ZX81. For the second count to be accurate the
- Spirograph
- For the
QUICK
display mode to function correctly theNTSC
option must be enabled. Works correctly inFAST
andSLOW
mode regardless of theNTSC
option
- For the
- Hot-Z II 64K
- Requires at least 32kB of RAM. Runs correctly with
M1NOT
set toOn
. As expected, the emulated ZX81 crashes ifM1NOT
is set tooff
- Requires at least 32kB of RAM. Runs correctly with
To enable chroma support set LowRAM on, and Memory to 48kB
- Celebration
- Against The Elements
- Colour 3D Monster Maze
- Attribute Mode Test Program
- HiRes Galaxians
- Ensure WRX RAM is disabled
- Chroma Slideshow
- This works well with
FrameSync
set toInterlaced
. Note that the program loads a series of image files. A config entry withFrameSync
set toInterlaced
needs to be created for each image file
- This works well with
- ROCK CRUSH 80
- This is a ZX80 game, but the
.p81
file will also run on the ZX81. IfSOUND
is set toCHROMA
notes played at start-up can be heard
- This is a ZX80 game, but the
Set SOUND
to either TV
or CHROMA
. If TV
is selected a background tone will be generated during normal operation. This tone is created by VSYNC (ZX81) or VSYNC and HSYNC (ZX80). If CHROMA
is selected a tone is only generated when vertical sync is lost
These really show off the capabilities of the ZX81 and are a good test that the emulator is accurate
- Multi Scroller Demo
- Plays sound, and also demos various text scrolling techniques on a basic 16kB ZX81. This demo requires very specific timing, so shows the accuracy of the emulator
- There are no limits
Both generate a display more than 320 pixels wide, so some information is not displayed in 640 by 480 mode (i.e. FiveSevenSix
is set to off
)
- 25thanni
- The scrolling "ticker" is more than 320 pixels wide, so all of it is not visible in 640 by 480 mode
- rezurrection
- The initial fast horizontal scrolling highlights the non-synchronised screen drawing of the emulator when running in 640 by 480 mode with
FrameSync
set toOff
, leading to visible tearing
- The initial fast horizontal scrolling highlights the non-synchronised screen drawing of the emulator when running in 640 by 480 mode with
- Ilena
- Best viewed with
FrameSync
set toInterlaced
- Best viewed with
- ZX80 3K QS DEFENDER
- This game generates 32 lines of text. In 640 by 480 mode the emulator only displays 30 line of text. Set
Centre
tooff
so that the score, which is towards the top of the display, is visible. The game is still playable without the bottom of the display being visible. The full display is visible in 720x576 mode (i.e.FixSevenSix
set toOn
). The QS sound board is emulated.VTOL
has to be increased to display a stable image. This replicates the behaviour of this program of a "real" ZX80
- This game generates 32 lines of text. In 640 by 480 mode the emulator only displays 30 line of text. Set
- Breakout
- Double Breakout
- Kong
- Pacman
- Metropolis
- This demo was a driver for adding a more accurate ZX80 emulation. It runs correctly for 4K and 8K ROMs with the latest version of picozx81
To enable chroma support set LowRAM on, and Memory to 48kB
- QS Defenda
- This game generates 31 lines of text, one less than ZX80 QS DEFENDER. In 640 by 480 mode the emulator only displays 30 line of text. Set
Centre
tooff
to display the top lines, which include the score. The game is still playable without the bottom line being visible. The full display is visible in 720x576 mode (i.e.FixSevenSix
set toOn
). The QS sound board is emulated correctly.VTOL
has to be increased to display a stable image. This replicates the behaviour of this program of a "real" ZX81
- This game generates 31 lines of text, one less than ZX80 QS DEFENDER. In 640 by 480 mode the emulator only displays 30 line of text. Set
- Wa-Tor
- This has a pseudo hi-res introduction screen. Towards the bottom of the screen is the text: "Experiment with predators and prey". On a "real" ZX81 the text is distorted, due to a variation in the time of the horizontal sync pulse. This emulator does not show the distortion
- rezurrection
- With default settings, the logo on the final screen "flashes" after the scrolling is complete. This is because the logo is displayed interlaced, at roughly 52Hz. Set
FrameSync
toInterlaced
to display the final screen correctly without flashes. A frame rate adjusted version of the final Rezurrection screen exists in the Demos example directory: head.p and config.ini. When run withFiveSevenSix
andFrameSync
set toon
orinterlaced
a stable interlaced image can be seen after the scrolling is complete
- With default settings, the logo on the final screen "flashes" after the scrolling is complete. This is because the logo is displayed interlaced, at roughly 52Hz. Set
- ZX80 Kong and ZX80 Pacman
- The Chroma 80 4K ROM versions use a loader program to set the colour data and then load the main program. The loader available in the supplied links uses a custom tape load routine that is not detected by picozx81. To create a compatible loader that uses that standard 4K ROM load routine use the Chroma Program Enhancement Creator. As the 4K ROM
LOAD
command does not take an argument, picozx81 will display the contents of the current directory when the loader program is run. Select the main program from the directory list and it will load and run, using the colour data loaded earlier
- The Chroma 80 4K ROM versions use a loader program to set the colour data and then load the main program. The loader available in the supplied links uses a custom tape load routine that is not detected by picozx81. To create a compatible loader that uses that standard 4K ROM load routine use the Chroma Program Enhancement Creator. As the 4K ROM
Notes:
- Prebuilt executable files for the 7 supported board types can be found here
- If a zip of the source files is downloaded from GitHub, it will be incomplete, as the zip will not contain the submodules. Zip files of the submodules would have to be downloaded separately from GitHub. It is easier to clone recursive the repository, as described in the following section
-
Install the Raspberry Pi Pico toolchain and SDK. SDK 2.x must be used
Instructions to do this for several operating systems can be found by downloading this pdf. Chapter 2 covers installation on the Raspberry Pi, chapter 9 describes the process for other operating systems
-
The vga display uses the
pico_scanvideo
library, which is part of thepico-extras
repository. Clone this repository, including submodulesgit clone --recursive https://github.com/raspberrypi/pico-extras.git
-
Clone this repository (i.e. picozx81), including submodules
git clone --recursive https://github.com/ikjordan/picozx81.git
-
create a build directory, move to that directory and build using CMake. By default an executable compatible with the Pimoroni vga board and a rp2040 will be created. This will be named
picozx81_vga_rp2040.uf2
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
-
To build for other boards with a RP2040, pass the board type as part of the cmake command. e.g.
Board | CMake | uf2 name |
---|---|---|
Pimoroni DVI | cmake -DPICO_BOARD=dviboard .. |
picozx81_dvi_rp2040.uf2 |
PicoMiteVGA | cmake -DPICO_BOARD=picomitevgaboard .. |
picozx81_picomitevga_rp2040.uf2 |
Olimex PICO DVI | cmake -DPICO_BOARD=olimexpcboard .. |
picozx81_olimexpc_rp2040.uf2 |
Pimoroni VGA | cmake -DPICO_BOARD=vgaboard .. |
picozx81_vga.uf2 |
Custom 332 VGA (similar to MCUME) | cmake -DPICO_BOARD=vga332board .. |
picozx81_vga332_rp2040.uf2 |
Cytron Maker based 222 VGA with CSYNC (similar to PICOZX) | cmake -DPICO_BOARD=vgamaker222cboard .. |
picozx81_vgamaker222c_rp2040.uf2 |
PICOZX without LCD | cmake -DPICO_BOARD=picozxboard .. |
picozx81_picozx_rp2040.uf2 |
PICOZX with LCD | cmake -DPICOZX_LCD=ON -DPICO_BOARD=picozxboard .. |
picozx81_picozx_lcd_rp2040.uf2 |
PICOZX in Spectrum case | cmake -DPICO_BOARD=picozxrealboard .. |
picozx81_picozxreal_rp2040.uf2 |
Pimoroni DVI with HDMI sound | cmake -DHDMI_SOUND=ON -DPICO_BOARD=dviboard .. |
picozx81_dvi_hdmi_sound_rp2040.uf2 |
Olimex PICO DVI with HDMI sound | cmake -DHDMI_SOUND=ON -DPICO_BOARD=olimexpcboard .. |
picozx81_olimexpc_hdmi_sound_rp2040.uf2 |
Wavesare PiZero with HDMI sound | cmake -DHDMI_SOUND=ON -DPICO_BOARD=wspizeroboard .. |
picozx81_wspizero_hdmi_sound_rp2040.uf2 |
Waveshare Pico-ResTouch-LCD-2.8 | cmake -DPICO_BOARD=lcdws28board .. |
picozx81_lcdws28_rp2040.uf2 |
Cytron Maker | cmake -DPICO_BOARD=lcdmakerboard .. |
picozx81_lcdmaker_rp2040.uf2 |
- Upload the
uf2
file to the Pico - Populate a micro SD Card with files you wish to run. Optionally add
config.ini
files to the SD Card. See here for examples of config files
Notes:
- To build for the RP2350 append -DPICO_MCU=rp2350 to the CMake command. The resulting
uf2
file will include rp2355 in its name - The
buildall
script in the root directory ofpicozx81
will builduf2
files for all supported combinations of mcu and board types - To debug using OpenOCD build and install OpenOCD as described in Getting Started with Raspberry Pi Pico-series
- If debugging using MS Visual Studio Code then install the Raspberry Pi Pico extension. Commands loaded by this extension are used to determine the active MCU type in
launch.json
- The original intention of the emulator was to provide an authentic '80s feel. It emulated the hardware that was advertised in the early '80s i.e. QS UDG, Sound, joystick, hi-res mono graphics. It has now been extended to provide emulation of some of the amazing ZX81 developments of recent years, such as Chroma 81. It supports the loading and saving of memory blocks, using a syntax similar to ZXpand
- The "Big Bang" ROM is supported, as this accelerates BASIC execution, and runs on the original ZX81 hardware
- Program debug support is limited to that provided by the ZX81 "in period", i.e. non-existent. It is recommended that one of the PC or Linux based ZX81 emulators with single step and breakpoint support are used to debug Z80 assembly programs
- To achieve a full speed emulation the Pico is overclocked to 252MHz (640x480) and 270MHz (720x576). There is a very slight risk that this may damage the Pico. However many other applications run the Pico at this frequency. By default the stock voltage is used (1.1V), this has been successfully tested on multiple Picos. If the emulator appears unstable it can be built to use 1.2V, add
-DOVER_VOLT
to the cmake command - The Pico only has 1 USB port. The Pimoroni, Olimex and Waveshare PiZero boards can be powered through a second on board USB power connector, allowing a keyboard to be connected to the Pico using an OTG adaptor
- To connect more than one peripheral (e.g. a keyboard and joystick) at the same time, a powered USB OTG hub is required. These 3 hubs have been successfully tested. 1, 2, 3. Plug the hub directly into the USB port on the Pico. The USB-A connector on the PICOZX boards can also be used
Note: Testing has shown that all of these hubs can support OTG and power delivery to the Pico simultaneously - On rare occasion, some USB keyboards and joysticks fail to be detected when connected via powered hubs. A re-boot of the Pico often results in successful detection
- The Waveshare PiZero has two USB-C connectors. Use the connector closest to the HDMI connector to provide power. Connect a keyboard to the other USB port using an OTG cable. If necessary, a female micro USB to male USB C adaptor can be used
- The board can be back powered by some TVs. This can cause the board to not start correctly. If this happens either connect the power before attaching the HDMI cable, or press the reset button on the board
- The PicoMiteVGA board has a PS/2 keyboard socket. Currently this is not supported, a USB keyboard must be used
- PicoMiteVGA only supports 1 level of Red and Blue, so it cannot display the full range of colours that Chroma can generate
- Some versions of the PicoMiteVGA board have a jumper to select between RGB and GRN mode. Select RGB mode
- PICOZX has a bank of 4 extra keys below the SD Card. These act as function keys.
Menu
maps toF1
,Reload
toF2
etc. If shift is pressed 4 is added to the function number. e.g.shift
+Menu
givesF5
(and so displays the keyboard) - The PICOZX + LCD code generates LCD output by default. To enable VGA output either hold down the the Fire button at start-up, or enable
VGA
in the config file - The PICOZX + LCD shares outputs with VGA. If the board is configured for VGA output, the intensity of the backlight of the LCD will vary with the contents of the VGA display
- The PICOZX for the ZX-Spectrum case has two extra buttons on the back (in addition to a reset button). Without shift these two buttons will generate
F2
andF5
. With shift they will generateF3
andF6
- Use the double shift mechanism to access all menus when using the PICOZX family
- To enter BOOTSEL mode on the PICOZX for the ZX-Spectrum press and hold the
R
key then press theF2
menu key. This allows new firmware to be loaded without needing to press the BOOTSEL key on the Pico
- The Waveshare Pico-ResTouch-LCD-2.8 board has a touch controller, but the emulator does not support its use
- The Olimex RP2040-PICO-PC board does not supply 5v to DVI pin 18. This may result in the board not being detected by some TVs. If necessary short the SJ1 connector so 5V is supplied
- If SJ1 is shorted the board may be back powered by some TVs. This can cause the board to not start correctly. If this happens either connect the power before attaching the HDMI cable, or press the reset button on the board
- The Cytron Maker Pi Pico has an onboard piezo buzzer. The audio quality is poor, but it can be used instead of speakers. If the buzzer is enabled (using the switch on the maker board) ensure that ACB Stereo is disabled
- The vgamaker222c build requires the following connections:
The Maker board can be used with a range of 320 by 240 LCDs, controlled over the SPI bus, with controllers from either the ILI9341 or ST7789 families. The boards are configured using entries in the default
section of the config file
The LCD should be connected to the Maker board as follows:
Function | Name | Pico GPIO Pin |
---|---|---|
Backlight | BL | 4 |
Chip Select | CS | 5 |
Clock | CLK | 6 |
Data In | DIN or MOSI | 7 |
Reset | RST | 8 |
Data / Command Selection | DC | 9 |
VCC | 3.3V | 3V3 (OUT) |
GND | Ground | Any Ground Pin |
Touchscreen functionality is not supported. Any pins used for the touchscreen do not need to be connected
All options are set in the [default]
section of the config.ini
file in the root directory of the SD Card.
Item | Description | Default Value |
---|---|---|
LCDInvertColour | Inverts the colour of the display. i.e. changes white to black and black to white | False |
LCDReflect | Defines the horizontal scan direction. Use if the K prompt is displayed on the right hand side of the display |
False |
LCDBGR | Set to true if blue displays as red and red displays as blue | False |
LCDRotate | Rotates the display through 180 degrees | False |
LCDSkipFrame | Displays every other frame, to reduce bandwidth | False |
e.g. to set LCDReflect
to true, add the following to the [default]
section of the configuration file: LCDReflect = True
Notes:
- If the configuration appears correct for a display, but no image appears, or the image is not stable, it could be that the display cannot support the SPI bus speed required to display every frame, or that cross talk is occurring between the wires connecting the display. In this case set
LCDFrameSkip = True
- It is recommended to use the Cytron maker board with the Pico pre-soldered, as this version can support higher bus speeds. If the version with a socket for a Pico is used, then the LCD display may not function correctly unless
LCDFrameSkip
is set toTrue
- If
LCDFrameSkip
equalsTrue
, then ifFrameSync
is set toInterlaced
it will be interpreted asOn
Display | Controller | Invert Colour | Reflect | Frame Skip | BGR |
---|---|---|---|---|---|
Waveshare 2" LCD | ST7789V | True | False | True | False |
Waveshare 2.4" LCD | ILI9341 | False | False | False | True |
Waveshare 2.8" LCD | ST7789 | True | True | False | False |
Generic 3.2" LCD | ILI9341 | False | False | False | True |
Example config.ini
settings for these LCDs can be seen here. Uncomment the lines in the section matching the LCD you wish to use
By default the display for the Waveshare Pico-ResTouch-LCD-2.8 is configured rotated, so that the usb connection and SD Card is at the bottom of the display. To undo the rotation, so that usb connection and SD Card is at the top, set LCDRotate = False
in the default section of the config file
With boards with connectors supplied for enough free GPIO pins it is possible to attach a 9 pin connector and then plug-in and use "in period" 9-pin joysticks
The lcdmaker, vgamaker222c, picomitevga, pizero and picozx builds support the connection of a 9-pin joystick connector
Solderless 9-Pin connectors can be sourced from e.g. ebay or amazon
pin number | 1 | 2 | 3 | 4 | 6 | 8 |
---|---|---|---|---|---|---|
lcdmaker | GP20 | GP21 | GP22 | GP26 | GP27 | Ground |
vgamaker222c | GP20 | GP21 | GP22 | GP26 | GP27 | Ground |
picomitevga | GP3 | GP4 | GP5 | GP22 | GP26 | Ground |
pizero | GP11 | GP12 | GP10 | GP15 | GP13 | Ground |
The picozx board has a 9-pin joystick port connector built in
To enable the nine pin joystick set NinePinJoystick
to On
in the [default]
section of the config.ini
file in the root directory
It is not necessary to create a NinePinJoystick
entry to use the joystick port on the picozx board
One intention of this project was to show what can be quickly achieved by leveraging other open source projects. The following excellent Open source projects have been used for source code and inspiration:
- sz81
- EightyOne Releases source
- MCUME
- pico-zxspectrum
- Pico DVI
- Pimoroni SD Card driver
- FatFS
- Config file parsing inih
Thanks to Paul Farrow for information on the Chroma expansion boards and the .p81
file format
There are not enough unused GPIO pins on the Pimoroni demo boards to allow the direct connection of a ZX80/81 keyboard, but it can be done by using another Pico to convert the ZX80/81 keyboard into a USB keyboard. It may seem excessive to use a whole Pico as a keyboard controller, but they are cheap and there is enough space to put the Pimoroni board, plus another Pico, plus a small USB hub into a ZX80 or ZX81 case
Code to convert a ZX8x keyboard to USB can be found at ZX81_USB_KBD. This code has been used to successfully connect a ZX81 keyboard to this emulator. If the keyboard is the only peripheral, then it can be plugged straight into the USB port of the Pico on the emulator board with the power connected to the USB power socket of the Pimoroni board. If other USB peripherals (such as another keyboard, or a USB joystick) also need to be connected then the ZX80/81 keyboard can be connected via a USB hub
To access the function menus from a ZX80/81 keyboard the doubleshift
configuration option must be enabled
The picozx board does support keyboard and joystick. This is achieved by using every available GPIO pin, and using VGA222 with CSYNC, together with mono audio
In an ideal world the latest versions of the excellent sz81 or EightyOne emulators would have been ported. An initial port showed that they are too processor intensive for an (overclocked) ARM M0+. An earlier version of sz81 (2.1.8) was used as a basis, with some Z80 timing corrections and back porting of the 207 tstate counter code from the latest sz81 (2.3.12). See here for a list of applications tested
The initial port from sz81 2.3.12 onto the Pico ran at approximately 10% of real time speed. Use of the Z80 emulator originally written for xz80 by Ian Collier, plus optimisation of the ZX81 memory access, display and plot routines allows the emulator to run at 100% of real time speed. The display of a full 320 by 240 image in real time (e.g. Maxhrg) uses approximately 83% of the available RP2040 CPU clock cycles with sound disabled and 87% with Zonx sound enabled when picozx81 is running with a 640x460 display and ZX81 hardware emulation. Figures are much lower for the RP2350 (56.5% without sound, 59% with sound)
ZX80 hardware emulation takes more CPU. Emulating an idle ZX80 with Zonx sound enabled takes approximately 94% of a 252 MHz RP2040 based Pico. Due to the nature of the ZX80 hardware display emulation, the CPU load drops, both in B&W and Chroma, when a ZX80 program is running. The CPU load is much lower on a RP2350 based Pico. An idle ZX80 with Zonx sound enabled takes approximately 65% of a 252 MHz RP2350 based Pico
The 640x480 display mode uses an overclock to 252MHz. The 720x576 display mode uses an overclock to 270MHz
Corrections to the tstate timings were made for ld a,n; ld c,n; ld e,n; ld l,n; set n,(hl); res n,(hl);
- Support for USB gamepads as well as joysticks
- Move to a Pi Zero to greatly increase processing power and use circle for fast boot times
MCUME demonstrated that a Raspberry Pi Pico based ZX80/81 emulator was feasible. The custom VGA RGB 332 board type is similar to the hardware required for MCUME
This emulator offers the following over MCUME:
- Support for USB keyboards and joysticks
- Emulation runs at full speed of a 3.25MHz ZX81
- Ability to save files
- Ability to load a program without reset
- Support for Hi-res and pseudo Hi-res graphics
- Support for multiple DVI, VGA and LCD boards
- Support for Chroma 80 and Chroma 81
- Support for programs which use more than 32 columns or 24 rows of characters
- ZonX, QS and TV Sound emulation
- Emulated QS UDG
- 50Hz and 60Hz emulation
- Emulator display refresh decoupled from Pico display rate
- Mapping of joystick inputs to specific key presses
- Hardware configuration associated with specific program files
- Builds under Linux (MCUME ZX80/81 emulator fails to build in a case sensitive file system)