Код:
.ORG 100H
START: DI
LXI SP,000F0H
LXI H,PAKPR ; откуда
LXI D, 0A000H ; куда
BEGIN: MOV A,M
STAX D
INX H
INR E
JNZ BEGIN
INR D
MOV A,D
CPI 0FFH
JC BEGIN ; цикл до адреса FF00h
LXI D, START
PUSH D ; для запуска распакованного
LXI H, PDATA
JMP 0A000H
PAKPR: .db 0FFh
;
.org 0A000H ; после компиляции удалить область от PAKPR до 0A000H и дописать в конец архив
;
;input: hl=compressed data start
; de=uncompressed destination start
unlzsa1:
mvi b,0
jmp ReadToken
;
NoLiterals:
xra m
push d
inx h
mov e,m
jm LongOffset
ShortOffset:
mvi d,0FFh
adi 3
cpi 15+3
jnc LongerMatch
CopyMatch:
mov c,a
CopyMatch_UseC:
inx h
xthl
xchg
dad d
mov a,m
inx h
stax d
inx d
dcx b
mov a,m
inx h
stax d
inx d
dcx b
dcx b
inr c
BLOCKCOPY1:
mov a,m
stax d
inx h
inx d
dcr c
jnz BLOCKCOPY1
xra a
ora b
jz $+7 ; >>>
dcr b
jmp BLOCKCOPY1
pop h ; <<<
ReadToken:
mov a,m
ani 70h
jz NoLiterals
cpi 70h
jz MoreLiterals
rrc
rrc
rrc
rrc
mov c,a
mov b,m
inx h
mov a,m ; <<<
stax d
inx h
inx d
dcr c
jnz $-5 ; >>>
push d
mov e,m
mvi a,8Fh
ana b
mvi b,0
jp ShortOffset
LongOffset:
inx h
mov d,m
adi -128+3
cpi 15+3
jc CopyMatch
LongerMatch:
inx h
add m
jnc CopyMatch
mov b,a
inx h
mov c,m
jnz CopyMatch_UseC
inx h
mov b,m
mov a,b
ora c
jnz CopyMatch_UseC
pop d
ret ; >>>>>>>>>>>>>>>
;
MoreLiterals:
xra m
push psw
mvi a,7
inx h
add m
jc ManyLiterals
CopyLiterals:
mov c,a
CopyLiterals_UseC:
inx h
dcx b
inr c
BLOCKCOPY2:
mov a,m
stax d
inx h
inx d
dcr c
jnz BLOCKCOPY2
xra a
ora b
jz $+7 ; >>>
dcr b
jmp BLOCKCOPY1
pop psw ; <<<
push d
mov e,m
jp ShortOffset
jmp LongOffset
ManyLiterals:
mov b,a
inx h
mov c,m
jnz CopyLiterals_UseC
inx h
mov b,m
jmp CopyLiterals_UseC
;
PDATA: .END