mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-01-19 15:30:08 +00:00
compression: update comparison
This commit is contained in:
parent
1ae6ddac20
commit
3b76177bec
@ -15,12 +15,15 @@ LINKERSCRIPTS = ../../linker_scripts/
|
|||||||
|
|
||||||
all: compression_test.dsk
|
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
|
cp $(EMPTYDISK) compression_test.dsk
|
||||||
$(DOS33) -y compression_test.dsk SAVE A HELLO
|
$(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 LZSA_TEST
|
||||||
$(DOS33) -y compression_test.dsk BSAVE -a 0x6000 EXOMIZER_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
|
ZX02_OPT_TEST: zx02_opt_test.o
|
||||||
ld65 -o ZX02_TEST zx02_test.o -C $(LINKERSCRIPTS)/apple2_6000.inc
|
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:
|
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
|
||||||
|
@ -4,6 +4,8 @@ LEVEL5.PNG (hires background image from Lemmings, 8k)
|
|||||||
Compressed Decompression
|
Compressed Decompression
|
||||||
File size Routine Size Time (cycles) FPS
|
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(?) ??? ?????
|
exomizer 3851(?) ??? ?????
|
||||||
zx02_opt 3869 138 bytes 7076f = 460,655 ~2.2
|
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
|
||||||
|
179
compression/comparison/zx02_fast.s
Normal file
179
compression/comparison/zx02_fast.s
Normal 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
|
||||||
|
|
32
compression/comparison/zx02_fast_test.s
Normal file
32
compression/comparison/zx02_fast_test.s
Normal 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"
|
145
compression/comparison/zx02_small.s
Normal file
145
compression/comparison/zx02_small.s
Normal 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
|
||||||
|
|
32
compression/comparison/zx02_small_test.s
Normal file
32
compression/comparison/zx02_small_test.s
Normal 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"
|
Loading…
x
Reference in New Issue
Block a user