9C08 IF
Submitted by Steve Fewell
Description:
Call routine &9D2F to set BASIC text pointer B to the BASIC text pointer A value and get the result of the
expression after the IF-Keyword.
If the result of the expression after ther 'IF-Keyword' is a String value then, a boolean or numerical IF-condition has
not been specified, so issue 'Type mismatch' error (i.e. IF "Hello" THEN was specified instead of IF A$ = "Hello" THEN).
If the result of the expression evaluation was a Floating-Point value (i.e. The negative flag is set), then call routine
&96C3 to convert the Floating-Point value (in the FWA) to an Integer value and place the result in the IWA.
[&9C12] Update the BASIC Text Pointer A Offset (at location &0A) to the BASIC Text Pointer B offset (this will
place the BASIC Text Pointer A so that is points to the location after the 'IF-Condition' expression.
If the IWA value is zero, then the IF-condition is False so, jump to &9C37 to process the ELSE part of the
IF-statement.
Otherwise continue to &9C20 to process the True part of the IF-Statement.
[&9C20] IF-Condition is True so, Process the Main part of the IF-Statement
If the next character after the IF-Condition expression (in X) is not #&8C 'THEN-Keyword', then jump to &900B to
execute the next program statement found after the IF-Condition.
Note: This is why you must include a THEN if you want to specify a GOTO without using the GOTO Keyword
(as in IF 1=1 THEN 1000); as without the THEN, BASIC would attempt to execute the Line Number and fail, as a
Keyword/variable name was not found!
Note: The Statement will automatically terminate if the ELSE keyword is found, so there is no need to skip the
'ELSE-statement' here.
Otherwise, (The 'THEN-Keyword' was found), Increment the BASIC Text Pointer A Offset (location &0A) to skip over the
'THEN-Token'.
Call routine &9B1E to check for a tokenised Line Number at the BASIC Text Pointer A location, and if a tokenised
Line Number is found then set the IWA to the untokenised Line Number value.
-
If a Line Number was found (carry flag is set) then jump to that Program Line, as follows:
- * Call routine &B836 to set &3D-&3E to the Start Address within the Program Code where the Line Number
- (specified in the IWA) is located and issue 'No such line' error if the specified line doesn't exist
- in the Program.
- * Call routine &9BC6 to Set the BASIC Text Pointer A offset to 1 (the start of the Program Line)
- and check for an Escape condition (If the Escape-Key has been pressed, then issue an 'Escape' error)
- * Jump to &B723 to Display the Line Number on the screen (if TRACE is currently active), Set the
- BASIC Text Pointer A Offset to 4 (to skip the 3-byte Line Number and 1-byte offset to the next line which
- are located at the start of the Program Line), Set the BASIC Text Pointer A to the address specified in
- locations &3D-&3E and jump to &900B to start executing the statement at the start of the specified
- Program Line.
Otherwise, (no tokenised Line Number found), jump to &900B to execute the next statement after the 'THEN-Keyword'.
[&9C37] If-Condition is False so, Process the ELSE part of the IF-Statement
Set Y to the BASIC Text Pointer A offset value (from location &0A).
[&9C39] Keep checking the character at the current position of the BASIC Text Pointer A (&0B-&0C plus offset
value (Y)). Set A to the character found at the current location.
-
If the current character (A) is '<cr>' (carriage return) then there is no ELSE-statement part to this IF-Statement,
so jump to &8FB8 to:
- * Add the BASIC Text Pointer A Offset value (location &0A) to the BASIC Text Pointer A value
- (&0B-&0C)
- * Reset the BASIC Text Pointer A Offset (location &0A) to 1
- * Skip the rest of the current Program Line, Find and execute the next Program Line
Increment Y, to move to the next character on the current Program Line.
If the character in A (the character read by &9C39) is not the 'ELSE-token' then, we haven't found the ELSE-Statement
part (if one exists) of the IF-Statement yet, so jump back to &9C39 to check the next character of the current Program
Line.
Otherwise, we have located the ELSE-Statement part of the IF-Statement, so Store Y back in the BASIC Text Pointer A
Offset (location &0A), so that BASIC Text Pointer A now points to the character after the 'ELSE-Token' and execute
the ELSE-part by jumping to &9C29, as follows:
[&9C29] Call routine &9B1E to check for a tokenised Line Number at the BASIC Text Pointer A location, and if a tokenised
Line Number is found then set the IWA to the untokenised Line Number value.
-
If a Line Number was found (carry flag is set) then jump to that Program Line, as follows:
- * Call routine &B836 to set &3D-&3E to the Start Address within the Program Code where the Line Number
- (specified in the IWA) is located and issue 'No such line' error if the specified line doesn't exist
- in the Program.
- * Call routine &9BC6 to Set the BASIC Text Pointer A offset to 1 (the start of the Program Line)
- and check for an Escape condition (If the Escape-Key has been pressed, then issue an 'Escape' error)
- * Jump to &B723 to Display the Line Number on the screen (if TRACE is currently active), Set the
- BASIC Text Pointer A Offset to 4 (to skip the 3-byte Line Number and 1-byte offset to the next line which
- are located at the start of the Program Line), Set the BASIC Text Pointer A to the address specified in
- locations &3D-&3E and jump to &900B to start executing the statement at the start of the specified
- Program Line.
Otherwise, (no tokenised Line Number found), jump to &900B to execute the next statement after the 'ELSE-Keyword'.
Note: As intended, BASIC does not stop checking for an 'ELSE-Token' if another 'IF-Statement' is found on the
current Line, as the ELSE will match both the outer IF-Statement and the inner IF-Statement.
I.e. IF A$ = "W" THEN w = w + 1:IF w > 25 THEN PRINT "A" ELSE PRINT "B"
In the above statement, "B" will be printed if A$ is not "W", or if A$ is "W" and w > 25! This is correct behaviour!
This also means that the ELSE part of an ON-GOTO-Statement will be handled in the same way.
I.e. IF A$ = "W" THEN ON A GOTO 10, 20, 30 ELSE 40
In the above statement, the Program will execute Line 40 if A$ is not "W", or if A$ is "W" and A is not 1, 2 or 3
This is correct as when BASIC is looking for an Else-Condition, it will handle the first 'ELSE-Token' it finds on the
Program Line.
Disassembly for the IF routine
9C05 |
L |
076 146 144 |
4C 92 90 |
JMP &9092 Type mismatch error |
9C08 |
/ |
032 047 157 |
20 2F 9D |
JSR &9D2F Ptr B = Ptr A & Get result of expression [PTR B] |
9C0B |
|
240 248 |
F0 F8 |
BEQ -8 --> &9C05 Type mismatch error |
9C0D |
|
016 003 |
10 03 |
BPL 3 --> &9C12 |
9C0F |
|
032 195 150 |
20 C3 96 |
JSR &96C3 Convert Float (FWA) to Integer (IWA) |
9C12 |
|
164 027 |
A4 1B |
LDY &1B |
9C14 |
|
132 010 |
84 0A |
STY &0A |
9C16 |
* |
165 042 |
A5 2A |
LDA &2A |
9C18 |
+ |
005 043 |
05 2B |
ORA &2B |
9C1A |
, |
005 044 |
05 2C |
ORA &2C |
9C1C |
- |
005 045 |
05 2D |
ORA &2D |
9C1E |
|
240 023 |
F0 17 |
BEQ 23 --> &9C37 Process the ELSE-part of the IF-Statement |
9C20 |
|
224 140 |
E0 8C |
CPX#&8C |
9C22 |
|
240 003 |
F0 03 |
BEQ 3 --> &9C27 |
9C24 |
L |
076 011 144 |
4C 0B 90 |
JMP &900B Process next BASIC program statement |
9C27 |
|
230 010 |
E6 0A |
INC &0A |
9C29 |
|
032 030 155 |
20 1E 9B |
JSR &9B1E Detokenise the Line Number at PTR A & Set IWA to the Line Number value |
9C2C |
|
144 246 |
90 F6 |
BCC -10 --> &9C24 |
9C2E |
6 |
032 054 184 |
20 36 B8 |
JSR &B836 Set &3D-&3E to the IWA Line's Start address & issue error if No Such Line |
9C31 |
|
032 198 155 |
20 C6 9B |
JSR &9BC6 Set PTR A Offset to 1 & Check for Escape error condition |
9C34 |
L# |
076 035 183 |
4C 23 B7 |
JMP &B723 Jump to Program Line specified |
9C37 |
|
164 010 |
A4 0A |
LDY &0A |
9C39 |
|
177 011 |
B1 0B |
LDA (&0B),Y |
9C3B |
|
201 013 |
C9 0D |
CMP#&0D |
9C3D |
|
240 009 |
F0 09 |
BEQ 9 --> &9C48 |
9C3F |
|
200 |
C8 |
INY |
9C40 |
|
201 139 |
C9 8B |
CMP#&8B |
9C42 |
|
208 245 |
D0 F5 |
BNE -11 --> &9C39 |
9C44 |
|
132 010 |
84 0A |
STY &0A |
9C46 |
|
240 225 |
F0 E1 |
BEQ -31 --> &9C29 |
9C48 |
L |
076 184 143 |
4C B8 8F |
JMP &8FB8 Update PTR A (Add offset value & reset offset to 1) & Process the next Program Line |
Or