*``````````````````````````````*
* SUBPOS :: SUBSTRING POSITION *
*-                            -*
* FIND THE POSITION OF A SUB-  *
* STRING WITHIN ANOTHER STRING *
*-                            -*
* CLOBBERS:                    *
*                              *
* FLAGS:  ????----  REG: AXYM  *
*-                            -*
* CYCLES: ???                  *
* SIZE:                        *
*-                            -*
* USAGE:                       *
*                              *
*  LDA #>STR ; STRING ADDR     *
*  PHA                         *
*  LDA #<STR                   *
*  PHA                         *
*  LDA #>SUB ; SUBSTR ADDR     *
*  PHA                         *
*  LDA #<SUB                   *
*  JSR SUBPOS                  *
*-                            -*
* ENTRY                        *
*                              *
* TOP OF STACK                 *
*                              *
* LOW BYTE OF RETURN ADDRESS   *
* LOW BYTE OF SUBSTRING ADDR   *
* HI BYTE OF SUBSTRING ADDR    *
* LO BYTE OF STRING ADDR       *
* HI BYTE OF STRING ADDRESS    *
* HI BYTE OF RETURN ADDRESS    *
*-                            -*
* EXIT                         *
*                              *
* TOP OF STACK                 *
*                              *
* LOW BYTE OF RETURN ADDRESS   *
* HI BYTE OF RETURN ADDRESS    *
*                              *
* .Y = CLOBBERED; TRASH        *
* .X = CLOBBERED; TRASH        *
* .A = INDEX OF SUBSTRING IF   *
*       FOUND; OTHERWISE, 0    *
*                              *
* [RETURN] = INDEX OF SUBSTR;  *
*            0 IF NOT FOUND    *
* [RETLEN] = 1 (INDEX LENGTH)  *
*-                            -*
* ADAPTED FROM LEVANTHAL AND   *
* WINTHROP'S /6502 ASSEMBLY    *
* LANGUAGE ROUTINES/. MAY NOT  *
* FALL UNDER APACHE 2.0 UNTIL  *
* HEAVILY MODIFIED.            *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
SUBPOS
*
** SAVE RETURN ADDRESS
*
         PLA
         STA   RETADR
         PLA
         STA   RETADR+1
*
** GET PARAMETERS
*
         PLA
         STA   ADDR2
         PLA
         STA   ADDR2+1
         PLA
         STA   ADDR1
         PLA
         STA   ADDR1+1
*
** RESTORE RETURN ADDRESS
*
         LDA   RETADR+1
         PHA
         LDA   RETADR
         PHA
*
:POS
         LDY   #0
         LDA   (ADDR1),Y  ; GET LENGTH OF STRING
         BEQ   :NOTFND    ; EXIT IF LENGTH = 0
         STA   :SLEN
         LDA   (ADDR2),Y  ; GET SUBSTR LENGTH
         BEQ   :NOTFND    ; EXIT IF SUB LENGTH = 0
         STA   :SUBLEN
*
** IF THE SUBSTR IS LONGER THAN STR, DECLARE THE
** SUBSTR NOT FOUND
*
         LDA   :SUBLEN
         CMP   :SLEN
         BEQ   :LENOK
         BCS   :NOTFND    ; CANNOT FIND SUBSTR IF
                          ; LONGER THAN STR
*
** START, SEARCH, CONTINUE UNTIL
** REMAINING STR SHORTER THAN SUBSTR
*
:LENOK
         LDA   #1
         STA   :SINDEX    ; START LOOKING AT FIRST
                          ; CHARACTER OF STRING
         LDA   :SLEN      ; CONT UNTIL REMAINING STR
                          ; TOO SHORT
         SEC              ; COUNT=STR LEN - SUB LEN+1
         SBC   :SUBLEN
         STA   :SCOUNT
         INC   :SCOUNT
*
** SEARCH FOR SUBSTRING IN STRING
*
:SLP1
         LDA   :SINDEX
         STA   :SIDX      ; START STR AT INDEX
         LDA   #1
         STA   :SUBIDX    ; START SUB IND AT 1
*
** LOOK FOR SUBSTRING BEGINNING AT INDEX
*
:CMPLP
         LDY   :SIDX
         LDA   (ADDR1),Y  ; GET NEXT CHAR FROM STR
         LDY   :SUBIDX
         CMP   (ADDR2),Y  ; COMPARE TO NEXT SUB CHAR
         BNE   :SLP2      ; BR IF SUB NOT HERE
         LDY   :SUBIDX
         CPY   :SUBLEN    ; TEST IF WE ARE DONE
         BEQ   :FOUND     ; BR IF ALL CHARS WERE EQUAL
         INY              ; ELSE INC TO NEXT CHAR
         STY   :SUBIDX
         INC   :SIDX
         JMP   :CMPLP     ; CONTINUE
*
** ARRIVE HERE IF SUBSTRING NOT FOUND
*
:SLP2
         INC   :SINDEX    ; INCREMENT INDEX
         DEC   :SCOUNT    ; DEC COUNT
         BNE   :SLP1      ; BR IF NOT DONE
         BEQ   :NOTFND    ; ELSE EXIT TO NOT FOUND
*
:FOUND
         LDA   :SINDEX    ; FOUND, A = STARTING IDX
         JMP   :EXIT
*
:NOTFND
         LDA   #0         ; SUB NOT FOUND, A=0
:EXIT
         STA   RETURN
         LDY   #1
         STY   RETLEN
         RTS
*
** DATA
*
:SLEN    DS    1
:SUBLEN  DS    1
:SINDEX  DS    1
:SUBIDX  DS    1
:SCOUNT  DS    1
:SIDX    DS    1
*
