*********************************************************
* KEYTRY - Try out keypad debounce and decode software  *
*	   Detect and debounce keys. When a key found   *
*	   change it to ASCII and display on LCD        *
*	   Debounce release of key and look for more    *
*********************************************************

* Register Equates
PORTA	EQU	$00	LCD display data
PORTB	EQU	$01	Keypad Row4,3,2,1;Col1,2,3,4
PORTC	EQU	$02	Fan*,Heat*,Cool*,Beep;ADen*,E,RS,R/W
DDRA	EQU	$04	Data direction, Port A (all output)
DDRB	EQU	$05	Data direction, Port B (7-4in,3-0out)
DDRC	EQU	$06	Data direction, Port C (all output)

* RAM Equates
KEYVAL	EQU	$9D	Keypad key (ASCII)
TEMPA	EQU	$9E	One byte temp storage location
TEMPX	EQU	$9F	One byte temp storage location

	ORG	$100
* Set Port data patterns and directions
INIT	LDA	#$E8	Fan*,Heat*,Cool*,Beep;ADen*,E,RS,R/W
	STA	PORTC	Initial values for Thermostat controls
	CLRA		Row3,2,1,0;Col1,2,3,4
	STA	PORTB	All cols initially off
	DECA		to $FF
	STA	DDRA	Port A all outputs
	STA	DDRC	Port C all outputs
	LDA	#$0F	Rows=in, Cols=outs
	STA	DDRB	Port B half ins, half outs

* LCD display peripheral needs to be initialized
	LDA	#$01
	JSR	WCTRL	Clear
	LDA	#$02
	JSR	WCTRL	Home
	LDA	#$38
	JSR	WCTRL	Function Set- 8-bit,2-line,5X7
	LDA	#$0C
	JSR	WCTRL	Display on, Cursor off
	LDA	#$06
	JSR	WCTRL	Entry mode- Inc addr, no shift

** END of INITIALIZATION ********************************

KEYTRY	LDA	#$0F
	STA	PORTB	Turn on all cols
ANYK	LDA	PORTB	Reads rows in upper 4
	AND	#$F0	Mask away cols
	BEQ	ANYK	Loop till a key is found
	JSR	DLY50	Debounce key
	LDX	#30	Pointer to last pair in KYTBL
KYLOOP	LDA	KYTBL,X	Get row/col pattern
	STA	PORTB	Drive cols
	CMP	PORTB	Check for row & col match
	BEQ	FOUND	If =; key found
	DECX		Point to next pair of entries
	DECX		in KYTBL
	BPL	KYLOOP	Loop if more entries
	BRA	KEYTRY	Key gone; start over
FOUND	LDA	KYTBL+1,X  Get key equiv from table
	STA	KEYVAL	Save for now
	LDA	#$80	Left end of 1st row
	JSR 	WCTRL	Position entry point
	LDA	KEYVAL	Get the ASCII key value
	JSR 	WDAT	Display the key
	LDA	#$0F
	STA	PORTB	Turn on all cols
TILRLS	LDA	PORTB	Reads rows in upper 4
	AND	#$F0	Mask away cols
	BNE	TILRLS	Loop till no key pressed
	JSR	DLY50	Debounce release
	BRA	KEYTRY	Look for another key


*********************************
* SUBROUTINES & CONSTANT TABLES *
*********************************

***
* DLY50 - Subroutine to delay ~50mS
* Save original accumulator value
* but X will always be zero on return
***

DLY50	STA	TEMPA	Save accumulator in RAM
	LDA	#32	Do outer loop 32 times
OUTLP	CLRX		X used as inner loop count
INNRLP	DECX		0-FF, FF-FE,...1-0 256 loops
	BNE	INNRLP	6cyc*256*1S/cyc = 1.536mS
	DECA		32-31, 31-30,...1-0
	BNE	OUTLP	1545cyc*32*1S/cyc=49.440mS
	LDA	TEMPA	Recover save Accumulator val
	RTS		** Return **

* Keypad Correspondance Table
*  1st entry of each pair is Row/Col bit pattern
*  2nd entry of each pair is ASCII equiv of key
*
* COL # ->   1  2  3  4
*            v  v  v  v
*                        This is layout of keypad
* ROW 1 ->   1  2  3  A
* ROW 2 ->   4  5  6  B
* ROW 3 ->   7  8  9  C
* ROW 4 ->   <  0  >  !
*
* Port B layout is  R4,R3,R2,R1; C1,C2,C3,C4  R's=ins, C's=outs
*
KYTBL	FCB	$18,'1	Row 1, Col 1 (Top Left)
	FCB	$28,'4	Row 2, Col 1
	FCB	$48,'7	Row 3, Col 1
	FCB	$88,'<	Row 4, Col 1
	FCB	$14,'2	Row 1, Col 2
	FCB	$24,'5	Row 2, Col 2
	FCB	$44,'8	Row 3, Col 2
	FCB	$84,'0	Row 4, Col 2
	FCB	$12,'3	Row 1, Col 3
	FCB	$22,'6	Row 2, Col 3
	FCB	$42,'9	Row 3, Col 3
	FCB	$82,'>	Row 4, Col 3
	FCB	$11,'A	Row 1, Col 4
	FCB	$21,'B	Row 2, Col 4
	FCB	$41,'C	Row 3, Col 4
	FCB	$81,'!	Row 4, Col 4 (Bot Right)

********************************************************
* WCTRL - Write control word to LCD peripheral         *
*	Enter with control word in accumulator         *
*	Return with original value of X                *
*	Delay ~4.5mS if A=$01 or $02 else delay ~120S *
********************************************************
WCTRL	STX	TEMPX	Save X
	STA	PORTA	Write control word to LCD
	BSET	2,PORTC	E->1
	BCLR	2,PORTC	E->0
	LDX	#20	20*6~*1S/~=120S
L120U	DECX		Delay loop ~120S
	BNE	L120U	20-19,19-18...1-0
	CMP	#$02	Commands $01 & $02 req extra delay
	BHI	ARN5M	If command > $02 skip long delay
L5M	JSR	ANRTS	JSR+RTS TAKES 12~ (just want delay)
	DECX		TAKES 3~ (X=0->1 on first pass)
	BNE	L5M	3~ Loop 256*18~*1S/~=4.608mS Delay
ARN5M	LDX	TEMPX	Restore X
ANRTS	RTS		** RETURN **

********************************************************
* WDAT - Write data word to LCD peripheral             *
*	Enter with data word in accumulator            *
*	Return with original values of X & A           *
*	Delay ~120S after data write                  *
********************************************************
WDAT	STX	TEMPX	Save X
	STA	TEMPA	Save A
	STA	PORTA	Write data word to LCD
	BSET	1,PORTC	RS->1
	BSET	2,PORTC	E->1
	BCLR	2,PORTC	E->0
	BCLR	1,PORTC	RS->0
	LDX	#20	20*6~*1S/~=120S
L120	DECX		Delay loop ~120S
	BNE	L120	20-19,19-18...1-0
	LDA	TEMPA	Restore A
	LDX	TEMPX	Restore X
	RTS		** RETURN **

