From 15A (Steven Flintham)
LZSS compression ROM 1.00
This ROM provides facilities to compress and decompress files using LZSS
compression. The files it uses are the same as those used by the utilities
on disc TBI-102 in the 8-Bit Software TBI pool. If you have used those
utilities you should note that because it can use sideways RAM as workspace
this ROM can compress using 12 offset bits on any machine.
LZSS compression is more advanced than the common run length compression. It
should be possible to obtain reasonable space savings on most files,
including programs, text and saved screens. Compression is relatively slow
and requires a lot of memory but decompression is quite fast and has more
reasonable memory requirements.
When compressing a file you need to specify the number of 'length' and
'offset' bits. If you don't, the default values of 12 length bits and
4 offset bits will be used. Roughly speaking, the number of length bits
determines how good the compression method is at spotting duplicate items
in the file being compressed and the number of offset bits determines the
maximum size of duplicate which can be handled.
This suggests that having these values as large as possible is always going to
be best but this is not the case, as storing larger values takes more space
in the compressed file. In practice to get optimum compression you need to
experiment. Most of the time you're probably better off just choosing some
'sensible' values and sticking to them.
Although I think this software is fairly reliable there is still a chance
that it will corrupt or destroy files when compressing or decompressing. You
are strongly advised to take care when using it and to have a backup of
any important data on the discs used.
In particular, just because a file compresses correctly it does NOT mean
that it will decompress correctly. If you intend to delete the original you
should decompress the compressed version first as a test and then check that
the decompressed file and original are the same (*DIFF is provided for this
purpose). It seems unlikely but it may be possible that even though a file
decompresses correctly once it will not do so at a later date.
You should also bear in mind that if a disc fault occurs in a compressed file
it will be almost impossible to recover using a sector editor or similar tool.
YOU SHOULD NOT KEEP ANYTHING IMPORTANT IN COMPRESSED FORM ONLY AND YOU USE
THESE UTILITIES ENTIRELY AT YOUR OWN RISK.
Loading the ROM into sideways RAM
Although it's called the 'LZSS compression ROM' it will actually only work
in sideways RAM. How to load it depends on your sideways RAM. If you have
a BBC then you could try:
*LOAD LZSSROM 8000
and on a Master or BBC B+ 128K you can use:
*SRLOAD LZSSROM 8000 Z Q
After loading the ROM you must press BREAK (or CTRL-BREAK on a Master) to
The ROM provides several new * commands. It supports *HELP and *HELP LZSSROM
gives a list of commands with their syntax. You can also get help on any
individual command by typing *HELP <command>.
*LZCOMPRESS is used to compress a file. The simplest way to use it is to type:
*LZCOMPRESS in out
which will compress the file "in" and produce a new compressed file called
"out". You can't compress a file over itself and trying to do so may lose
the file, so you shouldn't do:
*LZCOMPRESS in in
If you use the command like this then it will use the default setting of 12
offset bits and 4 length bits. This is a fairly good setting for most purposes
but not necessarily the best and other settings might give better compression
on some files. You can add up to two numbers after the filenames. The first
will be taken as the number of offset bits to use and the second, if present,
will set the number of length bits. So, for example, you could do:
*LZCOMPRESS in out 11 (11 offset bits, 4 length bits)
*LZCOMPRESS in out 8 4 (8 offset bits, 4 length bits)
*LZCOMPRESS in out 12 7 (12 offset bits, 7 length bits)
*LZCOMPRESS in out 9 5 (9 offset bits, 5 length bits)
Note that if you want to set the number of length bits yourself you have
to specify the number of offset bits as well. The ROM will give an error if
you give an unreasonable value for either value. The number of offset bits
must be in the range 6-12 inclusive and the number of length bits must be
between 4 and 7 inclusive. The number of offset bits must be greater than
the number of length bits.
Compression needs quite a lot of memory, the exact amount depending on the
number of offset and length bits (mainly on the number of offset bits). This
means that using *LZCOMPRESS may corrupt any programs or data in memory - it
is only designed to be used from the prompt and not in a program. An error
will occur if there isn't enough free RAM to do the compression. If this
happens you should try changing into a screen mode which uses less memory,
such as mode 7 or a shadow mode. It uses memory just below the start of
screen RAM in order to reduce the risk of corrupting a BASIC program or
other data but you should not rely on this.
If you want to compress several files and don't want to wait around to type
each command in, or if you have a set of files you will want to compress
more than once, you can put a list of *LZCOMPRESS commands in a file and
then *EXEC it. (This can be considered as a replacement for the LZSSBat
program included on 8BS disc TBI-102.)
*LZDECOMPRESS is used to decompress a file produced by *LZCOMPRESS. The
simplest way to use it is to type:
*LZDECOMPRESS in out
which will decompress "in" and produce a new file "out". If "in" isn't a
compressed file an error will be given. As with *LZCOMPRESS you must not
give the same filename twice or you will probably corrupt the file. Provided
the two filenames are different "in" is not changed.
Used like this *LZDECOMPRESS should not corrupt memory, although it will
be quite slow because of this. If there's nothing valuable in memory I
recommend adding a Q to the end of the command, like this:
*LZDECOMPRESS in out Q
If the decompressed file is short enough to fit in memory it will then
be decompressed much more quickly. If it's too large the Q will simply be
ignored. You can think of the Q as saying 'feel free to corrupt memory if
it will speed things up'.
The load and execution addresses for the file are stored when it is compressed
and *LZDECOMPRESS will restore them when it decompresses, so the decompressed
file should be almost indistinguishable from the original. As far as I'm
aware the only things which aren't preserved are the access permissions
(locked/unlocked on DFS). They are always set to the default value.
*DIFF compares two files. Its main use is for comparing an original file
with one which has been compressed and then decompressed in order to check
that the compression and decompression processes worked correctly. To use
it, just supply the two filenames:
*DIFF file1 file2
As *DIFF doesn't do anything to the files you can give the same filename
twice, although this is fairly pointless. It will compare the two byte-by-byte
and either report on the differences or say that they are identical. It
only checks the contents so the files may have different load and execution
addresses and access permissions even if *DIFF says they are identical.
Its name is about the only thing it has in common with the Unix command
diff, which is much more powerful and performs line-by-line comparison.
This is a version of the *LOAD command for compressed files. In its simplest
form you can use it just like the *LOAD command:
*LZLOAD in <hex load address>
As you might expect, if you aren't careful where you load the data you
might cause the machine to crash or important data to be corrupted.
You can speed things up slightly by adding a Q to the end of either of
these commands. This uses 512 bytes of memory as workspace, which will be
preserved, but it's difficult for the ROM to decide where to use for this
workspace. If it chooses wrongly it might crash the machine so you can
optionally follow the Q with the address (in hexadecimal) of 512 bytes of
workspace. This memory will be preserved by *LZLOAD.
This means that any of the following command forms can be used:
*LZLOAD file <load addr>
*LZLOAD file Q
*LZLOAD file Q <workspace addr>
*LZLOAD file <load addr> Q
*LZLOAD file <load addr> Q <workspace addr>
You should not try loading files into page 9 (&900-&9FF) as this is used by
the ROM as temporary workspace when necessary. It's restored afterwards,
which is normally exactly what's required, but it means that if you load
anything there it gets replaced by the original contents.
*LZRUN is a version of the *RUN command for compressed files. It's almost
identical to *LZLOAD, except that you can't specify a load address (the
original load address is used) and that it jumps to the execution address
after it finishes loading. This means that the following command forms can
*LZRUN file Q
*LZRUN file Q <workspace addr>
There is no provision for passing extra parameters on the command line as
there is with *RUN. *LZRUN is a bit of a bodge and in particular using it
is liable to cause problems when the program which has been run tries to
quit. If *LZRUN isn't up to the job you could try using *LZLOAD and then
just CALLing the execution address.
The same restrictions apply to files loaded in page 9 as for *LZLOAD.
Compressing several files
If you want to compress a group of several related files you should
consider using a program such as Chris Richardson's archiver to join them
all into a single file and then compressing that. This may give better
overall compression that compressing them individually and will also
avoid the hassle of having to decompress each one separately. However,
doing so increases the risk of data loss due to a disc corruption, since
if a disc error occurs anywhere in the large compressed file everything
is lost, whereas if all the files are compressed separately then only
a single compressed file is lost and the others can still be read. This
is particularly important since, as mentioned earlier, it will be almost
impossible to recover compressed files with a sector editor.
Recovering corrupt files
If a compressed file gets corrupted you might be able to recover the start
of it by trying to decompress it using *LZDECOMPRESS anyway and examining
the output file. You should not use the Q option when trying this as the
quick decompression code expects the file to be perfect and will crash the
computer, probably overwriting the ROM as well.
Second processor compatibility
I haven't been able to test the ROM with a second processor and I don't
really know enough about them to make a guess at whether it will work or
not. If you try it then be careful and please let me know what happened.
If you find any bugs or have any suggestions for improvement then feel free
to contact me, although I can't promise to do anything. Please write to:
6 Laythorpe Avenue
If you send a disc and want it back and/or want a reply then please send
an SAE. I can handle all standard disc formats (DFS/ADFS, 40/80 track,
single/double sided, 3.5 inch and 5.25 inch) but not (for example) 62-file
DFS discs as produced by some DFSes.
Members of 8-Bit Software can also contact me using the messaging system,
user ID 15A.
This software is (C) Steven Flintham 1996 and may be freely distributed
provided no charge is made for it.
Compressed files produced with the software have the same copyright
restrictions as the files which were compressed as far as I'm concerned. I
make no claim on them and so, if you wished, you could compress with my
software, write your own decompression code and be completely free of any
copyright restrictions imposed by me.
Although I don't think I have the right to impose such a condition I strongly
suspect that compressing a file belonging to someone else does not remove
their copyright, so distributing a compressed version of (say) a commercial
game would still be piracy.
I make no claim on the method of compression used. I am unaware of any patents
or similar which apply to the LZSS algorithm (in the UK at least - I think
there are some patents which apply in the US, although I don't know whether
they cover the exact method used by this program). Please contact me if
you have any complaints about the use of the LZSS algorithm in this software.