- C holds the "last edge"; the present border colour in bits 3 -> zero, and its bit 5 is 1 if the last reading of port 7FFE showed EAR on, zero if it was off. Action: set a counter at 16h/22d for the waiting loop. _05E9_LD_DELAY: decrement the counter - if it isn't yet zero jump back to LD DELAY - clear the carry flag. _05ED_LD_SAMPLE: increment the timing constant - if it is zero return; time is up - read port 7FFE - if the lo bit is zero return; the BREAK/SPACE key is pressed - compare the port input with the last edge - if there has been no change loop back to LD SAMPLE - (there is an edge) ones complement the last edge; 22h -> DDh, or 21h -> DEh, or vice versa - AND with 00000111b/07 to extract its last three bits as the border colour; 02 RED or 05 CYAN or 01 BLUE or 06 YELLOW - OR with 00001000b/08; sets bit 3 to turn MIC off - output the colour to port FE to change the border - set the carry and return. Exit: RET, in three places from LD SAMPLE. Output parameters: B holds zero if no edge was found, or records how many times the port was read until an edge was foundby the number of increments from its entry value - C still holds the border colour and pulse on/off state, reversed from the entry value if an edge was found - HL and DE are unchanged - carry signals "edge found" - NC and Z flags signal "no edge", NC and NZ signal BREAK. Called from: 056C LD START 058F LD SYNC (twice) 05E3 LD EDGE 2 Rems: 05E9 LD DELAY delay before entering loop 05ED LD SAMPLE gives timing of loop LD EDGE 2 subroutine 05E3 (05E7 LD EDGE 1) A double call of the LD EDGE routine: calls LD EDGE 1, returns if no edge is found, otherwise exits through LD EDGE 1 again. It therefore can find both the start and the end of a pulse from tape. The CALL and RET NC add 22d T states to the overall time, or 28d if not even one edge is found; so using thesame calculations as above, if LD EDGE 2 finds two edges the time is indicated by 59 * (b2 - B) + 808 + 22 = 59 * (b2 - B) + 830d T states if it only finds one edge it takes 15418 - B * 59 + 22 = 15440 - B * 59d T states if it finds no edge at all it takes 15446 - B * 59d T states Called from: 0574 LD WAIT 0580 LD LEADER 05CA LD 8 BITS L DELETE$ 2B72 (2AFF LET) Exit from: 2B66 L EXISTS (2AFF LET) LD FLAG 05B3 (0556 LD BYTES) Exit from: 05A9 LD LOOP (0556 LD BYTES) LD LEADER 0580 (0556 LD BYTES) Jumps from: auto LD LOOK H 0767 (0605 SAVE ETC) Jumps from: auto 078A LD TYPE 07AD LD CH PR Rems: 0558 LD BYTES called from 076E in LD LOOK H LD LOOP 05A9 (0556 LD BYTES) Jumps from: 05CA LD 8 BITS LD MARKER 05C8 (0556 LD BYTES) Jumps from: 058F LD SYNC LD NAME 07A6 (0605 SAVE ETC) Jumps from: 078A LD TYPE 07AD LD CH PR LD NEXT 05C2 (0556 LD BYTES) Jumps from: 05A9 LD LOOP LD PROG 0873 (0605 SAVE ETC) Jumps from: 082E LD DATA LD PROG 1 08AD (0605 SAVE ETC) Jumps from: 0873 LD PROG LD SAMPLE 05ED (0556 LD BYTES) Jumps from: auto LD START 056C (0556 LD BYTES) Jumps from: 0580 LD LEADER LD SYNC 058F (0556 LD BYTES) Jumps from: auto LD TYPE 078A (0605 SAVE ETC) Jumps from: 0767 LD LOOK H LD VERIFY 05BD (0556 LD BYTES) Jumps from: 05A9 LD LOOP LD WAIT 0574 (0556 LD BYTES) Jumps from: auto (twice) LD 8 BITS 05CA (0556 LD BYTES) Jumps from: auto L EACH CH 2B0B (2AFF LET) Jumps from: 2BIF L TEST CH leader (save/load) see timing leading space see 0C0A PO MSG leading zero see 2DE3 PRINT FP LEN key (B1) see also commands, functions and operators, KEYBOARD SCANNING, 022C extended mode table (b) The K key in E mode without shift produces the function LEN; it requires one string operand X$, and the value of the function is the length of the string X$. On execution, 24FB SCANNING quickly leads to 26DF S NEGATE. This converts the key code B1 first to 02, then to DE. Since LEN is a string -> numeric function its bit 6 is now resetmaking it 9E; priority 10h/16d is added. Code and priority 109E are now pushed on to the machine stack (270D S PUSH PO) while the string expression following LEN is evaluated. When the code is taken off the stack (2734 S LOOP), it is converted (2773 S TIGHTER) from 9E to 1E, the calculator offset for 3674 len. len subroutine 3674 Called only from 0028 FP CALC with the literal 1E; executes the LEN command. Input parameters: none - a set of string parameters is last value on the calculator stack. Action: call 2BF1 STK FETCH which puts the 5 bytes of thelast value into AEDCB; BC is now the length required. Exit: into 2D2B STACK BC, which puts the length on the stack. Output parameters: none - the last value is now the length of the string, replacing the parameters which were there on entry. length of BASIC line see BASIC line length of expression see strings length of INPUT LINE see IN VAR 6 in 20C1 IN ITEM 1 length of save/load block see program/data block length of strings see string parameters length of timing loop see timing loop length of variable or array see variables L ENTER subroutine 2BA6 Copies bytes from one location to another. It differs inthree respects from a plain LDIR instruction: - HL and DE hold the opposite from their normal inputs - it checks BC for zero before copying the bytes - on return, HL holds the original "destination" unchanged. The routine can just as well be called at 2BA7, using the normal inputs, but on output HL will still hold the "destination". In ROM, used only to copy FP numbers and strings, but could be of wide usefulness to m/c programmers. See useful routines. Input parameters: HL holds the first address of the destination - DE of the source - BC holds the number of bytes to be copied. Action: exchange HL and DE - if BC is zero return - copy the bytes. Exit: RET. Output parameters: if BC was zero returns with Z flag andHL and DE exchanged: otherwise with NZ, HL unchanged, DE the next address after the last one copied to. In any case BC zero. Exit from: 2B59 L NUMERIC 2BA3 L IN W/S LESS MASK 328A (3214 truncate) Jumps from: auto LESS THAN ZERO OPERATION see 3506 less-0 less-0 subroutine 3506 Called several times in ROM from 0028 FP CALC with literal 36. Not otherwise called in ROM, but could well be called direct. Checks if a FP number is negative: returns one for negative, zero for zero or positive - the opposite of 34F9 greater-0, except both return zero for zero. Input parameters: HL holds the first address of the FP number; if called from FP CALC, this will be the last value on the calculator stack, but in a direct call it could be anywhere. Action: zero A. _3507_SIGN_TO_C (the entry point from greater-0, but withFF in A): XOR the sign byte with A - rotate the hi bit into the carry; with zero A this makes carry for negative sign, with A = FF as in greater-0 it makes carry for positive sign. Exit: into 350B FP 0/1, which replaces the last value on the stack depending on the carry: zero for NC, one for C. Output parameters: all registers unchanged except A. The C flag shows the result. Called from: 1DDA NEXT LOOP 2DE3 PRINT FP 36AF int 37A1 ZPLUS 37E2 atn Rems: 34F9 greater-0 exits into, with opposite effect LET key (F1) see also commands, functions and operators, KEYBOARD SCANNING The L key in K mode produces the command LET. The "LET statement" must include - a string or numeric variable name, or array name with specified subscripts: the_variable_in_assignment. - "=" - an expression, string or numeric; it must match in status the variable in assignment. The command gives the variable in assignment the value of the expression, overwriting any value it had before. The command is read by 1B29 STMT L 1 referring through the syntax offset table 1A48 to the syntax parameter table 1A7A.1A7A P LET causes jumps to - 1C1F CLASS 01 to identify the variable in assignment - back to 1A7B to check that the "=" is there - 1C4E CLASS 02 which assigns the value to the variable and moves on to the next statement. The main executive routine is 2AFF LET, which is called by CLASS 02 through 1C56 VAL FET 1. 2B72 L DELETE$ example, LET A$(4 TO 8)="abcdefg" LET subroutine 2AFF Implements the LET command; also called in implementing FOR (1D16 F REORDER), INPUT (219B IN VAR 6) and READ (1C59 VAL FET 2)._Assigns_a_value, numeric or string, to a variable in assignment, whether_existing or_new. For variable in assignment see LET key above; an existing variable means one already in the variables area, a newvariable is one which only appears in the program listing or BASIC command. The last value on the calculator stack shows the value to be assigned: for a numeric variable this is the actual value,as an FP number, for a string variable it is a pair of string parameters showing the address in RAM where the string is to be found, its length and an indication whether it is an array element or slice. These string parameters aren't put in the variables area, as the FP number value of a numeric variable is;often they point to a string in the work space, which will be deleted as soon as the assignment is made, so the actual string of bytes is copied to the variables area rather than just its parameters. If the variable is a new variable, a space must be made for it; this space must allow for - the variable letter, which is flagged to show the variable type, see under variables, but which only occupies one byte except in the case of "long names", which are only used fornumeric variables - and five bytes for a numeric variable, or the length ofthe string value, plus two length bytes, for a string variable. A string slice cannot be "new", and nor can a string array element, as it must have been declared by a DIM statement. If is an old variable, the old value can simply be overwritten if it is a numeric variable, a string slice or arrayelement, since all numeric variable values are five bytes long and a new string slice or array element must be the same length as the old. But a_new_simple/single_string or_complete_simple _string requires the old string to be deleted and the new one put in the variables area. Before a string is copied to the variables area, it is first copied to the work space. There may well be a copy there already, if the expression to be assigned is the result of reading a variable or a function; but there won't be if it has been read direct from BASIC, as in LET h$ = "hello" or 10 LET h$ = "hello" so another copy is made, to be on the safe side.