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

📄 match_68.a

📁 汇编代码大全
💻 A
字号:
; This is a 68000 assembly language version of the Zip function; longest_match().  It is written for any 680x0 based computer, but at this; time the feature for runtime testing of CPU type is only supported for the; Amiga.  Hopefully a similar test for the Macintosh is possible, and for any; other system that supports both 68000 and 68020+ CPUs.  This is written by; Paul Kienitz, partially derived from a simpler version by Carsten Steger,; derived in turn from a 386 assembly function by Jean-loup Gailly and Uwe; Rommel... but also based directly on the C original.  No rights reserved.; ; The main difference of this from other longest_match() implementations is; that it includes both byte based and word based versions of the function,; and various symbols can be defined to select whether to use one routine or; the other, or to do a platform-specific test at runtime.  The symbols that; can be used to select behavior are as follows:;;   CPU020     if defined, use 68020 instructions always;   CPUTEST    if defined, check at runtime for CPU type.  Another symbol;               specifying the platform-specific test must be used with this.;               If neither of these is defined, use 68000 instructions only.;   AMIGA      use Amiga-specific test for 68020, if CPUTEST defined.  Also;               tells it to let a0/a1/d1 be clobbered by functions.;   ATSIGN     define entry symbols in @foo form as well as _foo, with;               @longest_match taking its parm in d0 instead of on the stack.;; NOTE: no provision is made for 16 bit ints.  All external int variables are; treated as 32 bit values.  This also assumes that longest_match's result is; returned in D0.        IFND    CPU020        IFND    CPUTESTCPU000  equ     1        ENDC        ENDC; global variables:        xref    _max_chain_length   ; unsigned int        xref    _prev_length        ; unsigned int        xref    _match_start        ; unsigned int        xref    _strstart           ; unsigned int        xref    _good_match         ; signed int        xref    _nice_match         ; signed int        xref    _window             ; array of unsigned char        xref    _prev               ; array of unsigned short; our entry points:        xdef    _match_init         ; void match_init(void);        xdef    _longest_match      ; int longest_match(unsigned cur_match);        IFD     ATSIGN        xdef    @match_init         ; for SAS assembler        xdef    @longest_match      ; ditto        ENDC        ; flag variable for remembering CPU type:        IFD     CPUTEST        section cpuflag,datais020:  ds.w    1        ENDC        section match,code_match_init:        IFD    ATSIGN@match_init:        ENDC        IFD     CPUTEST         ; now check for platform type        IFD     AMIGA           ; Amiga specific test for '020 CPU:        xref    _SysBase        NOLIST        INCLUDE       'exec/execbase.i'        LIST        clr.w   is020           ; default value is 68000         move.l  _SysBase,a0        btst    #AFB_68020,AttnFlags+1(a0)        beq.s   cheap        move.w  #1,is020cheap:        ELSE ; !AMIGA !!   Write an '020-detector for your system here!        ENDC ; AMIGA        ENDC ; CPUTEST        rts                ; match_init consists only of rts if CPUTEST unset        IFD     AMIGASAVEREGS        reg     d3-d7/a2/a3/a5      ; don't protect d0/d1/a0/a1        ELSESAVEREGS        reg     d1/d3-d7/a0-a3/a5   ; protect all but d0 return val        ENDCCur_Match       equr    d0                  ; Must be in d0!Best_Len        equr    d1Scan_Start      equr    d3Scan_End        equr    d4Limit           equr    d5Chain_Length    equr    d6Scan_Test       equr    d7Scan            equr    a0Match           equr    a1Prev_Address    equr    a2Scan_Ini        equr    a3Match_Ini       equr    a5MAX_MATCH       equ     258MIN_MATCH       equ     3WSIZE           equ     32768MAX_DIST        equ     WSIZE-MAX_MATCH-MIN_MATCH-1_longest_match:        move.l  4(sp),Cur_Match         ; stack arg to register        IFD     ATSIGN@longest_match:        ENDC        movem.l SAVEREGS,-(sp); setup steps common to byte and word versions:        move.l  _max_chain_length,Chain_Length        move.l  _prev_length,Best_Len        lea     _prev,Prev_Address        lea     _window,Match_Ini        move.l  _strstart,Limit        move.l  Match_Ini,Scan_Ini        addq    #MIN_MATCH,Match_Ini        add.l   Limit,Scan_Ini        subi.w  #MAX_DIST,Limit        bhi.s   limit_ok        moveq   #0,Limitlimit_ok:        cmp.l   _good_match,Best_Len        bcs.s   length_ok        lsr.l   #2,Chain_Lengthlength_ok:        subq.l  #1,Chain_Length        IFD     CPUTEST        tst.w   is020               ; can we use '020 stuff today?        bne     WORD_match        ENDC        IFND    CPU020; for 68000 or 68010, use byte operations:        moveq   #0,Scan_Start       ; clear 2nd and 4th bytes, use 1st & 3rd        moveq   #0,Scan_End        moveq   #0,Scan_Test        move.b  (Scan_Ini),Scan_Start        swap    Scan_Start        move.b  1(Scan_Ini),Scan_Start        move.b  -1(Scan_Ini,Best_Len),Scan_End        swap    Scan_End        move.b  0(Scan_Ini,Best_Len),Scan_End        bra.s   bdo_scanblong_loop:        move.b  -1(Scan_Ini,Best_Len),Scan_End        swap    Scan_End        move.b  0(Scan_Ini,Best_Len),Scan_Endbshort_loop:        add.w   Cur_Match,Cur_Match        move.w  0(Prev_Address,Cur_Match.l),Cur_Match        cmp.l   Limit,Cur_Match        dbls    Chain_Length,bdo_scan        bra     returnbdo_scan:        move.l  Match_Ini,Match        add.l   Cur_Match,Match        move.b  -MIN_MATCH-1(Match,Best_Len),Scan_Test        swap    Scan_Test        move.b  -MIN_MATCH(Match,Best_Len),Scan_Test        cmp.l   Scan_Test,Scan_End        bne.s   bshort_loop        move.b  -MIN_MATCH(Match),Scan_Test        swap    Scan_Test        move.b  -MIN_MATCH+1(Match),Scan_Test        cmp.l   Scan_Test,Scan_Start        bne.s   bshort_loop        move.w  #(MAX_MATCH-MIN_MATCH),Scan_Test        lea     MIN_MATCH(Scan_Ini),Scanbscan_loop:        cmpm.b  (Match)+,(Scan)+        dbne    Scan_Test,bscan_loop        subq    #1,Scan        sub.l   Scan_Ini,Scan        cmp.l   Best_Len,Scan        bls.s   bshort_loop        move.l  Scan,Best_Len        move.l  Cur_Match,_match_start        cmp.l   _nice_match,Best_Len        bcs.s   blong_loop        IFD     CPUTEST        bra     return        ENDC        ENDC ; !CPU020        IFND    CPU000        ; for 68020 or higher, use word operations even on odd addresses:WORD_match:        move.w  (Scan_Ini),Scan_Start        move.w  -1(Scan_Ini,Best_Len),Scan_End        bra.s   wdo_scanwlong_loop:        move.w  -1(Scan_Ini,Best_Len),Scan_Endwshort_loop:        add.w   Cur_Match,Cur_Match        move.w  (Prev_Address,Cur_Match.l),Cur_Match        cmp.l   Limit,Cur_Match        dbls    Chain_Length,wdo_scan        bra.s   returnwdo_scan:        move.l  Match_Ini,Match        add.l   Cur_Match,Match        cmp.w   -MIN_MATCH-1(Match,Best_Len),Scan_End        bne.s   wshort_loop        cmp.w   -MIN_MATCH(Match),Scan_Start        bne.s   wshort_loop        moveq   #((MAX_MATCH-MIN_MATCH)/2),Scan_Test    ; value = 127        lea     MIN_MATCH(Scan_Ini),Scanwscan_loop:        cmpm.w  (Match)+,(Scan)+        dbne    Scan_Test,wscan_loop        subq    #2,Scan        move.b  -MIN_MATCH+1(Match),Scan_Test        cmp.b   (Scan),Scan_Test        bne     steven        addq    #1,Scansteven:        sub.l   Scan_Ini,Scan        cmp.l   Best_Len,Scan        bls.s   wshort_loop        move.l  Scan,Best_Len        move.l  Cur_Match,_match_start        cmp.l   _nice_match,Best_Len        bcs.s   wlong_loop        ENDC ; !CPU000return:        move.l  Best_Len,d0             ; function return value        movem.l (sp)+,SAVEREGS        rts        end

⌨️ 快捷键说明

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