xrick2gs/asm/LZ4.s

152 lines
4.4 KiB
ArmAsm

*
* ORCA/M Format!!
* LZ4 Decompress by Brutal Deluxe!!!
*
case on
longa on
longi on
Dummy1 start ASMCODE
end
*
* int LZ4_Unpack(u8* pDest, u8* pPackedSource);
*
LZ4_Unpack start ASMCODE
pDest equ 5
pPackedSource equ 9
phb
phk
plb
sep #$20
lda pPackedSource+2,s ; Pull out the src/dst banks
xba
lda pDest+2,s ; Pull out the src/dst banks
rep #$31
tax ; Temp save in X
lda pDest,s
sta LZ4_Dst+1
lda pPackedSource+1,s ; address of packed source + 4, is the unpacked len
sta upl+2
lda pPackedSource,s
adc #12
sta upl+1
upl lda >0 ; packed length
adc #16 ; 16 bytes for packed buffer header
adc pPackedSource,s ; start of packed buffer
tay ; y has the pack data stop address
anop ; 1st packed Byte offset
lda pPackedSource,s ; skip 16 byte header on the source
adc #16
pha
txa
plx
jsr ASM_LZ4_Unpack
tay
anop ; Copy the Return address
lda 1,s
sta pPackedSource,s
lda 3,s
sta pPackedSource+2,s
tsc
sec
sbc #-8
tcs
tya ; return length
plb
rtl
*-------------------------------------------------------------------------------
ASM_LZ4_Unpack 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 = Header Size = 1st Packed Byte offset
STA LZ4_Match_5+2 ; Y = Pack Data Size
XBA ; => Return in A the length of unpacked Data
STA LZ4_ReadToken+3
STA LZ4_Match_1+3
STA LZ4_GetLength_1+3
REP #$30
STY LZ4_Limit+1
*--
LZ4_Dst LDY #$0000 ; Init Target unpacked Data offset
LZ4_ReadToken LDA >$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 A ; Literal Length use the 4 bit
LSR A
LSR A
LSR A
*--
LZ4_Literal_2 DEC A ; 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 SBC >$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 LDA >$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
*-------------------------------------------------------------------------------
end