BBS: Inland Empire Archive Date: 12-28-92 (06:12) Number: 357 From: RICH GELDREICH Refer#: NONE To: ALL Recvd: NO Subj: Bload Compressor/5 Conf: (2) Quik_Bas
'Page 5 of ENCODE13.BAS begins here.
SUB InitLZ77
FOR a = 0 TO (BufferSize + 1 + HashSize) - 1
NextCell(a) = Null: LastCell(a) = Null
NEXT
END SUB
'Initializes the ring buffer.
SUB InitRingBuffer
FOR a = 0 TO BufferSize - MaxMatch - 1: RingBuffer(a) = 0: NEXT
END SUB
'Stores the string at R into its linked list without scanning for a
'match.
SUB MakeString (BYVAL R)
LinkHead = (BufferSize + 1) + ((RingBuffer(R) * 14096& XOR _
RingBuffer(R + 1) * 77 XOR RingBuffer(R + 2)) MOD HashSize)
a = NextCell(LinkHead): NextCell(LinkHead) = R: LastCell(a) = R
LastCell(R) = LinkHead: NextCell(R) = a
END SUB
'Stores an uncompressed character and its flag to the output code
'buffer.
SUB OutputChar (BYVAL a)
OrMask = OrMask * 2 'send a binary 0
CodeBuffer(CodePointer) = a 'store the character
CodeCounter = CodeCounter + 1
IF CodeCounter = 16 THEN 'if 16 codes the write 'em out
'write the bit flags
WriteByte BitAccum AND 255: WriteByte BitAccum \ 256
'write the codes
FOR a = 0 TO CodePointer: WriteByte CodeBuffer(a): NEXT
CodePointer = 0: CodeCounter = 0: OrMask = 1: BitAccum = 0
ELSE
CodePointer = CodePointer + 1
END IF
END SUB
'Writes an EOF code to the output code buffer
SUB OutputEOF
BitAccum = BitAccum OR OrMask
CodeBuffer(CodePointer) = 15
CodeBuffer(CodePointer + 1) = 0: CodeBuffer(CodePointer + 2) = 255
WriteByte BitAccum AND 255: WriteByte BitAccum \ 256
FOR a = 0 TO CodePointer + 2: WriteByte CodeBuffer(a): NEXT
END SUB
'Outputs a match and its flag to the output code buffer.
SUB OutputMatch
BitAccum = BitAccum OR OrMask: OrMask = OrMask * 2
'Favor short matches(3-17 characters).
IF Match.Length < 18 THEN
CodeBuffer(CodePointer) = (Match.Length - (Threshold + 1)) OR _
(Match.Distance AND &HF) * 16
CodeBuffer(CodePointer + 1) = Match.Distance \ 16
CodePointer = CodePointer + 2
ELSE
CodeBuffer(CodePointer) = 15 OR (Match.Distance AND &HF) * 16
CodeBuffer(CodePointer + 1) = Match.Distance \ 16
CodeBuffer(CodePointer + 2) = Match.Length - 18
CodePointer = CodePointer + 3
END IF
CodeCounter = CodeCounter + 1
IF CodeCounter = 16 THEN
WriteByte BitAccum AND 255: WriteByte BitAccum \ 256
FOR a = 0 TO CodePointer - 1: WriteByte CodeBuffer(a): NEXT
CodePointer = 0: CodeCounter = 0: OrMask = 1: BitAccum = 0
END IF
END SUB
'Stores one byte into the disk output buffer, and flushes it when it
'is full.
SUB WriteByte (BYVAL a)
MID$(IOBuffer$, IOPointer, 1) = CHR$(a)
IOPointer = IOPointer + 1
IF IOPointer = 4097 THEN 'if buffer full then flush
PUT #1, , IOBuffer$: IOPointer = 1
END IF
END SUB
'Flushes the disk output buffer.
SUB WriteFlush
IOBuffer$ = LEFT$(IOBuffer$, IOPointer - 1): PUT #1, , IOBuffer$
END SUB
The source and OBJ for the assembly decompressor follows.
--- MsgToss 2.0b
* Origin: Computer Co-Op - Voorhees, NJ | Ted Hare (1:266/29)

Books at Amazon:
Back to BASIC: The History, Corruption, and Future of the Language
Hackers: Heroes of the Computer Revolution (including Tiny BASIC)
Go to: The Story of the Math Majors, Bridge Players, Engineers, Chess Wizards, Scientists and Iconoclasts who were the Hero Programmers of the Software Revolution
The Advent of the Algorithm: The Idea that Rules the World
Moths in the Machine: The Power and Perils of Programming
Mastering Visual Basic .NET