Submitted by Steve Fewell
Description:
Set the BASIC text pointer A address to PAGE (MSB from location &18, and LSB = #&00).
[&AF9D] Set Y to #&01.
[&AF9F] Load the next character of the program (from location (&0B-&0C) + Y).
If the character is negative (i.e. #&FF), then we have reached the end of the program without encountering a
definition for the subroutine, so jump to &AF83 to retrieve the BASIC text pointer A address from the 6502 stack
(this is the address of the line number which contains the subroutine call (FN/PROC) statement - which the error routine
will use to obtain the program error line number (located at the BASIC text pointer A address - without any offset, which
is why the offset value is not pulled from the stack)) and issue 'No such FN/PROC' error.
Set Y to #&04 (to skip the line number and offset byte at the start of the Progam Line).
[&AFA5] Skip any spaces at the start of the Program Line.
If the first non-space character at the start of the Program Line is #&DD (DEF-token), then jump to &AFBF to Check
whether the subroutine definition matches the subroutine name we require and if it does, then add it to the lookup table.
Note: For this reason, DEFs will only be recognised if they occur at the start of a Program Line (i.e. not on a multi-
statement Program Line (preceded by ':' or 'ELSE'). This makes sense, as the definition cannot be optional (i.e. inside an
IF-construct)!
[&AFB0] If 'DEF' was not found at the start of the program line, then continue searching through the program (starting
at the next program line), as follows:
Load the next line offset byte pointed to by offset 3 (Y = #&03) on the current program line (&0B-&0C).
Add this next line offset byte to the BASIC text pointer A address (&0B-&0C).
Jump back to &AF9D to check whether the next program line contains a DEFinition for the subroutine name that we are
looking for.
[&AFBF] Check whether the subroutine definition is for the subroutine that we require
Increment Y to point to the next character after the DEF Keyword and set the BASIC text pointer A offset (&0A) to
this value.
Call routine &8EE0 to skip any spaces after the DEF-Keyword.
Set X to the offset of the start of the Subroutine name (the current value of Y).
Add the offset of the start of the Subroutine name to the BASIC text pointer A LSB address (&0B), storing the result
in A.
Set Y to the BASIC Text Pointer A MSB value (from location &0C) and increment Y if the addition of the offset to the
LSB of the pointer address overflowed.
[&AFCF] Subtract 1 from the Start of the Subroutine name address (in A (LSB) and Y (MSB)) and store the result in
locations &3C (LSB) and &3D (MSB).
[&AFD9] Set Y to #&01 (to start comparing from the first character of the subroutine name).
[&AFDB] Increment X (The BASIC text pointer A (&0B-&0C) offset to the current subroutine name character.
Compare the next character of the subroutine name in the subroutine DEFinition (&3C-&3D) + Y (offset) with the
subroutine name, in the PROC/FN statement, that we are looking for (&37-&38) + offset (Y).
If the characters are not equal then jump to &AFB0 to continue searching for the subroutine definition starting at
the next Program Line.
[&AFE2] Otherwise, increment Y (to advance to the next character of the subroutine name) and compare Y with the
length of the subroutine name (as stored in location &39). If Y is not equal to the subroutine name length then jump
back to &AFDB to compare the next character.
[&AFE7] Otherwise, the subroutine names are equal (so far); so, Load A with the next character at (&3C-&3D)
+ Y (offset). This will obtain the next character of the subroutine name in the subroutine DEFinition statement.
Call routine &8D84 to check whether the character is a valid variable name character. If it is then the subroutine
names do not match (as the subroutine name in the DEFinitation statement is longer than the name we are looking for).
So, jump back to &AFB0 to continue searching for the subroutine definition starting at the next Program Line.
Otherwise, the subroutine names match, so Set Y to X (the offset to the end of the DEFinition subroutine name at
(&0B-&0C)), Add X to the &0B-&0C pointer (to update the BASIC text pointer A so that it points to the
position after the subroutine name in the DEFinition declaration (DEFPROC/DEFFN).
Call routine &9845 to add add the subroutine name to the appropriate lookup table (either 'FN' or 'PROC').
Set X to 1 (the number of bytes to allocate for the contents of the subroutine name in the lookup table).
Call routine &9883 to append ASCII+0 to the subroutine name (in the lookup table) - this is so that BASIC knows where
the variable name ends and the data starts) and allocate X - 1 bytes of space for the subroutine name lookup reference
(i.e. no bytes will be allocated yet!). 'No Room' error will be issued if there is no space for the subroutine name (Y) +
the '1-byte' (X) to be allocated.
Store the address in (&0B-&0C) [which points to the program position after the subroutine name (i.e. this will
either be the start of the subroutine's argument list (if a bracket is the character pointed to), or the first statement of
the subroutine)] at a 2-byte location starting at the address pointed to by VARTOP (&02-&03) - this will be the
next 2 bytes which would be allocated by the &988B routine.
Call routine &988B to allocate Y (2) bytes of space at the subroutine name parameter block location.
Now that the subroutine name has been set up in the lookup table, and the start address of the subroutine
definition has also been placed in this lookup table, jump to &B072 to initiate the call to the subroutine.
AF83 | h | 104 | 68 | PLA |
AF84 | 133 012 | 85 0C | STA &0C | |
AF86 | h | 104 | 68 | PLA |
AF87 | 133 011 | 85 0B | STA &0B | |
AF89 | ...'No such FN/PROC' error... | |||
AF97 | 165 024 | A5 18 | LDA &18 | |
AF99 | 133 012 | 85 0C | STA &0C | |
AF9B | d | 100 011 | 64 0B | STZ &0B |
AF9D | 160 001 | A0 01 | LDY#&01 | |
AF9F | 177 011 | B1 0B | LDA (&0B),Y | |
AFA1 | 0 | 048 224 | 30 E0 | BMI -32 --> &AF83 Retrieve PTR A address from the 6502 stack and issue 'No such FN/PROC' error |
AFA3 | 160 003 | A0 03 | LDY#&03 | |
AFA5 | 200 | C8 | INY | |
AFA6 | 177 011 | B1 0B | LDA (&0B),Y | |
AFA8 | 201 032 | C9 20 | CMP#&20 | |
AFAA | 240 249 | F0 F9 | BEQ -7 --> &AFA5 | |
AFAC | 201 221 | C9 DD | CMP#&DD | |
AFAE | 240 015 | F0 0F | BEQ 15 --> &AFBF Found DEF - check if definition matches the subroutine name we require | |
AFB0 | 160 003 | A0 03 | LDY#&03 | |
AFB2 | 177 011 | B1 0B | LDA (&0B),Y | |
AFB4 | 024 | 18 | CLC | |
AFB5 | e | 101 011 | 65 0B | ADC &0B |
AFB7 | 133 011 | 85 0B | STA &0B | |
AFB9 | 144 226 | 90 E2 | BCC -30 --> &AF9D | |
AFBB | 230 012 | E6 0C | INC &0C | |
AFBD | 128 222 | 80 DE | BRA -34 --> &AF9D | |
AFBF | 200 | C8 | INY | |
AFC0 | 132 010 | 84 0A | STY &0A | |
AFC2 | 032 224 142 | 20 E0 8E | JSR &8EE0 Get next non-space character pointed to by Ptr A | |
AFC5 | 152 | 98 | TYA | |
AFC6 | 170 | AA | TAX | |
AFC7 | 024 | 18 | CLC | |
AFC8 | e | 101 011 | 65 0B | ADC &0B |
AFCA | 164 012 | A4 0C | LDY &0C | |
AFCC | 144 002 | 90 02 | BCC 2 --> &AFD0 | |
AFCE | 200 | C8 | INY | |
AFCF | 024 | 18 | CLC | |
AFD0 | 233 000 | E9 00 | SBC#&00 | |
AFD2 | < | 133 060 | 85 3C | STA &3C |
AFD4 | 152 | 98 | TYA | |
AFD5 | 233 000 | E9 00 | SBC#&00 | |
AFD7 | = | 133 061 | 85 3D | STA &3D |
AFD9 | 160 001 | A0 01 | LDY#&01 | |
AFDB | 232 | E8 | INX | |
AFDC | < | 177 060 | B1 3C | LDA (&3C),Y |
AFDE | 7 | 209 055 | D1 37 | CMP (&37),Y |
AFE0 | 208 206 | D0 CE | BNE -50 --> &AFB0 | |
AFE2 | 200 | C8 | INY | |
AFE3 | 9 | 196 057 | C4 39 | CPY &39 |
AFE5 | 208 244 | D0 F4 | BNE -12 --> &AFDB | |
AFE7 | < | 177 060 | B1 3C | LDA (&3C),Y |
AFE9 | 032 132 141 | 20 84 8D | JSR &8D84 Check whether character is valid within a Variable name (letter, '_', or digit) | |
AFEC | 176 194 | B0 C2 | BCS -62 --> &AFB0 | |
AFEE | 138 | 8A | TXA | |
AFEF | 168 | A8 | TAY | |
AFF0 | 032 188 155 | 20 BC 9B | JSR &9BBC Update BASIC Text pointer A (Add offset value & then reset offset to 1) | |
AFF3 | E | 032 069 152 | 20 45 98 | JSR &9845 Create Lookup Table reference for Subroutine |
AFF6 | 162 001 | A2 01 | LDX#&01 | |
AFF8 | 032 131 152 | 20 83 98 | JSR &9883 Allocate space for variable | |
AFFB | 165 011 | A5 0B | LDA &0B | |
AFFD | 146 002 | 92 02 | STA (&02) | |
AFFF | 160 001 | A0 01 | LDY#&01 | |
B001 | 165 012 | A5 0C | LDA &0C | |
B003 | 145 002 | 91 02 | STA (&02),Y | |
B005 | 200 | C8 | INY | |
B006 | 032 139 152 | 20 8B 98 | JSR &988B Allocate an extra 2 bytes of memory for the subroutine name lookup reference | |
B009 | Lr | 076 114 176 | 4C 72 B0 | JMP &B072 Call Subroutine |