The ZX Spectrum BASIC experience, recreated.
ZXBasic recreates the look and feel of programming a real ZX Spectrum: a 256×192 display, Spectrum colors, color clash, and an optional phosphor CRT effect. Write a few lines, enter RUN, and watch them come to life—without giving up the convenience of a modern keyboard.
![]() Union Jack — PLOT, DRAW, and a splash of color. |
![]() Human Shader — a whole scene, calculated in BASIC. |
![]() ThunderCats — CIRCLE, DRAW, and a carefully closed FILL. |
These images were captured from ZXBasic using File → Save Screenshot. Click any image to view the program that produced it. Human Shader is inspired by humanshader.com and is best run at Unlimited speed using the walking/running toolbar button.
- Modern editing. Use native keyboard input, automatic uppercase, paste complete listings, click a listed line to edit it, and scroll with the mouse wheel.
- Spectrum-style display. Use Spectrum colors, flashing attributes, custom characters, and an optional phosphor CRT effect.
- Adjustable execution speed. Choose Spectrum speed, 10× Fast, or Unlimited, even while a program is running.
- Beeper audio. Play Spectrum-style square-wave tones with BASIC's
BEEP duration,pitchcommand. - Program files and snapshots. Open and save
.basfiles, import BASIC from 48K.snasnapshots, or drag either type onto the window. - Interruptible programs. Press Escape to stop a running program.
- Mouse input. Read the pointer and buttons from BASIC; the included Mouse Paint example demonstrates drawing, erasing, and flood fill.
Paste this program into ZXBasic, type RUN, and press Enter:
10 BORDER 0: PAPER 0: INK 6: BRIGHT 1: CLS
20 FOR A=0 TO 2*PI STEP PI/36
30 PLOT 128,88
40 DRAW 80*COS A,80*SIN A
50 NEXT ATry changing INK 6 to INK 3, or adjust the angle step on line 20, and run the program again.
Open a listing with File → Open, Ctrl+O (⌘+O on macOS), or drag and drop. Then type RUN.
| Program | Highlights |
|---|---|
| Human Shader | Builds a scene a block at a time. Unlimited speed recommended. Also available as a .sna snapshot. |
| Union Jack | Uses graphics commands and Spectrum attributes to draw the flag shown above. |
| Mouse Paint | Provides normal and bright inks, an eraser, and flood fill. |
| 3D Spinning Cube | Arrays + trigonometry + DRAW = a rotating wireframe cube. |
| Conway's Game of Life | Watch tiny patterns live, grow, and disappear. Also available as a .sna snapshot. |
| Web | Turn straight lines into a colorful animated web. |
| DTC | Make your own characters with POKE and CHR$. |
| FRAMES Clock | Turn the Spectrum's 50 Hz counter into a clock. |
| Joystick Move | Steer a * with the arrow keys and IN 31. |
ZXBasic includes a few additions and recently implemented Spectrum features that are especially useful for interactive programs:
CONTINUEresumes at the statement after the lastSTOP, preserving variables, loops, and subroutine state. The listing must not have changed since it stopped.FILL x,yflood-fills the enclosed region containing(x,y)using the current ink. Temporary drawing attributes work too—for example,FILL INK 2;128,88. The surrounding outline must be completely closed or the fill will escape through the gap.RENUMandRENUMBERrenumber the listing and update literal targets used byGO TO,GO SUB,THEN,RESTORE, andRUN. They default to10,10; use forms such asRENUMBER 100,5to choose the first line and step.
Mouse input is exposed through live, read-only numeric variables:
| Variable | Value |
|---|---|
_MX, _MY |
Current Spectrum pixel coordinates, or -1 outside the display. Reading _MX takes a new position sample. |
_OMX, _OMY |
Coordinates from the preceding _MX sample, useful for drawing continuous lines. |
_MB |
Mouse-button bitmask: left 1, right 2, middle 4. Values combine when multiple buttons are held. |
The Spectrum's 24-bit FRAMES system value is available through PEEK 23672, PEEK 23673, and PEEK 23674, least-significant byte first. It advances at 50 Hz and wraps after 16777215; see the FRAMES Clock for a complete example.
Editing programs and useful commands
Type a numbered line and press Enter to add or replace it:
10 BORDER 1
20 FOR A=-99 TO 99
30 PLOT A+110,80+30*SIN (A/12)
40 NEXT A
50 PAUSE 0The program automatically lists around the line you entered. The > marker follows the newest or selected line. Entering a line number on its own deletes that line.
Useful immediate commands include:
LIST
RUN
RUN 100
CONTINUE
BORDER 3: PAPER 2: CLS
RENUMBER 10,10
NEWPaste several numbered lines at once to add a complete listing. Direct commands can also contain multiple statements separated by colons. Escape clears the line currently being edited; while a program is running it breaks execution instead.
The walking/running toolbar icon rotates between Spectrum, Fast, and Unlimited speed. You can change speed while a program is running. Display → CRT effect switches between the processed phosphor treatment and a clean pixel display.
Language support and Spectrum memory
ZXBasic currently supports the core language needed by sizeable Spectrum programs:
- Numeric and string variables, expressions, slicing, and standard math/string functions.
LET,IF/THEN,FOR/NEXT,GO TO,GO SUB,RETURN,STOP,CONTINUE, andPAUSE.- Numeric and string arrays through
DIM, plusERASE. DEF FN/DEFFN,DATA,READ,RESTORE,INPUT, andINPUT LINE.PRINT,AT,TAB, print zones, scrolling, embedded color controls, block graphics, and UDGs.PLOT,DRAW, curvedDRAW,CIRCLE,FILL,POINT,ATTR, andSCREEN$.INK,PAPER,BRIGHT,FLASH,INVERSE,OVER,BORDER, andCLS.PEEK,POKE,CLEAR,RANDOMIZE,RND,INKEY$,REM, andBEEPaudio.IN 31for cursor-key joystick input: right1, left2, down4, and up8.
Display memory follows the Spectrum layout: addresses 16384–22527 expose its non-linear bitmap rows, and 22528–23295 expose the 32×24 color attribute map.
The 24-bit FRAMES system variable is available little-endian at addresses 23672–23674. It advances continuously at the PAL Spectrum rate of 50 Hz, wraps after 16777215, and can also be changed with POKE.
Font and mouse extension details
The original 96-character, 8×8 font is extracted from the standard Spectrum 48K ROM at development time and encoded directly in ZXBasic. No ROM file is required at runtime.
Mouse input is available to BASIC programs as live, read-only numeric variables. _MX and _MY use Spectrum pixel coordinates, with (0,0) at the bottom-left. Reading _MX samples the latest pointer position; _OMX and _OMY contain the preceding sample, which makes continuous lines easy to draw when pointer events skip pixels. _MX and _MY are -1 while the pointer is outside the display. _MB is a button bitmask: 1 for left, 2 for right, and 4 for middle.
The safe Spectrum expression USR "A" is supported for locating user-defined graphics data; letters A through U map to their traditional eight-byte RAM slots. CHR$ 144 through CHR$ 164 print those glyphs after their data has been written with POKE. Numeric USR and machine-code execution remain unsupported.
Installers are attached to the latest GitHub release:
- Windows: x64 Inno Setup installer, including the OpenAL runtime.
- macOS: Apple Silicon and Intel disk images.
ZXBasic requires the .NET 9 SDK. It uses Avalonia for its cross-platform desktop interface.
git clone --recurse-submodules https://github.com/deanthecoder/ZXBasic.git
cd ZXBasic
dotnet build ZXBasic.sln
dotnet test ZXBasic.sln
dotnet run --project src/ZXBasic/ZXBasic.csproj
To create local installers:
python Installer/pack.py
The GitHub Actions installer workflow builds the Windows and macOS packages and can publish them directly to a tagged GitHub release.
ZXBasic interprets BASIC directly; it is not a machine emulator. Z80 machine code and RANDOMIZE USR are outside its scope. IN 31 is available for cursor-key joystick input; other hardware-specific IN ports, OUT, printer commands, and tape commands are not supported.
Snapshot import supports uncompressed 48K .sna files and extracts their BASIC program. Other machine state and embedded machine-code routines are not executed.
ZXBasic source code, embedded font data, and the included example programs are available under the MIT License.



