ZX5 I/O stream decompressor. (last update: 09/10/21)
CODE: xxl
ENTRY:
mwa #packed_data ZX5_INPUT
mwa #destination ZX5_OUTPUT
jsr unZX5
packed_data
ins 'conan.zx5'
destination equ $A150
ZP equ $80
ZX5_OUTPUT equ ZP+0
copysrc equ ZP+2
offset equ ZP+4
offset2 equ ZP+6
offset3 equ ZP+8
len equ ZP+$A
pnb equ ZP+$C
zmienne ze strony zerowej można przenieść w inne miejsce (oprócz ZX5_OUTPUT i copysrc)
unZX5 lda #$ff
sta offset
sta offset+1
ldy #$00
sty len
sty len+1
lda #$80
dzx5s_literals
jsr dzx5s_elias
pha
cop0 jsr _GET_BYTE
ldy #$00
sta (ZX5_OUTPUT),y
inw ZX5_OUTPUT
lda len
bne @+
dec len+1
@ dec len
bne cop0
lda len+1
bne cop0
pla
asl @
bcs dzx5s_other_offset
dzx5s_last_offset
jsr dzx5s_elias
dzx5s_copy pha
lda ZX5_OUTPUT
clc
adc offset
sta copysrc
lda ZX5_OUTPUT+1
adc offset+1
sta copysrc+1
ldy #$00
ldx len+1
beq Remainder
Page lda (copysrc),y
sta (ZX5_OUTPUT),y
iny
bne Page
inc copysrc+1
inc ZX5_OUTPUT+1
dex
bne Page
Remainder ldx len
beq copyDone
copyByte lda (copysrc),y
sta (ZX5_OUTPUT),y
iny
dex
bne copyByte
tya
clc
adc ZX5_OUTPUT
sta ZX5_OUTPUT
bcc copyDone
inc ZX5_OUTPUT+1
copyDone stx len+1
stx len
pla
asl @
bcc dzx5s_literals
dzx5s_other_offset
asl @
bne dzx5s_other_offset_skip
jsr _GET_BYTE
sec ; można usunąć jeśli dekompresja z pamięci a nie pliku
rol @
dzx5s_other_offset_skip
bcc dzx5s_prev_offset
dzx5s_new_offset
sta pnb
asl @
ldx offset2
stx offset3
ldx offset2+1
stx offset3+1
ldx offset
stx offset2
ldx offset+1
stx offset2+1
ldx #$fe
stx len
jsr dzx5s_elias_loop
pha
ldx len
inx
stx offset+1
bne @+
pla
rts ; koniec
@ jsr _GET_BYTE
sta offset
ldx #$00
stx len+1
inx
stx len
pla
dec pnb
bmi @+
jsr dzx5s_elias_backtrack
@ inw len
jmp dzx5s_copy
dzx5s_prev_offset
asl @
bcc dzx5s_second_offset
ldy offset2
ldx offset3
sty offset3
stx offset2
ldy offset2+1
ldx offset3+1
sty offset3+1
stx offset2+1
dzx5s_second_offset
ldy offset2
ldx offset
sty offset
stx offset2
ldy offset2+1
ldx offset+1
sty offset+1
stx offset2+1
jmp dzx5s_last_offset
dzx5s_elias inc len
dzx5s_elias_loop
asl @
bne dzx5s_elias_skip
jsr _GET_BYTE
sec ; można usunąć jeśli dekompresja z pamięci a nie pliku
rol @
dzx5s_elias_skip
bcc dzx5s_elias_backtrack
rts
dzx5s_elias_backtrack
asl @
rol len
rol len+1
jmp dzx5s_elias_loop
Jeśli dane znajdują się w pliku a nie pamięci zamiast jsr GET_BYTE użyj jsr xBIOS_GET_BYTE
_GET_BYTE lda $ffff
ZX5_INPUT equ *-2
inw ZX5_INPUT
rts
zobacz: https://github.com/einar-saukas/ZX5
