1;===========================================================================
2; Copyright (c) 1990-1999 Info-ZIP.  All rights reserved.
3;
4; See the accompanying file LICENSE, version 1999-Oct-05 or later
5; (the contents of which are also included in zip.h) for terms of use.
6; If, for some reason, both of these files are missing, the Info-ZIP license
7; also may be found at:  ftp://ftp.cdrom.com/pub/infozip/license.html
8;===========================================================================
9; match.a -- optional optimized asm version of longest match in deflate.c
10; Written by Jean-loup Gailly
11; Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
12; using the code in match.S.
13; The major change in this code consists of removing all unaligned
14; word accesses, because they cause 68000-based Amigas to crash.
15; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc.
16; The program will then only run on 68020-based Amigas, though.
17; If you have reduced WSIZE in zip.h, then make sure this is
18; assembled with an equivalent -dWSIZE=<whatever>.
19;
20; This code will run with registerized parameters too, unless SAS
21; changes parameter passing conventions between new releases of SAS/C.
22
23
24Cur_Match       reg     d0      ; Must be in d0!
25Best_Len        reg     d1
26Loop_Counter    reg     d2
27Scan_Start      reg     d3
28Scan_End        reg     d4
29Limit           reg     d5
30Chain_Length    reg     d6
31Scan_Test       reg     d7
32Scan            reg     a0
33Match           reg     a1
34Prev_Address    reg     a2
35Scan_Ini        reg     a3
36Match_Ini       reg     a4
37
38MAX_MATCH       equ     258
39MIN_MATCH       equ     3
40        ifnd    WSIZE
41WSIZE           equ     32768
42        endc
43MAX_DIST        equ     WSIZE-MAX_MATCH-MIN_MATCH-1
44
45
46        xref    _max_chain_length
47        xref    _prev_length
48        xref    _prev
49        xref    _window
50        xref    _strstart
51        xref    _good_match
52        xref    _match_start
53        xref    _nice_match
54
55
56        section match,code
57
58        xdef    _match_init
59        xdef    @match_init
60        xdef    _longest_match
61        xdef    @longest_match
62
63
64_match_init:
65@match_init:
66        rts
67
68
69_longest_match:
70        move.l  4(sp),Cur_Match
71@longest_match:
72        ifd     UNALIGNED_OK
73        movem.l d2-d6/a2-a4,-(sp)
74        else
75        movem.l d2-d7/a2-a4,-(sp)
76        endc
77        move.l  _max_chain_length,Chain_Length
78        move.l  _prev_length,Best_Len
79        lea     _prev,Prev_Address
80        lea     _window+MIN_MATCH,Match_Ini
81        move.l  _strstart,Limit
82        move.l  Match_Ini,Scan_Ini
83        add.l   Limit,Scan_Ini
84        subi.w  #MAX_DIST,Limit
85        bhi.b   limit_ok
86        moveq   #0,Limit
87limit_ok:
88        cmp.l   _good_match,Best_Len
89        bcs.b   length_ok
90        lsr.l   #2,Chain_Length
91length_ok:
92        subq.l  #1,Chain_Length
93
94        ifd     UNALIGNED_OK
95
96        move.w  -MIN_MATCH(Scan_Ini),Scan_Start
97        move.w  -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
98
99        else
100
101        move.b  -MIN_MATCH(Scan_Ini),Scan_Start
102        lsl.w   #8,Scan_Start
103        move.b  -MIN_MATCH+1(Scan_Ini),Scan_Start
104        move.b  -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
105        lsl.w   #8,Scan_End
106        move.b  -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
107
108        endc
109
110        bra.b   do_scan
111
112long_loop:
113
114        ifd     UNALIGNED_OK
115
116        move.w  -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
117
118        else
119
120        move.b  -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
121        lsl.w   #8,Scan_End
122        move.b  -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
123
124        endc
125
126short_loop:
127        lsl.w   #1,Cur_Match
128        move.w  0(Prev_Address,Cur_Match.L),Cur_Match
129        cmp.w   Limit,Cur_Match
130        dbls    Chain_Length,do_scan
131        bra.b   return
132
133do_scan:
134        move.l  Match_Ini,Match
135        add.l   Cur_Match,Match
136
137        ifd     UNALIGNED_OK
138
139        cmp.w   -MIN_MATCH-1(Match,Best_Len.L),Scan_End
140        bne.b   short_loop
141        cmp.w   -MIN_MATCH(Match),Scan_Start
142        bne.b   short_loop
143
144        else
145
146        move.b  -MIN_MATCH-1(Match,Best_Len.L),Scan_Test
147        lsl.w   #8,Scan_Test
148        move.b  -MIN_MATCH(Match,Best_Len.L),Scan_Test
149        cmp.w   Scan_Test,Scan_End
150        bne.b   short_loop
151        move.b  -MIN_MATCH(Match),Scan_Test
152        lsl.w   #8,Scan_Test
153        move.b  -MIN_MATCH+1(Match),Scan_Test
154        cmp.w   Scan_Test,Scan_Start
155        bne.b   short_loop
156
157        endc
158
159        move.w  #(MAX_MATCH-MIN_MATCH),Loop_Counter
160        move.l  Scan_Ini,Scan
161scan_loop:
162        cmpm.b  (Match)+,(Scan)+
163        dbne    Loop_Counter,scan_loop
164
165        sub.l   Scan_Ini,Scan
166        addq.l  #(MIN_MATCH-1),Scan
167        cmp.l   Best_Len,Scan
168        bls.b   short_loop
169        move.l  Scan,Best_Len
170        move.l  Cur_Match,_match_start
171        cmp.l   _nice_match,Best_Len
172        bcs.b   long_loop
173return:
174        move.l  Best_Len,d0
175        ifd     UNALIGNED_OK
176        movem.l (sp)+,d2-d6/a2-a4
177        else
178        movem.l (sp)+,d2-d7/a2-a4
179        endc
180        rts
181
182        end
183