2F successively to 27, 1F, 17, 0F, 07 2E successively to 26, 1E, 16, 0E, 06 2D successively to 25, 1D, 15, 0D, 05 ... ... ... ... ... ... ... ... ... 28 successively to 20, 18, 10, 08, 00 - all the 28h/40d values from 00 to 27, one way or another. The rotation of the key bits produces zero if only one key was being pressed, but otherwise continue rotating the key bits and subtracting 08 from where it left off, to find another key value from the same line of keys. A shift byte and a "last key" byte are both set to FF initially; each time a pressed key is found, increment the shiftbyte, and return if the result isn't zero; otherwise copy the last key byte to the shift byte. The first time, the shift byte has its initial FF, so there is no return. The second time, it has the last key value, which was also FF, so there is still no return. Only if three keys are being pressed can the result of incrementing the last key value be non-zero and force a return with NZ. On exit from the loop, at most two keys being pressed: - if no key was found pressed the last key value is FF - if one or two were pressed it is the key value of the last one found - if no key or one key was pressed the shift byte is FF - if two were pressed it is the key value of the first ofthe two found - if the two keys pressed are both shifts the last key byte is symbol shift and the shift byte is caps shift; caps shift is bit zero of the first key bits read, so it is read first, and symbol shift is read last except for B, N and M. Four tests are made: Test 1: if the shift byte is FF return with zero; this signals "no shift", and the last key byte is the key value or FFfor no-key. Tests 2 and 3: if the shift byte is 27h caps shift or 18h symbol shift return with zero; again the last key byte is the key value or FF for no-key. Test 4: exchange the shift and last key bytes and if thelast key byte is symbol shift return with zero; this is either symbol shift B, N or M or caps + symbol shift together, E mode. Input parameters: none. Action: make the initial key value byte 2F - make the key value and shift byte both FF - make the port address FE - make the loop counter FE; on each turn of the loop thecounter is shifted left with zero into its lo bit, so its hi bitbecomes zero when eight turns of the loop have been made. Its successive values are 11111110b/FE 11111100b/FC ... ... ... 10000000b/80 00000000b/00 _0296_KEY_LINE: take the port input, reverse it, and AND it with 00011111b/1Fh - if the result is zero jump on to KEY DONE; no key pressed on this half-line, loop again. _029F_KEY_3KEYS (at least one key is being pressed): increment the shift byte - if the result isn't zero return; a return with NZ signals "three keys" or "two non-shift keys", see above. _02A1_KEY_BITS (valid keystroke): take 08 from the initial key value and rotate the key bits right, with zero into the hi bit and the lo bit into carry - if the lo bit was zero jump back to KEY BITS - (set bit found; there must be one, otherwise KEY LINE would have jumped on to KEY DONE. The initial key value has beencounted down to a key value for this key) put the previous key value in the shift byte and the new key value in the last key byte; if this is the first key found the shift byte will get FF - if the rotated key bits aren't zero yet jump back to KEY 3KEYS to find another key value. _02AB_KEY_DONE (no more keys pressed on this port): decrement the initial key value; 2F, 2E, ... 28 - shift the loop counter left with zero to its lo bit; coming from the carry flag, which became NC either from KEY LINEor from KEY BITS - if its hi bit wasn't zero, loop back to KEY LINE for the next input port - (all ports read) if the shift byte is FF return with Z; Test 1, the last key byte is the key value or FF for no-key - if the shift byte is 27h return with Z; Test 2 - if the shift byte is 18h return with Z; Test 3 - exchange shift/last key bytes; E to A, D to E, A to D - if the last key byte was 18h return with Z; Test 4. Exit: RET, from KEY 3KEYS or KEY DONE. Output parameters: D holds the shift byte: FF for no shift, 27h for CAPS SHIFT, 18h for SYMBOL SHIFT - E holds the key value: FF if no key found, otherwise as in the table at NB 1 in KEYBOARD SCANNING. - the Z flag indicates that a suitable key reading has been found, or no key is being pressed; NZ that three keys, or two non-shift keys, are being pressed. Called from: 02BF KEYBOARD 2634 S INKEY$ key set see KEYBOARD SCANNING, 5C00 KSTATE keystroke (key) see KEYBOARD SCANNING, 028E KEY SCAN key tables see 0333 K DECODE, KEYBOARD SCANNING, tables key values see KEYBOARD SCANNING KEY 3KEYS 029F (028E KEY SCAN) Exit from: 028E KEY SCAN through one of: 0296 KEY LINE 02A1 KEY BITS KEY=M&CL 10DB (10A8 KEY INPUT) Jumps from: 10A8 KEY INPUT K GRA DGT 0389 (0333 K DECODE) Exit from: 0333 K DECODE through 0367 K DIGIT K KLC DGT 039D (0333 K DECODE) Exit from: 0333 K DECODE through 0367 K DIGIT K KLC LET 034F (0333 K DECODE) Exit from: 0333 K DECODE K LOOK UP 034A (0333 K DECODE) Exit from: 0333 K DECODE through one of: 0341 K E LET (twice) 034F K KLC LET 0367 K DIGIT 0389 K GRA DGT (twice) 039D K KLC DGT K MAIN 032C (031E K TEST) Exit from: 031E K TEST K-mode see 5C41 MODE K NEW 02F1 (02BF KEYBOARD) Jumps from: 02D1 K CH SET K REPEAT 0310 (02BF KEYBOARD) Exit from: 02BF KEYBOARD through 02D1 K CH SET (twice) KSTATE system variable 5C00 Bytes: 8 Eight bytes in two sets, KSTATE0-3 and KSTATE4-7. They control the delays between keystroke acceptances, and are only used in 02BF KEYBOARD, see index entry for details: bit 0 is the main code bit 1 is the 5-call counter bit 2 is REPDEL/REPPER bit 3 is the final code. Can be freely used as spare memory when these routines aren't called - ie when the maskable interrupt is disabled. The first and fifth bytes should be loaded with FFh before enabling the interrupt. Written by: 02C6 K ST LOOP (decrements 5-call, sets free if zero) 02F1 K NEW (loads three bytes) 0310 K REPEAT (resets 5-call, decrements delay) 1219 RAM SET (sets both sets free) Read by: 02BF KEYBOARD (picks up address of KSTATE0) 02C6 K ST LOOP (checks first bit for "free") 02D1 K CH SET (checks main code with both first bytes) 0310 K REPEAT (reads final code) K ST LOOP 02C6 (02BF KEYBOARD) Jumps from: 02D1 K CH SET K TEST subroutine 031E Finds the main code from the key value and shift byte. The key value found by 028E KEY SCAN indexes the place of the key in the table at 0205; from 00 for "B" to 26h for "A", see the table in NB 1 of KEYBOARD SCANNING. The main code is the value found at that place; it is the character code of the capital letter or digit belonging to that key. On entry, the shift byte will be either FF no shift, 27h caps shiftor 18h symbol shift the key value will be either zero -> 27h, which includes both shift values, or FFh for "no key". The two values cannot be the same, unless they are both FF, signalling "no key, no shift". If the key value is 27h caps shift, the shift byte must be FF: because the key value always has the value which was readlast, and caps shift is read first of all. This is why the key table at 0205 has no table entry for this value. If the key value is 18h symbol shift and the shift value27h caps shift, the subroutine returns with 0E from the main code table. The notes refer to this sometimes as the "symbol shift" code and sometimes as the "code for either shift"; but itcan only be returned as a main code if_both caps and symbol shift were being pressed, and is therefore the main code for Extend mode on/off; see K DIGIT in the entry for 0333 K DECODE. Input parameters (they are the same as the output parameters of 028E K SCAN, apart from the flags which may have changed): D holds the shift byte, E the key value. Action: if the key value is FF no key or 27 caps shift return; this must be "caps shift and no key", see above - if the key value isn't 18h symbol shift jump on to K MAIN - (key value is 18h symbol shift) if the shift byte is FF no-shift return; you still have NC from the "CP 18h" a coupleof lines back, so this signals "no key". Key value symbol shift and shift byte no-shift must be "symbol shift and no key". _032C_K_MAIN: index into the main key table at 0205 with DE holding the key value; if the key value is 18h symbol shift the shift byte must be caps shift, and the table returns 0E for E mode - put the byte from the indexed address in A and set thecarry. - return. Exit: RET, from K TEST or K MAIN. Output parameters: A holds the main code - B holds the shift byte - the carry flag shows NC if no key was pressed or only a shift key. Called from: 02D1 K CH SET 2634 S INKEY$ K TOKENS 0364 (0333 K DECODE) Exit from: 0333 K DECODE through 034F K KLC LET K 8 & 9 0382 (0333 K DECODE) Exit from: 0333 K DECODE through 0367 K DIGIT K @ CHAR 03B2 (0333 K DECODE) Exit from: 0333 K DECODE through 039D K KLC DGT ----- L ADD$ 2BAF (2AFF LET) Exit from: 2AFF LET through 2B72 L DELETE$ LAST 386C (3851 to-power) Appropriately named; it is the last routine in the ROM! Exit from: 384A sqr and 3851 to-power through one of: 385D XISO 386A ONE last entry This term is used in 1219 RAM SET to indicate the bottomof the machine and GO SUB stacks. See GO SUB stack. LAST K system variable 5C08 Bytes: 1 Holds the final code of the last key read from the keyboard, see KEYBOARD SCANNING, 028E KEY SCAN. This is picked up by the input routine of channel K, see 10A8 KEY INPUT. Often useful in m/c programs; since reading the keyboard is handled automatically by the interrupt routines, LAST K will always holdthe latest keyboard reading at all times. If the interrupt is disabled, RST 38h will put it there, or the simplified WAIT KEY routine LD (IY-50),0 ;LAST K LOOP RST 38h LD A,(IY-50) AND A JR Z,LOOP will wait for a key input. Written by: 0308 K END Read by: 10A8 KEY INPUT Rems: 02BF KEYBOARD passes value if repeat status allows 02F1 K NEW gets ready to pass value last value on calculator stack see CALCULATE L CHAR 2B3E (2AEF LET) Jumps from: auto (twice) LD BLOCK subroutine 0802 Reports errors on LOAD/VERIFY/MERGE of a data block. Input parameters: same as 0556 LD BYTES, see below. Action: call LD BYTES and if this doesn't set the carry report "Tape loading error". Exit: RET. Output parameters: carry set. Called from: 08B6 ME CONTRL Exit from: 0800 VR CONT 3 084C LD DATA 1 08AD LD PROG 1 Rems: 0556 LD BYTES called by to LOAD or VERIFY data block