Submitted by Steve Fewell
Description:
Get the next non-space character pointed to by BASIC Text pointer A.
Subtract 1 from address pointed to by Text pointer A (plus Pointer A offset) and store
the new address in location &37-&38.
Store 5 in &3F (variable trype), as the default variable type (unless a % or $ is specified
at the end of the variable name) is a 5-byte Floating-Point value.
Backup the current PTR Offset value in X (to preserve the pointer to the start of the variable name).
Call routine &9AF6 to Check the variable name. This routine does the following:
1* Set Y = 1
2* Read next character from address pointed to by &37-&38.
3* If the next character is < "0" then exit.
4* If the next character is >= ":" and less then "@" then exit.
5* If the next character is "0" to "9" and Y = 1 then exit (variable cannot start with a digit).
6* If the next character is >= "[" and < "_" then exit.
7* If the next character is > "z" then exit.
8* Otherwise, the character is valid for the variable name, so increment Y & X (Ptr A offset)
and check next character (2*).
If Y is still 1 then no valid characters were found, so a variable name was not specified
after the DIM keyword, so issue a Bad DIM error.
if A (the Character after the last valid character of the variable name) is "(" (open bracket)
then jump to &9570 to dimension an Array variable.
If A is "$" or "%" then we have either a String or an Integer variable type, as both of
these has a parameter block size of 4 bytes, then decrement &3F (size of the variable
parameter block) from 5 (default - Float) to 4. Also, check the next charater pointed to
by &37-&38. If this character is "(" then jump to &9570 todimension an Array variable.
If the next character is not "(", or the variable was a Floating-Point value (no "%" or "$" after name),
then jump to &94BC to dimension a memory area.
&9570 - DIM Array variable
Increment Y to point to after bracket character (this is the variable name length we will pass to &8085).
Store back X to the PTR A offset (pointer to start of variable name).
Call routine &8085 to get the variable return address details.
If A is not 0 then an array with that name already exists, so issue a Bad Dim error as
we cannot have two arrays with the same name. &8085 sets &39 to the length of the variable name.
Call routine &9854 to add the new array name to the variable parameter block.
Set X to 1 (Number of bytes to reserve for the variable parameter block) and call routine &9883 to Allocate
variable parameter block space for the variable.
Store &3F to the stack (Variable type length - 5 for float, 4 for Integer/String).
Store 1 to the stack (this is the next Dimension subscript position in the variable parameter block).
Call &AE18 to set the IWA to 1.
[9589]
Push the current IWA value to the BASIC stack.
Call routine &926F to get the result of the expression pointed to by BASIC text pointer A
and convert the result to an Integer value (or issue Type Mismatch error if String value).
If any of the bytes &2C or &2D, or either of the top 2 bits of Byte &2B, are set
then the value is either negative or too large for an array subscript (>&3FFF (16383 in decimal)).
Increment the IWA value (routine &BEEF), we we need to define 1 more position that the value stated, in order
to make space for element 0 of the array.
Retrieve the "next Dimension subscript position in the variable parameter block" from the stack
and store &2A and &2B (the next dimension subscript value) to VARTOP + next subscript position in
parameter block value.
Increment the next subscript position by 2 (to obtain the next dimensions (if any) position
and store this value back on the stack.
Call routine &9503 to Multiply the specified subscript by any lower subscript values (the IWA value on the
Stack). This routine issues a Bad DIM error if the total number of elements is >FFFF.
Now, the IWA contains the current total number of elements in the array.
Check the next non-space character at BASIC Text Pointer A (&8CE5) and if the character is
a comma (','), thengo back to &9589, to store the current number of elements (IWA) on the Stack
and process the next dimension subscript in the array.
Otherwise, if the next non-space character is not a comma, then it needs to be a close bracket ')',
if it isn't a close bracket then there is an error with the structure of the DIM statement,
so issue a Bad DIM error.
Retrieve the Variable return type value, and store this value in location &3F.
[To do this the variable block offset (pointer to next free location in the Array's variable block header)
is temporarily retrieved, and stored back to the stack again, after we have retrieved the variable type.]
Set location &40 to zero. Now &3F-&40 contain the number of bytes required by the variable
return type [that is 4 for String/Integer and 5 for Floating-Point].
Multiply the number of elements by the number of bytes required by the variable return type.
This will set the IWA to the total number of bytes required for the array variable data.
Retrieve the Variable parameter block offset value (which points to the location after the last Subscript value)
from the stack, and add this to the IWA.
Now the IWA contains the total number of bytes required for the array storage (including the storage
required to hold the maximum subscript values for each dimension).
Copy the current VARTOP address to &37-&38.
Add the total number of bytes required for ther array's storage (&2A-&2B) to the
address pointed to by VARTOP. If this value exceeds &FFFF then issue a DIM space error.
If the new VARTOP value would run into the BASIC Stack then issue
the DIM space error, as there is not enough variable storage space left for the array.
Update VARTOP to point to the next free location after the array storage space.
Retrieve the offset to the next dimension in the variable parameter block (which actually
is a pointer to the first value, as there are no more dimensions to add) in the first
byte of the variable parameter block (pointed to by &37-&38 - the old VARTOP value!).
This byte specifies how many dimensions the array has.
Next, store zero in the array's element value locations to initialise all elements to blank.
[To get the value of the first element to byte, we set Y to &37 (Old VARTOP LSB value) + offset
to the first value, so that Y contains the LSB pointer to the first value in the array,
and clear &37, so now (&37),Y will return the first byte of the first array value].
[Keep storing zero until (&37), Y reaches the new value of VARTOP.]
Jump to &94FB to check for a comma at BASIC Text pointer A location, if there is a comma
there we have more arrays to define, so jump back to &9534.
Otherwise, jump to &9000 to continue processing the current BASIC command/program line.
&94BC - DIM Memory area
Decrement &0A (the BASIC Text pointer A), to disregard the last character we read (we needed to check
whether it was a '(' or not in order to know whether to DIM an array or memory).
Call routine &98AE to check for the variable's existence (and create a new variable if it doesn't
already exist).
If the variable name was not valid (zero flag set) then issue a Bad DIM error.
If the variable is a String variable (carry flag set), then issue a Bad DIM error,
as we need a variable that can hold the address value of the dimensioned memory space.
Call &BC43 to Push &2A, &2B and &2C to the 6502 stack (&2A-&2B is the
address of the variable's value, and &2C is the variable's type).
Call &96AF to get the result of the expression and convert the result to an Integer
if it was a Floating-Point value, or issue Type Mismatch error is a string value was returned.
Increment the IWA value (&BEEF), as we need to account for the 0th byte (i.e. DIM a% 0 - reserves
1-byte of storage). Now the IWA contains the number of bytes of memory to reserve.
If &2C or &2D contain a value then the amount of memory to reserve is either negative
or >FFFF, so issue a Bad DIM error.
Add the required number of bytes to reserve (IWA) to the current VARTOP address
(but dont update VARTOP value yet).
If the new VARTOP would run into the Stack then there is not enough room for the
required number of bytes of memory to be reserved, so issue a DIM Space error.
[Note: The variable is still defined even if there is not enough room to reserve the required memory!].
Set &2A-&2B to the previous VARTOP address (the start of the reserved memory).
Update VARTOP to point to the new VARTOP value.
Set &27 and A to #&40 (Integer result value), and call &B32B to set the
variable (whose value address and type are stored on the Stack) to the current result value
(in this case the value of the IWA, as the result type (&27) is Integer).
Call &9275 to reset BASIC Text Pointer A offset (&0A) to the BASIC Text Pointer B offset (&1B).
Continue to &94FB to check for a comma at BASIC Text pointer A location, if there is a comma
there we have more arrays to define, so jump back to &9534.
Otherwise, jump to &9000 to continue processing the current BASIC command/program line.
9534 | 032 224 142 | 20 E0 8E | JSR &8EE0 Get next non-space character pointed to by Ptr A | |
9537 | 152 | 98 | TYA | |
9538 | 024 | 18 | CLC | |
9539 | e | 101 011 | 65 0B | ADC &0B |
953B | 166 012 | A6 0C | LDX &0C | |
953D | 144 002 | 90 02 | BCC 2 --> &9541 | |
953F | 232 | E8 | INX | |
9540 | 024 | 18 | CLC | |
9541 | 233 000 | E9 00 | SBC#&00 | |
9543 | 7 | 133 055 | 85 37 | STA &37 |
9545 | 138 | 8A | TXA | |
9546 | 233 000 | E9 00 | SBC#&00 | |
9548 | 8 | 133 056 | 85 38 | STA &38 |
954A | 162 005 | A2 05 | LDX#&05 | |
954C | ? | 134 063 | 86 3F | STX &3F |
954E | 166 010 | A6 0A | LDX &0A | |
9550 | 032 246 154 | 20 F6 9A | JSR &9AF6 Check variable name | |
9553 | 192 001 | C0 01 | CPY#&01 | |
9555 | 240 213 | F0 D5 | BEQ -43 --> &952C Bad DIM error | |
9557 | ( | 201 040 | C9 28 | CMP#&28 |
9559 | 240 021 | F0 15 | BEQ 21 --> &9570 DIM Array variable | |
955B | $ | 201 036 | C9 24 | CMP#&24 |
955D | 240 004 | F0 04 | BEQ 4 --> &9563 | |
955F | % | 201 037 | C9 25 | CMP#&25 |
9561 | 208 010 | D0 0A | BNE 10 --> &956D | |
9563 | ? | 198 063 | C6 3F | DEC &3F |
9565 | 200 | C8 | INY | |
9566 | 232 | E8 | INX | |
9567 | 7 | 177 055 | B1 37 | LDA (&37),Y |
9569 | ( | 201 040 | C9 28 | CMP#&28 |
956B | 240 003 | F0 03 | BEQ 3 --> &9570 DIM Array variable | |
956D | L | 076 188 148 | 4C BC 94 | JMP &94BC DIM Memory area |
9570 | 200 | C8 | INY | |
9571 | 134 010 | 86 0A | STX &0A | |
9573 | 032 133 128 | 20 85 80 | JSR &8085 Get variable address | |
9576 | 208 180 | D0 B4 | BNE -76 --> &952C Bad DIM error | |
9578 | T | 032 084 152 | 20 54 98 | JSR &9854 Add new variable name to Variable Pointer table |
957B | 162 001 | A2 01 | LDX#&01 | |
957D | 032 131 152 | 20 83 98 | JSR &9883 Allocate space for new variable | |
9580 | ? | 165 063 | A5 3F | LDA &3F |
9582 | H | 072 | 48 | PHA |
9583 | 169 001 | A9 01 | LDA#&01 | |
9585 | H | 072 | 48 | PHA |
9586 | 032 024 174 | 20 18 AE | JSR &AE18 Set IWA to 1-byte (A) [i.e. 1] | |
9589 | & | 032 038 188 | 20 26 BC | JSR &BC26 Push IWA to Stack |
958C | o | 032 111 146 | 20 6F 92 | JSR &926F Evaluate Expression at BASIC Text pointer A convert result to integer |
958F | + | 165 043 | A5 2B | LDA &2B |
9591 | ) | 041 192 | 29 C0 | AND#&C0 |
9593 | , | 005 044 | 05 2C | ORA &2C |
9595 | - | 005 045 | 05 2D | ORA &2D |
9597 | 208 147 | D0 93 | BNE -109 --> &952C Bad DIM error | |
9599 | 032 239 190 | 20 EF BE | JSR &BEEF Increment IWA | |
959C | z | 122 | 7A | PLY |
959D | * | 165 042 | A5 2A | LDA &2A |
959F | 145 002 | 91 02 | STA (&02),Y | |
95A1 | 200 | C8 | INY | |
95A2 | + | 165 043 | A5 2B | LDA &2B |
95A4 | 145 002 | 91 02 | STA (&02),Y | |
95A6 | 200 | C8 | INY | |
95A7 | Z | 090 | 5A | PHY |
95A8 | 032 003 149 | 20 03 95 | JSR &9503 Multiply upper dimension value by lower dimenson subscript | |
95AB | 032 229 140 | 20 E5 8C | JSR &8CE5 Compare next non-space PTRA character with ',' | |
95AE | 240 217 | F0 D9 | BEQ -39 --> &9589 | |
95B0 | ) | 201 041 | C9 29 | CMP#&29 |
95B2 | 208 194 | D0 C2 | BNE -62 --> &9576 [Bad DIM error] | |
95B4 | 250 | FA | PLX | |
95B5 | h | 104 | 68 | PLA |
95B6 | 218 | DA | PHX | |
95B7 | ? | 133 063 | 85 3F | STA &3F |
95B9 | d@ | 100 064 | 64 40 | STZ &40 |
95BB | 032 008 149 | 20 08 95 | JSR &9508 Multiply upper dimension value by the lower dimension subscript | |
95BE | h | 104 | 68 | PLA |
95BF | H | 072 | 48 | PHA |
95C0 | e* | 101 042 | 65 2A | ADC &2A |
95C2 | * | 133 042 | 85 2A | STA &2A |
95C4 | 144 002 | 90 02 | BCC 2 --> &95C8 | |
95C6 | + | 230 043 | E6 2B | INC &2B |
95C8 | 165 003 | A5 03 | LDA &03 | |
95CA | 8 | 133 056 | 85 38 | STA &38 |
95CC | 165 002 | A5 02 | LDA &02 | |
95CE | 7 | 133 055 | 85 37 | STA &37 |
95D0 | 024 | 18 | CLC | |
95D1 | e* | 101 042 | 65 2A | ADC &2A |
95D3 | 168 | A8 | TAY | |
95D4 | + | 165 043 | A5 2B | LDA &2B |
95D6 | e | 101 003 | 65 03 | ADC &03 |
95D8 | + | 176 043 | B0 2B | BCS 43 --> &9605 DIM Space error |
95DA | 170 | AA | TAX | |
95DB | 196 004 | C4 04 | CPY &04 | |
95DD | 229 005 | E5 05 | SBC &05 | |
95DF | $ | 176 036 | B0 24 | BCS 36 --> &9605 DIM Space error |
95E1 | 132 002 | 84 02 | STY &02 | |
95E3 | 134 003 | 86 03 | STX &03 | |
95E5 | h | 104 | 68 | PLA |
95E6 | 7 | 146 055 | 92 37 | STA (&37) |
95E8 | e7 | 101 055 | 65 37 | ADC &37 |
95EA | 168 | A8 | TAY | |
95EB | 169 000 | A9 00 | LDA#&00 | |
95ED | d7 | 100 055 | 64 37 | STZ &37 |
95EF | 144 002 | 90 02 | BCC 2 --> &95F3 | |
95F1 | 8 | 230 056 | E6 38 | INC &38 |
95F3 | 7 | 145 055 | 91 37 | STA (&37),Y |
95F5 | 200 | C8 | INY | |
95F6 | 208 002 | D0 02 | BNE 2 --> &95FA | |
95F8 | 8 | 230 056 | E6 38 | INC &38 |
95FA | 196 002 | C4 02 | CPY &02 | |
95FC | 208 245 | D0 F5 | BNE -11 --> &95F3 | |
95FE | 8 | 228 056 | E4 38 | CPX &38 |
9600 | 208 241 | D0 F1 | BNE -15 --> &95F3 | |
9602 | L | 076 251 148 | 4C FB 94 | JMP &94FB Check if there are further Arrays to DIMension |
94B9 | L | 076 005 150 | 4C 05 96 | JMP &9605 DIM Space error |
94BC | 198 010 | C6 0A | DEC &0A | |
94BE | 032 174 152 | 20 AE 98 | JSR &98AE Evaluate variable name & create new variable | |
94C1 | i | 240 105 | F0 69 | BEQ 105 --> &952C Bad DIM error |
94C3 | g | 176 103 | B0 67 | BCS 103 --> &952C Bad DIM error |
94C5 | C | 032 067 188 | 20 43 BC | JSR &BC43 Push &2A, &2B & &2C to 6502 Stack |
94C8 | 032 175 150 | 20 AF 96 | JSR &96AF Get expression result & convert it to Integer | |
94CB | 032 239 190 | 20 EF BE | JSR &BEEF Increment IWA | |
94CE | - | 165 045 | A5 2D | LDA &2D |
94D0 | , | 005 044 | 05 2C | ORA &2C |
94D2 | X | 208 088 | D0 58 | BNE 88 --> &952C Bad DIM error |
94D4 | 024 | 18 | CLC | |
94D5 | * | 165 042 | A5 2A | LDA &2A |
94D7 | e | 101 002 | 65 02 | ADC &02 |
94D9 | 168 | A8 | TAY | |
94DA | + | 165 043 | A5 2B | LDA &2B |
94DC | e | 101 003 | 65 03 | ADC &03 |
94DE | 170 | AA | TAX | |
94DF | 196 004 | C4 04 | CPY &04 | |
94E1 | 229 005 | E5 05 | SBC &05 | |
94E3 | 176 212 | B0 D4 | BCS -44 --> &94B9 [DIM Space error] | |
94E5 | 165 002 | A5 02 | LDA &02 | |
94E7 | * | 133 042 | 85 2A | STA &2A |
94E9 | 165 003 | A5 03 | LDA &03 | |
94EB | + | 133 043 | 85 2B | STA &2B |
94ED | 132 002 | 84 02 | STY &02 | |
94EF | 134 003 | 86 03 | STX &03 | |
94F1 | @ | 169 064 | A9 40 | LDA#&40 |
94F3 | ' | 133 039 | 85 27 | STA &27 |
94F5 | + | 032 043 179 | 20 2B B3 | JSR &B32B Set Numeric variable |
94F8 | u | 032 117 146 | 20 75 92 | JSR &9275 Ptr A offset = Ptr B offset |
94FB | 032 229 140 | 20 E5 8C | JSR &8CE5 Compare next non-space PTRA character with ',' | |
94FE | 4 | 240 052 | F0 34 | BEQ 52 --> &9534 DIMension next array/variable |
9500 | L | 076 000 144 | 4C 00 90 | JMP &9000 Check for end of statement & process next BASIC program Statement |
9AF6 | 160 001 | A0 01 | LDY#&01 | |
9AF8 | 7 | 177 055 | B1 37 | LDA (&37),Y |
9AFA | 0 | 201 048 | C9 30 | CMP#&30 |
9AFC | 144 024 | 90 18 | BCC 24 --> &9B16 | |
9AFE | @ | 201 064 | C9 40 | CMP#&40 |
9B00 | 176 012 | B0 0C | BCS 12 --> &9B0E | |
9B02 | : | 201 058 | C9 3A | CMP#&3A |
9B04 | 176 016 | B0 10 | BCS 16 --> &9B16 | |
9B06 | 192 001 | C0 01 | CPY#&01 | |
9B08 | 240 012 | F0 0C | BEQ 12 --> &9B16 | |
9B0A | 232 | E8 | INX | |
9B0B | 200 | C8 | INY | |
9B0C | 208 234 | D0 EA | BNE -22 --> &9AF8 | |
9B0E | _ | 201 095 | C9 5F | CMP#&5F |
9B10 | 176 005 | B0 05 | BCS 5 --> &9B17 | |
9B12 | [ | 201 091 | C9 5B | CMP#&5B |
9B14 | 144 244 | 90 F4 | BCC -12 --> &9B0A | |
9B16 | ` | 096 | 60 | RTS |
9B17 | { | 201 123 | C9 7B | CMP#&7B |
9B19 | 144 239 | 90 EF | BCC -17 --> &9B0A | |
9B1B | ` | 096 | 60 | RTS |
BC43 | z | 122 | 7A | PLY |
BC44 | 250 | FA | PLX | |
BC45 | * | 165 042 | A5 2A | LDA &2A |
BC47 | H | 072 | 48 | PHA |
BC48 | + | 165 043 | A5 2B | LDA &2B |
BC4A | H | 072 | 48 | PHA |
BC4B | , | 165 044 | A5 2C | LDA &2C |
BC4D | H | 072 | 48 | PHA |
BC4E | 218 | DA | PHX | |
BC4F | Z | 090 | 5A | PHY |
BC50 | ` | 096 | 60 | RTS |
BEEF | * | 230 042 | E6 2A | INC &2A |
BEF1 | 208 010 | D0 0A | BNE 10 --> &BEFD | |
BEF3 | + | 230 043 | E6 2B | INC &2B |
BEF5 | 208 006 | D0 06 | BNE 6 --> &BEFD | |
BEF7 | , | 230 044 | E6 2C | INC &2C |
BEF9 | 208 002 | D0 02 | BNE 2 --> &BEFD | |
BEFB | - | 230 045 | E6 2D | INC &2D |
BEFD | ` | 096 | 60 | RTS |