TWO INTO ONE WILL GO (ZX81)
By Nick Goldman and Jerry Seabridge
from Sinclair User 17 (August 1983), page 86

One problem until now with the ZX-81 has been that when a program is loaded
from tape any previous program in the computer is NEWed and lost. That means
that two programs, each saved separately on tape, could not be merged into
one program. That would clearly be useful for, say, writing subroutines which
could be written and tested separately and then merged with a main program on
a different tape. The merge feature has been included on the Spectrum and the
routine we developed means that now two programs can quickly be combined into
one, with few restrictions on the programs so merged, on the ZX-81.

The procedure used is outlined and explanations of the important steps are
given. The basic theory is to reserve space in the 16K memory by putting
RAMTOP, the address of the first byte above the Basic system area, to a value
below the normal 16K value of 32768, and then transferring the first program,
byte by byte, into the reserved space.

The second program is then entered, along with a routine which will retrieve
the first program, add it to the second program, and correct the values of
line lengths  the third and fourth bytes in each program line, see page 171
of the ZX-81 manual - and so on, so that the program will not crash or behave
abnormally. Here is the procedure:

First, the user's first program is entered from cassette tape. Restrictions
on the program are that the line numbers must all be lower than 9899 but
greater than the greatest line number of the user's second program, yet to be
loaded. That is so that when the two programs are merged eventually, the line
numbers will be in the correct order and the computer will not crash. To this
program must then be added the final line:

   XXXX REM END

where XXXX is the line number, which must be big enough to make it the last
line of the first program but must still be less than 99. When the program is
entered, the following direct commands must be entered, in the correct order:

   LET X=PEEK 16396+256*PEEK 16397-1
   LET Y=49230-X
   PRINT Y

and the value of Y should be written or remembered. Then:

   POKE 16388,Y-256*INT(Y/256)
   POKE 16389,INT(Y/256)

X, the value of D FILE - see chapter 27 of the ZX-81 manual - minus one, is
the last byte of the program and is thus the last byte which must be
transferred. Y is the location where the first byte of the program will be
stored - 49230 was chosen as it leaves a little spare room before the end of
the computer's 16K; and RAMTOP is poked to that value - the two POKE commands
- so that when NEW is executed the transferred bytes will not be erased.

That can be verified by typing:

   PRINT PEEK 16388+256*PEEK 16389

which should give the value of Y which was written.

Next the following routine, lines 9900 to 9920, is added to the first
program:

   9900 FOR F=6509 TO X
   9910 POKE Y-16509+F,PEEK F
   9920 NEXT F

Then type:

   GOTO 9900

followed by:

   NEW

as soon as the computer has finished the loop starting in line 9900.

That routine copies the bytes of the first program into the memory, starting
at the location given by the variable Y. NEW is executed to clear everything
except those stored bytes. To verify that the first program is still stored
above RAMTOP, type:

   PRINT PEEK (your value of Y)*256 + PEEK (your value of Y + 1)

That should return with the first line number of your first program.

The next stage is to load your second program from tape. The program should
have all of its line numbers greater than 13 but smaller than the smallest
line number in the first program, so that, again, the eventual lines when
merged will be in the correct order.

Once that is done type in the following:

   1 POKE 16388,0
   2 POKE 16389,128
   3 FOR F=Y TO 99999
   4 IF PEEK F<>234 OR PEEK (F+1)<>42 OR PEEK (F+2)<>51 OR PEEK (F+3)<>41 OR
PEEK (F+4)<>118 THEN NEXT F
   5 FOR G=Y TO F+3
   6 POKE G+K-Y,PEEK G
   7 POKE G,0
   8 NEXT G
   9 POKE G,0
   10 FOR G=F+K-Y+4 TO 99999
   11 IF PEEK G<>118 THEN NEXT G
   12 POKE F+K-Y-2, PEEK (F+K-Y-2)-F+G-K+Y-4
   13 STOP

and then the following direct commands:

   LET Y=(your previous value of Y)
   LET K=PEEK 16396+256*PEEK 16397

and after those, REM statements must be typed-in, as follows:

   9900 REM XXXXXXXXXXXX
   XXXXXXXXXXXXXXXXXXXXX
   XXXXXXXXXXXXXXXXXXXXX
   XXXXXXXXXXXXXXXXXXXXX
   XXXXXXXXXXXXXXXXXXXXX
   XXXX
   9901 REM (100 Xs)

Each REM statement should include 100 Xs and there should be 10 such REM
statements for each 1K of the first program which has already been copied
above RAMTOP.

After one REM statement has been typed-in, the other can be duplicated
quickly by using the EDIT facility and adding 1 to the line number each time
the line is copied. In that manner the correct number of REM statements can
be produced quickly.

As soon as the REM lines have been typed-in, the command GOTO 1 should be
entered. The routine - lines 1 to 13 - will then transfer the first program
back from above RAMTOP back to the main program, and when the report code
9/11 - STOP executed in line 13 - is seen, the final. The merged program can
be tidied by deleting lines 1 to 13 and any left-over REM lines after line
9900 may also be removed.

This is how the final 13-line routine works:

The first two lines POKE RAMTOP to its usual (16K) value of 32768, that is so
that as the routine progresses, the space where the first lines were stored
can be over-written once those lines have been re-transferred, and that
enables longer programs to be merged.

Lines 3 to 4 check for the location of the REM command in the line:

   XXXX REM END

at the end of the first program, that being the marker used to indicate the
end of the first program, and the loop passes to line 5 with the variable F
being the location of this REM command.

The variable K which was defined previously by direct command is the location
of the first byte in the first REM line - line 9900 - and is the location
into which the first byte of the first program is POKEd. The REM statements
are used to reserve space below the Display File - we spent some time trying
to POKE the system variable D FILE but with no success - and the first
program is simply POKE into the locations occupied by the REM lines. Thus
lines 5 to 8 POKE the first program into the space reserved by the REM lines,
except for the CHR$ 118 which indicates the last character in the line:

   XXXX REM END

Lines 7 and 9 are to clear the space which was occupied by the first program.

Finally, lines 10 and 11 count the extra Xs left over from the last REM line
POKEd into and line 12 POKEs the new length of the last line into the
appropriate location. That means that the line

   XXXX REM END

will finally become:

   XXXX REM END (+ left-over Xs from the REM line)

e.g., XXXX REM END XXXXXXXXXXXXX

and the appearance of this is an indication that the merging is successful,
Of course, if the final REM line had exactly the correct number of Xs, the
line will remain

   XXXX REM END

Using this routine we believe that any two Basic programs can be merged into
one. Of course, that does not extend the limit of 16K imposed by having only
a 16K RAM pack and it should be noted that any variables stored will be lost
as the procedure is followed.

A large number of direct commands have been used where they could have been
included in the two routines we have given since if the procedure is to be
worthwhile it should be as short as possible.

For long programs it is obviously superior to run the two routines in FAST
mode but that is not very informative if for any reason the computer should
crash. Therefore until you are confident that you have the procedure correct,
we suggest that you take the extra time to run the routines in SLOW mode and
keep an eye on the computer, even if that takes a long time.

[The article 'Two Into One Will Go' is a procedure to merge two ZX81 BASIC  ]
[programs. I was going to type this in so that SU August 1983 for the ZX81  ]
[was also complete, but I found that this is not possible. The article      ]
[describes a procedure that requires the lines of BASIC shown to be typed in]
[after loading the users programs. It is therefore not possible create a    ]
[meaningful .P file.                                                   PaulF]