Chapter
Six
Execution Overview
During the editing and pre-compiling phase, the
user's statements were checked for correct syntax, tokenized, and put into the Statement
Table. Then direct statements were passed to the Program Executor for immediate processing,
while program statements awaited later processing by the Program Executor. We now
enter the execution phase of Atari BASIC. The Program Executor consists of three
parts: routines which simulate the function of individual statement types; an expression
execution routine which processes expressions (for example, A+B+3, A$(1,3), "HELP",
A(3)+7.26E-13); and the Execution Control routine, which manages the whole process.
Execution
Control
Execution Control is invoked in two situations. If the user has entered a direct
statement, Execution Control does some initial processing and then calls the appropriate
statement execution routine to simulate the requested operation. If the user has
entered RUN as a direct statement, the statement execution routine for RUN instructs
Execution Control to start processing statements from the beginning of the statement
table. When the editor has finished processing a direct statement, it initiates the
Execution Control routine EXECNL ($A95F). Execution Control's job is to manage the
process of statement simulation. The editor has saved the address of the statement
it processed in STMCUR and has put the statement in the Statement Table. Since this
is a direct statement, the line number is $8000, and the statement is saved as the
last line in the Statement Table. The fact that a direct statement is always the
last statement in the Statement Table gives a test for the end of a user's program.
The high- order byte of the direct statement line number ($8000) has its most significant
bit on. Loading this byte ($80) 49
Chapter
Six
into the 6502 accumulator will set the minus flag on. The line number
of any program statement isiess than; or equal to $7FFF. Loading the high order byte
($7F or less) of a program line number into the accumulator will set the 6502 minus
flag off. This gives a simple test for a direct statement. Initialization
Execution Control uses several parameters to help it manage the task of statement
execution. STMCUR holds the address in the Statement Table of the line currently
being processed. LLNGTH holds the length of the current line. NXTSTD holds the displacement
in the current line of the next statement to process. STMCUR already contains the
correct value when Execution Control begins processing. SETLNI ($B81B) is called
to store the correct values into LLNGTH and NXTSTD. Statement Execution Since
the user may have changed his or her mind about execution, the routine checks to
see if the user hit the break key. If the user did hit BREAK, Execution Control carries
out XSTOP ($B793), the same routine that is executed when the STOP statement is encountered.
At the end of its execution, the XSTOP routine gives control to the beginning of
the editor. If the user did not hit BREAK, Execution Control checks to see whether
we are at the end of the tokenized line. Since this is the first statement in the
line, we can't be at the end of the line. So why do the test? Because this part of
the routine is executed once for each statement in the line in order to tell us when
we do reach the end of the line. (The end-of-line procedure will be discussed later
in this chapter.) The statement length byte (the displacement to the next statement
in the line) is the first byte in a statement. (See Chapter 3.) The displacement
to this byte was saved in NXTSTD. Execution Control now loads this new statement's
displacement using the value in NXTSTD. The byte after the statement length in the
line is the statement name token. Execution Control loads the statement name token
into the A register. It saves the displacement to the next byte, the first of the
statement's tokens, in STINDEX for the use of the statement simulation routines.
50
Chapter
Six
The statement name token is used as an index to find this statement's
entry in the Statement Execution Table. Each table entry consists of the address,
minus 1, of the routine that will simulate that statement. This simulation routine
is called by pushing the address from the table onto the 6502 CPU stack and doing
an RTS. Later, when a simulation routine is finished, it can do an RTS and return
to Execution Control. (The name of most of the statement simulation routines in the
BASIC listing is the statement name preceded by an X: XFOR, XRUN, XLIST.) Most of
the statement simulation routines return to Execution Control after processing. Execution
Control again tests for BREAK and checks for the end of the line. As long as we are
not at end-of-line, it continues to execute statements. When we reach end-of-line,
it does some end-of-line processing. End-of-line Handling in a Direct Statement
When we come to the end of the line in a direct statement, Execution Control has
done its job and jumps to SNX3. The READY message is printed and control goes back
to the Program Editor. End-of-line Handling during Program Execution Program
execution is initiated when the user types RUN. Execution Control handles RUN like
any other direct statement. The statement simulation routine for RUN initial— izes
STMCUR, NXTSTD, and LLNGTH to indicate the first statement of the first line in the
Statement Table, then returns to Execution Control. Execution Control treats this
first program statement as the next statement to be executed, picking up the statement
name tokens and calling the simulation routines. Usually, Execution Control is unaware
of whether it is processing a direct statement or a program statement. End-of- line
is the only time the routine needs to make a distinction. At the end of every program
line, Execution Control gets the length of the current line and calls GNXTL to update
the address in STMCUR to make the next line in the Statement Table the new current
line. Then it calls TENDST ($A9E2) to test the new line number to see if it is another
program line or a direct statement. If it is a direct statement, we are at the end
of the user's program. 51
Chapter
Six
Since the direct statement includes the RUN command that started
program execution, Execution Control does not execute the line. Instead, Execution
Control calls the same routine that would have been calle'lif the program had contained
an END statement (XEND, at$B78D). XEND does some end-of- program processing, causes
READY to be printed, and returns to the beginning of the editor. If we are not at
the end of the user's program, processing continues with the new current line. Execution
Control Subroutines TENDST ($A9E2) Exit parameters: The minus flag is set on if
we are at the end of program. This routine checks for the end of the user's program
in the Statement Table. The very last entry in the Statement Table is always a direct
statement. Whenever the statement indicated by STMCUR is the direct statement, we
have finished processing the user's program. The line number of a direct statement
is $8000. The line number of any other statement is $7FFF or less. TENDST determines
if the current statement is the direct statement by loading the high-order byte of
the line number into the A register. This byte is at a displacement of one from the
address in STMCUR. If this byte is $80 (a direct statement), loading it turns the
6502 minus flag on. Otherwise, the minus flag is turned off. GETSTMT ($A9A2)
Entry parameters: TSLNUM contains the line number of the statement whose address
is required. Exit parameters: If the line number is found, the STMCUR contains the
address of the statement and the carry flag is set off (clear). If the line number
does not exist, STMCUR contains the address where a statement with that line number
should be, and the carry flag is set on (set). The purpose of this routine is to
find the address of the statement whose line number is contained in TSLNUM. The routine
saves the address currently in STMCUR into SAVCUR and then sets STMCUR to indicate
the top of the 52
Chapter
Six
Statement Table. The line whose address is in STMCUR is called the
current line or statement. GETSTMT then searches the Statement Table for the statement
whose line number is in TSLNUM. The line number in TSLNUM is compared to the line
number of the current line. If they are equal, then the required statement has been
found. Its address is in STMCUR, so GETSTMT clears the 6502 carry flag and is finished.
If TSLNUM is smaller than the current statement line number, GETSTMT gets the length
of the current statement by executing GETLL ($A9DD). GNXTL ($A9D0) is executed to
make the next line in the statement table the current statement by putting its address
into STMCUR. GETSTMT then repeats the comparison of TSLNUM and the line number of
the current line in the same manner. If TSLNUM is greater than the current line number,
then a line with this line number does not exist. STMCUR already points to where
the line should be, the 6502 carry flag is already set, and the routine is done.
GETLL ($A9DD) Entry parameters: STMCUR indicates the line whose length is
desired. Exit parameters: Register A contains the length of the current line. GETLL
gets the length of the current line (that is, the line whose address is in STMCUR).
The line length is at a displacement of two into the line. GETLL-loads the length
into the A register and is done. GNXTL ($A9D0) Entry parameters: STMCUR contains
the address of the current line, and register A contains the length of the current
line. Exit parameters: STMCUR contains the address of the next line. This routine
gets the next line in the statement table and makes it the current line. GNXTL adds
the length of the current line (contained in the A register) to the address of the
current line in STMCUR. This process yields the address of the next line in the statement
table, which replaces the value in STMCUR. 53
Chapter
Six
SETLN1 ($B81B) Entry parameters: STMCUR contains the address
of the current line. Exit parameters: LLNGTH contains the length of the current line.
NXTSTD contains the displacement in the line to the next statement to be executed
(in this case, the first statement in the line). This routine initializes several
line parameters so that Execution Control can process the line. The routine gets
the length of the line, which is at a displacement of two from the start of the line.
SETLN1 loads a value of three into the Y register to indicate the displacement into
the line of the first statement and stores the value into NXTSTD as the displacement
to the next statement for execution. SETLINE ($B818) Entry parameters: TSLNUM
contains the line number of a statement. Exit parameters: STMCUR contains the address
of the statement whose line number is in TSLNUM. LLNGTH contains the length of the
line. NXTSTD contains the displacement in the line to the next statement to be executed
(in this case, the first statement in the line). Carry is set if the line number
does not exist. This routine initializes several line parameters so that execution
control can process the line. SETLINE first calls GETSTMT ($A9A2) to find the address
of the line whose number is in TSLNUM and put that address into STMCUR. It then continues
exactly like SETLN1. 54
<-Chapter
05Chapter 07