home *** CD-ROM | disk | FTP | other *** search
- ;
- ; 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
-
-
-