TAPESYS 
by Paul Rhodes
from Your Computer, May 1984

QUICK LOAD

Paul Rhodes with a program to stop you pulling your hair out!

TAPESYS IS A machine code program for the 48K ZX Spectrum designed to
alleviate loading frustration. Its main purpose is to decrease loading
time, but it can also be used to save and load at a slower, more
reliable rate than normal. The program also includes a head reader
routine.

The program can be loaded to any location nnnnn in the top 32K of
memory - from 32768 to 63663. Before Loading, type
	CLEAR nnnnn-1
This protects Tapesys from the Basic system and the New command. Then
load with the line:
	LOAD "TAPESYS" CODE nnnnn

Once the code has been loaded, enter the command
	PRINT USR nnnnn
This will return the address from which the program can be run with
either:
	RANDOMIZE USR (run address)
or
	RANDOMIZE USR USR nnnnn
followed by a colon, and one of the commands Pause, Save, Load,
Verify, Merge or Cat. The syntax for these commands is the same as in
Sinclair Basic, including the use of Line, Code, Screen$ and Data as
described in the Spectrum manual, the only exception being Cat - under
key 9 - which is used with no parameters. Commands can be strung
together, separated by colons, as in Basic, for example
	RANDOMIZE USR USR nnnnn: PAUSE 4:
	SAVE "Program" LINE 10: CAT

This line will call the machine code, set it to run at speed 4, Save
the program to auto-run on loading from line 10, and finally enter the
head reading section of the program.

PAUSE: This command is used to select one of 10 operating speeds,
numbered 0 to 9. The syntax for the command is:
	PAUSE (required speed option)
The approximate baud rate will then be displayed at the bottom of the
screen - see table for more accurate figures. Pause 1 is equivalent to
the normal Spectrum load/save, while Pause 9 is nearly 2.5 times as
fast. Pause 0 is a special low speed, giving greater reliability when
loading. Note that a program or other data block can not be loaded at
a different speed to that at which it was saved, so commercial
software cannot be loaded using Tapesys - except at pause 1 - unless
you make a high or low speed copy of the program. The Pause command
can be used in conjunction with any of the other recognised commands.


-------------------------------------------------------
Approximate baud rates taking normal speed at 1500 baud
-------------------------------------------------------
	Pause	Baud Rate
-------------------------------------------------------
	0	1431
	1	1500
	2	1860
	3	1929
	4	2747
	5	3048
	6	3236
	7	3304
	8	3474
	9	3635
-------------------------------------------------------


SAVE, LOAD, VERIFY, MERGE: All these commands are used in exactly the
same way as in Basic. They must follow a Rand USR statement, as shown
above, and, if the speed is to be changed, a pause n command, as
already described. For example
	RANDOMIZE USR USR nnnnn: PAUSE 3:
	SAVE "name" DATA a$(): VERIFY "" DATA a$()
If you wished to save something else, say a screen, at the same speed,
then the pause 3 command would not have to be repeated, so the line
might read:
	RANDOMIZE USR USR nnnnn: SAVE "screen" SCREEN$
	
The program has two other features worth mentioning here. First, when
the item to be loaded is found in the tape, it is indicated on the
screen by a flashing asterisk alongside the name. Secondly, if an
error occurs during loading, other than Break, the program will
instruct you to rewind the tape to the beginning of the program and
will start the loading process again.

Now to the built-in head reader, which is called via the Cat command.
This routine will load headers from the tape - provided that they were
saved at the current operating speed - and will display the
information contained in them. This information consists of the type
of data on the tape - Basic program, "bytes" file, character ($) or
number (#) array; the filename; the auto-run Line number - for a Basic
program, the start address - for a "bytes" file - or the array name;
and the length of the data block. To exit from Cat, press Break.

The Tapesys program returns to Basic on encountering any character it
does not understand. The character could be a CHR$ 13 signifying the
end of the line, a command other than Save, Load, Verify, Merge, Cat
or Pause, or perhaps a colon placed immediately after a separating
colon. This last method can be used to return to Basic in the middle
of a line. For example
	RANDOMIZE USR USR nnnnn:
	LOAD "" CODE::BEEP 1,10

To enter the program, type
	CLEAR 49999
load your favourite hexloader, or type in and run listing 1. Enter
50000 decimal as the start address and 51871 as the end address. Then
enter the bytes from listing 3.

Once it has all been typed in, save it with the command
	SAVE "TAPESYS" CODE 50000,1872
and save the Basic hexloader, in case it is needed to rectify any
mistakes. Verify them both, enter New and type in and run listing 2.
This should produce a screen picture, save it at a speed you specify,
then clear the screen and attempt to reload it. If you get an error
during loading, remember: "If at first you don't succeed ...".

If however, the computer does not act as expected, then pull the plug
to clear the computer, type
	CLEAR 49999
and reload the code and the hexloader. Add the line in listing 4
[There was no "listing 4" in the article. JimG], and then type
	RUN 100


Check the bytes

The computer will then list the bytes for you to check against listing
3. Write down the address of any errors you see, and when the listing
has finished the computer will allow you to correct these mistakes.
When finished, type in S as the address, and the corrected code will
be saved. Finally, enter New and go back to listing 2.

Finally, I shall mention a few interesting sections of the program.
[The assembler listing referred to was not printed with the article.
JimG] Most important are the SABTS - SAVE bytes - and LDBTS - LOAD
bytes - which are almost directly copied from the equivalent ROM
routines. Other major sections equivalent to ROM routines are pointed
out within the listing, and for further details you should refer to
Dr. Ian Logan's excellent Complete Spectrum ROM Disassembly, which was
invaluable during the development of the Tapesys program. The major
extra routines I have added are those dealing with relocating the
program, decoding the Basic line, changing the speed, and the head
reader. I will now deal briefly with each of these.

The RELOCATE routine at the beginning of the program first works out
the displacement of the routine from the address to which it was
originally assembled - note that if you change the Org, you must also
change the LD BC,C350 at the beginning of the program to te new
address. On entry, BC always holds the number in the USR statement.
The start of the table of addresses to be altered - RELCD - is then
calculated using this displacement.

The routine fetches in turn all the 2-byte addresses until it comes
across a 0000 at which point it returns with the Run address - PSTRT -
in BC.

It adds the displacement to find the new address, fetches the 2-byte
number from this address, adds the displacement to this number, and
replaces it in the program, then jumps back to fetch the next address
for alteration. The routine modifies itself so running it a second
time will have the same effect, except to return and Run address,
which is why Randomize USR USR nnnnn works.

Decoding the Basic line is much simpler. It involves getting the next
character in the line after the colon and comparing it to each of the
six recognised commands in turn. If it matches, the correct routine is
activated, then the next statement is considered. Otherwise, a return
is made to Basic, with CH_ADD holding the address of the character
that does not match. Basic expects either a colon or Enter, so any
other character will give error C - Nonsense in Basic.

The changing of the speed involves altering the lengths of the delay
loops in SABTS and LDBTS. The eight values for each speed are stored
near the end of the program at PAUSD, the current speed number in
PAUSNO and the 'nnnn BD' messages at MSGP. The number of possible
values recognised is limited to the value in the CP instruction near
the beginning of the Pause routine.


Alter speeds easily

You can add your own speeds, or alter those included fairly easily,
mainly by trial and error - the methods for calculating the exact
values are too complicated to go into here, except that the fourth and
seventh numbers should be identical, and the fifth number two greater.
Remember, if you add a speed, you must also add a message to the MSGP
list, terminated by 8D hex, and alter the CP instruction mentioned
above. The routine that modifies the SABTS and LDBTS routines works on
a table of displacements at PAUSD2. For example, the second number
goes six bytes after the first, and the third, 14 bytes after the
second. If you modify the program at all within the SABTS, LDBTS or
TDE routines, you may have to alter those bytes too.

The CAT routine repeatedly loads a header from the tape and prints out
the type and name as usual, then jumps to the relevant routine for the
type to print out the line number / start address / array name, before
returning to the next header on the tape.

I hope the program saves you much time and, perhaps, gives you ideas
of your own to develop.
