EXTERNAL  INTEGER  FN  MATCH ADDR (INTEGER  PATTERN ADDRESS, PATTERN LENGTH, C 
                                            RANGE ADDRESS, RANGE LENGTH)
! Scans a row of RANGE LENGTH bytes at RANGE ADDRESS to find the first
! slice which matches the pattern of PATTERN LENGTH bytes at PATTERN ADDRESS.
! Returns the address of the first byte of the slice, if found: otherwise
! returns zero.  The pattern may overlap the range at either end.  A zero
! length pattern will produce a match and return a copy of RANGE ADDRESS
! as the result.  Otherwise zero or negative lengths, or lengths not less
! than 2**24, will produce a result of zero.  If the pattern is longer than
! the range then a zero result will also be returned.
LONG  INTEGER  SD
INTEGER  D
UNLESS  0<RANGE LENGTH<=X'00FFFFFF' C 
AND  0<=PATTERN LENGTH<=X'00FFFFFF' C 
THEN  RESULT  = 0
IF  PATTERN LENGTH=0 THEN  RESULT  = RANGE ADDRESS
D = RANGE LENGTH - PATTERN LENGTH + 1;  ! A match may start at any offset from 0
                                        ! to D-1 within the range, so this is 
                                        ! the number of bytes that can usefully
                                        ! be scanned for instances of the first
                                        ! byte of the pattern.
IF  D<=0 THEN  RESULT  = 0
   *LDTB_X'18000000';                   ! Byte vector descriptor.
   *LDB_PATTERN LENGTH
   *LDA_PATTERN ADDRESS
   *LB_(DR );                           ! Pick up first byte of pattern.
   *STD_SD;                             ! Save descriptor to pattern.
   *LDB_D;                              ! Construct descriptor to range (only
                                        ! the bytes which need to be checked
                                        ! against the leading byte of pattern).
   *LDA_RANGE ADDRESS
SCAN:
   *SWNE_L =DR ;                        ! Mask=0, Ref=1st. byte of pattern
                                        ! (in B register).
   *JCC_8,<NOT FOUND>;                  ! -> if no match found.
   !
   ! DR points to byte in range which matches first byte in pattern.
   *STD_TOS ;                           ! Save the pointer to it.
   *LDTB_SD;                            ! Pick up length of pattern.
   *LSD_SD;                             ! Acc points to pattern.
   *CPS_L =DR ;                         ! Try to match pattern.
   *JCC_8,<FOUND>;                      ! -> if match found.
   *LD_TOS ;                            ! If no match found, recover
                                        ! descriptor to residue of range,
   *MODD_1;                             ! skip past the last byte tested,
   *J_<SCAN>;                           ! and try again.
FOUND:
   *LSS_TOS ;                           ! Match found: pick up address where
   *EXIT_-64;                           ! it was found, and return that.
NOT FOUND:
   RESULT  = 0
END 
END  OF  FILE