compression: update comparison

This commit is contained in:
Vince Weaver 2022-06-06 01:19:58 -04:00
parent 1ae6ddac20
commit 3b76177bec
7 changed files with 421 additions and 8 deletions

View File

@ -15,12 +15,15 @@ LINKERSCRIPTS = ../../linker_scripts/
all: compression_test.dsk
compression_test.dsk: HELLO LZSA_TEST EXOMIZER_TEST ZX02_TEST
compression_test.dsk: HELLO LZSA_TEST EXOMIZER_TEST \
ZX02_OPT_TEST ZX02_SMALL_TEST ZX02_FAST_TEST
cp $(EMPTYDISK) compression_test.dsk
$(DOS33) -y compression_test.dsk SAVE A HELLO
$(DOS33) -y compression_test.dsk BSAVE -a 0x6000 LZSA_TEST
$(DOS33) -y compression_test.dsk BSAVE -a 0x6000 EXOMIZER_TEST
$(DOS33) -y compression_test.dsk BSAVE -a 0x6000 ZX02_TEST
$(DOS33) -y compression_test.dsk BSAVE -a 0x6000 ZX02_OPT_TEST
$(DOS33) -y compression_test.dsk BSAVE -a 0x6000 ZX02_SMALL_TEST
$(DOS33) -y compression_test.dsk BSAVE -a 0x6000 ZX02_FAST_TEST
@ -59,11 +62,29 @@ level5.exo: level5.hgr
###
ZX02_TEST: zx02_test.o
ld65 -o ZX02_TEST zx02_test.o -C $(LINKERSCRIPTS)/apple2_6000.inc
ZX02_OPT_TEST: zx02_opt_test.o
ld65 -o ZX02_OPT_TEST zx02_opt_test.o -C $(LINKERSCRIPTS)/apple2_6000.inc
zx02_opt_test.o: zx02_opt_test.s zx02_optim.s level5.zx02
ca65 -o zx02_opt_test.o zx02_opt_test.s -l zx02_opt_test.lst
###
ZX02_SMALL_TEST: zx02_small_test.o
ld65 -o ZX02_SMALL_TEST zx02_small_test.o -C $(LINKERSCRIPTS)/apple2_6000.inc
zx02_small_test.o: zx02_small_test.s zx02_small.s level5.zx02
ca65 -o zx02_small_test.o zx02_small_test.s -l zx02_small_test.lst
###
ZX02_FAST_TEST: zx02_fast_test.o
ld65 -o ZX02_FAST_TEST zx02_fast_test.o -C $(LINKERSCRIPTS)/apple2_6000.inc
zx02_fast_test.o: zx02_fast_test.s zx02_fast.s level5.zx02
ca65 -o zx02_fast_test.o zx02_fast_test.s -l zx02_fast_test.lst
zx02_test.o: zx02_test.s zx02_optim.s level5.zx02
ca65 -o zx02_test.o zx02_test.s -l zx02_test.lst
###
@ -78,4 +99,6 @@ level5.hgr: level5.png
clean:
rm -f HELLO LZSA_TEST EXOMIZER_TEST *~ *.o *.lst level5.lzsa
rm -f HELLO LZSA_TEST EXOMIZER_TEST \
ZX02_OPT_TEST ZX02_SMALL_TEST \
*~ *.o *.lst level5.lzsa

View File

@ -4,6 +4,8 @@ LEVEL5.PNG (hires background image from Lemmings, 8k)
Compressed Decompression
File size Routine Size Time (cycles) FPS
===========================================================
lzsa 4012 259 bytes 7cc5e = 511,070 ~2.0
lzsa_fast 4012 259 bytes 7cc5e = 511,070 ~2.0
exomizer 3851(?) ??? ?????
zx02_opt 3869 138 bytes 7076f = 460,655 ~2.2
zx02_small 3869 130 bytes 93CCB = 605,387 ~1.7
zx02_fast 3869 175 bytes 63EE8 = 409,320 ~2.5

View File

@ -0,0 +1,179 @@
; De-compressor for ZX02 files
; ----------------------------
;
; Decompress ZX02 data (6502 optimized format), optimized for speed:
; 175 bytes code, 48.1 cycles/byte in test file.
;
; Compress with:
; zx02 input.bin output.zx0
;
; (c) 2022 DMSC
; Code under MIT license, see LICENSE file.
ZP=$80
offset = ZP+0
ZX0_src = ZP+2
ZX0_dst = ZP+4
bitr = ZP+6
pntr = ZP+7
; Initial values for offset, source, destination and bitr
zx0_ini_block:
.byte $00, $00, <comp_data, >comp_data, <out_addr, >out_addr, $80
;--------------------------------------------------
; Decompress ZX0 data (6502 optimized format)
full_decomp:
; Get initialization block
ldy #7
copy_init: lda zx0_ini_block-1, y
sta offset-1, y
dey
bne copy_init
; Decode literal: Ccopy next N bytes from compressed file
; Elias(length) byte[1] byte[2] ... byte[N]
decode_literal:
jsr get_elias
dex
txa
sec
adc ZX0_src
sta ZX0_src
bcs plus1
dec ZX0_src+1
plus1:
txa
sec
adc ZX0_dst
sta ZX0_dst
bcs plus2
dec ZX0_dst+1
plus2:
txa
eor #$FF
tay
cop0: lda (ZX0_src), y
sta (ZX0_dst), y
iny
bne cop0
inc ZX0_src+1
inc ZX0_dst+1
asl bitr
bcs dzx0s_new_offset
; Copy from last offset (repeat N bytes from last offset)
; Elias(length)
jsr get_elias
dex
dzx0s_copy:
lda ZX0_dst
sbc offset ; C=0 from get_elias
sta pntr
lda ZX0_dst+1
sbc offset+1
sta pntr+1
txa
; sec
adc pntr
sta pntr
bcs plus3
dec pntr+1
sec
plus3:
txa
adc ZX0_dst
sta ZX0_dst
bcs plus4
dec ZX0_dst+1
plus4:
txa
eor #$FF
tay
cop1: lda (pntr), y
sta (ZX0_dst), y
iny
bne cop1
inc ZX0_dst+1
asl bitr
bcc decode_literal
; Copy from new offset (repeat N bytes from new offset)
; Elias(MSB(offset)) LSB(offset) Elias(length-1)
dzx0s_new_offset:
; Read elias code for high part of offset
jsr get_elias
beq exit ; Read a 0, signals the end
; Decrease and divide by 2
dex
txa
lsr ; @
sta offset+1
; Get low part of offset, a literal 7 bits
lda (ZX0_src), y
inc ZX0_src
bne plus5
inc ZX0_src+1
plus5:
; Divide by 2 low part
ror ; @
sta offset
; And get the copy length.
; Start elias reading with the bit already in carry:
ldx #1
bcc dzx0s_copy
jsr elias_skip1
bcc dzx0s_copy
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Read an elias-gamma interlaced code.
; ------------------------------------
get_elias:
; Initialize return value to #1
ldx #1
; Get first bit
asl bitr
beq elias_byte ; Need to read a new byte
elias_skip1:
txa
; Got ending bit, stop reading
bcc exit
elias_get: ; Read next data bit to LEN
asl bitr
rol ;@
tax
asl bitr
bne elias_skip1
elias_byte:
; Read new byte from stream
lda (ZX0_src), y
inc ZX0_src
bne plus6
inc ZX0_src+1
plus6:
;sec ; not needed, C=1 guaranteed from last bit
rol ;@
sta bitr
txa
; Got ending bit, stop reading
bcs elias_get
exit:
rts

View File

@ -0,0 +1,32 @@
.include "zp.inc"
.include "hardware.inc"
lzsa_test:
bit SET_GR
bit PAGE0
bit HIRES
bit FULLGR
; lda #<level5_lzsa
; sta getsrc_smc+1 ; LZSA_SRC_LO
; lda #>level5_lzsa
; sta getsrc_smc+2 ; LZSA_SRC_HI
;
; lda #$20
jsr full_decomp
; jsr decompress_lzsa2_fast
end:
jmp end
out_addr = $2000
.include "zx02_fast.s"
comp_data:
level5_zx02:
.incbin "level5.zx02"

View File

@ -0,0 +1,145 @@
; De-compressor for ZX02 files
; ----------------------------
;
; Decompress ZX02 data (6502 optimized format), optimized for minimal size:
; 130 bytes code, 72.6 cycles/byte in test file.
;
; Compress with:
; zx02 input.bin output.zx0
;
; (c) 2022 DMSC
; Code under MIT license, see LICENSE file.
ZP=$80
offset = ZP+0
ZX0_src = ZP+2
ZX0_dst = ZP+4
bitr = ZP+6
pntr = ZP+7
; Initial values for offset, source, destination and bitr
zx0_ini_block:
.byte $00, $00, <comp_data, >comp_data, <out_addr, >out_addr, $80
;--------------------------------------------------
; Decompress ZX0 data (6502 optimized format)
full_decomp:
; Get initialization block
ldy #7
copy_init: lda zx0_ini_block-1, y
sta offset-1, y
dey
bne copy_init
; Decode literal: Ccopy next N bytes from compressed file
; Elias(length) byte[1] byte[2] ... byte[N]
decode_literal:
jsr get_elias
cop0: jsr get_byte
jsr put_byte
bne cop0
asl bitr
bcs dzx0s_new_offset
; Copy from last offset (repeat N bytes from last offset)
; Elias(length)
jsr get_elias
dzx0s_copy:
lda ZX0_dst
sbc offset ; C=0 from get_elias
sta pntr
lda ZX0_dst+1
sbc offset+1
sta pntr+1
cop1:
lda (pntr), y
inc pntr
bne plus1
inc pntr+1
plus1: jsr put_byte
bne cop1
asl bitr
bcc decode_literal
; Copy from new offset (repeat N bytes from new offset)
; Elias(MSB(offset)) LSB(offset) Elias(length-1)
dzx0s_new_offset:
; Read elias code for high part of offset
jsr get_elias
beq exit ; Read a 0, signals the end
; Decrease and divide by 2
dex
txa
lsr ;@
sta offset+1
; Get low part of offset, a literal 7 bits
jsr get_byte
; Divide by 2
ror ;@
sta offset
; And get the copy length.
; Start elias reading with the bit already in carry:
ldx #1
jsr elias_skip1
inx
bcc dzx0s_copy
; Read an elias-gamma interlaced code.
; ------------------------------------
get_elias:
; Initialize return value to #1
ldx #1
bne elias_start
elias_get: ; Read next data bit to result
asl bitr
rol ;@
tax
elias_start:
; Get one bit
asl bitr
bne elias_skip1
; Read new bit from stream
jsr get_byte
;sec ; not needed, C=1 guaranteed from last bit
rol ;@
sta bitr
elias_skip1:
txa
bcs elias_get
; Got ending bit, stop reading
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
get_byte:
lda (ZX0_src), y
inc ZX0_src
bne plus3
inc ZX0_src+1
exit:
plus3: rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
put_byte:
sta (ZX0_dst),y
inc ZX0_dst
bne plus4
inc ZX0_dst+1
plus4: dex
rts

View File

@ -0,0 +1,32 @@
.include "zp.inc"
.include "hardware.inc"
lzsa_test:
bit SET_GR
bit PAGE0
bit HIRES
bit FULLGR
; lda #<level5_lzsa
; sta getsrc_smc+1 ; LZSA_SRC_LO
; lda #>level5_lzsa
; sta getsrc_smc+2 ; LZSA_SRC_HI
;
; lda #$20
jsr full_decomp
; jsr decompress_lzsa2_fast
end:
jmp end
out_addr = $2000
.include "zx02_small.s"
comp_data:
level5_zx02:
.incbin "level5.zx02"