CODE COMPRESSOR 1 - LERM SOFTWARE INTRODUCTION This manual together with the program is subject to COPYRIGHT laws, and other than for PERSONAL USE ONLY, may not be reproduced in any form. Apart from the legal aspect we ask that you consider the time and effort that has gone into the program, together with the cost of advertising - surely the program is well worth paying for!! We haven't secured CC1 so that you can easily transfer it to a drive if you have one. For those not satisfied with CC1 you must return the program STRAIGHT AWAY in order to claim a full refund What does the program do? Lerm CODE COMPRESSOR 1 (CC1) is a utility which will shrink the machine CODE of your programs (which can be expanded again once loaded) and thereby save on both space and loading time. Reductions in space are achieved by identifying blocks of IDENTICAL bytes and replacing them by 1-3 bytes depending on circumstances. Using this utility, screen displays can be reduced by typically 20-60%. One of the most valuable consequences of this compression is that it can aid the transfer to Micro, Wafa, or Disc drive, of some long programs which cannot be loaded DIRECTLY from your drive as they stand. The programs which cause these problems are those which have a large block of machine code with a low load address (the bytes start loading into address 2500 or lower). Such blocks cannot, for example, be loaded from m/drive, since they occupy the space required for m/drive channels and buffers (even more space is required by the Wafa-drive). By using CC1 the machine code block can be reduced in size so that it can be loaded directly from your drive. After loading in the compressed block, a single RANDOMISE USR call will "reclaim" the extra bytes used by your drive (i.e. it restores the system variables to their "power up" values). RAMTOP can then be reset to its required value (via a suitable CLEAR instruction) and the block of code expanded by another RANDOMISE USR call, and finally you may return to basic or jump directly to your machine code. LOADING IN CC1 Simply rewind the tape to the start. Enter LOAD"", press PLAY on your recorder and then wait until loading is complete. If you want to transfer the program to your drive then adopt the following procedure, altering the syntax to suit your drive system. In the example below we have assumed that you have a m/drive. (i) Enter CLEAR 39999. (ii) Enter LOAD "" CODE 40000 and play in the CC1 bytes. After loading is complete type in and run the following program, adapted as required. 10 PAPER 0: INK 0: BORDER 0: CLS 20 LOAD *"m";1;"cc1c" CODE 16384 30 RANDOMISE USR 16384: STOP 40 SAVE *"m";1;"cc1c" CODE 40000,2048 50 SAVE *"m";1;"cc1" LINE 10 Now enter RUN 40 and the program will save itself. Line 40 saves 2048 bytes of machine code, and line 50 the whole of the basic program. Line 10 clears the screen, line 20 loads is "cc1c" CODE into address 16384, and line 30 runs the cc1 program. OPERATING INSTRUCTIONS (a) Loading in your program Once loaded, CC1 always lists the available options. It will read in blocks of bytes only; BASIC and arrays cannot be tackled by CC1. Also because CC1 uses a number of system variables it is essential that these are not corrupted. Therefore, starting addresses of less than 23800 are not permitted, and the maximum block size than can be tackled by CC1 is 41736 bytes. The available loading options are: l - Load a block of bytes, taking both the START ADDRESS and the length from the HEADER. If the start address is less than 23800 an error message is given. Use this key to load if the code has a header, and that header indicates a loading in address of at least 23800 (the Lerm Advanced Header reader program "reads" headers). Any attempt to load a block of code at a low address will result in an error message. r - Relocate the next block of bytes, taking its length from the header. You will be prompted to provide a suitable start address at which the block is to be loaded. This option is used for code with a normal header, buy you must decide where CC1 should load the code. When using the "r" key to load, and you enter 28000 as the "START ADDRESS" this is equivalent to LOAD "" CODE 28000. h - load in a Headerless block of bytes. You will be prompted for a suitable "START ADDRESS" at which the block is to be loaded, just as in "r" above. This option does not check the initial parity byte which is loaded into START ADDRESS minus ONE, e.g. if you choose a START ADDRESS of 25000 for your bytes to be loaded, they will indeed load into 25000 and beyond, but IN ADDITION address 24999 will be corrupted, and contain the so called parity byte. For CODE this is usually 255. An error message will occur in the event of a tape loading error. THIS NEVER occurs when reading a HEADERLESS block. Using the above options you can load AS MANY BLOCKS of bytes as are required for a program. (b) Activating the compressor and saving When you have finished loading everything you require, hold down the CAPS SHIFT key, then press the "c" key (i.e. ENTER CAPITAL C). You will then be prompted for (i) the INITIAL address and (ii) the FINAL address of the bytes to be compressed. e.g. if you have loaded 6912 bytes into address 40000, and want to compress all the bytes then the INITIAL address is 40000, and the FINAL address 46911 (yes there are 6912 bytes from 40000 to 46911 INCLUSIVE!) (iii) You will then be prompted for the expansion TARGET ADDRESS (i.e. the address of the first byte to which the expanded code should be moved). This TARGET ADDRESS can be the same as the initial address (and frequently will be!), but if it ISN'T then IT MUST BE AT LEAST 3 BYTES LOWER. You will not be allowed to use nonsensical values. Example 1. Initial address = 40000 Final address = 46911 Target address = 16384 A screen string was loaded into 40000 and then compressed. When expanded back again it is moved to 16384-23295 inclusive. Example 2. Initial address = 23900 Final address = 65530 Target address = 23900 Here the original bytes were loaded into 23900, and then occupy up to and including address 65530. The bytes will be compressed by CC1, but when expanded again, having restored the system variables to the normal "power up" values, it is required that they re-occupy their original locations (i.e. from 23900 to 65530), just as they would have been if loaded from tape. (iv) The next stage requires you to indicate what it to be done after expansion has taken place. You can opt for EITHER a return to basic (key 1), OR a machine code jump (key 2). With the latter option you will be asked for the JUMP ADDRESS (i.e. the RANDOMISE USR number from which the machine code normally executes.) (v) When compression is complete you will be asked to enter the filename with which the compressed code is to be saved. The BASE ADDRESS of the compressed code will then be displayed, together with a prompt for making a tape copy of it. NOTE DOWN the BASE ADDRESS, as this will be the address FROM which code is saved AND it is the RANDOMISE USR number that will "reclaim" the system variables. NOTE: CC1 compresses code towards the top of memory. Example 3. In example 1 we had INITIAL ADDRESS 40000, FINAL ADDRESS 46911, and TARGET ADDRESS 16384, to compress a screen string. At stage (iv) we would have chosen to return to basic. At this stage a typical BASE ADDRESS might be 43300. This means that the following changes would have been made by CC1: Initial address Final address Length Before compression 40000 46911 6912 After compression 43300 46911 3612 Thus CC1 has compressed the code, the final address will always be the same, but the number of bytes will be reduced, saving, in the above example by 6912-3612 = 3300 bytes. When saving takes place CC1 will save 3612 bytes starting from 43300. NOTE also that this is the address to which the compressed code MUST be loaded back again for expansion to take place. The header given to the code will automatically reload the code into the BASE ADDRESS, but you must not re-direct the code using, for example, LOAD "" CODE 20000. The first 15 bytes of the compressed code (in ex.3 from 43300 to 43314) contain the machine code to restore the system variables to the normal "power up" values mentioned earlier. The next hundred or so are the expansion routine which is tailored to each compressed block (i.e. it has the initial, final and target addresses). Repeat copies of the compressed code are obtained by pressing capital C. When you have completed your work with CC1, hold down the caps shift key and press the "q" key (i.e. enter capital Q), and CC1 will NEW your Spectrum. OPERATING INSTRUCTIONS - EXPANSION As mentioned earlier, it is essential that all blocks of compressed code are loaded at their correct address (i.e. the BASE ADDRESS - which is given to the tape header). In future we will denote the value of this address by B (in ex.3 B=43300). (i) To set system variables to their normal "power up" values use RANDOMISE USR B (essential for drive owners who have upset the system variables by activating their drives). You may not want to restore the system variables in which case you can omit this step. (ii) To expand the block of bytes to their required TARGET ADDRESS use RANDOMISE USR (B+15) i.e. the expansion routine is always 15 bytes further on from the BASE ADDRESS. The expansion routine first copies itself to the printer buffer (at 23296) and then executes from there. If you wish to expand code into the printer buffer the expansion routine can be redirected to run from the screen by poking (B+18) and (B+19) with the required address. e.g. To move expansion routine to 20000, as 20000 = 78 x 256 + 32, you would POKE (B+18),32 and POKE (B+19),78 (note low byte, in this case 32, FIRST). EXAMPLE GAME - SCRABBLE - for DRIVE transfer application (this one of several versions that are available, so the loading address and/or the USR address could be different in your version) Load the large block of machine code into CC1 using the "l" key. From the LERM Advanced header reader you know in advance that this code loads into address 24400 (which is also the USR number) and is 41135 bytes long. As the start address is too low to load in the code straight from m/drive we need CC1. After loading in the original bytes from your tape press capital C. Enter INITIAL ADDRESS of 24400, FINAL ADDRESS of 65535, and TARGET ADDRESS of 24400. Then request a return to BASIC (key 1) when prompted. When compression has been completed enter the required file name (say "scrab"). CC1 will then indicate that the BASE ADDRESS of the compressed code is 26568 which is comfortably free of the M/drive channel area. Now save your copy of the compressed code onto tape. Transfer this code to your drive with one of our programs (if available), or if not then enter CLEAR 26567 (one less than the BASE ADDRESS), and the LOAD "" CODE and play in the "scrab" code from tape. Now save directly to your drive (e.g. for m/drive enter SAVE *"m";1;"scrab" CODE 26568,65536-26568). The scrabble BASIC should now be altered as follows: 10 CLEAR VAL "26567": LOAD *"m";VAL "1";"scrab" CODE VAL "26568": RANDOMISE USR VAL "26568": CLEAR VAL "24395": RANDOMISE USR VAL "26583": RANDOMISE USR VAL "24400" and saved onto your drive to auto-run from line 10 (alter as appropriate for your drive) Explanation: The compressed code "scrab" is loaded in, the clear number being, as usual, one less than the start address of the code. The USR 26568 restores the system variables to the normal "power up" values. Next the CLEAR 24395 is the normal CLEAR value (under the TARGET ADDRESS - leave at least 5 bytes!), then the RANDOMISE USR 26583 expands the code back to the original state. Finally the RANDOMISE USR 24400 is the original USR call to the machine code. Note that all the instructions are placed with a single line number, and VAL is frequently used. This keeps the size of the basic down to a minimum. (Note that the last USR 24400 could have been left out if, when using CC1 at step (b)(v) we had opted for key 2 (thus not returning to basic), and entered a JUMP ADDRESS of 24400). EXAMPLE - SCREEN STRING Load in CC1. Press the "r" key for loading. Let's imagine that say from address 40000 is "free". So when asked to enter the START ADDRESS enter 40000. After loading your screen string from tape, enter an INITIAL ADDRESS of 40000, a FINAL ADDRESS of 46911, and a TARGET ADDRESS of 16384. Select key 1 (returning to basic). After compression, CC1 gives you a BASE ADDRESS of 43912. Save with an appropriate filename (say "test") onto tape. New the program by entering capital Q. To reload your compressed code enter and run this program: 10 CLEAR 43911: LOAD "test" CODE 43912 20 RANDOMISE USR 43912: RANDOMISE USR 43927 Notes: the CLEAR number is one less than the BASE ADDRESS, the code loads into the BASE ADDRESS, and although the number wasn't strictly necessary, it is useful to keep. The RANDOMISE USR 43912 could have been left out as a drive wasn't used, and so the system variables probably weren't altered. The RANDOMISE USR 43927 sends the bytes to the screen. LERM CC1-v1, (c) 1986