; ; Copyright © 1991, 1992 by Walter Rothe. You may freely use and modify this ; program, but not for commercial profit. A modest fee for distribution is ; allowed. Derivative works must be released with source along with the ; executable or provisions made to provide the user source, if requested. ; Uploading source to a major bulletin board system within 6 months of the ; time of the request satisfies this requirement. This copyright notice ; must not be deleted from the source. ; ; Returns major term index if keyword match found, 2/3 if article delimiter ; found, and 4/5 if end of buffer pattern found. With the max number of major ; terms being 128, you would expect the major term index returned to be less ; than 256. However, duplicate keyword entries can have a major term index ; greater than 256. FAR DATA XDEF _FastSearch _FastSearch: LINK A5,#.2 MOVEM.L .3,-(SP) CLR.W D3 CLR.L D2 CLR.L D1 CLR.L D0 MOVEA.L 8(A5),A0 ;Argument #1 LEA _SubPat,A1 ;64kb indexed by two chars LEA _LowrCs,A4 ;Table to convert to lower case JLOOP: LEA _DsplTb,A2 ;Displ to 1st char of keyword LEA _FrstBt,A3 ;Table with 1st byte of keywords LEA _ScndBt,A6 ;Table with 2nd byte of keywords ; Begin checking input stream for specific two char patterns. ILOOP: MOVE.W (A0)+,D1 ; 8 clocks on 68K @ 7MHZ MOVE.B 0(A1,D1.L),D2 ; 14 clocks; Get maj term index BEQ ILOOP ; 10 clocks ; Since a two char match was found, go check to see if 1st 2 bytes of keyword ; matches the char at the predicted place in the input steam where it should ; be if the whole word matched. This is done for speed. MOVE.B 0(A2,D2.W),D0 ;Get displacement to 1st byte BEQ DUPLIC ;Check for duplicate two chars MOVE.B -128(A0,D0.W),D3 ;1st char of keyword to be chkd MOVE.B 0(A4,D3.W),D3 ;Convert to lower case CMP.B 0(A3,D2.W),D3 ;Compare 1st byte BNE ILOOP ;Loop if 1st byte did not match MOVE.B -127(A0,D0.W),D3 ;2nd char of keyword to be chkd MOVE.B 0(A4,D3.W),D3 ;Convert to lower case CMP.B 0(A6,D2.W),D3 ;Compare 2nd byte BNE ILOOP ;Loop if 2nd byte did not match ; Go check if the rest of the keyword matches with a less speed efficient code. MOVE.L D2,D4 ;Major term number LSL.L #3,D4 ;Index by long words(2 per) LEA _KWTbl,A2 ;Address of keyword table of pointers MOVEA.L 0(A2,D4.L),A6 ;Addr of rest of keyword(may be 2 when null) MOVEA.L 4(A2,D4.L),A2 ;Address of "End of keyword"(may be 0 for null) LEA -126(A0,D0.W),A3 ;Address of 3rd byte to test FCMP: CMPA.L A6,A2 ;Finished comparing all of keyword? BLT MATCH ;Yes, so must have matched. MOVE.B (A3)+,D3 ;Next byte from input stream MOVE.B 0(A4,D3.W),D3 ;Convert to lower case CMP.B (A6)+,D3 BNE JLOOP ;Jump on miscompare JMP FCMP MATCH3: SUBA.L #_DKWTbl+12,A6 ;Get index into dup kw tbl MOVE.L A6,D0 LSR.L #4,D0 ;Get major term # MOVE.L A0,_BufIdx ;Update index into buffer MOVEM.L (SP)+,.3 UNLK A5 RTS MATCH: MOVE.L D2,D0 ;Return major term number MOVE.L A0,_BufIdx ;Update index into buffer MOVEM.L (SP)+,.3 UNLK A5 RTS ; Comes here when more than one keyword has the same two char sub-pattern(>5), ; if the two char sub-pattern of the article separator is found(2/3), or if ; the end of buffer delimiter is found(4) DUPLIC: CMPI.W #4,D2 ;Major term number < 4? BGE NOTART ;Jump if not article separator MOVE.L _ArtSep,A2 ;Addr of rest of article separator MOVE.L _EOASep,D4 ;Addr of last byte of article separator to test LEA _DFASep,A3 ;Displacement to rest of art sep to check in buf MOVE.B -2(A3,D2.W),D0 ; LEA -128(A0,D0.W),A3 ;Address of 1st byte to test FCMP4: CMP.L A2,D4 ;Finished comparing all of keyword? BLT MATCH2 ;Yes, so must have matched. CMPM.B (A2)+,(A3)+ BEQ FCMP4 ;Jump if same JMP JLOOP ; NOTART: CMPI.W #6,D2 BLT EOB ;Jump if maj term number is 4 or 5 LSL.L #4,D2 ;4 long words per entry MOVEA.L D2,A6 ADDA.L #_DKWTbl,A6 ;Addr of 1st dupl keyword pointers FCMP3: MOVEA.L (A6)+,A2 ;Addr of 1st byte of keyword MOVE.L (A6)+,D4 ;Addr of last byte of keyword MOVE.L (A6)+,D0 ;Displacement to rest of keyword to test LEA -128(A0,D0.W),A3 ;Address of 1st byte to test FCMP2: CMP.L A2,D4 ;Finished comparing all of keyword? BLT MATCH3 ;Yes, so must have matched. MOVE.B (A3)+,D3 ;Next byte from input stream MOVE.B 0(A4,D3.W),D3 ;Convert to lower case CMP.B (A2)+,D3 BEQ FCMP2 ;Jump if same TST.L (A6) ;Addr of next dupl keyword data BEQ JLOOP MOVEA.L (A6),A6 JMP FCMP3 EOB: MOVEA.L _EOCB,A2 ;Get address of EOB CMPA.L A2,A0 ;Did EOB really occur or is it user data BLT JLOOP ;Jump if not MATCH2: MOVE.L D2,D0 ;D2 is 2/3 for article sep and 4 or 5 for EOB MOVE.L A0,_BufIdx ;Update index into buffer MOVEM.L (SP)+,.3 UNLK A5 RTS .2 EQU 0 .3 REG A2/A3/A4/D4 ; DSEG XREF _SubPat XREF _LowrCs XREF _DsplTb XREF _FrstBt XREF _ScndBt XREF _KWTbl XREF _DKWTbl XREF _EOCB XREF _ArtSep XREF _EOASep XREF _DFASep XREF _BufIdx END