8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


BASIC IV ROM Routines
Page Last Altered:


8FAE Execute next command line / program statement

Submitted by Steve Fewell

Description:

This routine has many entry points (depending on how the last statement finished and what needs to be done to tidy up
before the next statement can be executed. The entry points are listed between square brackets ([]).
Therefore, this routine may not necessarily be executed in the order described.

[&8FAE] Skip the rest of the line. This routine is called when a DATA keyword is found (as DATA statements are skipped
when reached and not executed (as the READ command controls how they are handled). It is also called when the DEF keyword
is found (as function and procedure definitions are not directly executed until they are called by an FN or PROC keyword).
This routine is also called when a REM keyword is found, to skip the rest of the line - as it is a comment line.
Additionally, this routine is also executed when a '*' command is found (the '*' command is first passed to the Operating
System OSCLI routine and then this routine skips the line - so that BASIC doesn't try to execute the '*' command.
The rest of the line is skipped as follows:
* Set A to #&0D (the end of line character - '<cr>').
* Set Y to the BASIC Text Pointer A offset (&0A) - 1.
* Keep incrementing Y and checking the character at BASIC Text pointer A (&0B-&0C) plus Y (offset) with the
character in A (the '<cr>' character) until the characters match.
* Call routine &9BBC to update the BASIC Text Pointer A address (to include the Y offset value) and to reset the offset
(&0A) to 1. (basically, this adds Y to the Text Pointer A address (&0B-&0C)).

[&8FBD] This routine checks whether the last character read (in A) is '<cr>', if it isn't then jump to &8FAE
to skip the rest of the line.
Now, we are at the end of the line (i.e. we have reached the '<cr>' character).

[&8FC1] If the BASIC Text pointer MSB address is #&07 then there are no more program lines to execute (as we were
executing a statement from the command line - and not from within a program), so jump to &8F86 to prompt for the next
command line input.

Set Y to #&01.
Load the next character (offset Y) from the BASIC text pointer A location.
If the character is negative (i.e. #&FF) then we have reached the end of the program, so jump to &8F86 to prompt
for the next command line input.

If the TRACE flag (location &20) is on (i.e. it's value is not zero), then:
* Set IWA to the Line number (MSB byte (&2B) = the first byte at BASIC Text pointer A (offset 1) and the LSB byte (&2A)
    = the second byte at BASIC text pointer A location (offset 2)).
* Call routine &9C4B to display the TRACE line number (in the IWA) on the screen.
[&8FDB] Set the BASIC Text pointer A offset (location &0A) to #&04 (i.e. the first character of the program
line - after the line number and line length).
Jump to &900D to execute the statement at the BASIC Text pointer A location.

[&8FEB] Check for special start statement characters '*', '=', 'EXT keyword' and '['
Set Y to the BASIC Text pointer A offset (location &0A) minus 1.
Load the character at the BASIC text pointer A location (plus offset - Y) (this should be the first character of the
BASIC statement).
If the character is '*' then jump to &8FA4 to execute the '*'-command.
If the character is '[' then set the OPT flag (location &28) to 3 (default setting) and jump to &8920 to begin
the assembly.
If the character is '=' then jump to &9060 to deal with returning from a function and setting the return variable's
value.
If the character is 'EXT keyword' then jump to &BE93 to execute the 'EXT =' statement. Note: In BASIC 2, it was not
possible to assign a file length (EXT) value, only to read the EXT value; therefore, only 1 BASIC token exists for the 'EXT'
keyword (unlike PTR, PAGE, LOMEM and HIMEM which have 2 keyword tokens, one for the setting of the value (where the keyword
occurs before the '='), and one for the reading of the value (where the keyword occurs after the '=')).
When BASIC version 4 was written, there was not enough spare BASIC Keyword token values to have two 'EXT' keywords
(one for 'EXT =' and the other for '= EXT'), so this workaround directly tests for the 'EXT' keyword appearing at the
start of a statement (along with the other special start statement characters '*', '[' and '=') in order to distinguish between
the reading of the EXT value and the writing of the EXT value. The EXT address in the keyword execution address table points to
the EXT read (=EXT) routine - this is used when the EXT keyword is not at the start of the BASIC program statement.

[&9000-&9048] Execute the BASIC statement
[&9000] Decrement the BASIC Text pointer A offset (location &0A).
[&9002] Call routine &9BA6 to check for the end of statement ('Syntax error' if ':', '<cr>' or 'ELSE' not found).
[&9005] Load the character pointed to by BASIC Text Pointer A.
If the character is not ':' then jump back to &8FBD to skip the rest of the program line and then proceed to execute
the statement on the next line.
[&900B] Set Y to the BASIC Text Pointer A offset (location &0A).
[&900D] Keep incrementing the BASIC Text Pointer A offset (location &0A) until we have found a non-space character.
This skips any spaces at the beginning of the BASIC Statement.

If the first non-space character is more than or equal to #&CF (PTR=, PAGE=,...,OSCLI), [i.e. it is not a Command
Line-only statement (e.g. OLD, NEW, RENUMBER, EDIT) or a middle of statement keyword (e.g. MID$, ELSE, AND, LEN), but a
valid keyword that can occur at the start of a program Statement], then:
[&9019] Jump to the keyword's execution address, as follows:
Multiply the character's ASCII Code by 2 & add the result to the base address &874D to form a pointer to the execution
address (LSB first, MSB next) of the required BASIC keyword. This resulting address is jumped to.
Example 1: Character = &CF [PTR= token] = 11001111 multiply by 2 = 10011110 (which is &9E in hex).
So, &874D + &9E = &87EB (The LSB of the execution address for the PTR= keyword (&87EC is the MSB of the address)).
Example 2: Character = &FF [OSCLI token] = 11111111 multiply by 2 = 11111110 (which is &FE in hex).
So, &874D + &FE = &884B (The LSB of the execution address for the OSCLI keyword (&884C is the MSB of the address)).

BASIC Keywords between 128 and 141 are not considered. as these Keywords are used in the middle of statements (and are not
functions), so the statements/expression handler will deal with these values. These keywords are as follows: AND, DIV, EOR,
MOD, OR, ERROR, LINE, OFF, STEP, SPC, TAB(, ELSE and THEN.

[&901E] Execute the BASIC Command line statement (which can include keywords OLD, NEW, AUTO, EDIT, etc...)
If the first/next non-space character on the command line is more than or equal to #&C6 ('AUTO') then jump back to &9019
to jump to the execution address for the BASIC keyword. This includes all BASIC statement start keywords (but not middle
of statement keywords like MID$, LEN, =PTR, AND, etc...).
Otherwise (the character is less than #&C6) continue to &9025 to check for a variable name.

[&9025] Check for variable name
If the character is less than #&CF then check whether it is a variable name as follows:
* Set BASIC Text pointer B location to the BASIC Text Pointer A location. (&19=&0B, &1A=&0C, &1B=Y)
* Call routine &9909 to evaluate a variable name at the BASIC text pointer B location.
* If routine &9909 returns with a value other than zero then jump to the LET keyword routine (address &904F).
  to assign a value to the variable, as the variable was found and the address of the variable's value was found
* Otherwise, (routine &9909 returned zero) the variable is either invalid or hasn't been created yet, so:
* Check the carry flag status (as returned by routine &9909). If carry is set then jump to &8FEB to
   check whether the BASIC statement begins with a special character ('*', '[', '=' or 'EXT keyword',
   and issue 'Syntax error' [via check end of statement routine &9BA6] if none of these special
   characters match the character at the start of the statement).
* Store the BASIC text pointer B offset (in X) back to location &1B.
* Call routine &9B86 to check whether the next non-space character after the variable name is an '=' character.
   If it isn't then issue the 'Mistake' error, as the variable assignment is not correct and a variable
   cannot appear at the start of a statement unless it is being assigned a value.
* Otherwise, '=' was found sucessfully.
* Call routine &9854 to add the new variable name to the variable pointer table.
* If the variable type is a float (location &2C contains #&05) then set X to #&06; otherwise, set X to
   #&05. This specifies the amount of space to allocate for the variable's value.
* Call routine &9883 to allocate space for the variable (and initialise it's value to zero/null).
* Decrement the BASIC text pointer A offset (so that BASIC Text pointer A points to the first character of the
   variable name) and continue to the LET keyword routine to evaluate the variable name (again!) and
   assign the value specified after the '=' to the variable.


Disassembly for the Execute next command line / program statement routine

8FAE   169 013 A9 0D LDA#&0D
8FB0   164 010 A4 0A LDY &0A
8FB2   136 88 DEY
8FB3   200 C8 INY
8FB4   209 011 D1 0B CMP (&0B),Y
8FB6   208 251 D0 FB BNE -5 --> &8FB3
8FB8   032 188 155 20 BC 9B JSR &9BBC Update BASIC Text pointer A (Add offset value & then reset offset to 1)
8FBB   128 004 80 04 BRA 4 --> &8FC1 Process the next program line
8FBD   201 013 C9 0D CMP#&0D
8FBF   208 237 D0 ED BNE -19 --> &8FAE Skip the rest of the line and process the next program line
8FC1   165 012 A5 0C LDA &0C
8FC3   201 007 C9 07 CMP#&07
8FC5   240 191 F0 BF BEQ -65 --> &8F86 Read & execute command line input
8FC7   160 001 A0 01 LDY#&01
8FC9   177 011 B1 0B LDA (&0B),Y
8FCB 0 048 185 30 B9 BMI -71 --> &8F86 Read & execute command line input
8FCD   166 032 A6 20 LDX &20
8FCF   240 010 F0 0A BEQ 10 --> &8FDB
8FD1 + 133 043 85 2B STA &2B
8FD3   200 C8 INY
8FD4   177 011 B1 0B LDA (&0B),Y
8FD6 * 133 042 85 2A STA &2A
8FD8 K 032 075 156 20 4B 9C JSR &9C4B Display current line number (IWA) on screen [if TRACE is on]
8FDB   160 004 A0 04 LDY#&04
8FDD   132 010 84 0A STY &0A
8FDF , 128 044 80 2C BRA 44 --> &900D
8FE1   169 003 A9 03 LDA#&03
8FE3 ( 133 040 85 28 STA &28
8FE5 L 076 032 137 4C 20 89 JMP &8920 '[' Begin Assembly
8FE8 L 076 147 190 4C 93 BE JMP &BE93 EXT =
8FEB   164 010 A4 0A LDY &0A
8FED   136 88 DEY
8FEE   177 011 B1 0B LDA (&0B),Y
8FF0 * 201 042 C9 2A CMP#&2A
8FF2   240 176 F0 B0 BEQ -80 --> &8FA4 '*'-Command
8FF4 [ 201 091 C9 5B CMP#&5B
8FF6   240 233 F0 E9 BEQ -23 --> &8FE1
8FF8   201 162 C9 A2 CMP#&A2
8FFA   240 236 F0 EC BEQ -20 --> &8FE8
8FFC = 201 061 C9 3D CMP#&3D
8FFE ` 240 096 F0 60 BEQ 96 --> &9060 '=' Return from Function Call (FN)
9000   198 010 C6 0A DEC &0A
9002   032 166 155 20 A6 9B JSR &9BA6 Check end of Statement
9005   178 011 B2 0B LDA (&0B)
9007 : 201 058 C9 3A CMP#&3A
9009   208 178 D0 B2 BNE -78 --> &8FBD Skip the rest of the line (until '<cr>' found) & process the next program line
900B   164 010 A4 0A LDY &0A
900D   230 010 E6 0A INC &0A
900F   177 011 B1 0B LDA (&0B),Y
9011   201 032 C9 20 CMP#&20
9013   240 246 F0 F6 BEQ -10 --> &900B
9015   201 207 C9 CF CMP#&CF
9017   144 012 90 0C BCC 12 --> &9025
9019   010 0A ASL A
901A   170 AA TAX
901B ÝM 124 077 135 7C 4D 87 JMP (&874D,X)
901E   032 224 142 20 E0 8E JSR &8EE0 Get next non-space character pointed to by Ptr A
9021   201 198 C9 C6 CMP#&C6
9023   176 244 B0 F4 BCS -12 --> &9019
9025   166 011 A6 0B LDX &0B
9027   134 025 86 19 STX &19
9029   166 012 A6 0C LDX &0C
902B   134 026 86 1A STX &1A
902D   132 027 84 1B STY &1B
902F   032 009 153 20 09 99 JSR &9909 Evaluate variable/array name & return the address of the value
9032   208 027 D0 1B BNE 27 --> &904F Create variable (LET)
9034   176 181 B0 B5 BCS -75 --> &8FEB
9036   134 027 86 1B STX &1B
9038   032 134 155 20 86 9B JSR &9B86 Check for '='
903B T 032 084 152 20 54 98 JSR &9854 Create new variable name in variable pointer table
903E   162 005 A2 05 LDX#&05
9040 , 228 044 E4 2C CPX &2C
9042   208 001 D0 01 BNE 1 --> &9045
9044   232 E8 INX
9045   032 131 152 20 83 98 JSR &9883 Allocate space for variable
9048   198 010 C6 0A DEC &0A
904A   ...LET keyword...

Disassembly for 9B86 Check for '=' routine

9B86   032 213 142 20 D5 8E JSR &8ED5 Get next non-space character (PTR B)
9B89 = 201 061 C9 3D CMP#&3D
9B8B   208 211 D0 D3 BNE -45 --> Mistake error
9B8D ` 096 60 RTS

 


 Back to 8BS
Or