Prev: 10996 Up: Map Next: 11249
11007: THE 'LET' COMMAND ROUTINE
Used by the routines at VAL_FET_1, FOR and INPUT.
This is the actual assignment routine for the LET, READ and INPUT commands.
When the destination variable is a 'newly declared variable' then DEST will point to the first letter of the variable's name as it occurs in the BASIC line. Bit 1 of FLAGX will be set.
However if the destination variable 'exists already' then bit 1 of FLAGX will be reset and DEST will point for a numeric variable to the location before the five bytes of the 'old number', and for a string variable to the first location of the 'old string'. The use of DEST in this manner applies to simple variables and to elements of arrays.
Bit 0 of FLAGX is set if the destination variable is a 'complete' simple string variable. (Signalling - delete the old copy.) Initially the current value of DEST is collected and bit 1 of FLAGS tested.
LET 11007 LD HL,(23629) Fetch the present address in DEST.
11010 BIT 1,(IY+55) Jump if handling a variable that 'exists already' (bit 1 of FLAGX reset).
11014 JR Z,L_EXISTS
A 'newly declared variable' is being used. So first the length of its name is found.
11016 LD BC,5 Presume dealing with a numeric variable - 5 bytes.
Enter a loop to deal with the characters of a long name. Any spaces or colour codes in the name are ignored.
L_EACH_CH 11019 INC BC Add '1' to the counter for each character of a name.
L_NO_SP 11020 INC HL Move along the variable's name.
11021 LD A,(HL) Fetch the 'present code'.
11022 CP " " Jump back if it is a 'space', thereby ignoring spaces.
11024 JR Z,L_NO_SP
11026 JR NC,L_TEST_CH Jump forward if the code is 33 to 255.
11028 CP 16 Accept, as a final code, those in the range 0 to 15.
11030 JR C,L_SPACES
11032 CP 22 Also accept the range 22 to 31.
11034 JR NC,L_SPACES
11036 INC HL Step past the control code after any of INK to OVER.
11037 JR L_NO_SP Jump back as these control codes are treated as spaces.
Separate 'numeric' and 'string' names.
L_TEST_CH 11039 CALL ALPHANUM Is the code alphanumeric?
11042 JR C,L_EACH_CH If It is so then accept it as a character of a 'long' name.
11044 CP "$" Is the present code a '$'?
11046 JP Z,L_NEW Jump forward as handling a 'newly declared' simple string.
The 'newly declared numeric variable' presently being handled will require BC spaces in the variables area for its name and its value. The room is made available and the name of the variable is copied over with the characters being 'marked' as required.
L_SPACES 11049 LD A,C Copy the 'length' to A.
11050 LD HL,(23641) Make HL point to the '128-byte' at the end of the variables area (E-LINE-1).
11053 DEC HL
11054 CALL MAKE_ROOM Now open up the variables area. Note: in effect BC spaces are made before the displaced '128-byte'.
11057 INC HL Point to the first 'new' byte.
11058 INC HL Make DE point to the second 'new' byte.
11059 EX DE,HL
11060 PUSH DE Save this pointer.
11061 LD HL,(23629) Fetch the pointer to the start of the name (DEST).
11064 DEC DE Make DE point to the first 'new' byte.
11065 SUB 6 Make B hold the 'number of extra letters' that are found in a 'long name'.
11067 LD B,A
11068 JR Z,L_SINGLE Jump forward if dealing with a variable with a 'short name'.
The 'extra' codes of a long name are passed to the variables area.
L_CHAR 11070 INC HL Point to each 'extra' code.
11071 LD A,(HL) Fetch the code.
11072 CP 33 Accept codes from 33 to 255; ignore codes 0 to 32.
11074 JR C,L_CHAR
11076 OR 32 Set bit 5, as for lower case letters.
11078 INC DE Transfer the codes in turn to the 2nd 'new' byte onwards.
11079 LD (DE),A
11080 DJNZ L_CHAR Go round the loop for all the 'extra' codes.
The last code of a 'long' name has to be ORed with 128.
11082 OR 128 Mark the code as required and overwrite the last code.
11084 LD (DE),A
The first letter of the name of the variable being handled is now considered.
11085 LD A,192 Prepare to mark the letter of a 'long' name.
L_SINGLE 11087 LD HL,(23629) Fetch the pointer to the letter (DEST).
11090 XOR (HL) A holds 0 for a 'short' name and 192 for a 'long' name.
11091 OR 32 Set bit 5, as for lower case letters.
11093 POP HL Drop the pointer now.
The subroutine L_FIRST is now called to enter the 'letter' into its appropriate location.
11094 CALL L_FIRST Enter the letter and return with HL pointing to 'new 128-byte'.
The 'last value' can now be transferred to the variables area. Note that at this point HL always points to the location after the five locations allotted to the number.
A 'RST 40' instruction is used to call the calculator and the 'last value' is deleted. However this value is not overwritten.
L_NUMERIC 11097 PUSH HL Save the 'destination' pointer.
11098 RST 40 Use the calculator to move STKEND back five bytes.
11099 DEFB 2 delete
11100 DEFB 56 end_calc
11101 POP HL Restore the pointer.
11102 LD BC,5 Give the number a 'length' of five bytes.
11105 AND A Make HL point to the first of the five locations and jump forward to make the actual transfer.
11106 SBC HL,BC
11108 JR L_ENTER
Come here if considering a variable that 'exists already'. First bit 6 of FLAGS is tested so as to separate numeric variables from string or array of string variables.
L_EXISTS 11110 BIT 6,(IY+1) Jump forward if handling any kind of string variable (bit 6 of FLAGS reset).
11114 JR Z,L_DELETE
For numeric variables the 'new' number overwrites the 'old' number. So first HL has to be made to point to the location after the five bytes of the existing entry. At present HL points to the location before the five bytes.
11116 LD DE,6 The five bytes of a number + 1.
11119 ADD HL,DE HL now points 'after'.
11120 JR L_NUMERIC Jump back to make the actual transfer.
The parameters of the string variable are fetched and complete simple strings separated from 'sliced' strings and array strings.
L_DELETE 11122 LD HL,(23629) Fetch the 'start' (DEST). Note: this line is redundant.
11125 LD BC,(23666) Fetch the 'length' (STRLEN).
11129 BIT 0,(IY+55) Jump if dealing with a complete simple string (bit 0 of FLAGX set); the old string will need to be 'deleted' in this case only.
11133 JR NZ,L_ADD
When dealing with a 'slice' of an existing simple string, a 'slice' of a string from an array of strings or a complete string from an array of strings there are two distinct stages involved. The first is to build up the 'new' string in the work space, lengthening or shortening it as required. The second stage is then to copy the 'new' string to its allotted room in the variables area.
However do nothing if the string has no 'length'.
11135 LD A,B Return if the string is a null string.
11136 OR C
11137 RET Z
Then make the required number of spaces available in the work space.
11138 PUSH HL Save the 'start' (DEST).
11139 RST 48 Make the necessary amount of room in the work space.
11140 PUSH DE Save the pointer to the first location.
11141 PUSH BC Save the 'length' for use later on.
11142 LD D,H Make DE point to the last location.
11143 LD E,L
11144 INC HL Make HL point 'one past' the new locations.
11145 LD (HL)," " Enter a 'space' character.
11147 LDDR Copy this character into all the new locations. Finish with HL pointing to the first new location.
The parameters of the string being handled are now fetched from the calculator stack.
11149 PUSH HL Save the pointer briefly.
11150 CALL STK_FETCH Fetch the 'new' parameters.
11153 POP HL Restore the pointer.
Note: at this point the required amount of room has been made available in the work space for the 'variable in assignment'; e.g. for the statement 'LET A$(4 TO 8)="abcdefg"' five locations have been made.
The parameters fetched above as a 'last value' represent the string that is to be copied into the new locations with Procrustean lengthening or shortening as required.
The length of the 'new' string is compared to the length of the room made available for it.
11154 EX (SP),HL 'Length' of new area to HL. 'Pointer' to new area to stack.
11155 AND A Compare the two 'lengths' and jump forward if the 'new' string will fit into the room, i.e. no shortening required.
11156 SBC HL,BC
11158 ADD HL,BC
11159 JR NC,L_LENGTH
11161 LD B,H However modify the 'new' length if it is too long.
11162 LD C,L
L_LENGTH 11163 EX (SP),HL 'Length' of new area to stack. 'Pointer' to new area to HL.
As long as the new string is not a 'null string' it is copied into the work space. Procrustean lengthening is achieved automatically if the 'new' string is shorter than the room available for it.
11164 EX DE,HL 'Start' of new string to HL. 'Pointer' to new area to DE.
11165 LD A,B Jump forward if the 'new' string is a 'null' string.
11166 OR C
11167 JR Z,L_IN_W_S
11169 LDIR Otherwise move the 'new' string to the work space.
The values that have been saved on the machine stack are restored.
L_IN_W_S 11171 POP BC 'Length' of new area.
11172 POP DE 'Pointer' to new area.
11173 POP HL The start - the pointer to the 'variable in assignment' which was originally in DEST. L_ENTER is now used to pass the 'new' string to the variables area.
The following short subroutine is used to pass either a numeric value from the calculator stack, or a string from the work space, to its appropriate position in the variables area.
The subroutine is therefore used for all except 'newly declared' simple strings and 'complete and existing' simple strings.
L_ENTER 11174 EX DE,HL Change the pointers over.
11175 LD A,B Check once again that the length is not zero.
11176 OR C
11177 RET Z
11178 PUSH DE Save the destination pointer.
11179 LDIR Move the numeric value or the string.
11181 POP HL Return with the HL register pair pointing to the first byte of the numeric value or the string.
11182 RET
When handling a 'complete and existing' simple string the new string is entered as if it were a 'newly declared' simple string before the existing version is 'reclaimed'.
L_ADD 11183 DEC HL Make HL point to the letter of the variable's name, i.e. DEST-3.
11184 DEC HL
11185 DEC HL
11186 LD A,(HL) Pick up the letter.
11187 PUSH HL Save the pointer to the 'existing version'.
11188 PUSH BC Save the 'length' of the 'existing string'.
11189 CALL L_STRING Use L_STRING to add the new string to the variables area.
11192 POP BC Restore the 'length'.
11193 POP HL Restore the pointer.
11194 INC BC Allow one byte for the letter and two bytes for the length.
11195 INC BC
11196 INC BC
11197 JP RECLAIM_2 Exit by jumping to RECLAIM_2 which will reclaim the whole of the existing version.
'Newly declared' simple strings are handled as follows:
L_NEW 11200 LD A,223 Prepare for the marking of the variable's letter.
11202 LD HL,(23629) Fetch the pointer to the letter (DEST).
11205 AND (HL) Mark the letter as required. L_STRING is now used to add the new string to the variables area.
The parameters of the 'new' string are fetched, sufficient room is made available for it and the string is then transferred.
L_STRING 11206 PUSH AF Save the variable's letter.
11207 CALL STK_FETCH Fetch the 'start' and the 'length' of the 'new' string.
11210 EX DE,HL Move the 'start' to HL.
11211 ADD HL,BC Make HL point one past the string.
11212 PUSH BC Save the 'length'.
11213 DEC HL Make HL point to the end of the string.
11214 LD (23629),HL Save the pointer briefly in DEST.
11217 INC BC Allow one byte for the letter and two bytes for the length.
11218 INC BC
11219 INC BC
11220 LD HL,(23641) Make HL point to the '128-byte' at the end of the variables area (E-LINE-1).
11223 DEC HL
11224 CALL MAKE_ROOM Now open up the variables area. Note: in effect BC spaces are made before the displaced '128-byte'.
11227 LD HL,(23629) Restore the pointer to the end of the 'new' string from DEST.
11230 POP BC Make a copy of the length of the 'new' string.
11231 PUSH BC
11232 INC BC Add one to the length in case the 'new' string is a 'null' string.
11233 LDDR Now copy the 'new' string + one byte.
11235 EX DE,HL Make HL point to the byte that is to hold the high-length.
11236 INC HL
11237 POP BC Fetch the 'length'.
11238 LD (HL),B Enter the high-length.
11239 DEC HL Back one.
11240 LD (HL),C Enter the low-length.
11241 POP AF Fetch the variable's letter.
The following subroutine is entered with the letter of the variable, suitably marked, in the A register. The letter overwrites the 'old 128-byte' in the variables area. The subroutine returns with the HL register pair pointing to the 'new 128-byte'.
L_FIRST 11242 DEC HL Make HL point to the 'old 128-byte'.
11243 LD (HL),A It is overwritten with the letter of the variable.
11244 LD HL,(23641) Make HL point to the 'new 128-byte' (E-LINE-1).
11247 DEC HL
11248 RET Finished with all the 'newly declared variables'.
Prev: 10996 Up: Map Next: 11249