1051 ED EDGE 2 look for last printable char before K CUR 111D ED COPY print cursor if at end of line 1BA1 OUT LINE5 check if time to print the cursor 18C1 OUT FLASH prints all flashing cursors 18E1 OUT CURS prepares to print editing cursor 1909 OUT C 2 prints editing cursor K DATA system variable 5C0D Bytes: 1 Holds the parameter of an embedded INK to OVER colour control while the control code is output through the current channel. The parameter is calculated by 1105 KEY DATA from the code temporarily supplied as a "final code" by keyboard scanning, see 0333 K DECODE. Written by: 1105 KEY DATA Read by: 110D KEY NEXT K DECODE subroutine 0333 see also KEYBOARD SCANNING especially NB 3 Interprets a keystroke. The main code has already been found by 031E K TEST: it may be a capital letter 41h -> 5Ah or digit 30h -> 39h space 20h, ENTER 0Dh E-mode on/off 0Eh; returned if both shifts are being pressed, see NB 2 in K MAIN under 031F K TEST. This subroutine considers the main code in relation to the key mode and the shift byte, and produces the final code. Inmany cases the final step is to K LOOK UP with the main code, tolook up the final code from one of the tables starting at 0205. The base address of a table is often not its start address, which is reached by adding to the base the smallest main code indexed. Eg the base of letter tables is the start less 41h, thecode for "A". Input parameters: E holds the main code - D holds the value of FLAGS: bit 3 indicates whether K or not-K mode is to be used - C holds the mode value from 5C41 MODE: zero for K, L or C modes, one for E mode, 2 for G mode - B holds the shift byte, FFh for no shift, 27h for CAPSSHIFT, 18h for SYMBOL SHIFT. Action: if the main code is less than 3A jump on to K DIGIT; jump on everything except letter keys - (letter keys) decrement the mode value - if it becomes negative jump on to K KLC LET; zero signals KLC mode - if it becomes zero jump on to K E LET; one signals E mode - (letter keys in G mode, user-defined graphics) add 4F to the main code and return; this works fine for udgs A -> U, but has the odd effect of producing the tokens RND, INKEY$, PI, FN, POINT for letters V -> Z _0341_K_E_LET (letter keys in E mode): make a base address for 022C table (b) E-mode unshifted letter keys - if the shift byte is FF jump on to K LOOK UP; no shift - (either shift pressed) make a base address for 0246 table (c) E-mode letter keys with either shift. _034A_K_LOOK_UP: add the main key code to the base address of the table - get the code at the resulting address - return. _034F_K_KLC_LET (letter keys in KLC modes): make a base address for 026A table (e) letter keys with symbol shift - if bit zero of the shift byte is zero jump back to K LOOK UP; 18h symbol shift is the only even shift byte - if bit 3 of FLAGS is set jump on to K TOKENS; K mode - if bit 3 of FLAGS2 is set or the shift byte isn't FF return with the main code unchanged, making an upper-case letter; CAPS LOCK is on or CAPS SHIFT pressed - (L mode, no shift) add 20h; makes the lower-case letter - return. _0364_K_TOKENS (letter keys in K mode): add A5 to the main code; this finds all the tokens on letter keys - return. _0367_K_DIGIT (non-letters): if the code is less than 30hreturn; 0D ENTER and 0E E-mode - (digit keys) decrement the mode value; cf K DECODE above - if it was zero jump on to K KLC DGT; KLC modes - if it wasn't one jump on to K GRA DGT - (one is E mode) make a base address for 0284 table (f)E-mode digit keys with symbol shift - if bit 5 of the shift byte is zero jump back to K LOOKUP; 18h symbol shift, the even shift byte - (digit keys, E mode, not symbol shift) if the code is more than 37h jump on to K 8 & 9 - (30h zero -> 37h seven) subtract 20h; now 10h -> 17h - if the shift byte is FF return; no shift, these are the interim PAPER codes. These codes and those for INK, BRIGHT and FLASH below are converted to the standard control code and parameter later, see 10A8 KEY INPUT - (caps shift) add 08; 18h -> 1Fh are the interim INK codes - return. _0382_K_8_&_9 (still E mode, 38h eight and 39h nine): subtract 36h - if the shift byte is FF return; correct interim codes for 02 BRIGHT on and 03 BRIGHT off - (caps shift on) add FE and return; correct interim codes for 00 FLASH on and 01 FLASH off. Adding FE instead of subtracting 02 sets the carry, but this flag never seems to get used. _0389_K_GRA_DGT (digit keys in G mode): make a base address for 0260 table (d) digit keys with caps shift - if the code is 39h nine or 30h zero jump back to K LOOK UP; GRAPHICS and DELETE - (31h -> 38h, the graphics forms) AND the code with 00000111b/07 and add 80h; this makes them 81h -> 88h, the codes for the TRUE VIDEO graphics - if the shift byte is FF return; no shift - (either shift pressed; INVERSE VIDEO graphics forms) XOR the code with 00001111b/0Fh and return; the hi digit is unchanged, the lo is reversed: 0000 -> 1111 0001 -> 1110 0010 -> 1101 0011 -> 1100 0100 -> 1011 0101 -> 1010 0110 -> 1001 0111 -> 1000 which are 08 -> 0F in reverse order, the correct codes for the INVERSE VIDEO graphics _039D_K_KLC_DGT (digit keys in KLC mode): - if the shift byte is FF return; the main code is the digit - make a base address for 0260 table (d) digit keys withcaps shift - if bit 5 of the shift byte is set jump back to K LOOK UP; caps shift - (symbol shift) subtract 10h from the code; this makes correct codes except for symbol shift two and symbol shift zero - if the result is 22h jump on to K @ CHAR; from the symbol shift two key - if it isn't 20h return; 20h from the symbol shift zerokey - (symbol shift zero key) make the code 5F underline andreturn. _03B2_K_@_CHAR: make the code 40h @; symbol shift two key. Exit: RET, from K DECODE, K LOOK UP, K KLC LET (twice), KTOKENS, K DIGIT (three times), K 8 & 9 (twice), K GRA DGT (twice), K KLC DGT (three times) and K @ CHAR. Output parameters: A holds the final key code. Called from: 02F1 K NEW 2634 S INKEY$ K DIGIT 0367 (0333 K DECODE) Jumps from: 0333 K DECODE K E LET 0341 (0333 K DECODE) Jumps from: 0333 K DECODE K END 0308 (02BF KEYBOARD) Exit from: 02BF KEYBOARD, via one of: 02F1 K NEW 0310 K REPEAT key see KEYBOARD SCANNING, 02BE KEY SCAN and individual tokens ABS, ACS etc key bits see KEYBOARD SCANNING KEY BITS 02A1 (028E KEY SCAN) Jumps from: auto KEYBOARD subroutine 02BF The master keyboard scanning routine, called fifty timesevery second by the maskable interrupt 0038 MASK INT, with all registers saved. See KEYBOARD SCANNING. Not otherwise called from ROM. It can be called from m/c, but this is pointless unless the interrupt is disabled; even then it is simpler to useRST 38h, except to avoid changing the values in 5C78 FRAMES. Reads the keyboard to get the main code, converts it to a final code and deposits this in 5C08 LAST K. Also handles the key delay. A keystroke isn't accepted until a certain number of interrupts have been counted since thelast acceptance. The count is kept in 5C00 KSTATE, which has eight bytes in two sets, bytes 0-3 and bytes 4-7, called KSTATE0and KSTATE4 in the notes: Byte zero or 4 holds the "set is free" signal FF, or the last main code accepted if the set isn't free. All main codes are less than 80h, so the hi bit of the code will be zero if thecode isn't free Byte one or 5 holds the "five-call counter" Byte 2 or 6 holds the "delay" value from REPPER/REPDEL Byte 3 or 7 holds the "final code" The loop K ST LOOP/K CH SET is turned twice every time the interrupt fires, whether a key is being pressed or not, except only if three keys or two main code keys are being pressed at once. The first turn checks KSTATE0, the second KSTATE4. On each turn the five-call counter is decremented, fromits start value of five; when it reaches zero the set is marked as free. If the key is a new one, ie the main code from the keyboard doesn't match byte zero of either of the KSTATE sets, and neither set is free, the subroutine returns after this double loop without any further action. Although the double loopitself takes no significant time, it takes five interrupts to free both KSTATE sets; since one will usually become free beforethe other, for a new key the delay is always five interrupts, one-tenth of a second, from the last key but one. When a set is free for a new main code - the main code is put in the first byte of the free set,marking it as not free - its five-call counter is reset to five - its delay byte is set to the value in 5C09 REPDEL - the code got by calling 0333 K DECODE with input parameters from 5C41 MODE, FLAGS and the shift byte, is put in its final code byte and in 5C08 LAST K. If the keyboard code matches either of the byte zero codes, ie if it repeats either the last input or the last but one, - its five-call counter is reset to five - its delay byte is counted down, and if it doesn't reachzero the subroutine returns without further action - but if it does, the delay byte is set to the value in 5C0A REPPER and the code is read from the final code byte of thekey set and put straight in 5C08 LAST K without calling K DECODE. [If you press eg the P key in K mode and hold it down, the output is PRINT PRINT PRINT ...; if you let it up and pause a little after the first keystroke, you get PRINT ppp ..., as you should.] Although in theory a match with the last key but one is significant, "no key" also counts down the counters, and the chances are the key set has been freed before the next-but-one keystroke; you would have to type pretty fast for the key beforelast to have any significance. Thus the waiting time for a key matching either the lastor the last but one is the number of interrupts in 5C09 REPDEL for the first repeat and that in 5C0A REPPER for further repeats. This makes the delay longer on the first repetition than on subsequent ones: normally REPDEL has 35d, making a delayof seven-tenths of a second, and REPPER has five, one-tenth of asecond, but these can be changed by POKing the svs. [Experiment will show that either "pot" or "pop" can be typed faster than "poo". This is because either the "t" or the second "p" waits only 1/10 second or less for a free key set, but the second "o" waits till REPDEL is counted down.] Input parameters: none. Action: call 028E KEY SCAN to read the keyboard - if the flag show NZ return; three keys or two main code keys are being pressed together - put a pointer on KSTATE0 for the first turn of the double loop. _02C6_K_ST_LOOP: if byte zero shows the set to be free jump on to K CH SET - (set not free) decrement its five-call counter - if this isn't now zero jump on to K CH SET - (counter zero) mark the set free with FF in byte zero. _02D1_K_CH_SET: put the pointer on KSTATE4 for the secondturn of the double loop - if the pointer has changed jump back to K ST LOOP for the second turn - (both sets checked) call 031E K TEST, which gets a main code from the keyboard's key value - if it returns with NC, return; "no key" or "shift only" - if the main code matches byte zero of either key set jump on to K REPEAT - if neither set is free return. _02F1_K_NEW (new code, free set found): put the main codein byte zero of the free set; this marks it as not free - put 5 in its five-call counter - put the counter from 5C09 REPDEL in its delay byte - get parameters from 5C41 MODE and FLAGS and call 0333 K DECODE; it returns the final code - put the code in the final code byte. _0308_K_END: put the code in 5C08 LAST K - set bit 5 of FLAGS; "new key accepted" - return. _0310_K_REPEAT (the keystroke repeats the code of the last keystroke): reset the five-call counter to 5 - decrement the delay byte - if it doesn't reach zero return - (zero delay) reload the delay byte from 5C0A REPPER - get the code from the final code byte - jump back to K END. Exit: RET, from K CH SET (twice), K END or K REPEAT. Output parameters: none - FLAGS bit 5 set if the code was accepted. Called from: 0048 KEY INT Rems: 1219 RAM SET frees KSTATE0 and KSTATE4 keyboard click see 5C39 PIP KEYBOARD DECODING SUBROUTINE see 0333 K DECODE KEYBOARD INPUT SUBROUTINE see 10A8 KEY INPUT keyboard interrupt see interrupts, KEYBOARD SCANNING, 0038 MASK INT KEYBOARD SCANNING see also shift keys The outline of these routines is as follows; the terminology used in the notes is followed as far as possible, but it isn't always consistent: The master routine is 02BF KEYBOARD. First it calls 028E KEY SCAN, which scans the keyboard and gets a_key_number or_key_value, depending on the position ofthe key on the keyboard, and a_shift_byte indicating which shiftis being pressed or_no-shift; see NB 1 below.