ZX0 I/O stream decompressor. (last update: 29/03/21)
CODE: xxl
ENTRY: destination adress store in ZX0_OUTPUT, ( no stream? source in ZX0_INPUT )
ZX0_OUTPUT equ ZP
copysrc equ ZP+2
mwa #packed_data ZX0_INPUT
mwa #destination ZX0_OUTPUT
jsr unZX0
FORMAT V2 !!! (last update: 10/10/21)
dzx0_standard
lda #$ff
sta offsetL
sta offsetH
ldy #$00
sty lenL
sty lenH
lda #$80
dzx0s_literals
jsr dzx0s_elias
pha
cop0 jsr get_byte
ldy #$00
sta (ZX0_OUTPUT),y
inw ZX0_OUTPUT
lda #$ff
lenL equ *-1
bne @+
dec lenH
@ dec lenL
bne cop0
lda #$ff
lenH equ *-1
bne cop0
pla
asl @
bcs dzx0s_new_offset
jsr dzx0s_elias
dzx0s_copy pha
lda ZX0_OUTPUT
clc
adc #$ff
offsetL equ *-1
sta copysrc
lda ZX0_OUTPUT+1
adc #$ff
offsetH equ *-1
sta copysrc+1
ldy #$00
ldx lenH
beq Remainder
Page lda (copysrc),y
sta (ZX0_OUTPUT),y
iny
bne Page
inc copysrc+1
inc ZX0_OUTPUT+1
dex
bne Page
Remainder ldx lenL
beq copyDone
copyByte lda (copysrc),y
sta (ZX0_OUTPUT),y
iny
dex
bne copyByte
tya
clc
adc ZX0_OUTPUT
sta ZX0_OUTPUT
bcc copyDone
inc ZX0_OUTPUT+1
copyDone stx lenH
stx lenL
pla
asl @
bcc dzx0s_literals
dzx0s_new_offset
ldx #$fe
stx lenL
jsr dzx0s_elias_loop
pha
php ; stream
ldx lenL
inx
stx offsetH
bne @+
plp ; stream
pla
rts ; koniec
@ jsr get_byte
plp ; stream
sta offsetL
ror offsetH
ror offsetL
ldx #$00
stx lenH
inx
stx lenL
pla
bcs @+
jsr dzx0s_elias_backtrack
@ inc lenL
bne @+
inc lenH
@ jmp dzx0s_copy
dzx0s_elias inc lenL
dzx0s_elias_loop
asl @
bne dzx0s_elias_skip
jsr get_byte
sec ; stream
rol @
dzx0s_elias_skip
bcc dzx0s_elias_backtrack
rts
dzx0s_elias_backtrack
asl @
rol lenL
rol lenH
jmp dzx0s_elias_loop
———————————————————————————————————————
———————————————————————————————————————
FORMAT V1 Stary !!! (last update: 29/03/21)
ZX0_OUTPUT equ ZP
copysrc equ ZP+2
unZX0 lda #$ff
sta offsetL
sta offsetH
ldy #$00
sty lenL
sty lenH
lda #$80
; Literal (copy next N bytes from compressed file)
; 0 Elias(length) byte[1] byte[2] ... byte[N]
dzx0s_literals
jsr dzx0s_elias
pha
cop0 jsr xBIOS_GET_BYTE
ldy #$00
sta (ZX0_OUTPUT),y
inw ZX0_OUTPUT
lda #$ff
lenL equ *-1
bne @+
dec lenH
@ dec lenL
bne cop0
lda #$ff
lenH equ *-1
bne cop0
pla
asl @
bcs dzx0s_new_offset
; Copy from last offset (repeat N bytes from last offset)
; 0 Elias(length)
jsr dzx0s_elias
dzx0s_copy
pha
lda ZX0_OUTPUT
clc
adc #$ff
offsetL equ *-1
sta copysrc
lda ZX0_OUTPUT+1
adc #$ff
offsetH equ *-1
sta copysrc+1
ldy #$00
ldx lenH
beq Remainder
Page lda (copysrc),y
sta (ZX0_OUTPUT),y
iny
bne Page
inc copysrc+1
inc ZX0_OUTPUT+1
dex
bne Page
Remainder ldx lenL
beq copyDone
copyByte lda (copysrc),y
sta (ZX0_OUTPUT),y
iny
dex
bne copyByte
tya
clc
adc ZX0_OUTPUT
sta ZX0_OUTPUT
bcc copyDone
inc ZX0_OUTPUT+1
copyDone stx lenH
stx lenL
pla
asl @
bcc dzx0s_literals
; Copy from new offset (repeat N bytes from new offset)
; 1 Elias(MSB(offset)) LSB(offset) Elias(length-1)
dzx0s_new_offset
jsr dzx0s_elias
pha
php
lda #$00
sec
sbc lenL
sta offsetH
bne @+
plp
pla
rts ; koniec
@ jsr xBIOS_GET_BYTE
plp
sta offsetL
ror offsetH
ror offsetL
ldx #$00
stx lenH
inx
stx lenL
pla
bcs @+
jsr dzx0s_elias_backtrack
@ inc lenL
bne @+
inc lenH
@ jmp dzx0s_copy
dzx0s_elias inc lenL
dzx0s_elias_loop
asl @
bne dzx0s_elias_skip
jsr xBIOS_GET_BYTE
sec ; można usunąć jeśli dekompresja z pamięci a nie pliku
rol @
dzx0s_elias_skip
bcc dzx0s_elias_backtrack
rts
dzx0s_elias_backtrack
asl @
rol lenL
rol lenH
jmp dzx0s_elias_loop
Jeśli dane znajdują się w pamięci a nie w pliku należy wymienić odwołania:
jsr xBIOS_GET_BYTE na jsr GET_BYTE
GET_BYTE lda $ffff
ZX0_INPUT equ *-2
inw ZX0_INPUT
rts
zobacz:
https://github.com/einar-saukas/ZX0
