Extensions to Basic

See all articles from SYNC v3 n5

Introduction

The Z80 microprocessor is the brain of your Sinclair computer. By itself, however, it is not very smart. It has no capacity to understand commands like PRINT and LET. When you use these commands, you are not directly telling the Z80 what to do. What the commands do is give instructions to the interpreter. The interpreter is itself a computer program and is located in memory locations 0 to 8191. It is written in a language the Z80 can understand called “machine language” or “machine code.” This language consists of numbers between 0 and 255. A table of these numbers and their mnemonics can be found in the Basic manual. A mnemonic is a label assigned to each machine code that more or less describes what it does.

We can write our own machine code programs, but it is not an easy process. The main advantage to writing them is that they execute very fast. They also do not take up much memory and sometimes are more flexible than Basic. The three Basic commands that deal with machine code are PEEK, POKE, and USR. PEEK allows you to examine a memory location and POKE allows you to change it. The USR routine tells the Z80 to start executing machine code at a particular location. Before you can use the POKE command to put numbers into memory you must first reserve an area for them. The Basic manual gives a detailed discussion of how to do this.

Presented below in Figure 1 are four machine code routines which imitate features that are standard on more expensive computers and that will extend your 8K ROM by adding new commands.

Figure 1. Summary of new routines.

The Routines
COMMAND               DESCRIPTION
10 RAND USR IV        Convert every character on screen to its
                      inverse.

10 PRINT USR FM       Print how many free bytes are in memory.

10 GOTO Z             Create an inverse program listing.

10 REM 10.3, SIN A,   These are two pseudo-DATA statements.
                      They can be placed anywhere in your
500 REM ABE,IKE       program. Each entry can be numeric or
                      string and is followed by a comma.

10 RAND USR RS        Perform the RESTORE command. This
                      must be used before any data is read. It can
                      also be used to read data more than once.

10 LET A$=""          READ the next data entry. Omit line 30 if
20 RAND USR RD        you are reading a string.
30 LET A=VAL A$

Use Listing 1 to enter the machine code listed in Figures 2 through 5. Verify your articles with both the addresses and the checksums printed by the program. If you make a mistake, simply press to enter to erase the last entry. 1K users will have to use CONT when screen overflow causes the program to stop. After you type the last number, the program should stop. You should then delete all the lines of the program except the first by typing in the line number and ENTER.

With the one line still in memory, type and RUN Listing 2. It will save itself to tape, so prepare your recorder in advance. After the SAVE, press ENTER. The screen will flicker for a moment and Listing 2 will be gone. The machine code, however, will have been relocated to the top of whatever memory size you have.

Listing 1. Machine Language Loader.

  1 REM ***************************************************************************************************************************************************
10 LET A=VAL "16514"
15 LET B=0
20 SCROLL
30 PRINT A;
40 INPUT A$
50 IF LEN A$ THEN GOTO VAL "100"
60 LET A=A-SGN PI
70 IF A<VAL "16514" THEN GOTO 10
80 LET B=B-PEEK A
90 GOTO 20
100 POKE A,VAL A$
110 LET B=B+PEEK A
120 PRINT TAB 10;A$;TAB 20;B
130 LET A=A+SGN PI
140 IF A<=16661 THEN GOTO 20

Listing 3 demonstrates the use of the various commands. It also declares the variables RS, RD, IV, FM, and Z. Note that Z is read from a REM statement. Start your recorder before running Listing 3, because it will also SAVE itself to tape. Afterwards you may want to delete all the lines except the last two, and SAVE result. If you have not used NEW or CLEAR, then the variables will go to tape also.

The procedure for LOADING the new commands is simple: LOAD Listing 2. Press ENTER. LOAD Listing 3 or its shortened version described above. Caution: This short version will only work if you are using the same memory configuration you were using before the SAVE. It is a good idea to hold onto all of Listing 3 in case you need it.

Practical Uses

If you have a long print out and little memory, you will probably get an error “4” due to screen overflow. This can be prevented with a line such as the following:

50 IF USR FM < 100 THEN CLS

This will let you avoid having to type “CONT” to get your program going again. It might be a little annoying, however, if the screen clears without your having a chance to read it. So, perhaps the following two lines would be better:

50 IF USR FM < 100 THEN PAUSE 40000
60 IF USR FM < 100 THEN CLS

This stops the program until you have had a chance to read the screen. Pressing any key will get it going again and will also clear the screen. Which version you use depends upon your application.

You can use the instant inverse routine to create some interesting visual effects. Listing 4 is a good attention catcher and would be useful in a shop window or in an exhibit at a computer fair. The first two lines create a collapsed display file and should be used only if you are using an expansion memory. Listing 5 shows how to create a full display (2K version). Listing 6 is a 1K version of the same thing.

On the television set that I use, inverse characters are much easier to read than normal ones. This is why I have included a “GOTO Z” feature. For me it is the only way I can read my programs. Not everyone will have this problem, but I am sure there are a few who do.

Listing 2.

 10 SAVE "2"
20 LET A=VAL "PEEK 16388+256*PEEK 16389"
30 INPUT B$
40 POKE 16515,129
50 LET A=A-120
60 LET B=A+3
70 LET C=VAL "16550"
80 GOSUB VAL "130"
90 LET B=A+29
100 LET C=VAL "16566"
110 GOSUB 130
120 PRINT USR 16634
130 LET E=VAL "INT (B/256)"
140 LET D=B-E*256
150 POKE C,D
160 POKE C+SGN PI,E
170 RETURN

Listing 3.

   1 SAVE "3"
10 LET RS=VAL "PEEK 16388+256*PEEK 16389"
20 LET RD=RS+42
30 LET FM=RS+79
40 LET IV=RS+94
50 REM COMMANDS :(USR ) FM IV RS RD , AND GOTO Z,9998,
60 PRINT USR FM
70 RAND USR RS
75 FOR L=1 TO 3
80 LET A$=""
90 RAND USR RD
100 IF L<3 THEN PRINT A$
105 NEXT L
110 LET Z=VAL A$
9998 LIST
9999 RAND USR IV

If you have to do any kind of record keeping, then the restore and read routines should be helpful. You can use the REM statements to store important telephone numbers, dates, appointments, birthdays, etc. They could also hold inventories, screen coordinates for plotting, machine code, or words like “CAT” and “DOG” for a computer version of “Hangman.”

Listing 7 is an example of a computer telephone directory that runs in 1K. The other ideas mentioned above I will leave as exercises for interested programmers. Feel free to substitute other phone numbers in line 10. This same program can be used to store other kinds of data where one item is directly related to another. An English to Spanish translator would be an example.

Listing 8 will graph any function you give it. First, you must input the function in terms of X. For example, if you wanted to graph (f(X) = 4X²+3X+2) then you would input 4*X*X+3*X+2. Then you have to input the lower and upper limits on X. If you were plotting a sine curve, for example, you would probably want to use limits of zero and two pi. The nice thing about this program is that the vertical limits are calculated automatically. This makes function plotting quite a bit easier.

Stored on REM statements are some functions you can select instead of your own. Each function is followed by its lower and upper limit. If you only have 1K RAM then you will not be able to use this feature. If this is the case, then enter the program without the USR routines in memory and omit lines 10, 20, 25, 35, 45, 80, 230, 300, and every line above 300.

You cannot plot more than one function on the screen at the same time, but none of the prompt messages will appear after the first graph. Prompt messages also do not appear on the 1K version described above.

I hope that these routines and programs are of use to you. If you have other ideas on how to extend the capabilities of this little computer in this way, drop a line to SYNC.

Figure 2. Restore and READ String Routines.

Assembly Listing                 Address   Machine Code    Checksum
RESTORE LD HL,16634 16514 33 250 64 347
FIND LD A,CODE "REM" 16517 62 234 643
LD BC,65536 16519 1 255 255 1154
CPIR 16522 237 177 1568
LD BC,5 16524 1 5 0 1574
AND A 16527 167 1741
SBC HL,BC 16528 237 66 2044
LD A,118 16530 62 118 2224
CP (HL) 16532 190 2414
JR Z,BELOW 16533 40 5 2459
ADD HL,BC 16535 9 2468
STASH LD (16507),HL 16536 34 123 64 2689
RET 16539 201 2890
BELOW ADD HL,BC 16540 9 2899
JR FIND 16541 24 230 3153
READ
CHARACTER LD HL,(16507) 16543 42 123 64 3382
LD A,118 16546 62 118 3562
CP (HL) 16548 190 3752
CALL Z,FIND 16549 204 33 64 4053
LD A,(HL) 16552 126 4179
INC HL 16553 35 4214
JR STASH 16554 24 236 4474
READ
STRING LD HL,(E-LINE) 16556 42 20 64 4600
DEC HL 16559 43 4643
PUSH HL 16560 229 4872
DEC HL 16561 43 4915
DEC HL 16562 43 4958
EX (SP),HL 16563 227 5185
LOOP PUSH HL 16564 229 5414
CALL READ
CHARACTER 16565 205 159 64 5842
POP HL 16568 225 6067
LD B,CODE"," 16569 6 26 6099
CP B 16571 184 6283
COMA DONE JR Z,DONE 16572 40 13 6336
LD (HL),A 16574 119 6455
INC HL 16575 35 6490
INC LEN$ EX (SP),HL 16576 227 6717
INC (HL) 16577 52 6769
JR NZ,NO CARRY 16578 32 3 6804
INC HL 16580 35 6839
INC (HL) 16581 52 6891
DEC HL 16582 43 6934
NO CARRY EX (SP),HL 16583 227 7161
DO MORE AND A 16584 167 7328
JR NC,LOOP 16585 48 233 7609
DONE EX (SP),HL 16587 227 7836
POP HL 16588 225 8061
NOP 16589 0 8061
JP ROM 16590 195 157 20 8433

Figure 3. FREE MEMORY Routine.

Assembly Listing                 Address   Machine Code    Checksum
FREE MEM LD HL,(STKEND) 16593 42 28 64 8567
LD B,H 16596 68 8635
LD C,L 16597 77 8712
LD HL,0 16598 33 0 0 8745
ADD HL,SP 16601 57 8802
CP A 16602 191 8993
SBC HL,BC 16603 237 66 9296
LD B,H 16605 68 9364
LD C,L 16606 77 9441
RET 16607 201 9642

Figure 4. INSTANT REVERSE Routine.

Assembly Listing                 Address   Machine Code    Checksum
IV LD HL,(D-FILE) 16608 42 12 64 9760
LD B,H 16611 68 9828
LD C,L 16612 77 9905
LD D,59 16613 22 59 9986
SLA D 16615 203 34 10223
LOOP LD HL,(VARS) 16617 42 16 64 10345
LD A,(BC) 16620 10 10355
CP D 16621 186 10541
JR Z,AGAIN 16622 40 3 10584
ADD A,128 16624 198 128 10910
LD (BC),A 16626 2 10912
AGAIN INC BC 16627 3 10915
CP A 16628 191 11106
SBC HL,BC 16629 237 66 11409
JR NZ,LOOP 16631 32 240 11681
RET 16633 201 11882

Figure 5. RELOCATION Routine.

Assembly Listing                 Address   Machine Code    Checksum
RELOCATE LD HL,(RAMTOP) 16634 42 4 64 11992
LD BC,-120 16637 1 136 255 12384
ADD HL,BC 16640 9 12393
PUSH HL 16641 229 12622
PUSH HL 16642 229 12851
EXX 16643 217 13068
POP BC 16644 193 13261
EXX 16645 217 13478
LD HL,16514 16646 33 130 64 13705
POP DE 16649 209 13914
LD BC,120 16650 1 120 0 14035
LDIR 16653 237 176 14448
EXX 16655 217 14665
DEC BC 16656 11 14676
OUT 253,A 16657 211 253 15140
JP NEW 16659 195 203 3 15541

Listing 4.

 1 SAVE "LISTING 4"
2 LPRINT "LISTING 4",,,,"USE FIRST TWO LINES ONLY WITH EXPANSION MEMORY",,,,"GRAPHICS KEYS IN LINE 30:5374TY5T55885E4W64261YT58",,
3 LLIST 10
4 LPRINT " SLOW ",," GOTO 0"
5 STOP
10 POKE 16389,68
20 CLS
30 PRINT AT VAL "9",VAL "2";"[graphics]";AT VAL "10",VAL "2";"[graphics]";AT VAL "11",VAL "2";"[graphics]"
40 FOR Z=NOT PI TO CODE "+"
50 UNPLOT Z+Z,Z
55 UNPLOT Z+Z+SGN PI,CODE "F"-Z
60 NEXT Z
63 RAND USR IV
70 GOTO CODE "Z"

Listing 5.

 1 SAVE "LISTING 5"
2 LPRINT "LISTING 5",,,,
3 LLIST 10
4 LPRINT " GOTO 0"
5 STOP
10 POKE 16389,255
20 CLS
30 SLOW
40 RAND USR IV
50 FOR A=1 TO 30
60 NEXT A
70 GOTO 40

Listing 6.

 1 SAVE "LISTING 6"
2 LPRINT "LISTING 6",,,,
3 LLIST 10
4 LPRINT " SLOW ",," GOTO 0"
5 STOP
10 FOR Z=NOT PI TO CODE "("
20 PRINT TAB CODE "S"
30 NEXT Z
40 RAND USR IV
50 GOTO CODE "A"

Listing 7.

  1 SAVE "LISTING 7"
2 LPRINT "LISTING 7",,,,
3 LLIST 10
4 LPRINT " GOTO 0"
5 STOP
10 REM JOHN,[phone number omitted],MIKE,[phone number omitted],CRUMP,[phone number omitted],
20 PRINT " INPUT NAME"
30 INPUT A$
40 RAND USR RS
50 LET B$=""
60 RAND USR RD
70 IF B$="DATA OUT" THEN GOTO VAL "20"
80 LET C$=""
90 RAND USR RD
100 IF B$<>A$ THEN GOTO VAL "50"
110 PRINT C$
120 GOTO VAL "20"
130 REM DATA OUT,

Listing 8.

   1 SAVE "LISTING 8"
2 LPRINT "LISTING 8",,,,
3 LLIST 10
4 LPRINT " GOTO 0"
5 STOP
10 LET F=SGN PI
20 GOSUB CODE " COPY "
25 IF F THEN PRINT "FUNCTION"
30 INPUT A$
35 IF F THEN PRINT "LOWER LIMIT"
40 INPUT X
45 IF F THEN PRINT "UPPER LIMIT"
50 INPUT A
60 LET K=X
70 FAST
80 IF F THEN CLS
85 LET F=NOT PI
90 LET DX=(A-X)/CODE "Z"
100 LET H=VAL A$
110 LET L=H
120 FOR I=NOT PI TO CODE "Z"
130 IF H<VAL A$ THEN LET H=VAL A$
140 IF L>VAL A$ THEN LET L=VAL A$
150 LET X=X+DX
160 NEXT I
170 LET X=K
180 SLOW
190 FOR I=NOT PI TO CODE "Z"
200 PLOT I,VAL "43"*(VAL A$-L)/(H-L)
210 LET X=X+DX
220 NEXT I
230 GOSUB VAL "400"
240 GOTO VAL "50"
300 RAND USR RS
310 FOR A=VAL "-2" TO VAL "10"
320 FOR B=NOT PI TO VAL "24" STEP VAL "8"
330 LET A$=""
340 IF B OR A<NOT PI THEN RAND USR RD
350 IF NOT B AND A>-SGN PI THEN LET A$=STR$ A
360 PRINT TAB B;A$;
370 NEXT B
380 NEXT A
390 REM ***,SELECT,OPTION,***,OPTION,FN,RANGE,, INPUT ,YOUR,OWN FN,
400 INPUT B
420 IF NOT B THEN RETURN
430 RAND USR RS
440 FOR A=SGN PI TO VAL "3*B+8"
450 LET A$=""
460 RAND USR RD
470 NEXT A
480 FOR A=-SGN PI TO SGN PI
491 LET B$=""
500 RAND USR RD
510 IF A<NOT PI THEN LET A$=B$
520 IF NOT A THEN LET X=VAL B$
530 NEXT A
540 LET A=VAL B$
550 GOTO VAL "60"
1000 REM SIN X,0,2*PI,COS X,0,2*PI,TAN X,-1,1,SIN X+SIN (2*X)+SIN (3*X),0,4*PI,ASN X,-1,1,LN X,.1,2.7,EXP X,-1,1,ABS (X-INT X-.5),0,3,1/X,.1,2,EXP -(X*X),-2,2,

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.