48k Spectrum
Technical Information
ZX Basic

This guide does not teach BASIC, rather how BASIC is implemented and how it can be used to control the Spectrum.

There are basically six types. The first byte of a variable stores the first letter of the variable in bits 0 to 4 and the type in bits 5 to 7.

Type Use
2 String
3 Numeric with a single letter name
4 Numeric array
5 Numeric with a multiple letter name
6 Character array (dimensioned string)
7 Index array (used in a FOR loop)

Most versions of BASIC store variables as they are created and when extending a variable (e.g. A$=A$+"x") large memory shifts are needed. Not with the Spectrum. It's that old Sinclair genius at it again.

Each time a string (or array) is referenced on the left hand side of a LET, its old value is destroyed by moving the variables areas down to close up the memory space that it occupied, then re-created as if it were a new variable. By product of this are that no garbage collection is required to remove old variables and that frequently used variables are always at the top of the variable stack.

BASIC Storage

Each line of ZX BASIC is stored using the following format:
2 byte line number| 2 byte length of text plus ENTER| text| 1 byte ENTER (2 byte numbers are MSB first).

If A is the address of the start of a BASIC line then DEF FNL(A)=256*PEEK(A)+PEEK(A+1) will return its line number. When FNL(A) is the same as VARS, the program is finished.

Although ZX BASIC only allows line numbers in the range 1 to 9999 you can poke new addresses for line numbers in the range 0 to 61439. Changing a line to 0 will make it undeletable.

Built in commands (e.g. GOTO, TO, FOR, POKE) are not stored as text within the text area, but by there byte codes, described in Appendix A of the Spectrum manual (again, anyone got an electronic copy).

All numeric constants are stored in two forms: one as a string for the display screen, and the other as a 5 byte number. Character code 14 is used to indicate that a five byte floating point number follows, and is used by the LIST command to skip over internal formatted numbers.

Renumbering by changing the data has one flaw: GOTO and GOSUB commands are not changed.

Yet another innovation in ZX BASIC is the way the FOR LOOP is handled. To allow nesting a FOR stack needs to be implemented to know where the NEXT command will transfer control to. This is similar to the way the GOSUB stack is implemented in ZX BASIC. ZX BASIC does not use a FOR stack and provides quite a few advantages.

Each time a FOR statement is encountered, the variable area is searched for the same variable name in the FOR statement and it is deleted. Then a variable of type 7 (as above) is created. The format is as follows:

1 byte Type + first letter| 5 byte value| 5 byte Limit| 5 byte Step| 2 byte Line No.| 1 byte Statement No. The limit and step are as described in the FOR statement (e.g. FOR x=1 to 5 STEP 2). The line no. and Statement No. determine where the NEXT statement returns to.

When a NEXT is encountered, the step is added to the value and the result compared with the limit. If the result exceeds to limit then the loop ends, otherwise the program loops to the loop line.

This means that a GOTO (although not recommended for niceness purposes) can be used to jump out of a loop. Another effect is that improper nesting is valid, e.g.

10 FOR I=1 TO 10
20 FOR J=1 TO 10

Line 40 transfers control to line 20 ten times for values of I from 1 to 10, each time through the loop line 20 creates the index variable J and sets its value to 1. Line 50 causes the loop on K to be carried out 10 times. Each time through this loop the NEXT I at line 40 doesn't repeat because the value stored in I is already bigger than the limit. It does increase the value by adding the step!



Expansion Connector
Built in I/O
ULA Output
ULA Input
System Variables
ZX Basic
I/O Streams
Video Display
Tape, Sound, Printer
Interface 1
©2002 ZeDeX82