×   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

AF97 Add Subroutine Name to FN/PROC Variable Lookup Table

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.


Disassembly for the Add Subroutine Name to FN/PROC Variable Lookup Table routine

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

 


 Back to 8BS
Or