⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flate.s

📁 zip压缩
💻 S
📖 第 1 页 / 共 2 页
字号:
        tst.w           mem_mode+INTSIZE-2-X(G)   ; test lower word if long        beq.s           @fm        jsr             _memflush               ; ignores the unshrink flag        bra.s           @fe@fm:    jsr             _flush@fe:    lea             8+INTSIZE+G_SIZE(sp),sp        move.l          (sp)+,d2                 ENDM                ENDC    ; ?FUNZIP; Here are the two bit-grabbing macros, defined in their NO_CHECK_EOF form:;;   #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE)<<k;k+=8;}};   #define DUMPBITS(n) {b>>=(n);k-=(n);};; Without NO_CHECK_EOF, NEEDBITS reads like this:;;   {while(k<(n)){int c=NEXTBYTE;if(c==EOF)return 1;b|=((ulg)c)<<k;k+=8;}};; NEEDBITS clobbers d0, d1, a0, and a1, none of which can be used as the arg; to the macro specifying the number of bits.  The arg can be a shortword memory; address, or d2-d7.  The result is copied into d1 as a word ready for masking.; DUMPBITS has no side effects; the arg must be a d-register (or immediate in the; range 1-8?) and only the lower byte is significant.NEEDBITS        MACRO   _1@nb:    cmp.w           _1,k            ; assert 0 < k <= 32 ... arg may be 0        bhs.s           @ne@loop:        NEXTBYTE                        ; returns in d0.l                 IFNDEF NO_CHECK_EOF        cmp.w           #EOF,d0        beq             error_return                 ENDC   ; !NO_CHECK_EOF@nok:   lsl.l           k,d0        or.l            d0,b        addq.w          #8,k        cmp.w           _1,k            ;bra.s @nb        bcs             @loop           ;@ne:    move.l          b,d1            ; return a copy of b in d1                ENDMDUMPBITS        MACRO   _1        lsr.l           _1,b            ; upper bits of _1 are ignored??        sub.b           _1,k                ENDM; This is a longword version of the mask_bits constant array:longmasks:      dc.l    $00000000,$00000001,$00000003,$00000007,$0000000F                dc.l    $0000001F,$0000003F,$0000007F,$000000FF,$000001FF                dc.l    $000003FF,$000007FF,$00000FFF,$00001FFF,$00003FFF                dc.l    $00007FFF,$0000FFFF,0,0,0,0,0,0,0,0,0,0,0,0,0,0    xdef longmasks  ; XXX; ******************************************************************************; 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:                IFDEF   REENT_G        move.l          8(a5),G                ELSE        lea             _G,G            ; G is now a global instance                IFDEF   X        lea             (X,G),G                ENDIF                ENDC        lea             longmasks,lmask        move.l          bb-X(G),b        MOVINT          bk-X(G),k                IFDEF   INT16        moveq           #0,w            ; keep this usable as longword                ENDC        MOVINT          wp-X(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]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,tnewtop:  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-X(G),a0                ELSE          move.l        redirslide-X(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,tdistop:    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             bra        error_return            ; then faildisgo:      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         distopdisbrk:   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      edocopy:    move.l       #WSIZE,e        ; copy the duplicated string           and.l        #WSIZE-1,d      ; ...but first check if the length           cmp.l        d,w             ; will overflow the window...           blo.s        ddgw            sub.l       w,e           bra.s        dadwddgw:       sub.l       d,edadw:      cmp.l        #$08000,e       ; also, only copy <= 32K, so we can           bls.s        dnox            ; use a dbra loop to do it            move.l      #$08000,ednox:      cmp.l        n,e           bls.s        delen            move.l      n,edelen:     sub.l        e,n             ; size of sub-block to copy in this pass                IF      SIZEOF_slide>4           lea          redirslide-X(G),a0                ELSE           move.l       redirslide-X(G),a0                ENDC           move.l       a0,a1           add.l        w,a0            ; w and d are valid longwords           add.l        d,a1; Now at this point we could do tests to see if we should use an optimized; large block copying method such as movem's, but since (a) such methods require; the source and destination to be compatibly aligned -- and odd bytes at each; end have to be handled separately, (b) it's only worth checking for if the; block is pretty large, and (c) most strings are only a few bytes long, we're; just not going to bother.  Therefore we check above to make sure we move at; most 32K in one sub-block, so a dbra loop can handle it.dshort:    move.l       e,d0           subq         #1,d0           ; assert >= 0dspin:      move.b      (a1)+,(a0)+            dbra        d0,dspin           add.l        e,w           add.l        e,d           cmp.l        #WSIZE,w           blo.s        dnfl            FLUSH       w            ext.l       d0              ; does a test as it casts to long            bne         return            moveq       #0,wdnfl:      tst.l        n               ; need to do more sub-blocks?           bne          docopy          ; yes          moveq         #0,e            ; restore zeroness in upper bytes of e          bra           main_loop       ; break (newtop loop)nonleng: cmp.w          #INVALID,e      ; bottom of newtop loop -- misc. code         bne.s          tailgo          ; invalid code?          bra           error_return    ; then failtailgo:  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            newtopfinish: MOVINT          w,wp-X(G)       ; done: restore cached globals        MOVINT          k,bk-X(G)        move.l          b,bb-X(G)        moveq           #RET_OK,d0      ; return "no error"return: movem.l         (sp)+,savregs        unlk            a5        rtserror_return:        moveq           #RET_ERR,d0     ; return "error occured"        bra             return

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -