[
Index] [
Previous] [
Next]
1.18 Variable Management
Dim
Declares an array. Note that the start of this function handler is some way down in the block (at 0716).
Get next program character and return if null byte at end of line has been reached.
0711
2B
DimContd
DCX H
0713
C8
RZ
Syntax check for a comma.
0715
2C
','
Set return address to DimContd above.
0719
C5
PUSH B
Set A to a non-zero number before falling into GetVar+1. This indicates to GetVar that we're declaring rather than accessing an array.
071A
F6AF
ORI AF
GetVar
Given that HL points to a variable name that's been encountered during program interpretation, this function will return in DE a pointer to that variable's value. If the variable does not exist, then (space permitting) this function also allocates and initialises it.
??? Signalling this is a real call to GetVar, not dropped in from DIM
071B
AF
GetVar
XRA A
Get variable name into BC, B=first char and C=(optional) second char. Notice we Syntax Error out if the first character is not alphabetic.
071F
46
MOV B,M
0726
AF
XRA A
0727
4F
MOV C,A
0729
D22E07
JNC 072E
072C
4F
MOV C,A
If next char is '(' then we're dealing with an array and so jump to GetArrayVar (the following block) to deal with it.
072E
D628
SUI '('
Preserve program ptr on stack, and get VAR_ARRAY_BASE into DE and VAR_BASE into HL. This is where we iterate through the stored variables (ie from VAR_BASE to VAR_ARRAY_BASE) to see if the variable has already been declared.
0733
E5
PUSH H
0737
EB
XCHG
Loop to find the variable if it's already been allocated. If HL==DE then we've reached VAR_ARRAY_BASE without finding it, and so can jump ahead to allocate a new variable.
073F
79
MOV A,C
0740
96
SUB M
0741
23
INX H
0742
C24707
JNZ 0747
0745
78
MOV A,B
0746
96
SUB M
0747
23
INX H
0748
CA8207
JZ 0782
074B
23
INX H
074C
23
INX H
074D
23
INX H
074E
23
INX H
Prepare to alloc a new variable, but first we have to do something slightly bizarre... we check the return address to see if it's the expression evaluator that's called us, and if it is then we exit without allocating. Notice that (assuming we haven't been called by the evaluator) the prog ptr on the stack is kept in place.
0752
E1
AllocNewVar
POP H
HL=prog ptr
0753
E3
XTHL
(SP)=prog ptr, HL=ret.addr.
0754
D5
PUSH D
0755
11F606
LXI D,06F6
an address inside EvalTerm
0759
D1
POP D
075D
E3
XTHL
(SP)=ret.addr, HL=prog ptr.
075E
E5
PUSH H
Prog ptr back on stack
Allocate memory for the variable. We need a space of 6 bytes to be inserted before the array variables storage pointed to by VAR_ARRAY_BASE, so we copy that block up 6 bytes in memory.
075F
C5
PUSH B
Preserve var name on stack
0760
010600
LXI B,0006
0766
E5
PUSH H
0767
09
DAD B
0768
C1
POP B
0769
E5
PUSH H
076D
E1
POP H
Update VAR_ARRAY_BASE cos the array block has been moved up 6 bytes.
0771
60
MOV H,B
0772
69
MOV L,C
Initialise the new variable to zero.
0776
2B
InitVarLoop
DCX H
0777
3600
MVI M,00
Restore variable name to DE and write it to the first 2 bytes of the variable's storage.
077D
D1
POP D
077E
73
MOV M,E
077F
23
INX H
0780
72
MOV M,D
0781
23
INX H
Swap HL and DE so that DE points to the variable value, then restore the prog ptr to HL and return
0782
EB
XCHG
0783
E1
POP H
0784
C9
RET
Function exit for when called by EvalTerm. Here we set FACCUM to zero (don't know why), restore the prog ptr to HL and return.
0785
327201
AlreadyAllocd
STA
FACCUM+3
A was set to zero at 075A.
0788
E1
POP H
0789
C9
RET
GetArrayVar
Accesses or allocates an array variable. The contents of DIM_OR_EVAL indicate whether we're dealing with an array declaration (ie a DIM statement) or whether an array element is being accessed. In the former case DIM_OR_EVAL is 0xEF, otherwise it is 0.
Preserve variable name on stack.
078A
C5
GetArrayVar
PUSH B
Push declare-or-access flag on stag
078E
F5
PUSH PSW
Get array subscript into CDE
Syntax check for closing bracket ')'
0793
29
')'
Restore declare-or-access flag
0794
F1
POP PSW
Get variable name from stack into DE; HL becomes the subscript previously in DE; previous value of HL goes on stack.
0798
E3
XTHL
0799
EB
XCHG
Multiply the subscript by 4 and stick it on the stack.
079A
29
DAD H
079B
29
DAD H
079C
E5
PUSH H
Load HL with the base of array storage and LXI into FindArray+2
07A0
01C109
LXI B,....
Find the array loop. First thing we do is advance the array ptr by {subscript}
07A1
C1
FindArray
POP B
07A2
09
DAD B
07A3
EB
XCHG
If we've reached VAR_TOP then we know the array has not already been declared, so we can jump forward to allocate it.
07A4
E5
PUSH H
07A9
EB
XCHG
07AA
D1
POP D
Advance to the next array in the block.
07AF
E3
XTHL
07B1
E1
POP H
Array found. If we're in a DIM statement then this is a duplicate definition error. You can only DIM an array the once.
07B6
3A5B01
LDA DIM_OR_READ
07B9
B7
ORA A
07BA
1E12
MVI E,12
Array element retrieval. First we ???
07BF
D1
POP D
07C0
1B
DCX D
07C1
E3
XTHL
If the subscript is greater than or equal to the number of array elements, then 'Bad Subscript' error.
07C3
1E10
MVI E,10
Return with DE pointing to the element value, and HL the prog ptr.
07C8
D1
POP D
07C9
19
DAD D
07CA
D1
POP D
07CB
EB
XCHG
07CC
C9
RET
Allocate space for the array. Here, DE holds the array name and HL points to where it is going to be stored. We start by storing the array name.
07CD
73
AllocArray
MOV M,E
07CE
23
INX H
07CF
72
MOV M,D
07D0
23
INX H
If DIM_OR_EVAL is zero (indicating array access), then jump ahead with DE=????
07D1
112C00
LXI D,002C
07D4
3A5B01
LDA 015B
07D7
B7
ORA A
07D8
CAE107
JZ 07E1
DIM_OR_EVAL is not zero, therefore we're declaring the array. Here we restore the array elements size to DE, save it again, add 4, and write that value to follow the array name.
07DB
D1
POP D
07DC
D5
PUSH D
07DD
13
INX D
07DE
13
INX D
07DF
13
INX D
07E0
13
INX D
Write out array size.
07E1
D5
PUSH D
07E2
73
MOV M,E
07E3
23
INX H
07E4
72
MOV M,D
07E5
23
INX H
07E6
E5
PUSH H
Check the new VAR_TOP won't interfere with the stack, and update VAR_TOP.
07E7
19
DAD D
Initialise all array elements to 0.
07EE
D1
POP D
07EF
2B
InitElements
DCX H
07F0
3600
MVI M,00
07F2
E7
RST 4
07F6
C3BF07
JMP 07BF
[Index] [Previous] [Next]