ZX5 decompressor

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