From 2682bc5d1d864341aaeb42a449db73c3ecd16d70 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Wed, 30 Dec 2020 19:07:31 +0000 Subject: Initial import --- tools/rasm/decrunch/lz4_docent.asm | 118 +++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 tools/rasm/decrunch/lz4_docent.asm (limited to 'tools/rasm/decrunch/lz4_docent.asm') diff --git a/tools/rasm/decrunch/lz4_docent.asm b/tools/rasm/decrunch/lz4_docent.asm new file mode 100644 index 0000000..a0b2188 --- /dev/null +++ b/tools/rasm/decrunch/lz4_docent.asm @@ -0,0 +1,118 @@ +; decompress raw lz4 data packet +; on entry hl - start of packed buffer, de - destination buffer, bc - size of packed data +LZ4_decompress_raw: + push de ; store original destination pointer + push hl ; store start of compressed data source + add hl,bc ; calculate end address of compressed block + ld b,h ; move end address of compressed data to bc + ld c,l + pop hl ; restore start of compressed data source + push bc ; store end address of compessed data +; now hl - start of packed buffer, de - destination, bc - end of packed buffer + ld b,0 ; clear b, c is set later + +; get decompression token +LZ4_GetToken: + xor a ; reset c flag for sbc later + ld a,(hl) ; read token + inc hl + push af ; store token +; unpack 4 high bits to get the length of literal + rlca + rlca + rlca + rlca +; copy literals + and #f ; token can be max 15 - mask out unimportant bits + jr z,LZ4_skipcalc ; there is no literals, skip calculation of literal size + ld c,a ; set the count for calculation + cp #f ; if literal size <15 + jr nz, LZ4_copyliterals ; copy literal, else +; calculate total literal size by adding contents of following bytes + push de ; store destination + ex de,hl +; a = size of literal to copy, de=pointer to data to be added + ld h,0 ; set hl with size of literal to copy + ld l,a + +LZ4_calcloop: + ld a,(de) ; get additional literal size to add + inc de + ld c,a ; set bc to the length of literal + add hl,bc ; add it to the total literal length + cp #ff ; if literal=255 + jr z,LZ4_calcloop ; continue calculating the total literal size + ld b,h ; store total literal size to copy in bc + ld c,l + ex de,hl ; hl now contains current compressed data pointer + pop de ; restore destination to de + +LZ4_copyliterals: + ldir ; copy literal to destination + +LZ4_skipcalc: +; check for end of compressed data + pop af ; restore token, carry is cleared because of xor a at the beginning of GetToken + pop bc ; restore end address of compressed data + push hl ; store current compressed data pointer + sbc hl, bc ; check if we reached the end of compressed data buffer + pop hl ; restore current compressed data pointer + jr z,LZ4_decompress_success ; decompression finished + push bc ; store end address of compressed data + +; Copy Matches + and #f ; token can be max 15 - mask out unimportant bits. resets also c flag for sbc later +; get the offset + ld c,(hl) + inc hl + ld b,(hl) ; bc now contains the offset + inc hl + push hl ; store current compressed data pointer + push de ; store destination pointer + + ex de,hl + sbc hl,bc ; calculate from the offset the new decompressed data source to copy from +; hl contains new copy source, de source ptr + + ld b,0 ; load bc with the token + ld c,a + cp #f ; if matchlength <15 + jr nz, LZ4_copymatches ; copy matches. else + +; calculate total matchlength by adding additional bytes + push hl ; store current decompressed data source +; a = size of match to copy, de= pointer to data to be added + ld h,0 ; set hl with initial matchlength to copy + ld l,a +LZ4_calcloop2: + ld a,(de) ; get additional matchlength to add + inc de + ld c,a ; set bc to the matchlength + add hl,bc ; add it to the total match length + cp #ff ; if matchlength=255 + jr z,LZ4_calcloop2 ; continue calculating the total match length + ld b,h ; store total matchlength to copy in bc + ld c,l + pop hl ; restore current decompressed data source + pop af ; set stack to proper position by restoring destination pointer temporarily into af + ex de,hl + ex (sp),hl ; update current compressed data pointer on the stack to the new value from de + ex de,hl + push af ; restore stack + +LZ4_copymatches: + pop de ; restore destination pointer + inc bc ; add base length of 4 to get the correct size of matchlength + inc bc + inc bc + inc bc + ldir ; copy match + pop hl ; restore current compressed data source + jr LZ4_GetToken ; continue decompression +LZ4_decompress_success: + pop hl ; store destination pointer + sbc hl,de ; calculate the number of decompressed bytes + xor a ; clear exit code + ret + + -- cgit v1.2.3