TS1000/TS1500 Program Chaining, Part Four

Author(s): Earl Dunnington
Pub Details: Time Designs Magazine v3 n1 (Volume 3, Issue 1)
Date: November/December 1986
Pages: 15-16

For a practical demonstration of a chained program, using the Above RAMTOP method of passing data from one module to another, I have chosen one consisting of three modules. A module to set RAMTOP (“RT”), a text entry module (“TE”), and a text LPRINT module (“PRT”). The program will allow you to enter, store above RAMTOP and print out a set of lines consisting of 32 characters per line. The number of lines in a set is available as follows:

USER RAM          LINES PER SET
2K                           41
16K                         489
32K                        1001
48K                        1513

With a full 64k memory, the 8k area between the ROM and the system variables area is available and the program could be modified to store an additional 256 lines per set.

In addition to the computer, a tape recorder, and a TS2040 or equivalent 32 column printer, you will need two tapes. Optionally, one of these can be a telephone answering machine message cassette tape–either 60 sec. (RS #43-406) or 3 min. (RS #43-407)–price: $4.95 each. These are both endless loop tapes. If you plan on adding more modules to the program, then purchase the 3 minute tape. I have not found a supplier for a longer endless tape.

Figure No.1 is the program listing for the “RT” module that sets RAMTOP to address 17096. Line 1 is set up to receive a four byte machine code routine to be POKEd by lines 141 to 144, which are then deleted. Line 10 makes the module self running when the program is recorded with the direct command: GOTO 10. Line 20 prevents a TV interupt from occuring during the execution of the program. Lines 30 and 40 POKE the desired address of RAMTOP into the system variable RAMTOP. Lines 50 thru 80 POKE the four addresses under the desired address of RAMTOP with the decimal values that must normally be there (except after a GOSUB and before a RETURN) for the computer to operate properly. Lines 90 and 100 POKE the system variable ERR_SP with the address in line 80 (i.e.; the addresses of the first item on the new Machine Stack). Line 110 calls the machine code routine that is POKEd into the REM statement (Line 1) by lines 141 to 144. Line 120 in conjunction with 140 activates the actual resetting of RAMTOP to the desired address. Line 130 automatically loads the next self running module if the tape is not stopped. Unfortunately, there is no provision in Sinclair BASIC by which you can directly address any of the Z80 internal registers. You must resort to machine code and the USR function. Looking on the left side of page 138 in the TS 1000 or page 142 in the TS 1500 User Manuals, you will find that the Z80 assembler language mnemonic corresponding to the decimal value 49 in line 141 is ld sp,NN. This means load the machine stack pointer registers S and P with the address represented by the values stored in the next two addresses (low byte then high byte). In this case the values 196 and 66 POKEd into addresses 16515 and 16516 by lines 142 and 143. Locating decimal code 201 in the same appendix, you will find that it stands for ret (return). In this case, this returns you to the next line of the BASIC program after the USR function. I hope you noticed that I did not need to use the word hexadecimal until now. Dr. Ian Logan, the leading authority on the Sinclair ZX, TS1000/1500, and Spectrum ROM, states in his book, UNDERSTANDING YOUR ZX81: “The principal behind Hex coding is once again very simple, but it takes a very long time to become fluent in its use, and even programmers of some years experience still have trouble”. Because of the interference with the existing GOSUB and machine stacks, RAMTOP must be moved down a minimum of sixty addresses or up a least two addresses using this routine.

Figure No.2 is the listing for the text entry (“TE”) module. The program is designed to use as little display as posssible, in order to be able to store more text. Top Down programming was not used in order to locate the text entry loop at the front of the program, adding to the entry speed of text. For the same reason, some memory saving techniques are not used in some places of lines 20 through 80. The dimension for T$ and the value of the variable B, are to be entered by direct commands prior to recording the program. The STOP in line 30 is typed using the shifted A key.

Figure No.3 is the listing for the LPRINT module (“PRT”). The programming is fairly straightforward. The dimension for A$ and the value for the variable B are to be entered by direct commands before recording the module.

As each of the modules will fit in 1k of RAM, in order to save both loading time and tape, set RAMTOP to 17408 before typing in each module. To do this enter:

POKE 16388,0
POKE 16389,68
NEW

I advise using a regular tape as a master, recording each module with the normal SAVE command before recording it on an operating tape using the GOTO command. Those who elected to use an endless tape as their operating must locate the place where the ends of the tape are spliced with a yellow strip. Never try to rewind an endless tape. The are designed to operate in one direction only. Be sure you turn the sprocket in the correct direction when locating the yellow splice. After locating the splice, make an audio recording, using the built-in mic, of one word only, such as “start” or “one”. This will make it easy to locate the splice again should you need to re-record the program. The three modules will just fit on a one minute endless tape without much to spare.

Set RAMTOP to 17408 with the commands given above. Type in the listing of Figure No.1. After checking the program against the listing, record it on the master tape using SAVE “RT”. Now use the command GOTO 141 which will poke the machine code into the REM statement. Delete lines 141 to 144. Record the second version of the module on the master tape using the SAVE command. Without rewinding, remove the master tape from the recorder, replacing it with the operating tape and recording the module using the command GOTO 10. When the diagonal LOAD command lines appear on the screen, stop the tape. Without rewinding, remove the operating tape, replacing it with the master.

Again set RAMTOP to 17408. Type in the listing of Figure No.2. Check the program against the listing. Enter the direct commands:

DIM T$(32)
LET B= (as listed below)
User RAM      B
2K RAM    18409
16K RAM   32745
32K RAM   49129
48K RAM   65513

Record this module on the master tape using SAVE “TE”, then on the operating tape using GOTO 140. When STOP THE TAPE appears on the screen then stop the tape. Replace the operating tape with the master tape.

As the TE module does not change RAMTOP, you can clear the program using NEW. Type in the listing in Figure No. 3 for the “PRT” module. After checking for typing errors, enter the direct commands:

DIM A$(1)
LET B=(as listed above).

Those using endless tape, replace REWIND TAPE in line 100 with spaces. Save this module on the master tape using SAVE “PRT” then on the operating tape using GOTO 10. When STOP TAPE appears on the screen, then stop the tape.

To operate the program, turn off the computer and then power up. Those not using endless tape must rewind the operating tape. Enter the direct command: LOAD “RT”. Then start the tape. When the second module has loaded and STOP TAPE appears on the screen, stop the tape. When the cursor appears on the screen you can start typing in text. The left hand quote symbol marks the end of a 32 character line. After checking the text, use the enter key. Corrections must be made before the enter key is pressed. Spaces to fill out a line need not be typed. Any characters over 32 will be dropped. To stop text entry use the shifted STOP on the A key as the first entry of the next line. Follow the directions on the screen to load the LPRINT module. After the text is printed you have the option of printing another copy or reloading the text entry module to enter a new set of text.

In the CONCLUSION of this series, I will cover how the values for RAMTOP and for the variable B were determined.

FIGURE NO. 1

   1 REM 1234
10 SAVE "RT"
20 FAST
30 POKE VAL "16388",VAL "200"
40 POKE VAL "16389",VAL "66"
50 POKE VAL "17095",VAL "62"
60 POKE VAL "17094",VAL "0"
70 POKE VAL "17093",VAL "6"
80 POKE VAL "17092",VAL "118"
90 POKE VAL "16386",VAL "196"
100 POKE VAL "16387",VAL "66"
110 RAND USR VAL "16514"
120 GOSUB VAL "140"
130 LOAD "TE"
140 RETURN
141 POKE 16514,49
142 POKE 16515,196
143 POKE 16516,66
144 POKE 16517,201

FIGURE NO. 2

  10 INPUT T$
20 FOR N=1 TO 32
30 IF T$(1)=" STOP " THEN GOTO
VAL "90"
40 POKE A,CODE T$(N)
50 LET A=A+1
60 IF A=B THEN GOTO VAL "90"
70 NEXT N
80 GOTO 10
90 POKE A,VAL "227"
100 PRINT AT SIN PI,SIN PI;"PRE
SS ANY KEY THEN START TAPE"
110 PAUSE VAL "32768"
120 CLS
130 LOAD "PRT"
140 SAVE "TE"
150 PRINT AT SIN PI,SIN PI;"STO
P TAPE"
160 PAUSE VAL "120"
170 PRINT AT SIN PI,SIN PI;"ENT
ER TEXT"
180 LET A=VAL "17097"
190 GOTO VAL "10"

FIGURE NO. 3

  10 SAVE "PRT"
20 PRINT AT SIN PI,SIN PI;"STO
P TAPE"
30 PAUSE VAL "120"
40 PRINT AT SIN PI,SIN PI;"PRI
NT TEXT? ENTER Y/N"
50 INPUT A$
60 CLS
70 IF A$="N" THEN GOTO VAL "10
0"
80 IF A$="Y" THEN GOTO VAL "14
0"
90 GOTO VAL "40"
100 PRINT "REWIND TAFE,PRESS KE
Y,START TAPE"
110 PAUSE VAL "32768"
120 CLS
130 LOAD "TE"
140 FOR N=VAL "17097" TO B
150 IF PEEK N=VAL "227" THEN GO
TO VAL "180"
160 LPRINT CHR$ PEEK N;
170 NEXT N
180 LPRINT
190 GOTO VAL "40"