[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
0712 D7 RST NextChar
0713 C8 RZ
Syntax check for a comma.
0714 CF RST SyntaxCheck
0715 2C ','
Set return address to DimContd above.
0716 011107 Dim LXI B,DimContd
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
071C 325B01 STA DIM_OR_EVAL
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
0720 CD8004 CALL CharIsAlpha
0723 DAD001 JC SyntaxError
0726 AF XRA A
0727 4F MOV C,A
0728 D7 RST NextChar
0729 D22E07 JNC 072E
072C 4F MOV C,A
072D D7 RST NextChar
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 '('
0730 CA8A07 JZ GetArrayVar
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
0734 2A6901 LHLD VAR_ARRAY_BASE
0737 EB XCHG
0738 2A6701 LHLD VAR_BASE
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.
073B E7 FindVarLoop RST CompareHLDE
073C CA5207 JZ AllocNewVar
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
074F C33B07 JMP FindVarLoop
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
0758 E7 RST CompareHLDE
0759 D1 POP D
075A CA8507 JZ AlreadyAllocd
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
0763 2A6B01 LHLD VAR_TOP
0766 E5 PUSH H
0767 09 DAD B
0768 C1 POP B
0769 E5 PUSH H
076A CDA701 CALL CopyMemoryUp
076D E1 POP H
076E 226B01 SHLD VAR_TOP
Update VAR_ARRAY_BASE cos the array block has been moved up 6 bytes.
0771 60 MOV H,B
0772 69 MOV L,C
0773 226901 SHLD VAR_ARRAY_BASE
Initialise the new variable to zero.
0776 2B InitVarLoop DCX H
0777 3600 MVI M,00
0779 E7 RST CompareHLDE
077A C27607 JNZ InitVarLoop
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
078B 3A5B01 LDA DIM_OR_EVAL
078E F5 PUSH PSW
Get array subscript into CDE
078F CD8804 CALL GetSubscript
Syntax check for closing bracket ')'
0792 CF RST SyntaxCheck
0793 29 ')'
Restore declare-or-access flag
0794 F1 POP PSW
0795 325B01 STA DIM_OR_EVAL
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
079D 2A6901 LHLD VAR_ARRAY_BASE
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
07A5 2A6B01 LHLD VAR_TOP
07A8 E7 RST CompareHLDE
07A9 EB XCHG
07AA D1 POP D
07AB CACD07 JZ AllocArray
Advance to the next array in the block.
07AE F7 RST PushNextWord
07AF E3 XTHL
07B0 E7 RST CompareHLDE
07B1 E1 POP H
07B2 F7 RST PushNextWord
07B3 C2A107 JNZ FindArray
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
07BC C2D501 JNZ Error
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.
07C2 E7 RST CompareHLDE
07C3 1E10 MVI E,10
07C5 D2D501 JNC Error
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
07E8 CDC301 CALL CheckEnoughMem
07EB 226B01 SHLD VAR_TOP
Initialise all array elements to 0.
07EE D1 POP D
07EF 2B InitElements DCX H
07F0 3600 MVI M,00
07F2 E7 RST 4
07F3 C2EF07 JNZ InitElements
07F6 C3BF07 JMP 07BF

 


[Index] [Previous] [Next]