;******************************************; ; KEYBOARD SCANNER USING THE 83C751 ; ; OUTPUT INTERFACE IS PC-AT COMPATABLE ; ; Date: 06-OCT-88 ; ; Edited: 14-OCT-88 (Key scan OK) ; ; Edited: 14-OCT-88 (Table scan OK) ; ; Edited: 28-OCT-88 (Serial Output) ; ; ; ; Programmer-----> Jim Greene ; ; SIGNETICS CORPORATION ; ;******************************************; $MOD751 $DEBUG $Title(83C751 PC-AT Keyboard Scanner) ; Port Usage: ; P1 COLUMN side of Matrix ; P3 ROW side of Matrix ; P0.0 Clock out ; P0.1 Serial Data out ;Register Usage ; R7 Column Offset Count ; R6 Debounce Hi count value ; R5 Bebounce Lo count value ;Internal RAM Usage COLUMN EQU 20H ;Key pressed is in this COLUMN (P3) ROW EQU 21H ;Contains ROW from P1 BUFFER EQU 22H ;Byte to be sent to GRID TAB EQU 23H ;Holds pointer for table ; TAB Contents 00-07H (/;P0ZAQ1) ; 10-17H (.LO9XSW2) ; 20-27H (,KI8CDE3) ; 30-37H (MJU7VFR4) ; 40-47H (NHY6BGT5) ; 50-57H (=|space|enter|_|_|shift|ctrl|fct'n) ORG 00H ;Power-on starts here AJMP MAIN ORG 30H MAIN: MOV SP, #07H MOV PSW, #00H ;RB 0 MOV P0, #0FFH ;Set clock & data lines in 1 state ACALL LOOK ;Scan the keyboard DO: MOV DPTR, #TABLE ;DPTR has base address of table MOV A, TAB ;Put offset in A MOVC A, @A+DPTR ;Get byte from TABLE MOV BUFFER, A ;Put hex byte in buffer ACALL SEND ;Send it to the GRID JMP MAIN $EJECT LOOK: MOV P1, #0FFH MOV P3, #0H MOV R0, #021H LOOK1: MOV A, P1 JB PSW.0, SEE_IT ;CHECK PARITY, IF SET KEY DOWN JMP LOOK1 SEE_IT: MOV ROW, A ;Save P1 row ACALL DEBOUNCE ;Let the key settle MOV A, P1 ;Lets look again CJNE A,P1, LOOK ;If the same continue, else abort MOV P3, #0FFH ; JNB ROW.0, SCAN0 JNB ROW.1, SCAN1 JNB ROW.2, SCAN2 JNB ROW.3, SCAN3 JNB ROW.4, SCAN4 JNB ROW.5, SCAN5 JMP LOOK1 ;*********************************; ; DEBOUNCE SUBROUTINE STARTS HERE ; ;*********************************; DEBOUNCE: MOV R6, #20H ;THIS IS SUPPOSED TO BE L0: MOV R5, #20H ;ABOUT 30ms OR SO. L1: DJNZ R5, L1 ; DJNZ R6, L0 ; RET ;We're done go back $EJECT SCAN0: MOV P1, #0FEH ;See if its column 0 MOV ROW, #00H ACALL SEARCH ;SEARCH examines row inputs JMP DO SCAN1: MOV P1, #0FDH ;Scope out column 1 MOV ROW, #10H ACALL SEARCH ; JMP DO SCAN2: MOV P1, #0FBH ;Column 2 MOV ROW, #20H ACALL SEARCH ; JMP DO SCAN3: MOV P1, #0F7H ;# 3 MOV ROW, #30H ACALL SEARCH JMP DO SCAN4: MOV P1, #0EFH ;# 4 MOV ROW, #40H ACALL SEARCH ; JMP DO SCAN5: MOV P1, #0DFH ;# 5 MOV ROW, #50H ACALL SEARCH ; JMP DO SEARCH: MOV R7, #00H ;R7 is row pointer MOV A, P3 ;Is it this one? R7 starts at 0 MOV COLUMN, A ;Save COLUMN-but it may not be valid JNB COLUMN.0, IT_IS ;Lets try again INC R7 ; JNB COLUMN.1, IT_IS ; INC R7 ; JNB COLUMN.2, IT_IS ; INC R7 ; JNB COLUMN.3, IT_IS ; INC R7 ; JNB COLUMN.4, IT_IS ; INC R7 ; JNB COLUMN.5, IT_IS ; INC R7 ; JNB COLUMN.6, IT_IS ; INC R7 ; JNB COLUMN.7, IT_IS ; RET IT_IS: MOV TAB, ROW ;Put hi nibble in TAB MOV COLUMN, R7 ;COLUMN now has offset MOV A, R7 ;Put row offset in A ORL TAB, A ;TAB is table pointer MOV B, TAB ;Put it here for emulation purposes RET $EJECT ORG 150H ;*******************************; ; SEND SUBROUTINE STARTS ; ; HERE. BUFFER HAS BYTE ; ; TO BE SENT TO PC-AT ; ;*******************************; SEND: MOV PSW, #018H ;RB 3 MOV R2, #00H ;R2 IS CHAR COUNTER S0: MOV A, BUFFER ;CHAR IS IN A S1: MOV R2, #00H MOV R3, A ;SAVE CHAR IN R3 FOR PARITY & KEY UP JNB P0.1, SEND ;Test data for a 1 JNB P0.0, SEND ;Test clock for a 1 CLR C ;GET SET TO SEND SPACE BIT MOV P0.1, C ;PUT IT ON DATA LINE --____ ACALL PULSE ;WAIT AND CLOCK ---_-- BIT_LOOP: RRC A ;PUT "0 BIT" IN CARRY INC R2 ;1st BIT IS IN CARRY MOV P0.1, C ;1st IS ON DATA LINE --____---- ACALL PULSE ; ---_---_-- CJNE R2, #08H, BIT_LOOP; SENT 8 BITS YET? MOV R2, #00H MOV A, R3 ;SET UP FOR PARITY MOV C, PSW.0 ;DO IT CPL C ;PARITY+ACC=EVEN, WE NEED ODD MOV P0.1, C ; ACALL PULSE ;WAIT AND CLOCK SETB P0.1 ;DATA=1 FOR STOP BIT ACALL PULSE ;WAIT AND CLOCK MOV P0, #0FFH ;RAISE ALL LINES MOV R6, #0FFH A1: MOV R5, #0FFH A2: DJNZ R5, A2 DJNZ R6, A1 ME: JNB P0.1, ME YOU: JNB P0.0, YOU MOV A, BUFFER CJNE A, #0F0H, HA MOV R6, #0FFH I: MOV R5, #0FFH THEY: DJNZ R5, THEY DJNZ R6, I MOV BUFFER, #059H AJMP SEND PULSE: MOV R5, #07H ;WAIT U1: DJNZ R5, U1 CLR P0.0 ;CREATE FALLING EDGE OF CLOCK MOV R5, #07H ;WAIT SOME MORE U2: DJNZ R5, U2 ; SETB P0.0 ;CREATE RISING EDGE OF CLOCK RET HA: MOV A, #00H JMP MAIN $EJECT ;*******************************; ; LOOK-UP TABLE ; ; STARTS HERE ; ;*******************************; ORG 300H TABLE: DB 04AH ; / DB 04CH ; : DB 04DH ; P DB 045H ; 0 DB 01AH ; Z DB 01CH ; A DB 015H ; Q DB 016H ; 1 ORG 310H DB 049H ; . DB 04BH ; L DB 044H ; O DB 046H ; 9 DB 022H ; X DB 01BH ; S DB 01DH ; W DB 01EH ; 2 ORG 320H DB 041H ; , DB 042H ; K DB 043H ; I DB 03EH ; 8 DB 021H ; C DB 023H ; D DB 024H ; E DB 026H ; 3 ORG 330H DB 03AH ; M DB 03BH ; J DB 03CH ; U DB 03DH ; 7 DB 02AH ; V DB 02BH ; F DB 02DH ; R DB 025H ; 4 ORG 340H DB 031H ; N DB 033H ; H DB 035H ; Y DB 036H ; 6 DB 032H ; B DB 034H ; G DB 02CH ; T DB 02EH ; 5 ORG 350H DB 055H ; = DB 029H ; space bar DB 05AH ; enter key DB 000H ; NO KEY ON BOARD DB 000H ; NO KEY ON BOARD DB 059H ; shift key DB 066H ; control key SENDS BACK SPACE DB 0F0H ; function SENDS UP KEY + FOLLOWING KEY END