|Issue 3||"Variables on a Theme"|
The system variables are bytes in the
Spectrum ROM which allow the computer to know all the things it should do
to operate in the way you've come to
expect. The information, such as how
the Spectrum's memory is laid out, is
held in the system variables in these
addresses so that the computer can get
hold of it and update it as and when required. |
We can make use of the information stored in these memory locations in our programs, either by reading information already there or changing it to make the computer do something it might not otherwise do, or sometimes do it more easily.
Not all of them are that much use to us. And certainly not all of them ought to be changed. Some will cause the computer to crash, or the computer may simply ignore you. Some can be happily changed under certain circumstances only, and most within strict limitations. I hope to give you some guidelines as to what can and can't be done, but hopefully you will learn your own little PEEKs and POKEs in time as well.
23552 to 23559 KSTATE reading the keyboardWhen the processor is interrupted (50 times every second in the UK normally) one of the things done is to read the keyboard and store the results here. The bytes have different uses. Not all can be practically used by the programmer. You can use this program to examine what's going on in the eight bytes of KSTATE. Run it and press various keys to see what effect individual keys have, such as the Shift keys, and what effect going from one key to another has.
10 FOR A=23552 TO 23559
|System variables are bytes in memory which help the Spectrum remember certain things it needs to know about itself- if you like, the housekeeping routines. Delve deeper into the Spectrum ROM with Dilwyn Jones in this, the first of two articles which investigate the complete available set of system variables, giving comprehensive guidelines as to what you can and can't do with them.|
Pressing both Shift keys simultaneously
produces 14. This program will demonstrate this:
10 LET A=PEEK 23556
do much you could not do with INKEY$,
except that it could be used to type
ahead one character. If you try this program, you will find that if you press a key
when invited to do so, the key is indicated
on the screen in a short while even
though the program may not have got as
far as line 50 when you pressed a key.
The code of the last key pressed is
stored here and stays here until another
key is pressed. It is possible to test for a
newly pressed key by examining bit 5 of
the system variable FLAGS 23611.
This would be '1' for a key just pressed.
10 PRINT "Press a key now"
delay in the UK is one-fiftieth of a
second and starts off at 35/50 of a
second. You can happily POKE this if,
for instance, you want the key to start
repeating immediately. The cursors
become rather difficult to control if you,
say, POKE 23561,1. POKE 23561,0
effectively turns off the auto-repeat,
actually giving a delay of about five
seconds like POKE 23561,255. |
23562 REPPER delay between repeatsThis system variable controls the length of time between repeats once the auto- repeat has actually begun. The time is in fiftieths of a second in the UK. If you effectively want to turn off the auto- repeat for any reason, POKE 23562,0 or POKE 23562,255 gives about five seconds between repeats. If you wish to edit long program lines (eg. a long PRINT statement) then POKE 23562,1 will speed up moving the cursor to the right place. But beware of changing 23562 too much at the same time or you may speed up the cursor so much it becomes difficult to control. Its normal value is 5/50 to a second or one tenth of a second.
23563/4 DEFADDThe address of the argument of a user- defined function in a program; ie. if you had DEF FN A(B) in a program line, the value in 23563/4 would be the address of the letter B in the brackets in that line while only the function is being used. The best way to PEEK into 23563/4 to show this is to put the PEEK as a part of the FN to be evaluated as there is always a zero there unless the function is being evaluated. So the line:
10 PRINT PEEK 23563+256*PEEK 23564
The first 14 bytes on a basic Spectrum
contain addresses relating to channels
and streams. Streams -3 to +3 are
stored in two bytes each. |
23606/7 CHARSThis system variable has as normal values:
23606 contains 0
23607 contains 60
This system variable points to the start of the character set that the computer uses for printing on the screen and the printer. SCREEN$ also uses this system variable. The normal address pointed to is 15360 which is 256 less then the address of the start of the ROM character set. (256 less because the character generator is accessed by something similar to PEEK 23606 + 256 * PEEK 23607 + CODE "A" * 8 and since the first character is a space, and the code of a space is 32 you can see that 8 * 32 is 256). The character generator is 768 bytes long, so if you wish to set up a new character set you must set aside this number of bytes in case it is overwritten by Basic - you wouldn't get a crash, you'd just end up with gibberish.
Mention was made of SCREEN$ using this system variable - in fact, you may be aware of the problem that SCREEN$ does not recognise user- defined graphics normally, unless they happen to be similar to an existing Spectrum character. In fact, SCREEN$ works by picking up the address of the start of the character generator and looking through the table until it finds a matching character. Now since the Spectrum screen is bit-mapped rather than memory-mapped like some computers, once anything is printed on the screen it stays the same even if you change the character in memory. So we could temporarily change the pointer to the character set to point to the user- defined graphics and look up there.
One snag is that although there is a system variable that tells us where the user-defined graphics start, this address is 256 or more - so we must subtract 256. This conveniently means we subtract one from the high byte. This program should demonstrate:
10 FOR X=144 TO 164
in the range of the user-defined
Here is one way to do this. X is the x co-ordinate across the screen and Y is the y co-ordinate down the screen of the location SCREEN$ is to examine. A check is first of all made that SCREEN$ does not find one of the normal characters there, then returns if one is found. The character at Y,X is returned in A$. Line 8025 is needed only if you are using a character set other than the ROM one. If you are using the ROM character set, then delete line 8025 and replace lines 8070 and 8080 with the alternative versions that follow.
8000 REM SCREEN$ FOR UDGs
down the keyboard response (since
computing stops as the bleep is sounded). Usually, the one to use is POKE
23610 ERR_NRControls error report number and normally has a value of 255 unless an error arises, when it contains one less than the error report codes printed, eg. for error 4, out of memory, it would contain a three. The message printed out is contained in ROM starting at address 5010 decimal. The end of the message is signified by the last character in the message having bit 7 set to a one. After the error message comes the '© 1982 Sinclair Research Ltd.' message that you see after switch-on or NEW. You can POKE 23610 to generate an error to stop the program, but since the message printed is fixed and in ROM, you may end up with garbage.
If you wanted to simulate an 'out of memory' error you would end a program with POKE 23610,3. This would not work as any program line; you'd have to ensure that it was the last line, as once a condition arises to end a program, only then is 23610 looked at to determine what is printed.
23611 FLAGSThis system variable contains various flags controlling the Basic system and generally should not be POKEd. However, some of the flags can be usefully PEEKed.
Bit 0: Being a one indicates no space to be printed before the next keyword.
Bit 1: This bit being set to a one indicates that the print output is to be send to the printer. A zero would mean it is to be sent to the TV screen.
Bit 5: Any newly pressed key is indicated by its code being stored in 23560 (the LASTK system variable) and bit 5 of 23611 (FLAGS) is set to indicate that a new key has been pressed.
Bit 7: Syntax flag.
These will be of more use when using ROM routines in a machine code program.
23613/4 ERR_SPKeeps track of the address on the machine stack where the appropriate return data lies. Try calling a few GOSUBs with no matching RETURNs and watch this point down the memory. Now you can see what happens and why this occurs when you run out of memory in a situation like this. Also, try PEEKing
the contents of the three addresses
(the base of which is pointed to by
23613/4) to see what return data actually
10 LET A=PEEK 23613 + 255*PEEK 23614
BORDER colour. Take a look at Table
By POKEing various values into this system variable you could achieve a flashing, bright, multicoloured lower screen, or make both PAPER and INK the same colour to prevent other people getting at your programs - however, any alteration would have to be made blind. You could also make INPUTs extra bright to stand out.
23627/8 VARSThe pointer to the start of the variables store. Apart from finding your way into the variables area, you can find the length of the Basic program with this expression. This excludes screen, system variables, stacks and variables.
LET bytes=PEEK 23567 + 256*PEEK 23628 - PEEK 23635 - 256*PEEK 23636
where you're typing ...
10 FOR A=0 TO 255
program, eg. in 10 LET A = 5, it would
point to the address of the letter A. |
It can also be used to find the memory address of a numeric variable, if you use something like LET A=A as in the following program:
10 LET A=5
|This article is extracted from Dilwyn Jones' book, Beyond Simple Basic - Delving Deeper Into Your ZX Spectrum. This book was first published by Interface Publications, n-nn xxxxxxxxxx xxxx xxxxxx, xxxxxx xn nxx, and is priced at £7.95.|