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.