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
