mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-01-01 05:31:52 +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
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
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…
Reference in New Issue
Block a user