1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-26 08:32:00 +00:00
cc65/libsrc/common/lz4.s

287 lines
4.8 KiB
ArmAsm
Raw Normal View History

2017-06-06 15:48:25 +00:00
;
; Lauri Kasanen, 6 Jun 2017
; (C) Mega Cat Studios
; An optimized LZ4 decompressor
2017-06-09 07:42:24 +00:00
;
; Almost 7 times faster, uses no RAM (vs 14 bytes BSS), and takes 1/4 the space
; vs the official C source.
2017-06-06 15:48:25 +00:00
;
2017-06-06 16:31:16 +00:00
.importzp sp, sreg, regsave, regbank
.importzp tmp1, tmp2, tmp3, tmp4, ptr1, ptr2, ptr3, ptr4
.macpack longbranch
.import memcpy_upwards,pushax,popax
.export _decompress_lz4
2017-06-06 15:48:25 +00:00
2017-06-09 07:37:50 +00:00
out = regsave
written = regsave + 2
tmp = tmp1
token = tmp2
offset = ptr3
in = sreg
outlen = ptr4
2017-06-06 15:48:25 +00:00
; ---------------------------------------------------------------
; void decompress_lz4 (const u8 *in, u8 * const out, const u16 outlen)
; ---------------------------------------------------------------
2017-06-06 16:31:16 +00:00
.segment "CODE"
2017-06-06 15:48:25 +00:00
2017-06-06 16:31:16 +00:00
.proc _decompress_lz4: near
2017-06-06 15:48:25 +00:00
2017-06-09 07:37:50 +00:00
sta outlen
stx outlen+1
2017-06-06 15:48:25 +00:00
2017-06-06 16:31:16 +00:00
jsr popax
2017-06-09 07:37:50 +00:00
sta out
stx out+1
2017-06-06 15:48:25 +00:00
2017-06-06 16:31:16 +00:00
jsr popax
2017-06-09 07:37:50 +00:00
sta in
stx in+1
2017-06-06 15:48:25 +00:00
;
; written = 0;
;
2017-06-06 16:31:16 +00:00
lda #$00
2017-06-09 07:37:50 +00:00
sta written
2017-06-06 15:48:25 +00:00
;
; while (written < outlen) {
;
2017-06-06 16:31:16 +00:00
jmp L0046
2017-06-06 15:48:25 +00:00
;
; token = *in++;
;
2017-06-09 07:40:17 +00:00
L0004: ldy #$00
2017-06-09 07:37:50 +00:00
lda (in),y
sta token
2017-06-06 15:48:25 +00:00
2017-06-09 07:37:50 +00:00
inc in
2017-06-06 16:31:16 +00:00
bne L000A
2017-06-09 07:37:50 +00:00
inc in+1
2017-06-06 15:48:25 +00:00
L000A:
;
; offset = token >> 4;
;
2017-06-06 16:31:16 +00:00
ldx #$00
lsr a
lsr a
lsr a
lsr a
2017-06-09 07:37:50 +00:00
sta offset
stx offset+1
2017-06-06 15:48:25 +00:00
;
; token &= 0xf;
; token += 4; // Minmatch
;
2017-06-09 07:37:50 +00:00
lda token
2017-06-06 16:31:16 +00:00
and #$0F
clc
2017-06-09 07:40:17 +00:00
adc #$04
2017-06-09 07:37:50 +00:00
sta token
2017-06-06 15:48:25 +00:00
;
; if (offset == 15) {
;
2017-06-09 07:37:50 +00:00
lda offset
2017-06-06 16:31:16 +00:00
cmp #$0F
L0013: bne L001A
2017-06-06 15:48:25 +00:00
;
; tmp = *in++;
;
2017-06-09 07:40:17 +00:00
ldy #$00
2017-06-09 07:37:50 +00:00
lda (in),y
sta tmp
2017-06-06 15:48:25 +00:00
2017-06-09 07:37:50 +00:00
inc in
2017-06-06 16:31:16 +00:00
bne L0017
2017-06-09 07:37:50 +00:00
inc in+1
2017-06-06 15:48:25 +00:00
L0017:
;
; offset += tmp;
;
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc offset
sta offset
2017-06-06 16:31:16 +00:00
lda #$00
2017-06-09 07:37:50 +00:00
adc offset+1
sta offset+1
2017-06-06 15:48:25 +00:00
;
; if (tmp == 255)
;
2017-06-09 07:37:50 +00:00
lda tmp
2017-06-06 16:31:16 +00:00
cmp #$FF
2017-06-06 15:48:25 +00:00
;
; goto moreliterals;
;
2017-06-06 16:31:16 +00:00
jmp L0013
2017-06-06 15:48:25 +00:00
;
; if (offset) {
;
2017-06-09 07:37:50 +00:00
L001A: lda offset
ora offset+1
2017-06-06 16:31:16 +00:00
beq L001C
2017-06-06 15:48:25 +00:00
;
; memcpy(&out[written], in, offset);
;
2017-06-09 07:37:50 +00:00
lda out
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc written
2017-06-06 16:31:16 +00:00
sta ptr2
2017-06-09 07:37:50 +00:00
lda out+1
adc written+1
2017-06-06 16:31:16 +00:00
tax
lda ptr2
stx ptr2+1
jsr pushax
2017-06-09 07:37:50 +00:00
lda in
ldx in+1
2017-06-06 16:31:16 +00:00
sta ptr1
stx ptr1+1
2017-06-09 13:57:47 +00:00
; ldy #$00 - not needed as pushax zeroes Y
2017-06-06 16:31:16 +00:00
jsr memcpy_upwards
2017-06-06 15:48:25 +00:00
;
; written += offset;
;
2017-06-09 07:37:50 +00:00
lda offset
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc written
sta written
lda offset+1
adc written+1
sta written+1
2017-06-06 15:48:25 +00:00
;
; in += offset;
;
2017-06-09 07:37:50 +00:00
lda offset
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc in
sta in
lda offset+1
adc in+1
sta in+1
2017-06-06 15:48:25 +00:00
;
; if (written >= outlen)
;
2017-06-09 07:37:50 +00:00
L001C: lda written
cmp outlen
lda written+1
sbc outlen+1
2017-06-06 15:48:25 +00:00
;
; return;
;
2017-06-06 16:31:16 +00:00
bcc L0047
rts
2017-06-06 15:48:25 +00:00
;
; memcpy(&offset, in, 2);
;
2017-06-09 07:40:17 +00:00
L0047: ldy #$00
2017-06-09 07:37:50 +00:00
lda (in),y
sta offset
2017-06-06 16:31:16 +00:00
iny
2017-06-09 07:37:50 +00:00
lda (in),y
sta offset+1
2017-06-06 15:48:25 +00:00
;
; in += 2;
;
2017-06-06 16:31:16 +00:00
lda #$02
clc
2017-06-09 07:37:50 +00:00
adc in
sta in
2017-06-06 16:31:16 +00:00
bcc L002F
2017-06-09 07:37:50 +00:00
inc in+1
2017-06-06 15:48:25 +00:00
;
; copysrc = out + written - offset;
;
2017-06-09 07:37:50 +00:00
L002F: lda out
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc written
2017-06-09 13:57:47 +00:00
tay
2017-06-09 07:37:50 +00:00
lda out+1
adc written+1
2017-06-06 16:31:16 +00:00
tax
2017-06-09 13:57:47 +00:00
tya
2017-06-06 16:31:16 +00:00
sec
2017-06-09 07:37:50 +00:00
sbc offset
2017-06-06 16:31:16 +00:00
sta ptr1
txa
2017-06-09 07:37:50 +00:00
sbc offset+1
2017-06-06 16:31:16 +00:00
sta ptr1+1
2017-06-06 15:48:25 +00:00
;
; offset = token;
;
2017-06-06 16:31:16 +00:00
lda #$00
2017-06-09 07:37:50 +00:00
sta offset+1
lda token
sta offset
2017-06-06 15:48:25 +00:00
;
; if (token == 19) {
;
2017-06-06 16:31:16 +00:00
cmp #$13
L0045: bne L003C
2017-06-06 15:48:25 +00:00
;
; tmp = *in++;
;
2017-06-09 07:40:17 +00:00
ldy #$00
2017-06-09 07:37:50 +00:00
lda (in),y
sta tmp
2017-06-06 15:48:25 +00:00
2017-06-09 07:37:50 +00:00
inc in
2017-06-06 16:31:16 +00:00
bne L0039
2017-06-09 07:37:50 +00:00
inc in+1
2017-06-06 15:48:25 +00:00
L0039:
;
; offset += tmp;
;
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc offset
sta offset
2017-06-06 16:31:16 +00:00
tya
2017-06-09 07:37:50 +00:00
adc offset+1
sta offset+1
2017-06-06 15:48:25 +00:00
;
; if (tmp == 255)
;
2017-06-09 07:37:50 +00:00
lda tmp
2017-06-06 16:31:16 +00:00
cmp #$FF
2017-06-06 15:48:25 +00:00
;
; goto morematches;
;
2017-06-06 16:31:16 +00:00
jmp L0045
2017-06-06 15:48:25 +00:00
;
; memcpy(&out[written], copysrc, offset);
;
2017-06-09 07:37:50 +00:00
L003C: lda out
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc written
2017-06-06 16:31:16 +00:00
sta ptr2
2017-06-09 07:37:50 +00:00
lda out+1
adc written+1
2017-06-06 16:31:16 +00:00
tax
lda ptr2
stx ptr2+1
jsr pushax
jsr memcpy_upwards
2017-06-06 15:48:25 +00:00
;
; written += offset;
;
2017-06-09 07:37:50 +00:00
lda offset
2017-06-06 16:31:16 +00:00
clc
2017-06-09 07:37:50 +00:00
adc written
sta written
lda offset+1
adc written+1
L0046: sta written+1
2017-06-06 15:48:25 +00:00
;
; while (written < outlen) {
;
2017-06-09 07:37:50 +00:00
lda written
cmp outlen
lda written+1
sbc outlen+1
2017-06-06 16:31:16 +00:00
jcc L0004
2017-06-06 15:48:25 +00:00
2017-06-06 16:31:16 +00:00
rts
2017-06-06 15:48:25 +00:00
.endproc