Archive-Unzip-Burst
view release on metacpan or search on metacpan
unzip-6.0/amiga/flate.a view on Meta::CPAN
; ******************************************************************************
; Here we go, finally:
xdef _inflate_codes
_inflate_codes:
link a5,#-8
movem.l savregs,-(sp)
; 8(a5) = tl, 12(a5) = td, 16(a5) = bl, 18|20(a5) = bd... add 4 for REENT_G
; -4(a5) = ml, -8(a5) = md, both unsigned long.
; Here we cache some globals and args:
IFD REENT_G
move.l 8(a5),G
ELSE
lea _G,G ; G is now a global instance
ENDC
lea longmasks,lmask
move.l bb(G),b
MOVINT bk(G),k
IFD INT16
moveq #0,w ; keep this usable as longword
ENDC
MOVINT wp(G),w
moveq #0,e ; keep this usable as longword too
MOVINT 16+G_SIZE(a5),d0
asl.w #2,d0
move.l (lmask,d0.w),-4(a5) ; ml = mask_bits[bl]
MOVINT 16+INTSIZE+G_SIZE(a5),d0
asl.w #2,d0
move.l (lmask,d0.w),-8(a5) ; md = mask_bits[bd]
xdef newtop
xdef nonlit
xdef distop
xdef docopy
xdef nonleng
xdef tailgo
xdef finish
xdef disbrk
main_loop:
NEEDBITS 14+INTSIZE+G_SIZE(a5) ; (unsigned) bl
and.l -4(a5),d1 ; ml
IFNE SIZEOF_huft-8
mulu #SIZEOF_huft,d1
ELSE
asl.l #3,d1
ENDC
move.l 8+G_SIZE(a5),t ; tl
add.l d1,t
newtop: move.b h_b(t),d0
DUMPBITS d0
move.b h_e(t),e
cmp.b #32,e ; is it a literal?
bne nonlit ; no
move.w h_v_n(t),d0 ; yes
IFGT SIZEOF_slide-4
lea redirslide(G),a0
ELSE
move.l redirslide(G),a0
ENDC
move.b d0,(a0,w.l) ; stick in the decoded byte
addq.l #1,w
cmp.l #WSIZE,w
blo main_loop
FLUSH w
ext.l d0 ; does a test as it casts long
bne return
moveq #0,w
bra main_loop ; break (newtop loop)
nonlit: cmp.b #31,e ; is it a length?
beq finish ; no, it's the end marker
bhi nonleng ; no, it's something else
NEEDBITS e ; yes: a duplicate string
move.w e,d0
asl.w #2,d0
and.l (lmask,d0.w),d1
moveq #0,n ; cast h_v_n(t) to long
move.w h_v_n(t),n
add.l d1,n ; length of block to copy
DUMPBITS e
NEEDBITS 14+(2*INTSIZE)+G_SIZE(a5) ; bd, lower word if long
and.l -8(a5),d1 ; md
IFNE SIZEOF_huft-8
mulu #SIZEOF_huft,d1
ELSE
asl.l #3,d1
ENDC
move.l 12+G_SIZE(a5),t ; td
add.l d1,t
distop: move.b h_b(t),d0
DUMPBITS d0
move.b h_e(t),e
cmp.b #32,e ; is it a literal?
blo.s disbrk ; then stop doing this
cmp.b #INVALID,e ; is it bogus?
bne.s disgo
moveq #RET_ERR,d0 ; then fail
bra return
disgo: and.w #$001F,e
NEEDBITS e
move.w e,d0
asl.w #2,d0
and.l (lmask,d0.w),d1
IFNE SIZEOF_huft-8
mulu #SIZEOF_huft,d1
ELSE
asl.l #3,d1
ENDC
move.l h_v_t(t),t
add.l d1,t
bra distop
disbrk: NEEDBITS e
move.l e,d0
asl.w #2,d0
and.l (lmask,d0.w),d1
move.l w,d
move.w h_v_n(t),d0 ; assert top word of d0 is zero
sub.l d0,d
sub.l d1,d ; distance back to copy the block
DUMPBITS e
( run in 0.480 second using v1.01-cache-2.11-cpan-140bd7fdf52 )