; KEYPAD.ASM, FOR THE INDUSTROLOGIC DIO51
; READ A KEYPAD CONNECTED TO PORT 1
; TRANSMIT ASCII VALUES OF ANY KEYS PRESSED TO THE SERIAL PORT

	ORG	0		;RESTART VECTOR

				;MINIMUM SETUP TO TRANSMIT TO THE SERIAL PORT
	MOV	TMOD,#21H	;T1=BAUD TIMER, T0=16 BIT
	MOV	SCON,#50H	;MODE 1, 8 BIT UART, VAR. BAUD RATE USING T1
	MOV	A,#0FAH		;22.1184 MHZ CRYSTAL, BAUD RATE 9600
	MOV	TH1,A		;TIMER 1 IS FOR BAUD RATE
	MOV	TL1,A
	SETB	TR1		;START THE BAUD RATE TIMER

	MOV	P1,#0FFH	;INITIALIZE PORT 1 TO ALL HIGH


REPEAT:	CALL	KEYPAD		;SEE IF KEYPAD HAS BEEN USED
	JZ	REPEAT		;NULL CHARACTER, NO KEY PRESSED
	CALL	TXCHAR		;TRANSMIT CHARACTER IN ACC
	CALL	QSDEL		;DELAY A QUARTER OF A SECOND
	JMP	REPEAT


				;TRANSMIT CHARACTER IN ACC
TXCHAR:	MOV	SBUF,A		;PUT CHARACTER IN TRANSMIT BUFFER
	JNB	TI,$		;LOOP UNTIL (ALMOST) FINISHED TRANSMITTING
	CLR	TI		;TI IS SET AT THE BEGINNING OF THE STOP BIT
	RET			;SO WE NEED TO WAIT THAT MUCH LONGER



QSDEL:	MOV	R7,#25		;1/4 SECOND DELAY
QSDEL1:	CALL	MS10		;10 MILLISECOND DELAY
	DJNZ	R7,QSDEL1
	RET

KPDELAY:
				;FOR 22.1184MHZ CRYSTAL
MS10:	MOV	R6,#40		;10 mS
MS11:	MOV	R5,#229		;250 uS
	DJNZ	R5,$		;INNER LOOP
	DJNZ	R6,MS11		;OUTER LOOP
	RET




; READ A 4 BY 4 SWITCH MATRIX KEYPAD (WIRED LIKE THE INDUSTROLOGIC KP16)
; ASCII VALUE OF CHARACTER PRESSED IS RETURNED IN ACCUMULATOR
; IF NO KEY IS PRESSED, RETURNS NULL CHARACTER (ZERO)

; P1.7, KP16 PIN 8, ROW 4  --------------------+
; P1.6, KP16 PIN 7, ROW 3  ------------------+ |
; P1.5, KP16 PIN 6, ROW 2  ----------------+ | |
; P1.4, KP16 PIN 5, ROW 1  --------------+ | | |
; P1.3, KP16 PIN 4, COL 4  ---------+    | | | |
; P1.2, KP16 PIN 3, COL 3  -------+ |    | | | |
; P1.1, KP16 PIN 2, COL 2  -----+ | |    | | | |
; P1.0, KP16 PIN 1, COL 1  ---+ | | |    | | | |
;                             | | | |    | | | |
;                                        | | | |
;                             1 2 3 A  --+ | | |
;                             4 5 6 B  ----+ | |
;                             7 8 9 C  ------+ |
;                             * 0 # D  --------+


KEYPAD:
KP10:	MOV	P1,#0EFH	;SET ROW 1 LOW
	CALL	KPDELAY		;SLIGHT DELAY TO GIVE TIME TO PRESS SWITCH

KP11:	JB	P1.0,KP12	;SKIP IF BIT STILL HIGH
	MOV	A,#'1'		;RETURN THE KEY PRESSED
	RET

KP12:	JB	P1.1,KP13	;SKIP IF BIT STILL HIGH
	MOV	A,#'2'		;RETURN THE KEY PRESSED
	RET

KP13:	JB	P1.2,KP14	;SKIP IF BIT STILL HIGH
	MOV	A,#'3'		;RETURN THE KEY PRESSED
	RET

KP14:	JB	P1.3,KP20	;SKIP IF BIT STILL HIGH
	MOV	A,#'A'		;RETURN THE KEY PRESSED
	RET

KP20:	MOV	P1,#0DFH	;SET ROW 2 LOW
	CALL	KPDELAY		;SLIGHT DELAY TO GIVE TIME TO PRESS SWITCH

KP21:	JB	P1.0,KP22	;SKIP IF BIT STILL HIGH
	MOV	A,#'4'		;RETURN THE KEY PRESSED
	RET

KP22:	JB	P1.1,KP23	;SKIP IF BIT STILL HIGH
	MOV	A,#'5'		;RETURN THE KEY PRESSED
	RET

KP23:	JB	P1.2,KP24	;SKIP IF BIT STILL HIGH
	MOV	A,#'6'		;RETURN THE KEY PRESSED
	RET

KP24:	JB	P1.3,KP30	;SKIP IF BIT STILL HIGH
	MOV	A,#'B'		;RETURN THE KEY PRESSED
	RET

KP30:	MOV	P1,#0BFH	;SET ROW 3 LOW
	CALL	KPDELAY		;SLIGHT DELAY TO GIVE TIME TO PRESS SWITCH

KP31:	JB	P1.0,KP32	;SKIP IF BIT STILL HIGH
	MOV	A,#'7'		;RETURN THE KEY PRESSED
	RET

KP32:	JB	P1.1,KP33	;SKIP IF BIT STILL HIGH
	MOV	A,#'8'		;RETURN THE KEY PRESSED
	RET

KP33:	JB	P1.2,KP34	;SKIP IF BIT STILL HIGH
	MOV	A,#'9'		;RETURN THE KEY PRESSED
	RET

KP34:	JB	P1.3,KP40	;SKIP IF BIT STILL HIGH
	MOV	A,#'C'		;RETURN THE KEY PRESSED
	RET

KP40:	MOV	P1,#07FH	;SET ROW 4 LOW
	CALL	KPDELAY		;SLIGHT DELAY TO GIVE TIME TO PRESS SWITCH

KP41:	JB	P1.0,KP42	;SKIP IF BIT STILL HIGH
	MOV	A,#'*'		;RETURN THE KEY PRESSED
	RET

KP42:	JB	P1.1,KP43	;SKIP IF BIT STILL HIGH
	MOV	A,#'0'		;RETURN THE KEY PRESSED
	RET

KP43:	JB	P1.2,KP44	;SKIP IF BIT STILL HIGH
	MOV	A,#'#'		;RETURN THE KEY PRESSED
	RET

KP44:	JB	P1.3,KP50	;SKIP IF BIT STILL HIGH
	MOV	A,#'D'		;RETURN THE KEY PRESSED
	RET

KP50:	MOV	P1,#0FFH	;RETURN PORT TO INITIAL VALUE
	MOV	A,#0		;RETURN A NULL IF NO KEY PRESSED
	RET


	END
