summaryrefslogtreecommitdiff
path: root/human68k/match.s
diff options
context:
space:
mode:
Diffstat (limited to 'human68k/match.s')
-rw-r--r--human68k/match.s163
1 files changed, 163 insertions, 0 deletions
diff --git a/human68k/match.s b/human68k/match.s
new file mode 100644
index 0000000..4e6bc1c
--- /dev/null
+++ b/human68k/match.s
@@ -0,0 +1,163 @@
+*===========================================================================
+* 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.s -- optional optimized asm version of longest match in deflate.c
+* Written by Jean-loup Gailly
+*
+* Adapted for X68000 by NIIMI Satoshi <a01309@cfi.waseda.ac.jp>
+* 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 machines to crash.
+* For maximum speed, UNALIGNED_OK can be defined.
+* The program will then only run on 68020-based machines, though.
+
+
+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
+WSIZE equ 32768
+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
+
+
+ .xdef _match_init
+ .xdef _longest_match
+
+ .text
+ .even
+
+
+_match_init:
+ rts
+
+
+_longest_match:
+ move.l 4(sp),Cur_Match
+.ifdef UNALIGNED_OK
+ movem.l d2-d6/a2-a4,-(sp)
+.else
+ movem.l d2-d7/a2-a4,-(sp)
+.endif
+ 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
+
+.ifdef UNALIGNED_OK
+ move.w -MIN_MATCH(Scan_Ini),Scan_Start
+ move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),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.w),Scan_End
+ lsl.w #8,Scan_End
+ move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
+.endif
+
+ bra.b do_scan
+
+long_loop:
+
+.ifdef UNALIGNED_OK
+ move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
+.else
+ move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End
+ lsl.w #8,Scan_End
+ move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End
+.endif
+
+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
+
+.ifdef UNALIGNED_OK
+ cmp.w -MIN_MATCH-1(Match,Best_Len.w),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.w),Scan_Test
+ lsl.w #8,Scan_Test
+ move.b -MIN_MATCH(Match,Best_Len.w),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
+.endif
+
+ 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
+.ifdef UNALIGNED_OK
+ movem.l (sp)+,d2-d6/a2-a4
+.else
+ movem.l (sp)+,d2-d7/a2-a4
+.endif
+ rts
+
+ end