8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


Page Last Altered:

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

 


 Back to 8BS
Or