8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


Page Last Altered:

AC36 INSTR(

Submitted by Steve Fewell

Description:

Call &9D3B to obtain the result of the expression at BASIC Text pointer B. This value should be the String value to
search within for the search string value.
If the value of the expression is not a String then issue a 'Type mismatch' error, as a string to search value was not
found.

If the next non-space character at BASIC Text pointer B is not a comma ',', then issue 'Missing ,' error.
Otherwise, increment BASIC Text pointer B offset (to point to the character after the comma).

Push the SWA String value (the String to search within) to the BASIC Stack.
Call &9D3B to obtain the result of the expression after the comma. This value should be the String value to search
for. The INSTR function will search for this string occuring within the first String value specified (the value that is now
on the stack).
If the value of the expression is not a String then issue a 'Type mismatch' error, as a search string value was not found.

Set the IWA LSB byte value (&2A) to 1. This is the default search starting position within the String being searched.
Increment the BASIC Text pointer B offset (&1B) to skip the next non-space character, which should be either a comma
(if a search starting position is being specified) or a close bracket (to indicate the end of the INSTR statement).

If the next non-space character (the character that was skipped over) was not a ')' (close bracket) then we are not at the
end of the INSTR statement yet, so:
* Check that the skipped character was a comma (if not then issue 'Missing ,' error)
* Push the SWA String value (the string to search for) to the BASIC stack
* Get the Integer result of the expression (after the comma) and place the Integer value in the IWA
* Check that the next non-space character is a closing ')' (to terminate the INSTR statement), if not then issue a
     'Missing )' error
* Retrieve the second String value (the string to search for) from the BASIC stack.
Set X to the IWA's LSB value (&2A). This is the starting search position within the 'String to search within' value.
If X is zero then set X to 1 (as 0 is an invalid starting position within a String value).
Store X back to the IWA (&2A) location.

Set A to X and then decrement X (storing the new X value in location &2D).
Add the Stack pointer value (in locations &04-&05) to A (the String Starting position before X was
decremented, i.e. the Starting position including the String length byte).
Store the result in &37-&38. Now locations &37-&38 point to the required Starting character of the first String
value (which is currently located on the BASIC stack).

Set A to the length of the String on the stack (the string to search within). Note: the length of the String on the BASIC
Stack is the byte currently pointed to by the stack pointer (&04-&05), i.e. the last byte pushed to the stack.

Subtract the value at location &2D from A (the length of the String on the stack). This will deduct the search starting
position (minus 1) that was specified from the length of the String to search within (the string on the BASIC stack).
If the result of the subtraction underflowed then the Search Starting position is greater than the String to search within, so:
jump to &AC9F to clear stack space used by the String value & exit with IWA = 0, as the search string (SWA) was not
found.

Subtract the length of the SWA (the String to search for) from the previous subtraction result. If the subtraction
underflows then the String to search for is larger than the String value to search within, so [&AC9F] restore the
BASIC Stack space used by the String and exit with the IWA = 0, as the search value was not found.

Add 1 to A (to obtain the number of searches required).
Store A in location &2B. This is the number of searches that we need to perform before we know whether the search String
value was found or not. This value (as calculated above) can be simply calculated as:
        Number of Searches (location &2B) = length of String to search within - (starting position -1) - length of search string + 1

Restore the stack space used by the string on the stack (but leave the value of the string where it is, as &37-&38
point to the String's value - which will be accessable as long as nothing else is pushed to the BASIC stack (causing the
value to be overwritten)).

[&AC89] Set Y to 0 and X to the length of the Search String (the string value in the SWA).
If X is 0 then the length of the search string is zero, so jump to &AC9A to exit with the IWA = ?&2A (i.e. the search
starting position value - as a null String value (of zero bytes long) is always found within another String value (so the
INSTRing location for the null string is the starting position of the search.

[&AC8F] Compare the next byte (at offset Y) of the String pointed to by &37-&38 (the first string value,
i.e. the String to search within) with the next byte of the SWA (at offset Y).

If the characters match then increment Y (to point to the next character), decrement X (length of search value) and, if
X has reached zero (no more characters of the search value to check) we have found a match, so exit with the IWA = ?&2A
(i.e. the position of the match within the String value pointed to by &37-&38). Otherwise, jump to &AC8F to
check the next character of the search String value against the next character of the &37-&38 String value.

If the characters do not match then try the next character of the String pointed to by &37-&38 as follows:
* [&ACA6] Increment &2A (the current position within the String pointed to by &37-&38)
* Decrement &2B (the number of characters of the &37-&38 String value at which to begin a search)
* If &2B has reached zero, then we have checked for the search String value at all required positions in the
    &37-&38 String value without finding a match, so exit with IWA = 0 (as end of String
    value was reached without finding a match).
* Increment the &37-&38 pointer to point to the next character of the String value
* Jump to &AC89 to check for the search SWA value at the new &37-&38 position within the String value


Disassembly for the INSTR routine

AC36 ; 032 059 157 20 3B 9D JSR &9D3B Evaluate expression at BASIC Text pointer B
AC39   208 145 D0 91 BNE -111 --> &ABCC [JMP &9092 - Type mismatch error]
AC3B , 224 044 E0 2C CPX#&2C
AC3D   208 024 D0 18 BNE 24 --> &AC57
AC3F   230 027 E6 1B INC &1B
AC41 Q 032 081 188 20 51 BC JSR &BC51 Push SWA to Stack
AC44 ; 032 059 157 20 3B 9D JSR &9D3B Evaluate expression at BASIC Text pointer B
AC47   208 131 D0 83 BNE -125 --> &ABCC [JMP &9092 - Type mismatch error]
AC49   169 001 A9 01 LDA#&01
AC4B * 133 042 85 2A STA &2A
AC4D   230 027 E6 1B INC &1B
AC4F ) 224 041 E0 29 CPX#&29
AC51   240 013 F0 0D BEQ 13 --> &AC60
AC53 , 224 044 E0 2C CPX#&2C
AC55   240 003 F0 03 BEQ 3 --> &AC5A
AC57 L 076 246 142 4C F6 8E JMP &8EF6 'Missing ,' error
AC5A   032 164 150 20 A4 96 JSR &96A4 Push SWA to stack, get Integer result of expression & check for closing ')'
AC5D   032 210 188 20 D2 BC JSR &BCD2 Pop String (SWA) from the stack
AC60 * 166 042 A6 2A LDX &2A
AC62   208 002 D0 02 BNE 2 --> &AC66
AC64   162 001 A2 01 LDX#&01
AC66 * 134 042 86 2A STX &2A
AC68   138 8A TXA
AC69   202 CA DEX
AC6A - 134 045 86 2D STX &2D
AC6C   024 18 CLC
AC6D e 101 004 65 04 ADC &04
AC6F 7 133 055 85 37 STA &37
AC71   169 000 A9 00 LDA#&00
AC73 e 101 005 65 05 ADC &05
AC75 8 133 056 85 38 STA &38
AC77   178 004 B2 04 LDA (&04)
AC79 8 056 38 SEC
AC7A - 229 045 E5 2D SBC &2D
AC7C ! 144 033 90 21 BCC 33 --> &AC9F
AC7E 6 229 054 E5 36 SBC &36
AC80   144 029 90 1D BCC 29 --> &AC9F
AC82 i 105 000 69 00 ADC#&00
AC84 + 133 043 85 2B STA &2B
AC86   032 225 188 20 E1 BC JSR &BCE1 Restore Stack Space used by String (without overwriting the SWA)
AC89   160 000 A0 00 LDY#&00
AC8B 6 166 054 A6 36 LDX &36
AC8D   240 011 F0 0B BEQ 11 --> &AC9A
AC8F 7 177 055 B1 37 LDA (&37),Y
AC91   217 000 006 D9 00 06 CMP &0600,Y
AC94   208 016 D0 10 BNE 16 --> &ACA6
AC96   200 C8 INY
AC97   202 CA DEX
AC98   208 245 D0 F5 BNE -11 --> &AC8F
AC9A * 165 042 A5 2A LDA &2A
AC9C L 076 024 174 4C 18 AE JMP &AE18 Set IWA to the 8-bit value in A
AC9F   032 225 188 20 E1 BC JSR &BCE1 Restore Stack Space used by String (without overwriting the SWA)
ACA2   169 000 A9 00 LDA#&00
ACA4   128 246 80 F6 BRA -10 --> &AC9C
ACA6 * 230 042 E6 2A INC &2A
ACA8 + 198 043 C6 2B DEC &2B
ACAA   240 246 F0 F6 BEQ -10 --> &ACA2
ACAC 7 230 055 E6 37 INC &37
ACAE   208 217 D0 D9 BNE -39 --> &AC89
ACB0 8 230 056 E6 38 INC &38
ACB2   128 213 80 D5 BRA -43 --> &AC89

 


 Back to 8BS
Or