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