Skip to content

Instantly share code, notes, and snippets.

@digarok
Created October 29, 2018 15:35
Show Gist options
  • Save digarok/88402a5a0e8a61fe85cbabdf072fcf85 to your computer and use it in GitHub Desktop.
Save digarok/88402a5a0e8a61fe85cbabdf072fcf85 to your computer and use it in GitHub Desktop.
LZ4 65816 decompress special format
* Format is : 2-byte length word followed by compressed stream
MX %00
*-------------------------------------------------------------------------------
LZ4_Unpack STY LZ4_DestOffset+1 ; Y = Destination offset
STX LZ4_HeaderLenByte+1 ; X = Src offset (with 2 byte len header)
STX LZ4_HeaderAddr+1 ; and the address of the offset
STA LZ4_Literal_3+1 ; Uncompress a LZ4 Packed Data buffer (64 KB max)
SEP #$20 ; A = Bank Src,Bank Dst
STA LZ4_Match_5+1 ; X = SRC Byte offset
STA LZ4_Match_5+2 ;
XBA ; => Return in A the length of unpacked Data
STA LZ4_ReadToken+3
STA LZ4_Match_1+3
STA LZ4_GetLength_1+3
STA LZ4_HeaderLenByte+3
REP #$30
LZ4_HeaderLenByte LDAL $AA0000 ; Y = the packed data size
INC ;
INC ; skip 2 bytes of length word
CLC
LZ4_HeaderAddr ADC #$FFFF ; and add address of packed data
STA LZ4_Limit+1
INX ; advance src index past len bytes
INX
*--
LZ4_DestOffset LDY #$0000 ; Init Target unpacked Data offset
LZ4_ReadToken LDAL $AA0000,X ; Read Token Byte
INX
STA LZ4_Match_2+1
*----------------
LZ4_Literal AND #$00F0 ; >>> Process Literal Bytes <<<
BEQ LZ4_Limit ; No Literal
CMP #$00F0
BNE LZ4_Literal_1
JSR LZ4_GetLengthLit ; Compute Literal Length with next bytes
BRA LZ4_Literal_2
LZ4_Literal_1 LSR ; Literal Length use the 4 bit
LSR
LSR
LSR
*--
LZ4_Literal_2 DEC ; Copy A+1 Bytes
LZ4_Literal_3 MVN $AA,$BB ; Copy Literal Bytes from packed data buffer
PHK ; X and Y are auto incremented
PLB
*----------------
LZ4_Limit CPX #$AAAA ; End Of Packed Data buffer ?
BEQ LZ4_End
*----------------
LZ4_Match TYA ; >>> Process Match Bytes <<<
SEC
LZ4_Match_1 SBCL $AA0000,X ; Match Offset
INX
INX
STA LZ4_Match_4+1
*--
LZ4_Match_2 LDA #$0000 ; Current Token Value
AND #$000F
CMP #$000F
BNE LZ4_Match_3
JSR LZ4_GetLengthMat ; Compute Match Length with next bytes
LZ4_Match_3 CLC
ADC #$0003 ; Minimum Match Length is 4 (-1 for the MVN)
*--
PHX
LZ4_Match_4 LDX #$AAAA ; Match Byte Offset
LZ4_Match_5 MVN $BB,$BB ; Copy Match Bytes from unpacked data buffer
PHK ; X and Y are auto incremented
PLB
PLX
*----------------
BRA LZ4_ReadToken
*----------------
LZ4_GetLengthLit LDA #$000F ; Compute Variable Length (Literal or Match)
LZ4_GetLengthMat STA LZ4_GetLength_2+1
LZ4_GetLength_1 LDAL $AA0000,X ; Read Length Byte
INX
AND #$00FF
CMP #$00FF
BNE LZ4_GetLength_3
CLC
LZ4_GetLength_2 ADC #$000F
STA LZ4_GetLength_2+1
BRA LZ4_GetLength_1
LZ4_GetLength_3 ADC LZ4_GetLength_2+1
RTS
*----------------
LZ4_End TYA ; A = Length of Unpack Data
RTS
*-------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment