- M in the M/P flag signals "not a number array"; this was set in V EACH. The search of the variables area is therefore complete, unless the Z flag shows zero; an array element or slice is required, and the carry flag shows NC; the required variable has beenfound. When both these conditions exist the search is completedby a call to STK VAR, with the parameters listed above. In 26C9 S LETTER, indexed under 24FB SCANNING, the call follows immediately, except for a "Variable not found" report if the carry flag was set; in other cases the following routine comes before checking the flags and calling STK VAR: _1C22_VAR_A_1: zero FLAGX, signalling in bit 1, "old variable found" in bit 0, "slice or array element"; in other words, "don't delete the old variable copy". The other bits are irrelevant here. - if there is no carry jump on to VAR A 2; the variable was found. It is an array or string if the Z/NZ flag shows zero - (new variable) set bit 1 of FLAGX; "new variable" - if the Z flag shows NZ jump on to VAR A 3; a simple variable. See below, after STK VAR - (an array) report "Variable not found"; the array should have been set up by a DIM. _1C30_VAR_A_2 (declared variables): if the flag shows zero call 2996 STK VAR, misprinted VARS; the continuation of VARA 2 is described following STK VAR below. _2996_STK_VAR subroutine (a variable is found and identified as an array or string): zero an array/string index; signalling an array - zero a dimension counter - if syntax is being checked jump on to SV COUNT; this is a jump into the element counting loop with a loop counter of zero - in effect 256d. The loop is turned, without concern for anything except correct placing of commas and subscripts being within limits, until either a 29h ) is encountered in the BASIC or 256d turns have been completed. As only 255d dimensions are allowed, completing 256d turns counts as an error - (run time) check the hi bit of the code at the variables pointer; simple strings have zero there - if it isn't zero jump on to SV ARRAYS; an array variable - (simple string) increment the array/string index; one for a simple string. _29A1_SV_SIMPLE$: step on the variables pointer and read the length bytes which follow the variable letter - put the pointer on the start of the actual string - call 2AB2 STK STO $, misprinted STK STORE, to put the start address, length and array/string index on the calculator stack; they are the string parameters - read the code in the BASIC line and jump on to SV SLICE?. _29AE_SV_ARRAYS (array variable, numeric or string, run time): move the variables pointer past the length bytes - get the dimension counter from the dimension number ofthe array - check bit 6 of the "abcxxxxx" byte; zero for numeric, one for strings - if it is a numeric array jump on to SV PTR - (string array) decrement the dimension counter; the last dimension, the number of characters in each element, gets special treatment later in SV ELEM$ - if this makes zero jump back to SV SIMPLE$; the stringarray had only one dimension. Handle it as a simple string, but with the array/string index still zero - read the code at the BASIC pointer - if it isn't 28h ( report "Subscript wrong"; there mustbe at least one subscript. This is run time, but this error would be missed in syntax checking. _29C0_SV_PTR: jump on into the element counting loop at SV COUNT. _29C3_SV_COMMA (the element counting loop returns to hereafter reading each dimension until the dimension counter steps down to zero; HL holds the element count so far and the BASIC pointer has been moved on past the last subscript): read the code in BASIC - if it is a comma, jump on to SV LOOP; there is anothersubscript - (not a comma, no more subscripts) check the syntax flag - if this is run time report "Subscript wrong"; as the loop counter hasn't reached zero, there_ought to be another subscript - (syntax checking) check the string/numeric flag - if it isn't zero jump on to SV CLOSE; a string array, the code may be CC TO or 29h ) - (numeric array) if the BASIC code isn't 29h ), report "Nonsense in BASIC" - (finished syntax checking numeric array) move on the BASIC pointer and return; see VAR A 2 continued below. _29DB_SV_CLOSE (syntax checking string array): if the code is 29h ), jump on to SV DIM; the BASIC may hold something like a$(x)(y), indicating a slice - if the code isn't CC TO report "Nonsense in BASIC". _29E0_SV_CH_ADD (still syntax checking string arrays; theBASIC code just read is TO): move the BASIC pointer back one andjump on to SV SLICE. _29E7_SV_COUNT (entry point to the element counting loop): zero the element counter; it will accumulate the serial number of the specified element in the string of elements following the variable name in the variables area. _29EA_SV_LOOP: move on the BASIC pointer; now on the subscript in BASIC - check the syntax and string/array flags and jump on toSV MULT unless_both flags are set - (syntax checking of string arrays) read the code underthe BASIC pointer - if it is 29h ) jump on to SV DIM; there are no more subscripts - if it is CC TO jump back to SV CH ADD; for slicing. _29FB_SV_MULT (DE is the variables pointer, one before the address of the dimension size in the variables area) call 2AEE DE,(DE+1) to get the dimension size corresponding to the next subscript and move on the variables pointer to the address of the next dimension. See NB 1. above for the calculation. The first dimension size is the b in Y = X * b + (y - 1) - call 2ACC INT EXP1 with the dimension size as limit; it gets the subscript y - if y > b report "Subscript wrong" - decrement y to y - 1 - call 2AF4 GET HL*DE to get X * b - add (y - 1); the result is the updated element counter - loop back to SV COMMA, counting down the dimension counter - (dimension counter has gone to zero) if bit 7 of the "abcxxxxx" byte is set flag NZ; syntax checking, and the loop has made 256d turns. _2A12_SV_RPT_C: if NZ is flagged report "Nonsense in BASIC" - if bit 6 of the "abcxxxxx" byte is set jump on to SV ELEM$; string array - (numeric array) if the code at the BASIC pointer isn't29h ) report "Subscript wrong". _2A22_SV_NUMBER (numeric array, the element counter holdsthe number of elements up to but not including the one specified): move on the BASIC pointer; now one past the ")" - call 2AF4 GET HL*DE with the element counter and 05; all the elements of a number array are FP numbers, occupying five bytes each - add the result to the variables pointer; it had reached the address of the last dimension number in the variables area, just before the first element, so this makes theaddress of the first byte of the specified element - return; see VAR A 2 continued below. _2A2C_SV_ELEM$ (string array, the element counter holds the number of elements up to but not including the one specified): call 2AEE DE,(DE+1) once more; the dimension counterwas decremented in SV ARRAYS, so there is one more dimension, the number of characters in each element - call 2AF4 GET HL*DE to multiply the element counter bythe dimension size for the last time; getting the total number of characters in all the elements up to but not including the one specified - add the result to the variables pointer; it had reached the address of the last dimension number in the variables area, just before the first element, so this makes theaddress of the first byte of the specified string element - call 2AB1 STK ST 0 to put the string parameters on thestack indexed as an array; the dimension size is the length and the final variables pointer address is the start - read the code at the BASIC pointer - if it is 29h ) jump on to SV DIM - if it isn't a comma report "Subscript wrong". _2A45_SV_SLICE (entry may be from SV CH ADD, SV SLICE? ordirect from SV ELEM$, but the BASIC pointer is in any case on the code before a separate slicing subscript in brackets, or before the last subscript of a string array, which is always read as a slice): call 2A52 SLICING to change the string parameters to those of the slice. _2A48_SV_DIM (entry may be from SV CLOSE, SV LOOP, SV DIM, or direct from SV SLICE, but the BASIC pointer is always ona closing bracket): move on the BASIC pointer. _2A49_SV_SLICE? (entry may be from SV SIMPLE? or direct, but the BASIC pointer in any case has just moved past a string array specification): if the code is 28h ( jump back to SV SLICE - zero bit 6 of FLAGS; "string result" - return. In the most important case return is into: _1C30_VAR_A_2 (continued): if bit 6 of FLAGS is set jump on to VAR A 3; the variable is numeric - (string variables) zero an array/slice flag; for use if syntax checking - in run time, call 2BF1 STK FETCH, which gets the startaddress of the string into DE, its length into BC, and the array/slice flag in A; 00 for arrays/slices, ie "overwrite old copy", 01 for simple strings ie "delete old copy". In syntax checking, the array/slice flag is left at zero - transfer the array/slice flag to bit 0 of FLAGX. _1C46_VAR_A_3: put the values from STK VAR in 5C72 STRLENand 5C4D DEST; these are different values according to the string/numeric status and declared/undeclared status of the variable: for details see 5C72 STRLEN. - return. Exit (from STK VAR; as usual, not counting error reports): RETs - from SV COMMA if checking syntax of numeric arrays - from SV NUMBER if a number element was found in run time - from SV SLICE? for string arrays. Output parameters: if a number element was found, HL holds the address of its first byte. Otherwise string parameterson the calculator stack. FLAGS bit 6 shows the status of the result - for the values in 5C72 STRLEN and 5C4D DEST see 5C72 STRLEN. LOOK VARS called from: 0652 SA DATA 1C1F CLASS 01 1C6C CLASS 04 26C9 S LETTER 2C02 DIM STK VAR called from: 1C30 VAR A 2 (misprinted STK VARS) 26C9 S LETTER (misprinted STK VARS) 2C05 D RPORT C Rems: 27BD S FN SBRN called by SCANNING (26C9 S LETTER) 288D SF VALUE sets DEFADD to make it check DEF FN 2951 STK F ARG (see STK F ARG under LOOK VARS for comment on this baffling note) 2981 SFA MATCH vble found in DEF FN, no need 2991 SFA END drops some pointers from LOOK VARS loop see timing loop control variable, looping line and statement numbers, looping variable of FOR ... NEXT loop, see variables, FOR ... NEXT loops loop counter see 5C67 BREG loudspeaker, LOUDSPEAKER ROUTINES see 03B5 BEEPER lower case letters see character codes lower display, lower part of display/screen lower print line, lower screen see DISPLAY AREA LOWER SCREEN COPYING SUBROUTINE see 111D ED COPY LPRINT key (E0) see also commands, functions and operators, KEYBOARD SCANNING, 022C extended mode key table (b) The C key in E mode without shift produces the command LPRINT. The command can be followed by all the same parameters, etc, as the PRINT command, but the colour controls are ineffective. It produces printout through stream 3, ie to the ZXprinter. The command is read by 1B29 STMT L 1 referring through the syntax offset table 1A48 to the syntax parameter table 1A7A.1AD9 P LPRINT causes a jump via 1C11 CLASS 05 and 1C16 JUMP C R to the executive routine 1FC9 LPRINT. LPRINT subroutine 1FC9 Called only from 1AD9 P LPRINT in the syntax parameter table; executes the LPRINT command. Exactly like 1FCD PRINT, see index entry, except that channel P is opened instead of channel S, ie output is sent to the ZX printer not to the screen. L SINGLE 2B4F (2AFF LET) Jumps from: 2B29 L SPACES L SPACES 2B29 (2AFF LET) Jumps from: 2B0C L NO SP (twice) L STRING subroutine 2BC6 Adds a new complete simple string variable at the end ofthe variables area. Input parameters: A holds the variable letter, with the first three flag bits already correct; 010 for a simple string - the string parameters are the last value on the calculator stack. Action: call 2BF1 STK FETCH to put the string parameters in BCDEA - add the length to the start address; making a pointer to the last byte of the string - save this address in 5C4D DEST - increment the length by three; allowing three extra bytes for the variable letter and the string length - get a pointer from 5C59 E LINE to the end of the variables area and decrement it to below the 80-byte - call 1655 MAKE ROOM to make room for the string at theend of the variables area - copy the string from its last byte whose address is in5C4D DEST, with an extra byte in case its length is zero; the extra byte is immediately overwritten by the length bytes - insert the length bytes just after the position for the variable letter. Exit: into 2BEA L FIRST, which puts the variable letter byte in the place of the old 80-byte. Output parameters: A still holds the variable letter - HL holds the address one past the required address - BC holds the length. Called from: 2BAF L ADD$ Exit from: 2AFF LET 2BC0 L NEW$ L TEST CH 2B1F (2AFF LET) Jumps from: 2B0C L NO SP ----- machine stack see GO SUB stack MAIN ADD 155D (see BASIC INTERPRETER) Jumps from: 12CF MAIN 3