×   Main Menu ALL The 8BS News Manuals (New menu) Links Worth a Look Tools Disc and Basic Webring Site Map 8BS Guestbook Old Guest Book Me The Barnsley Rovers   
8-Bit Software

The BBC and Master Computer Public Domain Library



9073 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.

[&9073] 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 &9C80 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)).

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

[&9086] 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 &904B 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 &904B 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 &9D0F to display the TRACE line number (in the IWA) on the screen.
[&90A0] 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 &90D2 to execute the statement at the BASIC Text pointer A location.

[&90B0] 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 &9069 to execute the MOS '*'-command.
If the character is '[' then set the OPT flag (location &28) to 3 (default setting) and jump to &89DD to begin
the assembly.
If the character is '=' then jump to &9123 to deal with returning from a function and setting the return variable's
value.
If the character is 'EXT keyword' then jump to &BED3 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.

[&90C5-&910B] Execute the BASIC statement
[&90C5] Decrement the BASIC Text pointer A offset (location &0A).
[&90C7] Call routine &9C6A to check for the end of statement ('Syntax error' if ':', '<cr>' or 'ELSE' not found).
[&90CA] Load the character pointed to by BASIC Text Pointer A.
If the character is not ':' then jump back to &9082 to skip the rest of the program line and then proceed to execute
the statement on the next line.
[&90D0] Set Y to the BASIC Text Pointer A offset (location &0A).
[&90D2] 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:
[&90DE] Jump to the keyword's execution address, as follows:
Multiply the character's ASCII Code by 2 & add the result to the base address &880A 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, &880A + &9E = &88A8 (The LSB of the execution address for the PTR= keyword (&88A9 is the MSB of the address)).
Example 2: Character = &FF [OSCLI token] = 11111111 multiply by 2 = 11111110 (which is &FE in hex).
So, &880A + &FE = &8908 (The LSB of the execution address for the OSCLI keyword (&8909 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.

[&90E3] 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 &90DE
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 &90EA to check for a variable name.

[&90EA] 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)
    (Changes from BASIC IV: &1B isn't set to Y as routine &99D6 now does this).
* Call routine &99D6 to evaluate a variable name at the BASIC text pointer B location.
* If routine &99D6 returns with a value other than zero then jump to the LET keyword routine (address &9112).
  to assign a value to the variable, as the variable was found and the address of the variable's value was found
* Otherwise, (routine &99D6 returned zero) the variable is either invalid or hasn't been created yet, so:
* Check the carry flag status (as returned by routine &99D6). If carry is set then jump to &90B0 to
   check whether the BASIC statement begins with a special character ('*', '[', '=' or 'EXT keyword',
   and issue 'Syntax error' [via check end of statement routine &9C6A] 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 &9C4A 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 &9923 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 &9952 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

9073

 

169 013

A9 0D

LDA#&0D

9075

 

164 010

A4 0A

LDY &0A

9077

 

136

88

DEY

9078

 

200

C8

INY

9079

 

209 011

D1 0B

"CMP (&0B),Y"

907B

 

208 251

D0 FB

BNE -5 --> &9078

907D

 

032 128 156

20 80 9C

JSR &9C80 Update BASIC Text pointer A (Add offset value & then reset offset to 1)

9080

 

128 004

80 04

BRA 4 --> &9086 Process the next program line

9082

 

201 013

C9 0D

CMP#&0D

9084

 

208 237

D0 ED

BNE -19 --> &9073 Skip the rest of the line and process the next program line

9086

 

165 012

A5 0C

LDA &0C

9088

 

201 007

C9 07

CMP#&07

908A

 

240 191

F0 BF

BEQ -65 --> &904B Read & execute command line input

908C

 

160 001

A0 01

LDY#&01

908E

 

177 011

B1 0B

"LDA (&0B),Y"

9090

0

048 185

30 B9

BMI -71 --> &904B Read & execute command line input

9092

 

166 032

A6 20

LDX &20

9094

 

240 010

F0 0A

BEQ 10 --> &90A0

9096

+

133 043

85 2B

STA &2B

9098

 

200

C8

INY

9099

 

177 011

B1 0B

"LDA (&0B),Y"

909B

*

133 042

85 2A

STA &2A

909D

 

032 015 157

20 0F 9D

JSR &9D0F Display current line number (IWA) on screen [if TRACE is on]

90A0

 

160 004

A0 04

LDY#&04

90A2

 

132 010

84 0A

STY &0A

90A4

","

128 044

80 2C

BRA 44 --> &90D2

90A6

 

169 003

A9 03

LDA#&03

90A8

(

133 040

85 28

STA &28

90AA

L

076 221 137

4C DD 89

JMP &89DD '[' Begin Assembly

90AD

L

076 211 190

4C D3 BE

JMP &BED3 EXT =

90B0

 

164 010

A4 0A

LDY &0A

90B2

 

136

88

DEY

90B3

 

177 011

B1 0B

"LDA (&0B),Y"

90B5

*

201 042

C9 2A

CMP#&2A

90B7

 

240 176

F0 B0

BEQ -80 --> &9069 '*'-Command

90B9

[

201 091

C9 5B

CMP#&5B

90BB

 

240 233

F0 E9

BEQ -23 --> &90A6

90BD

 

201 162

C9 A2

CMP#&A2

90BF

 

240 236

F0 EC

BEQ -20 --> &90AD

90C1

=

201 061

C9 3D

CMP#&3D

90C3

^

240 094

F0 5E

BEQ 94 --> &9123 '=' Return from Function Call (FN)

90C5

 

198 010

C6 0A

DEC &0A

90C7

j

032 106 156

20 6A 9C

JSR &9C6A Check end of Statement

90CA

 

178 011

B2 0B

LDA (&0B)

90CC

:

201 058

C9 3A

CMP#&3A

90CE

 

208 178

D0 B2

BNE -78 --> &9082 Skip the rest of the line (until '<cr>' found) & process the next program line

90D0

 

164 010

A4 0A

LDY &0A

90D2

 

230 010

E6 0A

INC &0A

90D4

 

177 011

B1 0B

"LDA (&0B),Y"

90D6

 

201 032

C9 20

CMP#&20

90D8

 

240 246

F0 F6

BEQ -10 --> &90D0

90DA

 

201 207

C9 CF

CMP#&CF

90DC

 

144 012

90 0C

BCC 12 --> &90EA

90DE

 

10

0A

ASL A

90DF

 

170

AA

TAX

90E0

124 010 136

7C 0A 88

"JMP (&880A,X)"

90E3

 

032 157 143

20 9D 8F

JSR &8F9D Get next non-space character pointed to by Ptr A

90E6

 

201 198

C9 C6

CMP#&C6

90E8

 

176 244

B0 F4

BCS -12 --> &90DE

90EA

 

166 011

A6 0B

LDX &0B

90EC

 

134 025

86 19

STX &19

90EE

 

166 012

A6 0C

LDX &0C

90F0

 

134 026

86 1A

STX &1A

90F2

 

032 214 153

20 D6 99

JSR &99D6 Evaluate variable/array name & return the address of the value

90F5

 

208 027

D0 1B

BNE 27 --> &9112 Create variable (LET)

90F7

 

176 183

B0 B7

BCS -73 --> &90B0

90F9

 

134 027

86 1B

STX &1B

90FB

J

032 074 156

20 4A 9C

JSR &9C4A Check for '='

90FE

#

032 035 153

20 23 99

JSR &9923 Create new variable name in variable pointer table

9101

 

162 005

A2 05

LDX#&05

9103

","

228 044

E4 2C

CPX &2C

9105

 

208 001

D0 01

BNE 1 --> &9108

9107

 

232

E8

INX

9108

R

032 082 153

20 52 99

JSR &9952 Allocate space for variable

910B

 

198 010

C6 0A

DEC &0A

910D

  ...LET keyword...

Disassembly for 9C4A Check for '=' routine

9C4A

 

032 146 143

20 92 8F

JSR &8F92 Get next non-space character (PTR B)

9C4D

=

201 061

C9 3D

CMP#&3D

9C4F

 

208 211

D0 D3

BNE -45 --> Mistake error

9C51

`

96

60

RTS

 


 Back to 8BS
Or