; ******************************************************************* ; * * ; * Keyboard Input Routine Version 1.1 * ; * Pete Turnbull, 30-Dec-1995 * ; * * ; * Derived from original EXIDY monitor routine. * ; * Some labels have been changed to lower case for clarity. * ; * * ; * Modifications: * ; * 1) We preserve the state of the non-keyboard parts of Port FE, * ; * which are used for the tape motors (bits 4-5, stored in * ; * (IY+cmtrfg), possibly also with baud rate info), baud rate * ; * (bit 6, stored in (IY+tapes)) and tape/RS232 select bit * ; * (bit 7, stored in (IY+tapes)). * ; * 2) We no longer use bit4 in E; it was redundant. Also removed * ; * redundant JP mloop preceding "finend:" - it could never be * ; * executed. Also removed redundant SCF, etc. * ; * 3) We don't use Instruction Table for graphics; instead the * ; * Graphics Table contains actual graphic codes - any 00H code * ; * means there's no graphic for this key (equivalent to 00H in * ; * old INSTBL). * ; * 4) We don't test every bit in every section, but stop searching * ; * as soon as we find a key pressed. This was previously * ; * required to detect combinations of SHIFT/LOCK/CTRL/GRAPHIC. * ; * 5) Test SHIFT/LOCK/CONTROL/GRAPHIC *after* we have found a * ; * keypress. Still start scan with section 0, except that we * ; * only check for RUN/STOP (ie, only one key) in section 0. * ; * 6) We no longer set bits in B according to D (for SHIFT etc). * ; * Instead, B is set directly by code that checks section 0 * ; * for SHIFT/LOCK/CONTROL/GRAPHIC. This means some flags in B * ; * are in different bit positions than before. * ; * * ; ******************************************************************* ; FALSE EQU 0 TRUE EQU NOT FALSE ; ROM EQU TRUE ; must be true in final version ; COND ROM ORG 0EB1CH ; ROM routine must be here ELSE ORG 06000H ; in RAM, for testing ENDC ; GETIY EQU 0E1A2H ; monitor "find MWA" routine lstkey EQU 06CH ; offset to "last key" in MWA cmtrfg EQU 045H ; offset to motor flags store tapes EQU 03DH ; offset to baud rate, tape/RS232 status ; kyport EQU 0FEH ; on Exidy computer dtime EQU 810 ; to make 10ms debounce at 12.638MHz rtime EQU 5000 ; REPEAT key time, 16 per second ; CHRIN1 EQU $ KEYBD: PUSH IY CALL GETIY PUSH BC PUSH DE PUSH HL PUSH IX ; ; Test for REPEAT key ; LD A, (IY + cmtrfg) ; get tape flags, bits 4,5 OR (IY + tapes) ; and tape speed/RS232, bits 6,7 AND 0F0H ; other bits set to zero INC A ; REPEAT key is in column 1 OUT (kyport), A ; send mask IN A, (kyport) BIT 1, A ; REPEAT? JR NZ, norpt ; no - go on LD DE, rtime repet: DEC DE LD A, D OR E JR NZ, repet LD A, (IY+lstkey) ; get last key pressed JP finend ; go back (to caller) ; norpt: LD C, kyport ; load keyboard port number LD IX, gratbl ; load table pointer LD A, (IY + cmtrfg) ; get tape flags, bits 4,5 OR (IY + tapes) ; and tape speed/RS232, bits 6,7 AND 0F0H ; other bits set to zero LD H, A ; put Port FE status in H ; ; For Section 0, we only test bit 0 (RUN/STOP) ; Otherwise, we test all 5 bits, by ANDing with L ; sloop: OUT (C), H ; output section number LD L, 1 ; load bit position register bloop: IN A, (C) ; input section byte AND L ; test bit JP NZ, abit1 ; jump if bit=1, ie no key ; ; Now we have seem to have a key ; LD DE, dtime deboun: DEC DE ; should be about 10ms LD A, D OR E JR NZ, deboun ; 6+4+4+12 T-cycles = 12.34µs IN A, (C) ; key still pressed? AND L ; test same bit JP NZ, abit1 ; jump if not still pressed ; ; We definitely have a key which should return a code ; Let's see if we need SHIFT/LOCK/CONTROL/GRAPHIC ; coded: LD A, H ; for the serial port bits AND 0F0H ; clear for section 0 OUT (C), A IN B, (C) ; get shift etc keys PUSH HL ; save section/bit for release test PUSH IX ; copy IX to HL POP HL ; HL now has pointer into table ; ; We can decide which table to use by looking at B ; BIT 1, B ; test for GRAPHIC key JR NZ, notgra ; jump if GRAPHIC wasn't pressed ; ; It's for a graphic character. We use one table for both shifted and unshifted. ; LD A, (HL) ; get character code OR A ; see if there's a valid graphic here JR Z, notgra ; if not, must be something else BIT 4, B ; see if SHIFT-GRAPHIC JR NZ, finop SET 6, A ; if shifted, set shift bit JR finop ; that's all, for a graphic code ; ; It's *not* a graphic character, so work out which table, and use it... ; notgra: LD DE, contbl-gratbl ; all are same size, so DE=difference ADD HL, DE ; point into control table BIT 2, B ; test for CONTROL key JR Z, gotkey ; done, if CONTROL ADD HL, DE ; else point into shift table BIT 4, B ; test for SHIFT key JR Z, gotkey ; done, if SHIFT ADD HL, DE ; else point into shift-lock table BIT 3, B ; test for LOCK key JR Z, gotkey ; done, if LOCK ADD HL, DE ; else point into unshift table gotkey: LD A, (HL) ; get character from table ; finop: POP HL ; was pushed after "coded:" ; ; Now we have the code, wait for key to be released ; PUSH AF ; save character code OUT (C), H ; re-set section waitk: IN A, (C) ; re-fetch section byte AND L ; mask for our key JR Z, waitk POP AF JR finend ; we've got the key, finish up ; ; this is the end of the loop(s) ; abit1: INC IX ; next key, increment table pointer LD A, H ; see which section we're in AND 0FH ; test for section 0 JR Z, secend ; only do one bit in section 0 RLC L ; shift L mask to next bit position LD A, 20H ; test for last bit position CP L JP NZ, bloop secend: INC H ; next section LD A, H ; test for end AND 0FH ; exclude serial port bits JP NZ, sloop ; not 16 yet, stay in loop finend: POP IX ; restore registers POP HL POP DE POP BC OR A ; did we get a character? JR Z, keyret ; skip if not LD (IY+lstkey), A ; save in case of REPEAT later keyret: POP IY RET ; ; Graphic table ; gratbl: DEFB 000H ; (0) DEFB 08CH, 000H, 000H, 08DH, 000H ; (1) DEFB 0A8H, 0A7H, 09AH, 08EH, 080H ; (2) DEFB 0A9H, 09CH, 09BH, 08FH, 081H ; (3) DEFB 09DH, 091H, 090H, 083H, 082H ; (4) DEFB 0ABH, 0AAH, 09EH, 092H, 084H ; (5) DEFB 0ADH, 0ACH, 09FH, 093H, 085H ; (6) DEFB 0A1H, 095H, 0A0H, 094H, 086H ; (7) DEFB 0AEH, 0A2H, 096H, 088H, 087H ; (8) DEFB 0B0H, 0AFH, 0A3H, 097H, 089H ; (9) DEFB 0A5H, 0A4H, 099H, 098H, 08AH ; (A) DEFB 0A6H, 000H, 000H, 08CH, 08BH ; (B) DEFB 0BCH, 0B8H, 0B5H, 0B1H, 000H ; (C) DEFB 0BDH, 0B9H, 0B6H, 0B3H, 0B2H ; (D) DEFB 0BEH, 0BAH, 000H, 0B7H, 0B4H ; (E) DEFB 000H, 000H, 000H, 0BFH, 0BBH ; (F) ; ; Control table ; contbl: DEFB 03H ; (0) DEFB 0CH, 00H, 20H, 0BH, 1BH ; (1) DEFB 18H, 1AH, 01H, 11H, 31H ; (2) DEFB 03H, 04H, 13H, 17H, 32H ; (3) DEFB 06H, 12H, 05H, 34H, 33H ; (4) DEFB 02H, 16H, 07H, 14H, 35H ; (5) DEFB 0DH, 0EH, 08H, 19H, 36H ; (6) DEFB 0BH, 09H, 0AH, 15H, 37H ; (7) DEFB 2CH, 0CH, 0FH, 39H, 38H ; (8) DEFB 2FH, 2EH, 3BH, 10H, 30H ; (9) DEFB 1CH, 00H, 1DH, 1BH, 3AH ; (A) DEFB 1FH, 0DH, 0AH, 1EH, 2DH ; (B) DEFB 2BH, 2AH, 2FH, 2DH, 20H ; (C) DEFB 30H, 31H, 01H, 17H, 37H ; (D) DEFB 2EH, 1AH, 11H, 13H, 39H ; (E) DEFB 00H, 00H, 00H, 3DH, 33H ; (F) ; ; Shift table ; shitbl: DEFB 03H ; (0) DEFB 0CH, 00H, 20H, 09H, 1BH ; (1) DEFB 58H, 5AH, 41H, 51H, 21H ; (2) DEFB 43H, 44H, 53H, 57H, 22H ; (3) DEFB 46H, 52H, 45H, 24H, 23H ; (4) DEFB 42H, 56H, 47H, 54H, 25H ; (5) DEFB 4DH, 4EH, 48H, 59H, 26H ; (6) DEFB 4BH, 49H, 4AH, 55H, 27H ; (7) DEFB 3CH, 4CH, 4FH, 29H, 28H ; (8) DEFB 3FH, 3EH, 2BH, 50H, 30H ; (9) DEFB 7CH, 60H, 7DH, 7BH, 2AH ; (A) DEFB 7FH, 0DH, 0AH, 7EH, 3DH ; (B) DEFB 2BH, 2AH, 2FH, 2DH, 20H ; (C) DEFB 30H, 31H, 01H, 17H, 37H ; (D) DEFB 2EH, 1AH, 11H, 13H, 39H ; (E) DEFB 00H, 00H, 00H, 3DH, 33H ; (F) ; ; Shift-lock table ; slotbl: DEFB 1BH ; (0) DEFB 0CH, 00H, 20H, 0BH, 1BH ; (1) DEFB 58H, 5AH, 41H, 51H, 31H ; (2) DEFB 43H, 44H, 53H, 57H, 32H ; (3) DEFB 46H, 52H, 45H, 34H, 33H ; (4) DEFB 42H, 56H, 47H, 54H, 35H ; (5) DEFB 4DH, 4EH, 48H, 59H, 36H ; (6) DEFB 4BH, 49H, 4AH, 55H, 37H ; (7) DEFB 2CH, 4CH, 4FH, 39H, 38H ; (8) DEFB 2FH, 2EH, 3BH, 50H, 30H ; (9) DEFB 5CH, 40H, 5DH, 5BH, 3AH ; (A) DEFB 5FH, 0DH, 0AH, 5EH, 2DH ; (B) DEFB 2BH, 2AH, 2FH, 2DH, 20H ; (C) DEFB 30H, 31H, 34H, 38H, 37H ; (D) DEFB 2EH, 32H, 35H, 36H, 39H ; (E) DEFB 00H, 00H, 00H, 3DH, 33H ; (F) ; ; Unshifted table ; unstbl: DEFB 1BH ; (0) DEFB 0CH, 00H, 20H, 0BH, 1BH ; (1) DEFB 78H, 7AH, 61H, 71H, 31H ; (2) DEFB 63H, 64H, 73H, 77H, 32H ; (3) DEFB 66H, 72H, 65H, 34H, 33H ; (4) DEFB 62H, 76H, 67H, 74H, 35H ; (5) DEFB 6DH, 6EH, 68H, 79H, 36H ; (6) DEFB 6BH, 69H, 6AH, 75H, 37H ; (7) DEFB 2CH, 6CH, 6FH, 39H, 38H ; (8) DEFB 2FH, 2EH, 3BH, 70H, 30H ; (9) DEFB 5CH, 40H, 5DH, 5BH, 3AH ; (A) DEFB 5FH, 0DH, 0AH, 5EH, 2DH ; (B) DEFB 2BH, 2AH, 2FH, 2DH, 20H ; (C) DEFB 30H, 31H, 34H, 38H, 37H ; (D) DEFB 2EH, 32H, 35H, 36H, 39H ; (E) DEFB 00H, 00H, 00H, 3DH, 33H ; (F)