;---------------------------------------------------------
;
;   LZ4 block 68k depacker
;   Written by Arnaud Carré ( @leonard_coder )
;   https://github.com/arnaud-carre/lz4-68k
;
;   LZ4 technology by Yann Collet ( https://lz4.github.io/lz4/ )
;
;---------------------------------------------------------

; Normal version: 180 bytes ( 1.53 times faster than lz4_smallest.asm )
;
; input: a0.l : packed buffer
;        a1.l : output buffer
;        d0.l : LZ4 packed block size (in bytes)
;
; output: a1.l pointing to end of output buffer
;

lz4_depack:
        lea     (a0,d0.l),a2    ; packed buffer end

        moveq.l #0,d0
        moveq.l #0,d2
        moveq.l #0,d3
        moveq.l #15,d4
        bra.s   .tokenLoop

.lenOffset
        move.b  (a0)+,d1        ; read 16bits offset, little endian, unaligned
        move.b  (a0)+,-(sp)
        move.w  (sp)+,d3
        move.b  d1,d3
        movea.l a1,a3
        sub.l   d3,a3
        moveq.l #$f,d1
        and.w   d0,d1
        cmp.b   d4,d1
        bne.s   .small

.readLen0
        move.b  (a0)+,d2
        add.l   d2,d1
        not.b   d2
        beq.s   .readLen0

        addq.l  #4,d1
.copy
        move.b  (a3)+,(a1)+
        subq.l  #1,d1
        bne.s   .copy
        bra     .tokenLoop

.small
        add.w   d1,d1
        neg.w   d1
        jmp     .copys(pc,d1.w)
        REPT    15
        move.b  (a3)+,(a1)+
        ENDR
.copys
        move.b  (a3)+,(a1)+
        move.b  (a3)+,(a1)+
        move.b  (a3)+,(a1)+
        move.b  (a3)+,(a1)+

.tokenLoop
        move.b  (a0)+,d0
        move.l  d0,d1
        lsr.b   #4,d1
        beq.s   .lenOffset
        cmp.b   d4,d1
        beq.s   .readLen1

.litcopys
        add.w   d1,d1
        neg.w   d1
        jmp     .copys2(pc,d1.w)
        REPT    15
        move.b  (a0)+,(a1)+
        ENDR
.copys2
        cmpa.l  a0,a2
        bne     .lenOffset
        rts

.readLen1
        move.b  (a0)+,d2
        add.l   d2,d1
        not.b   d2
        beq.s   .readLen1

.litcopy
        move.b  (a0)+,(a1)+
        subq.l  #1,d1
        bne.s   .litcopy

        ; end test is always done just after literals
        cmpa.l  a0,a2
        bne     .lenOffset

.over
        rts

