File "KEY12.ASM"

Full Path: /home/analogde/www/private/Projet/KEY12.ASM
File size: 3.79 KB
MIME-type: text/plain
Charset: utf-8

;
;  KEY12.ASM
;  ---------
;	KEYPAD routines for Axiom HC12 development boards.  KEYPAD uses Port H.
;
;  Variables - calling program must reserve these:
;  -----------
;     Global variables
;  	OLDKEY	1 byte, stores the previous key value for debouncing
;
;     Local variables
;	CNT1	1 byte, temporary debounce counter
;	TMP1	1 byte, temporary storage variable
;
;  Subroutines:
;  -----------
;  INITKEY:	Initialize KEYPAD
;  GETKEY:	Wait for key released then wait for key pressed.  Return it in A
;  KEYWAIT:	Wait for key to be released
;  KEYSCAN:	Do a quick scan of the KEYPAD. Return A=key if pressed, 0 if not
;  KEYDLY:	Delay, wait for lines to settle

; Define Key Character Table

_KEY_TBL:  FCC	'A321B654C987D#9*'


;-------
GETKEY:
	jsr	KEYWAIT		; wait for any keys to be released
	jsr	KEYSCAN		; scan keypad for new key
	tsta			; key pressed?
	beq	GETKEY		; loop if no
	rts

;-------
; loop until no key is pressed
KEYWAIT:
	jsr	KEYSCAN		; scan keypad
	tsta			; key pressed?
	bne	KEYWAIT		; loop if yes
	rts

; Scan KEYPAD for input. return A=0 no input else A=key
; columns are active low, rows are then read active low
KEYSCAN:
	bclr	PORTH,#$0F	; clear all KEYPAD columns
	ldaa	PORTH		; get KEYPAD port
	anda	#$F0		; key mask
	eora	#$F0		; test for any low
	beq	KEYRESET	; branch if NO key pressed

;-------
; here if a key is pressed, determine which one
KEYSCAN1:
	bset	PORTH,#$0F	; set all KEYPAD columns HIGH
	clrb			; clear row counter
	bclr	PORTH,#$01	; clear column 1
	jsr	KEYSCAN2	; get KEYPAD row status
	bne	KEYROW		; branch if a key pressed, find row
	ldab	#$04		; next row count
	bset	PORTH,#$01	; set column 1

	bclr	PORTH,#$02	; clear column 2
	jsr	KEYSCAN2	; get KEYPAD row status
	bne	KEYROW		; branch if a key pressed, find row
	ldab	#$08		; next row count
	bset	PORTH,#$02	; set column 2

	bclr	PORTH,#$04	; clear column 3
	jsr	KEYSCAN2	; get KEYPAD row status
	bne	KEYROW		; branch if a key pressed, find row
	ldab	#$0C		; next row count
	bset	PORTH,#$04	; set column 3

	bclr	PORTH,#$08	; clear column 4
	jsr	KEYSCAN2	; get KEYPAD row status
	bne	KEYROW		; branch if a key pressed, find row
	bra	KEYRESET	; NO key pressed, reset

KEYSCAN2:
	jsr	KEYDLY		; wait for lines to settle
	ldaa	PORTH		; get KEYPAD port
	anda	#$F0		; key mask
	eora	#$F0		; test for any low
	rts

; here if a key is pressed, B=row count, A=row value
KEYROW:
	clr	TMP1		; clear offset count
KEYROW1:
	lsla			; shift row value to low nibble
	bcs	KEYROW2		; column found, go compute offset
	inc	TMP1		; incriment offset counter
	bra	KEYROW1		; loop
KEYROW2:
	addb	TMP1		; add column offset to row value
	ldx	#_KEY_TBL	; get start of key table
	ldaa	B,X		; load offset key value in a
			; key pressed in A, debounce
	ldab	#$04		; see if we already debounced this key
	cmpb	CNT1		;
	bne	KEYCOUNT	; branch if not, continue debounce
	rts			; same key pressed, already said so, return it
KEYCOUNT:
	cmpa	OLDKEY		; same key pressed as last time?
	bne	KEYNEW		; no, debounce new key
	inc	CNT1		; incriment debounce counter
	ldab	#$04		; finished debouncing?
	cmpb	CNT1		;
	bne	KEYNO		; branch if no
	rts			; return key
KEYNEW:
	clr	CNT1		; start new key debounce
	staa	OLDKEY		; save new key for debouncing
KEYNO:
	clra			; return no key pressed yet
	rts
;-------
KEYRESET:
	bset	PORTH,#$0F	; set all KEYPAD columns HIGH
;	clr	CNT1		; clear debounce counter
	clr	OLDKEY		; clear any old key
	clra			; clear key status
	rts
;-------
KEYDLY:
	clr	TMP1		; clear offset count
KEYDLY1:
	inc	TMP1		; incriment counter
	brclr	TMP1,#$08,KEYDLY1	; loop if time not yet up
	rts

;-------
; Initialize KEYPAD
; Port H 0-3 must be output
;        4-7 must be input
INITKEY:
	ldaa	#$0F	; set Port H direction (0=input, 1=output)
	staa	DDRH	;
	rts