BASILS'
COMPENDIUM
John (Basil) Wentworth
1413 Elliston Drive
Bloomington, In. 47401
PEEK, POKE & USR
This chapter will review the operation of the ZX81 memory, it will discuss PEEK and POKE and it will introduce the USR command.
First, let's take a look at another utility program on a "play-by-ear" basis, just to keep up the interest. This one is the classic line renumber program. (Fred Nachbaur would call it a half-program, since it does not make appropriate adjustments in GOTO and GOSUB destinations, but it's still pretty impressive--especially when you remember that it is only 34 bytes long.)
Now, enter the "rough draft" 1 REM line shown in Figure 2-1,
- Fig 2-1 REM FOR RENUMBER -FIRST DRAFT-
and proof read it via the rudimentary loader program of Figure 2-2, (Keep in mind that it will not run until all the periods (.) have been poked with the data in table 2-4. The first column is the address + 16500 and the second column is the data to be poked.-ed.) You'll find the loader a little different from the one in the last issue, in that only one column of figures is displayed now. There's nothing sinister in this change — it's just that the new form is easier to work with when it has to handle a number of different programs. The number of bytes has also been changed, of course, to fit the length of the new program.
Code: Select all
FIGURE 2-2. THE RUDIMENTARY LOADER
10 REM PROOFREADING THE PROGRAM
20 FOR F=16514 TO 16547
30 PRINT F;TAB 6; PEEK F;TAB 10;CHR$ PEEK F
40 NEXT F
50 STOP
100 REM POKEING THE VACANCIES
110 INPUT A
120 PRINT A;TAB 6;
130 LET A=A+16500
140 INPUT B
150 POKE A,B
160 PRINT PEEK A
170 GOTO 110
After you've proofread the line (Figure 2-3),
- Fig 2-3 PROOFREADING THE PROVISIONAL 1 REM
POKE in the vacancies, as shown in Figure 2-4,
Code: Select all
FIGURE 2-4.
POKING THE VACANCIES
ADRESS VALUE
+16500
21 117
26 252
33 248
34 112
36 113
42 68
43 77
45 195
and proofread the final version as per Figure 2-5.
- Fig 2-5 PROOFREADING THE FINAL 1 REM
Now you'll find that the command, RAND USR 16514, changes all your program lines into a neat sequence. It probably louses up your whole program if it has any GOSUBs or GOTOs in it though.
If you want a different line number sequence, you can change the interval between line numbers by POKEing the desired number into 16539. You can change the number of the second line by POKEing your desires to 16515. (All line numbers must be less than 256, of course.) Line number one will remain unchanged, no matter what you do with the program. Now, back to our general discussion.
ZX/TS Memory
You will remember that your computer stores information in the form of "bytes," each of which is an integer between 0 and 255, inclusive. Every time you press a key (except for SHIFT, DELETE, and such), that keystroke is translated into the appropriate byte, and stored in memory. (Sometimes the computer volunteers a few extra bytes that you didn't ask for. We'll call them "housekeeping" bytes, and discuss them later on.)
To see what these bytes look like, enter and RUN the mini-program shown in Figure 2-6. Note that 16509 is the address of the first byte of the program.
16509 is the address of the first program byte. That's a number worth remembering!
Code: Select all
FIGURE 2-6. A PEEK AT THE MEMORY
200 FOR M=16509 TO 19558
210 PRINT PEEK M;" ";
220 NEXT M
What you see on the screen is the contents of the first 50 bytes in the program area of the RAM. With a few exceptions, these bytes correspond to the keystrokes that you entered. These exceptions, the housekeeping bytes that we mentioned above, are very important to the writer of machine code. Don't worry, we'll get around to them before too long.
The PEEK command lets you look at the contents of any memory location. POKE, on the other hand, lets you change the contents of any RAM location you choose, to any number you specify (0 to 255 inclusive).
To watch POKE at work, leave the program of Figure 2-6 in the computer, and enter the command:
You'll find that line
ten [sic:200] has been changed to read:
To see the significance of the bytes stored in memory, restore line
10 [200] to its original form, and change line
20 [210] to read:
RUN the program. Do you see the words and characters that you recognize from the program? The apparently meaningless stuff represents those "housekeeping" bytes.
ZX/TS Character Set
If your going to use the El Minimo Loader, described later on (which we have been using with our demonstration programs, without telling you about it), it will be useful for you to understand the computer's character set.
The entire set is printed in your Instruction book. Alternatively, you can look at the character corresponding to any number N (always 0 to 255, inclusive) by using the command:
You can print out the whole set by the program in Figure 2-7, if you prefer.
To understand the POKE exercise you just went through, enter the command:
The computer will return the symbol 7. Maybe you have deduced that 16518 is the address of the digit that you just changed from 5 to 7.
The USR Command
The trigger for a machine code routine is the symbol USR (under the L key). USR must always be followed by a memory location telling the computer where to start executing the machine code. For the moment, let's represent that address by LL.
Whenever the computer senses this trigger, as in PRINT USR LL, RAND USR LL, LET A=USR LL or the like, it reacts like a Pavlovian dog, jumping into the memory at LL, and scooting through the program like a mad fiend, at a speed of tens of thousands of operations per second. If there are no instructions to the contrary, the sequence of operations will follow the program bytes in the order in which they occur.
If the program (as per listing) encounters the RETurn instruction (address 16529 or 16533), the computer will RETurn to BASIC. If there are no valid RETurn addresses (the Stack Pointer, SP, will contain the address that the computer will RETurn to), well, you are on your own. Stand by to pull the plug. At this point, of course, you have lost everything in memory. Believe me, it's easier to include RETurn (extra, well placed RETurns won't hurt you).
If the trigger command is PRINT USR LL, the machine code routine will end by printing the value of a variable (register) known as BC. More precisely, it will print:
based on the values that the registers B and C have taken at the time the program RETurns to BASIC. If the USR command does not include PRINT, the output may be in the form of some other action based on the value of BC. For instance, GOTO, USR LL and LIST USR LL are both perfectly valid commands, as long as LL has a value that can be handled by the computer.
In all cases, the computer will enter the machine code at LL, execute the machine code until it meets a RETurn, and then try to execute the BASIC command, substituting the final value of BC for USR LL.
That's all for now, but there will be more.
Code: Select all
FIGURE 2-7. THE ZX81/TS1000 CHARACTER SET
300 FOR M=0 TO 255
310 PRINT CHR$ M;" ";
320 NEXT M