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 |
Or