Code:
; This is LZ-like decompressor. I wish I know the author.
; It reads the stream of control words and data bytes and writes the output
; according to the control sequences commands:
; 1 - copy single byte
; 00 - copy, small offset (signed byte), 2..5 bytes to copy (two control bits)
; 01 - copy, big offset (13 bits), 2..9 bytes to copy (3 bits),
; stored in packed word oooooccc oooooooo, where "o" is offset, "c" is count;
; in case of ccc == 000, count is the next byte from stream plus 1.
;
; Registers usage:
; AX - general purpose (control words, data bytes)
; SI - source index, offset of packed data
; DI - destination index, offset of unpacked data
; BP - control word
; DX - number of bits in control word remaining
; CX - size of block to copy from behind
; BX - offset of block to copy from behind (signed int16, negative)
proc decompress near
mov dx, 10h ; DX is a bit counter for BP
lodsw
mov bp, ax ; BP is a control word (contains bit commands)
HandleBits:
shr bp, 1 ; Get the least significant bit (LSB) of BP into CF and shift right BP.
dec dx
jnz short GetCopyMode
; Read new control word if the old one is exhausted. Below there are several checks like this.
lodsw
mov bp, ax
mov dl, 10h
GetCopyMode:
jnb short GetBytesCount ; CF=0, need to count number of bytes to copy
movsb ; CF=1, single byte needs to be copied
jmp short HandleBits
GetBytesCount:
xor cx, cx ; CX needs to contain number of bytes to copy
shr bp, 1
dec dx
jnz short GetOffsetSize
lodsw
mov bp, ax
mov dl, 10h
GetOffsetSize:
jb short ReadBigOffset ; CF=1, offset is big
shr bp, 1 ; CF=0, offset is small
dec dx
jnz short FewBytesToCopy; we need to copy from 2 up to 5 bytes
lodsw
mov bp, ax
mov dl, 10h
FewBytesToCopy:
rcl cx, 1 ; get bit 1 of the count from CF into CX LSB
shr bp, 1
dec dx
jnz short LookBehind
lodsw
mov bp, ax
mov dl, 10h
LookBehind:
rcl cx, 1 ; get bit 0 of the count from CF into CX LSB
inc cx ; add 2
inc cx ; because we won't waste data for 1 bit copying
lodsb ; time to read offset
mov bh, 0FFh ; it's gonna be negative 'cause we copy from our tail
mov bl, al ; now BX contains negative offset
jmp short CopyDataBytes
nop ; alignment instruction, never mind
ReadBigOffset:
lodsw ; this word is packed
mov bx, ax ; BL becomes lower part of the offset
mov cl, 3
shr bh, cl ; get 5 higher bits of BH
or bh, 0E0h ; and set 3 higher bits; full offset is constructed
and ah, 7 ; get 3 lower bits of AH
jz short LotsBytesToCopy
mov cl, ah
inc cx ; in this part we're going to copy from 2 up to 9 bytes, as you see
inc cx
CopyDataBytes:
mov al, [es:bx+di]
stosb
loop CopyDataBytes
jmp short HandleBits
LotsBytesToCopy:
lodsb ; in this part, we can copy up to 256 bytes
or al, al
jz short UnpackComplete; end of the stream
mov cl, al ; otherwise, copy some more bytes
inc cx
jmp short CopyDataBytes
UnpackComplete:
retn
endp decompress
Is anyone can help me to identify the decompression algorithm?