2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; Lauri Kasanen, 6 Jun 2017
|
|
|
|
; (C) Mega Cat Studios
|
|
|
|
; An optimized LZ4 decompressor
|
|
|
|
;
|
|
|
|
|
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
|
|
|
|
|
|
|
_out = regsave
|
|
|
|
_written = regsave + 2
|
|
|
|
_tmp = tmp1
|
|
|
|
_token = tmp2
|
|
|
|
_offset = ptr3
|
|
|
|
_in = sreg
|
|
|
|
_outlen = ptr4
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------
|
|
|
|
; 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-06 16:31:16 +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
|
|
|
|
sta _out
|
|
|
|
stx _out+1
|
2017-06-06 15:48:25 +00:00
|
|
|
|
2017-06-06 16:31:16 +00:00
|
|
|
jsr popax
|
|
|
|
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
|
|
|
|
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-06 16:31:16 +00:00
|
|
|
L0004: ldy #0
|
|
|
|
lda (_in),y
|
|
|
|
sta _token
|
2017-06-06 15:48:25 +00:00
|
|
|
|
2017-06-06 16:31:16 +00:00
|
|
|
inc _in
|
|
|
|
bne L000A
|
|
|
|
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
|
|
|
|
sta _offset
|
|
|
|
stx _offset+1
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; token &= 0xf;
|
|
|
|
; token += 4; // Minmatch
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda _token
|
|
|
|
and #$0F
|
|
|
|
clc
|
|
|
|
adc #4
|
|
|
|
sta _token
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; if (offset == 15) {
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda _offset
|
|
|
|
cmp #$0F
|
|
|
|
L0013: bne L001A
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; tmp = *in++;
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
ldy #0
|
|
|
|
lda (_in),y
|
|
|
|
sta _tmp
|
2017-06-06 15:48:25 +00:00
|
|
|
|
2017-06-06 16:31:16 +00:00
|
|
|
inc _in
|
|
|
|
bne L0017
|
|
|
|
inc _in+1
|
2017-06-06 15:48:25 +00:00
|
|
|
L0017:
|
|
|
|
;
|
|
|
|
; offset += tmp;
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
clc
|
|
|
|
adc _offset
|
|
|
|
sta _offset
|
|
|
|
lda #$00
|
|
|
|
adc _offset+1
|
|
|
|
sta _offset+1
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; if (tmp == 255)
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda _tmp
|
|
|
|
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-06 16:31:16 +00:00
|
|
|
L001A: lda _offset
|
|
|
|
ora _offset+1
|
|
|
|
beq L001C
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; memcpy(&out[written], in, offset);
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda _out
|
|
|
|
clc
|
|
|
|
adc _written
|
|
|
|
sta ptr2
|
|
|
|
lda _out+1
|
|
|
|
adc _written+1
|
|
|
|
tax
|
|
|
|
lda ptr2
|
|
|
|
stx ptr2+1
|
|
|
|
jsr pushax
|
|
|
|
lda _in
|
|
|
|
ldx _in+1
|
|
|
|
sta ptr1
|
|
|
|
stx ptr1+1
|
|
|
|
ldy #0
|
|
|
|
jsr memcpy_upwards
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; written += offset;
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda _offset
|
|
|
|
clc
|
|
|
|
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-06 16:31:16 +00:00
|
|
|
lda _offset
|
|
|
|
clc
|
|
|
|
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-06 16:31:16 +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-06 16:31:16 +00:00
|
|
|
L0047: ldy #0
|
|
|
|
lda (_in),y
|
|
|
|
sta _offset
|
|
|
|
iny
|
|
|
|
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
|
|
|
|
adc _in
|
|
|
|
sta _in
|
|
|
|
bcc L002F
|
|
|
|
inc _in+1
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; copysrc = out + written - offset;
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
L002F: lda _out
|
|
|
|
clc
|
|
|
|
adc _written
|
|
|
|
pha
|
|
|
|
lda _out+1
|
|
|
|
adc _written+1
|
|
|
|
tax
|
|
|
|
pla
|
|
|
|
sec
|
|
|
|
sbc _offset
|
|
|
|
sta ptr1
|
|
|
|
txa
|
|
|
|
sbc _offset+1
|
|
|
|
sta ptr1+1
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; offset = token;
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda #$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-06 16:31:16 +00:00
|
|
|
ldy #0
|
|
|
|
lda (_in),y
|
|
|
|
sta _tmp
|
2017-06-06 15:48:25 +00:00
|
|
|
|
2017-06-06 16:31:16 +00:00
|
|
|
inc _in
|
|
|
|
bne L0039
|
|
|
|
inc _in+1
|
2017-06-06 15:48:25 +00:00
|
|
|
L0039:
|
|
|
|
;
|
|
|
|
; offset += tmp;
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
clc
|
|
|
|
adc _offset
|
|
|
|
sta _offset
|
|
|
|
tya
|
|
|
|
adc _offset+1
|
|
|
|
sta _offset+1
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; if (tmp == 255)
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda _tmp
|
|
|
|
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-06 16:31:16 +00:00
|
|
|
L003C: lda _out
|
|
|
|
clc
|
|
|
|
adc _written
|
|
|
|
sta ptr2
|
|
|
|
lda _out+1
|
|
|
|
adc _written+1
|
|
|
|
tax
|
|
|
|
lda ptr2
|
|
|
|
stx ptr2+1
|
|
|
|
jsr pushax
|
|
|
|
jsr memcpy_upwards
|
2017-06-06 15:48:25 +00:00
|
|
|
;
|
|
|
|
; written += offset;
|
|
|
|
;
|
2017-06-06 16:31:16 +00:00
|
|
|
lda _offset
|
|
|
|
clc
|
|
|
|
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-06 16:31:16 +00:00
|
|
|
lda _written
|
|
|
|
cmp _outlen
|
|
|
|
lda _written+1
|
|
|
|
sbc _outlen+1
|
|
|
|
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
|
|
|
|
|