summaryrefslogtreecommitdiff
path: root/amiga/match.a
diff options
context:
space:
mode:
Diffstat (limited to 'amiga/match.a')
-rw-r--r--amiga/match.a182
1 files changed, 182 insertions, 0 deletions
diff --git a/amiga/match.a b/amiga/match.a
new file mode 100644
index 0000000..ec5bcf0
--- /dev/null
+++ b/amiga/match.a
@@ -0,0 +1,182 @@
+;===========================================================================
+; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+;
+; See the accompanying file LICENSE, version 1999-Oct-05 or later
+; (the contents of which are also included in zip.h) for terms of use.
+; If, for some reason, both of these files are missing, the Info-ZIP license
+; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+;===========================================================================
+; match.a -- optional optimized asm version of longest match in deflate.c
+; Written by Jean-loup Gailly
+; Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de>
+; using the code in match.S.
+; The major change in this code consists of removing all unaligned
+; word accesses, because they cause 68000-based Amigas to crash.
+; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc.
+; The program will then only run on 68020-based Amigas, though.
+; If you have reduced WSIZE in zip.h, then make sure this is
+; assembled with an equivalent -dWSIZE=<whatever>.
+;
+; This code will run with registerized parameters too, unless SAS
+; changes parameter passing conventions between new releases of SAS/C.
+
+
+Cur_Match reg d0 ; Must be in d0!
+Best_Len reg d1
+Loop_Counter reg d2
+Scan_Start reg d3
+Scan_End reg d4
+Limit reg d5
+Chain_Length reg d6
+Scan_Test reg d7
+Scan reg a0
+Match reg a1
+Prev_Address reg a2
+Scan_Ini reg a3
+Match_Ini reg a4
+
+MAX_MATCH equ 258
+MIN_MATCH equ 3
+ ifnd WSIZE
+WSIZE equ 32768
+ endc
+MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1
+
+
+ xref _max_chain_length
+ xref _prev_length
+ xref _prev
+ xref _window
+ xref _strstart
+ xref _good_match
+ xref _match_start
+ xref _nice_match
+
+
+ section match,code
+
+ xdef _match_init
+ xdef @match_init
+ xdef _longest_match
+ xdef @longest_match
+
+
+_match_init:
+@match_init:
+ rts
+
+
+_longest_match:
+ move.l 4(sp),Cur_Match
+@longest_match:
+ ifd UNALIGNED_OK
+ movem.l d2-d6/a2-a4,-(sp)
+ else
+ movem.l d2-d7/a2-a4,-(sp)
+ endc
+ move.l _max_chain_length,Chain_Length
+ move.l _prev_length,Best_Len
+ lea _prev,Prev_Address
+ lea _window+MIN_MATCH,Match_Ini
+ move.l _strstart,Limit
+ move.l Match_Ini,Scan_Ini
+ add.l Limit,Scan_Ini
+ subi.w #MAX_DIST,Limit
+ bhi.b limit_ok
+ moveq #0,Limit
+limit_ok:
+ cmp.l _good_match,Best_Len
+ bcs.b length_ok
+ lsr.l #2,Chain_Length
+length_ok:
+ subq.l #1,Chain_Length
+
+ ifd UNALIGNED_OK
+
+ move.w -MIN_MATCH(Scan_Ini),Scan_Start
+ move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
+
+ else
+
+ move.b -MIN_MATCH(Scan_Ini),Scan_Start
+ lsl.w #8,Scan_Start
+ move.b -MIN_MATCH+1(Scan_Ini),Scan_Start
+ move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
+ lsl.w #8,Scan_End
+ move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
+
+ endc
+
+ bra.b do_scan
+
+long_loop:
+
+ ifd UNALIGNED_OK
+
+ move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
+
+ else
+
+ move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End
+ lsl.w #8,Scan_End
+ move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End
+
+ endc
+
+short_loop:
+ lsl.w #1,Cur_Match
+ move.w 0(Prev_Address,Cur_Match.L),Cur_Match
+ cmp.w Limit,Cur_Match
+ dbls Chain_Length,do_scan
+ bra.b return
+
+do_scan:
+ move.l Match_Ini,Match
+ add.l Cur_Match,Match
+
+ ifd UNALIGNED_OK
+
+ cmp.w -MIN_MATCH-1(Match,Best_Len.L),Scan_End
+ bne.b short_loop
+ cmp.w -MIN_MATCH(Match),Scan_Start
+ bne.b short_loop
+
+ else
+
+ move.b -MIN_MATCH-1(Match,Best_Len.L),Scan_Test
+ lsl.w #8,Scan_Test
+ move.b -MIN_MATCH(Match,Best_Len.L),Scan_Test
+ cmp.w Scan_Test,Scan_End
+ bne.b short_loop
+ move.b -MIN_MATCH(Match),Scan_Test
+ lsl.w #8,Scan_Test
+ move.b -MIN_MATCH+1(Match),Scan_Test
+ cmp.w Scan_Test,Scan_Start
+ bne.b short_loop
+
+ endc
+
+ move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter
+ move.l Scan_Ini,Scan
+scan_loop:
+ cmpm.b (Match)+,(Scan)+
+ dbne Loop_Counter,scan_loop
+
+ sub.l Scan_Ini,Scan
+ addq.l #(MIN_MATCH-1),Scan
+ cmp.l Best_Len,Scan
+ bls.b short_loop
+ move.l Scan,Best_Len
+ move.l Cur_Match,_match_start
+ cmp.l _nice_match,Best_Len
+ bcs.b long_loop
+return:
+ move.l Best_Len,d0
+ ifd UNALIGNED_OK
+ movem.l (sp)+,d2-d6/a2-a4
+ else
+ movem.l (sp)+,d2-d7/a2-a4
+ endc
+ rts
+
+ end