aboutsummaryrefslogtreecommitdiff
path: root/tools/rasm_src/decrunch/lz4_docent.asm
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-11-05 11:22:55 +0000
committerJuan J. Martinez <jjm@usebox.net>2023-11-05 11:31:28 +0000
commit2fbdf974338bde8576efdae40a819a76b2391033 (patch)
tree64d41a37470143f142344f9a439d96de3e7918c2 /tools/rasm_src/decrunch/lz4_docent.asm
downloadkitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.tar.gz
kitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.zip
Initial import of the open source release
Diffstat (limited to 'tools/rasm_src/decrunch/lz4_docent.asm')
-rw-r--r--tools/rasm_src/decrunch/lz4_docent.asm118
1 files changed, 118 insertions, 0 deletions
diff --git a/tools/rasm_src/decrunch/lz4_docent.asm b/tools/rasm_src/decrunch/lz4_docent.asm
new file mode 100644
index 0000000..a0b2188
--- /dev/null
+++ b/tools/rasm_src/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
+
+