1. 1s 2. (a) 3. (b)
4. (a) it can be any of keys in row 3 (3, 7, B, or F) (b) it can by any of keys in row 0 (0, 4, 8, or C) 5. (a) all rows are grounded at the same time
(b) the columns are read
(c) the columns data is checked to see if there is a zero in it; if there is a zero then it goes to the next step of key identification, otherwise it repeats step b and c
6. (a) ground one row at a time (b) read the columns
(c) check for a zero in column data
(d) if zero found, it goes to find out which column it belongs to and gets the scan code, otherwise it goes back to step a
7.
;the following look-up scan codes are in the data segment
KCOD_0 DB 0,1,2,3,4 ;key codes for row zero KCOD_1 DB 5,6,7,8,9 ;key codes for row one KCOD_2 DB 0AH,0BH,0CH,0DH,0EH ;key codes for row two KCOD_3 DB 0FH,10H,11H,12H,13H ;key codes for row three
;the following is from the code segment
PUSH BX ;save BX
SUB AL,AL ;AL=0 to ground all rows rows at once OUT PORT_A,AL ;to ensure all keys are open (no contact)
K1: IN AL,PORT_B ;read the columns
AND AL,00011111B ;mask the unused bits (D7-D5) CMP AL,00011111B ;are all keys released
JNE K1 ;keep checking for all keys released CALL DELAY ;wait for 20 ms
K2: IN AL,PORT_B ;read columns AND AL,00011111B ;mask D7-D5
CMP AL,00011111B ;see if any key pressed? JE K2 ;if none keep checking
CALL DELAY ;wait 20 ms for debounce ;after the debounce see if still pressed
IN AL,PORT_B ;read columns AND AL,00011111B ;mask D7-D5
CMP AL,00011111B ;see if any key closed? JE K2 ;if none keep polling ;now ground one row at a time and read columns to find the key
MOV AL,11111110B ;ground row 0 (D0=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00011111B ;mask unused bits (D7-D5) CMP AL,00011111B ;see which column
JE RO_1 ;if none go to grounding row 1
MOV BX,OFFSET KCOD_0 ;set BX=start of table for column 0 keys JMP FIND_IT ;identify the key
RO_1: MOV AL,11111101B ;ground row 1 (D1=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00011111B ;mask unused bits (D7-D5) CMP AL,00011111B ;see which column
JE RO_2 ;if none go to grounding row 2
MOV BX,OFFSET KCOD_1 ;set BX=Start of table for column 1 keys JMP FIND_IT ;identify the key
RO_2: MOV AL,11111011B ;ground row 2 (D2=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00011111B ;mask unused bits (D7-D5) CMP AL,00011111B ;see which column
MOV BX,OFFSET KCOD_2 ;set BX=start of table for column 2 keys JMP FIND_IT ;identify the key
RO_3: MOV AL, 11110111B ;ground row 3 (D3=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00011111B ;mask unused bits (D7-D5) CMP AL,00011111B ;see which column
JE K2 ;if none then false input repeat the process MOV BX,OFFSET KCOD_3 ;set BX=start of table for column 3 keys ;A key press has been detected and the row identified. Now find which key.
FIND_IT: RCR AL,1 ;rotate the column input to search for 0 JNC MATCH ;if zero, go get the code
INC BX ;if not point at the next code JMP FIND_IT ;and keep searching ;GET THE CODE FOR THE KEY PRESSED AND RETURN
MATCH: MOV AL,[BX] ;get the code pointed by BX
POP BX ;return with AL=code for pressed key
RET
8.
;the following look-up scan codes are in the data segment
KCOD_0 DB 0,1,2,3,4,5 ;key codes for row zero KCOD_1 DB 6,7,8,9,0AH,0BH ;key codes for row one KCOD_2 DB 0CH,0DH,0EH,0FH,10H,11H ;key codes for row two KCOD_3 DB 12H,13H,14H,15H,16H,17H ;key codes for row three KCOD_4 DB 18H,19H,1AH,1BH,1CH,1DH ;key codes for row four KCOD_5 DB 1EH,1FH,20H,21H,22H,23H ;key codes for row five
;the following is from the code segment
PUSH BX ;save BX
SUB AL,AL ;AL=0 to ground all rows at once OUT PORT_A,AL ;to ensure all keys are open (no contact)
K1: IN AL,PORT_B ;read the columns
AND AL,00111111B ;mask the unused bits (D7-D6) CMP AL,00111111B ;are all keys released
JNE K1 ;keep checking for all keys released CALL DELAY ;wait for 20 ms
K2: IN AL,PORT_B ;read columns AND AL,00111111B ;mask D7-D6
CMP AL,00111111B ;see if any key pressed? JE K2 ;if none keep checking
CALL DELAY ;wait 20 ms for debounce ;after the debounce see if still pressed
IN AL,PORT_B ;read columns AND AL,00111111B ;mask D7-D6
CMP AL,00111111B ;see if any key closed? JE K2 ;if none keep polling ;now ground one row at a time and read columns to find the key
MOV AL,11111110B ;ground row 0 (D0=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00111111B ;mask unused bits (D7-D6) CMP AL,00111111B ;see which column
JE RO_1 ;if none go to grounding row 1
MOV BX,OFFSET KCOD_0 ;set BX=start of table for column 0 keys JMP FIND_IT ;identify the key
RO_1: MOV AL,11111101B ;ground row 1 (D1=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00111111B ;mask unused bits (D7-D6) CMP AL,00111111B ;see which column
JE RO_2 ;if none go to grounding row 2
MOV BX,OFFSET KCOD_1 ;set BX=Start of table for column 1 keys JMP FIND_IT ;identify the key
RO_2: MOV AL,11111011B ;ground row 2 (D2=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00111111B ;mask unused bits (D7-D6) CMP AL,00111111B ;see which column
JE RO_3 ;if none go to grounding row 3
MOV BX,OFFSET KCOD_2 ;set BX=start of table for column 2 keys JMP FIND_IT ;identify the key
RO_3: MOV AL,11110111B ;ground row 3 (D3=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00111111B ;mask unused bits (D7-D6) CMP AL,00111111B ;see which column
JE RO_4 ;if none then go to grounding row 4 MOV BX,OFFSET KCOD_3 ;set BX=start of table for column 3 keys
JMP FIND_IT
RO_4: MOV AL,11101111B ;ground row 4 (D4=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00111111B ;mask unused bits (D7-D6) CMP AL,00111111B ;see which column
JE RO_5 ;if none then go to grounding row 5 MOV BX,OFFSET KCOD_4 ;set BX=start of table for column 5 keys
JMP FIND_IT
RO_5: MOV AL,11011111B ;ground row 5 (D5=0)
OUT PORT_A,AL
IN AL,PORT_B ;read all columns AND AL,00111111B ;mask unused bits (D7-D6) CMP AL,00111111B ;see which column
JE K2 ;if none then false input repeat the process MOV BX,OFFSET KCOD_5 ;set BX=start of table for column 3 keys ;A key press has been detected and the row identified. Now find which key.
FIND_IT: RCR AL,1 ;rotate the column input to search for 0 JNC MATCH ;if zero, go get the code
INC BX ;if not point at the next code JMP FIND_IT ;and keep searching ;GET THE CODE FOR THE KEY PRESSED AND RETURN
MATCH: MOV AL,[BX] ;get the code pointed by BX
POP BX ;return with AL=code for pressed key
RET
9. The main advantage is that it does not tie down the microprocessor. The disadvantage is that it is not versatile. 10. To use a separate microprocessor (microcontroller) from the main CPU to scan the keys (polling) and use
interrupts to inform the main CPU. This allows programming the keyboard itself which is much more versatile.