From 30bf0f51335e87812ffeb54e9437f0b6a1514d67 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Tue, 6 Sep 2022 07:37:20 +0100 Subject: Updated rasm to 1.7 --- tools/rasm/decrunch/unlzsa2_fast.asm | 189 +++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100755 tools/rasm/decrunch/unlzsa2_fast.asm (limited to 'tools/rasm/decrunch/unlzsa2_fast.asm') diff --git a/tools/rasm/decrunch/unlzsa2_fast.asm b/tools/rasm/decrunch/unlzsa2_fast.asm new file mode 100755 index 0000000..8c6b5b1 --- /dev/null +++ b/tools/rasm/decrunch/unlzsa2_fast.asm @@ -0,0 +1,189 @@ +; +; Speed-optimized LZSA2 decompressor by spke & uniabis (216 bytes) +; + + DEFINE UNROLL_LONG_MATCHES ; uncomment for faster decompression of very compressible data (+38 bytes) +; DEFINE BACKWARD_DECOMPRESS ; uncomment for data compressed with option -b + + IFNDEF BACKWARD_DECOMPRESS + + MACRO NEXT_HL + inc hl + ENDM + + MACRO ADD_OFFSET + ex de,hl : add hl,de + ENDM + + MACRO COPY1 + ldi + ENDM + + MACRO COPYBC + ldir + ENDM + + ELSE + + MACRO NEXT_HL + dec hl + ENDM + + MACRO ADD_OFFSET + ex de,hl : ld a,e : sub l : ld l,a + ld a,d : sbc h : ld h,a ; 4*4+3*4 = 28t / 7 bytes + ENDM + + MACRO COPY1 + ldd + ENDM + + MACRO COPYBC + lddr + ENDM + + ENDIF + + +macro DecompressLZSA2 +@lzsa2 + ; A' stores next nibble as %1111.... or assumed to contain trash + ; B is assumed to be 0 + ld b,0 : scf : exa : jr .ReadToken + +.ManyLiterals: ld a,18 : add (hl) : NEXT_HL : jr nc,.CopyLiterals + ld c,(hl) : NEXT_HL + ld a,b : ld b,(hl) + jr .NEXTHLuseBC + + +.MoreLiterals: ld b,(hl) : NEXT_HL + scf : exa : jr nc,.noUpdatemoar + + ld a,(hl) : or #F0 : exa + ld a,(hl) : NEXT_HL : or #0F + rrca : rrca : rrca : rrca + +.noUpdatemoar ;sub #F0-3 : cp 15+3 : jr z,ManyLiterals + inc a : jr z,.ManyLiterals : sub #F0-3+1 + +.CopyLiterals: ld c,a : ld a,b : ld b,0 + COPYBC + push de : or a : jp p,.CASE0xx ;: jr CASE1xx + + cp %11000000 : jr c,.CASE10x + +.CASE11x cp %11100000 : jr c,.CASE110 + + ; "111": repeated offset +.CASE111: ld de,ix : jr .MatchLen + + +.Literals0011: jr nz,.MoreLiterals + + ; if "LL" of the byte token is equal to 0, + ; there are no literals to copy +.NoLiterals: or (hl) : NEXT_HL + push de : jp m,.CASE1xx + + ; short (5 or 9 bit long) offsets +.CASE0xx ld d,#FF : cp %01000000 : jr c,.CASE00x + + ; "01x": the case of the 9-bit offset +.CASE01x: cp %01100000 : rl d + +.ReadOffsetE ld e,(hl) : NEXT_HL + +.SaveOffset: LD ix,de + +.MatchLen: inc a : and %00000111 : jr z,.LongerMatch : inc a + +.CopyMatch: ld c,a +;.useC + ex (sp),hl ; BC = len, DE = offset, HL = dest, SP ->[dest,src] + ADD_OFFSET ; BC = len, DE = dest, HL = dest-offset, SP->[src] + COPY1 + COPYBC +.popSrc pop hl + + ; compressed data stream contains records + ; each record begins with the byte token "XYZ|LL|MMM" +.ReadToken: ld a,(hl) : and %00011000 : jp pe,.Literals0011 ; process the cases 00 and 11 separately + + rrca : rrca : rrca + + ld c,a : ld a,(hl) ; token is re-read for further processing +.NEXTHLuseBC NEXT_HL + COPYBC + + ; the token and literals are followed by the offset + push de : or a : jp p,.CASE0xx + +.CASE1xx cp %11000000 : jr nc,.CASE11x + + ; "10x": the case of the 13-bit offset +.CASE10x: ld c,a : exa : jr nc,.noUpdatecase10x + + ld a,(hl) : or #F0 : exa + ld a,(hl) : NEXT_HL : or #0F + rrca : rrca : rrca : rrca + +.noUpdatecase10x ld d,a : ld a,c + cp %10100000 : dec d : rl d : jr .ReadOffsetE + + + + ; "110": 16-bit offset +.CASE110: ld d,(hl) : NEXT_HL : jr .ReadOffsetE + + + + + ; "00x": the case of the 5-bit offset +.CASE00x: ld c,a : exa : jr nc,.noUpdatecase00x + + ld a,(hl) : or #F0 : exa + ld a,(hl) : NEXT_HL : or #0F + rrca : rrca : rrca : rrca + +.noUpdatecase00x ld e,a : ld a,c + cp %00100000 : rl e : jp .SaveOffset + + +.LongerMatch: scf : exa : jr nc,.noUpdatelongermatch + + ld a,(hl) : or #F0 : exa + ld a,(hl) : NEXT_HL : or #0F + rrca : rrca : rrca : rrca + +.noUpdatelongermatch sub #F0-9 : cp 15+9 : jr c,.CopyMatch + + +.LongMatch: add (hl) : NEXT_HL : jr c,.VeryLongMatch + + ld c,a +.useC ex (sp),hl + ADD_OFFSET + COPY1 + + ; this is an unrolled equivalent of LDIR + xor a : sub c + and 32-1 : add a + ld (.jrOffset),a : jr nz,$+2 +.jrOffset EQU $-1 +.fastLDIR repeat 32 + COPY1 + rend + jp pe,.fastLDIR + jp .popSrc + +.VeryLongMatch: ld c,(hl) : NEXT_HL + ld b,(hl) : NEXT_HL : jr nz,.useC + pop de : ret + +mend + + + + + -- cgit v1.2.3