Making Backups for Machine Language Tapes

See all articles from SYNC v3 n1

Not long ago I bought a cassette of utility routines for my 16K ZX81. Although the routines on the tape were just what I needed, there was one problem: the program was in machine language and once LOADed above RAMTOP it ignored my SAVE commands. If something happened to that tape I was out of luck since I had no backup — unless I could make one by some method other than SAVE.

There are two methods which can be used to make a backup.

1. Copying to a Second Tape

The first technique is to simply copy the tape onto a second tape. This requires either a tape copier or a second tape recorder.

Place the original tape in Recorder 1 and a blank tape in Recorder 2. Use one of the Sinclair recorder leads to connect the earphone (output) jack of Recorder 1 to the microphone (input) jack of Recorder 2. Set Recorder 2 to RECORD and PAUSE, and (if it has one) the automatic level control (ALC) to OFF. Set the volume controls of each recorder to midrange. Start RECORDing on the second, then PLAYing on the first. After the recording is complete, try LOADing the program as usual with your recorder. Very likely you will have to try several different volume settings on your copying set up before getting a LOADable copy. A recording level meter on Recorder 2 helps. I found that I could not get a satisfactory recording without the ALC of Recorder 2 OFF.

2. Copying with PEEK and POKE

The second technique uses the PEEK and POKE facilities of the ZX81. The program to do this is Listing 1. Like the machine language routines that you see published, the software that I purchased is LOADed into memory above RAMTOP. RAMTOP is the address of the first nonexistent byte at the upper end of memory, which means that you cannot store anything at or above it—at least that is what the computer thinks. However, the address of RAMTOP is stored in the two bytes with addresses of 16388 and 16389. You can change these two bytes with POKE, and fool the computer into thinking that some existing memory is nonexistent. This memory is hidden from Basic and so is protected for machine language use.

PRINT PEEK 16388 + 256 * PEEK will tell you the address of RAMTOP, which is normally 32768 with the 16K RAM attached. The bytes stored at 16388 and 16389 (found by PEEKing each location) are 0 and 128. Note that 0 + 256 * 128 = 32768. Before loading a machine language tape, one or both of these bytes are changed by POKEing in new values to give RAMTOP a new, lower, address to correspond to the number of bytes required for the machine language routine. For example, the software I purchased comes with instructions to POKE 16389,124. So RAMTOP is now 0 + 256 * 124 = 31744, a difference of 32768 − 31744 = 1024 bytes. If you had a program with instructions to POKE 16388,100 and POKE 16389,125, then the new address of RAMTOP is 100 + 256 * 125 = 32100, and the number of bytes protected is 32768 − 32100 = 668.

To make a copy of your machine language software, LOAD the program according to the instructions which accompany it. Then ENTER or LOAD the program in Listing 1. RUN the program and ENTER the requested data. Because the program runs in FAST, the screen blanks out while the program PEEKs the machine code into the variable array E. When the program stops with 9/310, prepare to SAVE the program. To SAVE, enter GOTO after you have begun recording. When you LOAD this SAVEd tape (LOAD “P”) after altering RAMTOP as your machine language program requires, it is self-RUNning so the screen will blank out while the code is POKEd in above RAMTOP.

If you want to SAVE a copy of Listing 1 without any machine language code so that you can LOAD it in for a variety of machine language routines, enter SAVE “P”, not GOTO 370.

The program as shown in Listing 1 is meant to be self documenting and user-friendly. But this is not necessary for operation of the program. Since this probably makes the program too large for a 1K machine, and makes it take longer to LOAD in any case, you might want to shorten it a bit. You can easily calculate the new address of RAMTOP and the number of bytes protected. So you could easily eliminate all REMs and replace lines 10 through 260 with

10 FAST
20 LET C = (calculated bytes protected)
30 LET D = (calculated new RAMTOP ) − 1

In summary, you can make back up tapes for machine language routines which are LOADed above RAMTOP by copying your original tape from one recorder to a tape in a second recorder, or you can use a single recorder and the Basic program in Listing 1 to PEEK out the code for SAVEing and POKE it back in when LOADing from your back-up tape.

Listing 1.

  40 FAST
50 PRINT TAB 7;"ML PROGRAM BACKUP"
60 PRINT
70 REM "ENTER PARAMETERS FOR YOUR ML PROGRAM"
80 PRINT "ENTER THE NUMBER TO BE POKED"
90 PRINT TAB 10;"INTO 16388",,
100 PRINT TAB 7;"IF NONE, ENTER 0"
110 INPUT A
120 CLS
130 PRINT "ENTER THE NUMBER TO BE POKED"
140 PRINT TAB 10;"INTO 16389",,
150 PRINT TAB 7;"IF NONE, ENTER 0"
160 INPUT B
170 CLS
180 PRINT "ENTER YOUR NORMAL RAMTOP"
190 PRINT "(17408 FOR 1K, 32768 FOR 16K)"
200 INPUT R
210 CLS
220 REM "C = NUMBER OF BYTES PROTECTED"
230 LET C=R-(A+256*B)
240 REM "D = LAST BYTE BEFORE NEW RAMTOP"
250 LET D=(A+256*B)-1
260 REM "STORE MACHINE LANGUAGE IN E"
270 DIM E(C)
280 FOR N=1 TO C
290 LET E(N)=PEEK (D+N)
300 NEXT N
310 STOP
320 REM "PUT ML ABOVE RAMTOP"
330 FOR N=1 TO C
340 POKE (D+N),E(N)
350 NEXT N
360 STOP
370 SAVE "P"
380 GOTO 0330

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