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
30 PRINT J,I
40 NEXT I
50 NEXT J
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!
|