ZX81 BASIC, VAR definition in memory I
Posted: Sat Oct 25, 2014 3:36 pm
As previously announced you can define labels direct in memory in the VAR section instead of putting LET statements into the program. This saves time and used memory because the variables are defined already for use and has some more advantages. The disadvantage is, that the program must not be started with RUN but with GOTO instead (example GOTO 1 for the beginning). An alternative is to define the label AUTORUN: in the source in front of the desired BASIC line:
The above code shows a complete ZX81 BASIC program. There is no change for the startup section but at the end the include of ZX81POST.INC is replaced by ZX81DISP.INC which will define only a valid DFILE but no empty VAR section like the ZX81POST.INC does. Important is the following label VARS_ADDR: followed by the variables needed and the end marker $80 (or 80h) at the end followed by the label WORKSPACE:. The labels are important as they set the appropriate system variables of the ZX81 program.
A numeric variable can be defined using the directive VAR, followed by the name and an (optional) initialization with "=" and the desired value. You can see a big difference in the code above between the variable definition in memory with the name just followed by the 5 byte floating point value (6 bytes only) and the definition in a LET statement in the program with 16 bytes in this example (3 times space required) through LET statement, ASCII value, line number, line length - so quite a lot overhead. When the program runs, it will create the variable additionally in the memory (var section). So regarding this the direct definition takes only a quarter of memory.
In the example above the AUTORUN: label is set in front of the PRINT A statement. This will print 100 after loading or after repeat start with GOTO 40 but the LET value 99 after RUN.
Some random definition of numeric variables here:
Numeric variables can consist of one or more letters, followed by a 5 byte floating point value. Several bits in the first and last letter define the type of variable (numeric, string, array). The initialization is optional, see definition of variable E which is initialized automatically with zero as the is no value given. This feature is not very useful for a single numeric variable but could save a lot of work when creating arrays.
The last definition of F is a loop variable like used in a FOR-NEXT loop. There are 4 values given, the current value, the limit, the step width and the line to jump to, usually set to the line number of FOR statement+1. If not existing BASIC jumps automatically to the next existing line number. The first 3 values are defined as floating point values and the last one as word. Take note that the line number as word is here defined as little endian as it is defined as big endian in the program listing.
The NEXT mechanism functions without a FOR statement if the variable is defined as loop variable in the var section in memory. The whole loop variable takes 18 byte in memory as there is additional 25 or 33 byte taken in the definition statement FOR depending of STEP is used or not. When the variable is created during program running you have to calculate all in all with about 50 bytes, so quite more. Additionally it is easy to manipulate this variable in the memory as well to modify the line number to jump to, the current value or similar.
Here is a funny program using NEXT without FOR:
Numeric arrays are defined similar. Here it is quite convenient that arrays are automatically initialized with zero but you can give other initial values as well easily.
Arrays can be initialized complete with G(4), partly with H(5) or not at all with K(10).
The above definition shows the init of a 2-dimensional array and definition of all values. If there are many values it is helpful to break the line with "\" (backslash) and continue in the next line like shown. This is not allowed inside a string but maybe used in the same way when initializing string values. The second definition shows an easy way of occupying a lot of memory (about 5000 bytes here for M, 5 bytes per floating point).
Code: Select all
format zx81
;labelusenumeric
;LISTOFF
// hardware options to be set and change defaults in ZX81DEF.INC
MEMAVL = MEM_16K // can be MEM_1K, MEM_2K, MEM_4K, MEM_8K, MEM_16K, MEM_32K, MEM_48K
// default value is MEM_16K
STARTMODE EQU SLOW_MODE // SLOW or FAST
DFILETYPE EQU AUTO // COLLAPSED or EXPANDED or AUTO
STARTUPMSG EQU 'CREATED WITH ZX81-IDE' // any message will be shown on screen after loading, max. 32 chars
include 'SINCL-ZX\ZX81.INC' // definitions of constants
;LISTON
AUTOLINE 10
REM 'VAR DEFINITION'
LET A=99
AUTORUN:
PRINT A
;LISTOFF
include 'SINCL-ZX\ZX81DISP.INC' ; include D_FILE and needed memory areas
;LISTON
VARS_ADDR:
VAR A=100
db 80h
WORKSPACE:
assert ($-MEMST)<MEMAVL
// end of program
Code: Select all
009C: [40A5] 00 1E 0C 00 F1 26 14 25 LET A=99
25 7E 87 46 00 00 00 76
AUTORUN:
00AC: [40B5] 00 28 03 00 F5 26 76 PRINT A
;LISTON
VARS_ADDR:
03CC: [43D5] 66 87 48 00 00 00 VAR A=100
03D2: [43DB] 80 db 80h
WORKSPACE:
In the example above the AUTORUN: label is set in front of the PRINT A statement. This will print 100 after loading or after repeat start with GOTO 40 but the LET value 99 after RUN.
Some random definition of numeric variables here:
Code: Select all
VARS_ADDR:
03B8: [43C1] 66 87 48 00 00 00 VAR A=100
03BE: [43C7] 67 87 76 00 00 00 VAR B=123
03C4: [43CD] 68 87 B0 00 00 00 VAR C=-88
03CA: [43D3] 69 87 30 00 00 00 VAR D=+88
03D0: [43D9] 6A 00 00 00 00 00 VAR E
03D6: [43DF] A6 27 A8 00 00 00 00 00 VAR ABC=0
03DE: [43E7] A7 31 26 27 31 A6 9F 0F VAR BLABLA=12E8
0D 18 00
03E9: [43F2] EE 84 20 00 00 00 85 20 VAR I=10,20,2,41
00 00 00 82 00 00 00 00
29 00
03FB: [4404] 80 db 80h
WORKSPACE:
The last definition of F is a loop variable like used in a FOR-NEXT loop. There are 4 values given, the current value, the limit, the step width and the line to jump to, usually set to the line number of FOR statement+1. If not existing BASIC jumps automatically to the next existing line number. The first 3 values are defined as floating point values and the last one as word. Take note that the line number as word is here defined as little endian as it is defined as big endian in the program listing.
The NEXT mechanism functions without a FOR statement if the variable is defined as loop variable in the var section in memory. The whole loop variable takes 18 byte in memory as there is additional 25 or 33 byte taken in the definition statement FOR depending of STEP is used or not. When the variable is created during program running you have to calculate all in all with about 50 bytes, so quite more. Additionally it is easy to manipulate this variable in the memory as well to modify the line number to jump to, the current value or similar.
Here is a funny program using NEXT without FOR:
Code: Select all
AUTOLINE 10
REM 'FUNNY PROGRAM'
AUTORUN:
PRINT I
NEXT I
;LISTOFF
include 'SINCL-ZX\ZX81DISP.INC' ; include D_FILE and needed memory areas
;LISTON
VARS_ADDR:
VAR I=10,20,2,11
db 80h
WORKSPACE:
Code: Select all
VARS_ADDR:
03AE: [43B7] 8C 17 00 01 04 00 81 00 VAR G(4)=1,2,3,4
00 00 00 82 00 00 00 00
82 40 00 00 00 83 00 00
00 00
03C8: [43D1] 8D 1C 00 01 05 00 81 00 VAR H(5)=1,2
00 00 00 82 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00
03E7: [43F0] 90 35 00 01 0A 00 00 00 VAR K(10)
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
041F: [4428] 80 db 80h
WORKSPACE:
Code: Select all
VARS_ADDR:
VAR L(3,5)=11,12,13,14,15,\
21,22,23,24,25,\
31,32,33,34,35
VAR M(1000)
db 80h
WORKSPACE: