ZX Spectrum BASIC: A Modern Developer's Survival Guide
You can find the complete manual for ZX Spectrum BASIC in the resources section of this site.
Key Differences from others BASICs
Version for LLMs
If you're working with an LLM, this abbreviated version of the ZX Spectrum BASIC guide on the Wiki will help clue the LLM into the differences.
Program Structure
Typical of other 1980s BASICs, ZX Spectrum BASIC had the following structure:
- Programs are composed of numbered lines (1-9999)
- Line numbers determine execution order
- No block structures or multi-line IF statements
- No
WHILE/UNTILloops or other modern control structures - Statements in a line are separated by colons (:)
- No procedures or multi-line functions
- All variables are global (except in user-defined functions, which can only evaluate a single expression)
Variables
- Plain numeric variables: letters and digits starting with a letter, spaces ignored
- Single letter names are required all other kinds of variables, specifically:
- String variables (e.g.,
a$) - Arrays, both numeric and string (e.g.,
n(10),v$(10,20)) FORloop variables (e.g.,FOR i=1 TO 10)- User-defined functions (e.g.,
DEF FN f(x) = x^2 + 1)
- String variables (e.g.,
- Case-insensitive
- String in string arrays must have fixed length specified in DIM
Indexing
Arrays are 1-based, not 0-based and use parentheses for indexing, not square brackets.
DIM fib(10): LET fib(1) = 1: LET fib(2) = 1
FOR i = 3 TO 10: LET fib(i) = fib(i-1) + fib(i-2): NEXT i
FOR i = 1 TO 10: PRINT fib(i): NEXT i
You can use array syntax to access a specific character in a string:
LET a$ = "HELLO"
PRINT a$(5) ' Prints "O"
String Slice Syntax
- Many other BASICs access portions of strings using
MID$or similar, this is not how it works on the ZX Spectrum - Use the
TOkeyword with a range of characters to get a slice of a string—unlike slices in Python, the range is inclusive.
LET a$ = "HELLO"
PRINT a$(2 TO 4) ' Prints "ELL"
LET a$(2 TO 4) = "IPP" ' Changes a$ to "HIPPO"
Control Flow
IF/THENonly works for single statementsGOTOandGOSUBare primary control mechanisms- No
ELSEclause - must use multiple IF statements FOR/NEXTloops require single-letter control variablesTHEN GOTO 1000cannot be abbreviated toTHEN 1000
Key Implementation Details
- Line numbers determine execution order
- Line editing and LIST work with line numbers
- Lines can be deleted by entering just their line number (!!)
- Variables cleared on RUN but not on GOTO
- Numbers stored as five-byte floating point with one byte exponent and four byte mantissa
- Approximately 9.5 significant digits accuracy
- Range approximately 10^-38 to 10^38
- String storage uses fixed lengths
- No user-defined functions except via DEF FN
Essential Commands
Note: In the examples below, we use ' for comments for readability, but on the actual ZX Spectrum you must use REM for comments, or :REM if not at the start of a line.
Program Control
RUN ' Start program from beginning
GOTO n ' Jump to line n
GOSUB n ' Call subroutine at line n
RETURN ' Return from subroutine
STOP ' Stop program execution
CONTINUE ' Resume after STOP
Variables
LET x = 42 ' Assign value (LET is required)
DIM a(10) ' Create numeric array
DIM a$(10,20) ' Create string array (20 chars per string)
Input/Output
PRINT x ' Print value
PRINT "Hi" ' Print string
INPUT x ' Get numeric input
INPUT a$ ' Get string input
INPUT "Prompt: ";x ' Input with prompt
Control Structures
IF x=0 THEN PRINT "Zero" ' Single line only
FOR n=1 TO 10 ' Must use single letter
PRINT n
NEXT n
10 IF x<0 THEN GOTO 50 ' Multi-line if requires GOTO
20 PRINT "Positive"
30 GOTO 60
50 PRINT "Negative"
60 REM Rest of program
Common Pitfalls
- Forgetting LET in assignments
x = 5 ' SYNTAX ERROR
LET x = 5 ' Correct
- Using complex IF structures
' This won't work:
IF x>0 THEN
PRINT "Positive"
ELSE
PRINT "Negative"
ENDIF
' Must use:
10 IF x>0 THEN GOTO 40
20 PRINT "Negative"
30 GOTO 50
40 PRINT "Positive"
50 REM Continue...
- Variable name limitations
counter = 1 ' Invalid - no LET
FOR counter = 1 ' Invalid - must be single letter
FOR i = 1 ' Valid
- String handling gotchas
DIM a$(10) ' Creates ONE string of fixed length 10
DIM a$(10,20) ' Creates array of 10 strings, each length 20
LET a$ = "Long" ' Truncated or padded to match DIMed length
Best Practices
-
Line Numbers
- Start with line 10, increment by 10
- Leave gaps for inserting code
- Use round numbers (100, 200, etc.) for major sections
-
Program Structure
- 10-90: Initialization
- 100+: Main program
- 1000+: Subroutines
- 9000+: Error handling
-
Variable Names
- Use meaningful single letters where possible
- i,j,k for loop counters
- x,y,z for coordinates
For example: ```basic 10 REM Initialize variables 20 LET score = 0: REM Current player score 30 LET x = 128: REM Screen center X 40 LET y = 88 REM Screen center Y 50 FOR i = 1 TO 10: REM Main game loop 60 REM Rest of program...
-
Error Handling
- Keep track of error states manually
- Use GOTO for error conditions
- Add error checking before calculations
Remember: ZX Spectrum BASIC is very different from modern structured programming. Embrace GOTOs and line numbers—they're your friends here!
(When logged in, completion status appears here.)