8-Bit Software

The BBC and Master Computer Public Domain Library

Back to 8BS Or Back to Disassembly


Page Last Altered:

9534 DIM

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.


Disassembly for the DIM routine

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

DIM Array
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

DIM Memory Area
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

Check variable name
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

Store &2A-&2C on Stack
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

Increment IWA value
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

 


 Back to 8BS
Or