Prev: 2AF4 Up: Map Next: 2BF1
2AFF: 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.
Input
Output
LET 2AFF LD HL,($5C4D) Fetch the present address in DEST.
2B02 BIT 1,(IY+$37) Jump if handling a variable that 'exists already' (bit 1 of FLAGX reset).
2B06 JR Z,L_EXISTS
A 'newly declared variable' is being used. So first the length of its name is found.
2B08 LD BC,$0005 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 2B0B INC BC Add '1' to the counter for each character of a name.
L_NO_SP 2B0C INC HL Move along the variable's name.
2B0D LD A,(HL) Fetch the 'present code'.
2B0E CP " " Jump back if it is a 'space'; thereby Ignoring spaces.
2B10 JR Z,L_NO_SP
2B12 JR NC,L_TEST_CH Jump forward if the code is +21 to +FF.
2B14 CP $10 Accept, as a final code, those in the range +00 to +0F.
2B16 JR C,L_SPACES
2B18 CP $16 Also accept the range +16 to +1F.
2B1A JR NC,L_SPACES
2B1C INC HL Step past the control code after any of INK to OVER.
2B1D JR L_NO_SP Jump back as these control codes are treated as spaces.
Separate 'numeric' and 'string' names.
L_TEST_CH 2B1F CALL ALPHANUM Is the code alphanumeric?
2B22 JR C,L_EACH_CH If It is so then accept it as a character of a 'long' name.
2B24 CP "$" Is the present code a '$'?
2B26 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 2B29 LD A,C Copy the 'length' to A.
2B2A LD HL,($5C59) Make HL point to the '+80-byte' at the end of the variables area (E-LINE-1).
2B2D DEC HL
2B2E CALL MAKE_ROOM Now open up the variables area. Note: in effect BC spaces are made before the displaced '+80-byte'.
2B31 INC HL Point to the first 'new' byte.
2B32 INC HL Make DE point to the second 'new' byte.
2B33 EX DE,HL
2B34 PUSH DE Save this pointer.
2B35 LD HL,($5C4D) Fetch the pointer to the start of the name (DEST).
2B38 DEC DE Make DE point to the first 'new' byte.
2B39 SUB $06 Make B hold the 'number of extra letters' that are found in a 'long name'.
2B3B LD B,A
2B3C 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 2B3E INC HL Point to each 'extra' code.
2B3F LD A,(HL) Fetch the code.
2B40 CP $21 Accept codes from +21 to +FF; ignore codes +00 to +20.
2B42 JR C,L_CHAR
2B44 OR $20 Set bit 5, as for lower case letters.
2B46 INC DE Transfer the codes in turn to the 2nd 'new' byte onwards.
2B47 LD (DE),A
2B48 DJNZ L_CHAR Go round the loop for all the 'extra' codes.
The last code of a 'long' name has to be ORed with +80.
2B4A OR $80 Mark the code as required and overwrite the last code.
2B4C LD (DE),A
The first letter of the name of the variable being handled is now considered.
2B4D LD A,$C0 Prepare to mark the letter of a 'long' name.
L_SINGLE 2B4F LD HL,($5C4D) Fetch the pointer to the letter (DEST).
2B52 XOR (HL) A holds +00 for a 'short' name and +C0 for a 'long' name.
2B53 OR $20 Set bit 5, as for lower case letters.
2B55 POP HL Drop the pointer now.
The subroutine L_FIRST is now called to enter the 'letter' into its appropriate location.
2B56 CALL L_FIRST Enter the letter and return with HL pointing to 'new +80-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 $28' instruction is used to call the calculator and the 'last value' is deleted. However this value is not overwritten.
L_NUMERIC 2B59 PUSH HL Save the 'destination' pointer.
2B5A RST $28 Use the calculator to move STKEND back five bytes.
2B5B DEFB $02 delete
2B5C DEFB $38 end_calc
2B5D POP HL Restore the pointer.
2B5E LD BC,$0005 Give the number a 'length' of five bytes.
2B61 AND A Make HL point to the first of the five locations and jump forward to make the actual transfer.
2B62 SBC HL,BC
2B64 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 2B66 BIT 6,(IY+$01) Jump forward if handling any kind of string variable (bit 6 of FLAGS reset).
2B6A 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.
2B6C LD DE,$0006 The five bytes of a number + 1.
2B6F ADD HL,DE HL now points 'after'.
2B70 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 2B72 LD HL,($5C4D) Fetch the 'start' (DEST). Note: this line is redundant.
2B75 LD BC,($5C72) Fetch the 'length' (STRLEN).
2B79 BIT 0,(IY+$37) 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.
2B7D 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'.
2B7F LD A,B Return if the string is a null string.
2B80 OR C
2B81 RET Z
Then make the required number of spaces available in the work space.
2B82 PUSH HL Save the 'start' (DEST).
2B83 RST $30 Make the necessary amount of room in the work space.
2B84 PUSH DE Save the pointer to the first location.
2B85 PUSH BC Save the 'length' for use later on.
2B86 LD D,H Make DE point to the last location.
2B87 LD E,L
2B88 INC HL Make HL point 'one past' the new locations.
2B89 LD (HL)," " Enter a 'space' character.
2B8B 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.
2B8D PUSH HL Save the pointer briefly.
2B8E CALL STK_FETCH Fetch the 'new' parameters.
2B91 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.
2B92 EX (SP),HL 'Length' of new area to HL. 'Pointer' to new area to stack.
2B93 AND A Compare the two 'lengths' and jump forward if the 'new' string will fit into the room, i.e. no shortening required.
2B94 SBC HL,BC
2B96 ADD HL,BC
2B97 JR NC,L_LENGTH
2B99 LD B,H However modify the 'new' length if it is too long.
2B9A LD C,L
L_LENGTH 2B9B 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.
2B9C EX DE,HL 'Start' of new string to HL. 'Pointer' to new area to DE.
2B9D LD A,B Jump forward if the 'new' string is a 'null' string.
2B9E OR C
2B9F JR Z,L_IN_W_S
2BA1 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 2BA3 POP BC 'Length' of new area.
2BA4 POP DE 'Pointer' to new area.
2BA5 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 2BA6 EX DE,HL Change the pointers over.
2BA7 LD A,B Check once again that the length is not zero.
2BA8 OR C
2BA9 RET Z
2BAA PUSH DE Save the destination pointer.
2BAB LDIR Move the numeric value or the string.
2BAD POP HL Return with the HL register pair pointing to the first byte of the numeric value or the string.
2BAE 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 2BAF DEC HL Make HL point to the letter of the variable's name, i.e. DEST-3.
2BB0 DEC HL
2BB1 DEC HL
2BB2 LD A,(HL) Pick up the letter.
2BB3 PUSH HL Save the pointer to the 'existing version'.
2BB4 PUSH BC Save the 'length' of the 'existing string'.
2BB5 CALL L_STRING Use L_STRING to add the new string to the variables area.
2BB8 POP BC Restore the 'length'.
2BB9 POP HL Restore the pointer.
2BBA INC BC Allow one byte for the letter and two bytes for the length.
2BBB INC BC
2BBC INC BC
2BBD 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 2BC0 LD A,$DF Prepare for the marking of the variable's letter.
2BC2 LD HL,($5C4D) Fetch the pointer to the letter (DEST).
2BC5 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 2BC6 PUSH AF Save the variable's letter.
2BC7 CALL STK_FETCH Fetch the 'start' and the 'length' of the 'new' string.
2BCA EX DE,HL Move the 'start' to HL.
2BCB ADD HL,BC Make HL point one past the string.
2BCC PUSH BC Save the 'length'.
2BCD DEC HL Make HL point to the end of the string.
2BCE LD ($5C4D),HL Save the pointer briefly in DEST.
2BD1 INC BC Allow one byte for the letter and two bytes for the length.
2BD2 INC BC
2BD3 INC BC
2BD4 LD HL,($5C59) Make HL point to the '+80-byte' at the end of the variables area (E-LINE-1).
2BD7 DEC HL
2BD8 CALL MAKE_ROOM Now open up the variables area. Note: in effect BC spaces are made before the displaced '+80-byte'.
2BDB LD HL,($5C4D) Restore the pointer to the end of the 'new' string from DEST.
2BDE POP BC Make a copy of the length of the 'new' string.
2BDF PUSH BC
2BE0 INC BC Add one to the length in case the 'new' string is a 'null' string.
2BE1 LDDR Now copy the 'new' string + one byte.
2BE3 EX DE,HL Make HL point to the byte that is to hold the high-length.
2BE4 INC HL
2BE5 POP BC Fetch the 'length'.
2BE6 LD (HL),B Enter the high-length.
2BE7 DEC HL Back one.
2BE8 LD (HL),C Enter the low-length.
2BE9 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 +80-byte' in the variables area. The subroutine returns with the HL register pair pointing to the 'new +80-byte'.
L_FIRST 2BEA DEC HL Make HL point to the 'old +80-byte'.
2BEB LD (HL),A It is overwritten with the letter of the variable.
2BEC LD HL,($5C59) Make HL point to the 'new +80-byte' (E-LINE-1).
2BEF DEC HL
2BF0 RET Finished with all the 'newly declared variables'.
Prev: 2AF4 Up: Map Next: 2BF1