File "KEYLCD-E.ASM"

Full Path: /home/analogde/www/private/Projet/Example/HC11/KEYLCD-E.ASM
File size: 5.89 KB
MIME-type: text/plain
Charset: utf-8

**************************************************************************
* KEYLCD-E
*	Simple program to read the Axiom CME11A8 or CMM SS: keypad and
*	echo the keys to the LCD screen.
*
**************************************************************************
       OPT  l
       ORG $2000		* start code at 2000h
       JMP  MAIN		* jump over data to start of program

LCDBAS EQU  $B5F0		* LCD port address
PORTD  EQU  $1008		* port D address
PDDR   EQU  $1009		* port D direction register
PORTE  EQU  $100A		* port E address
IO     EQU  $3E         	* port D direction value

BUF1   RMB  1			* temporary storage variables
BUF2   RMB  1
BUF3   RMB  1
BUF4   RMB  1
BUF5   RMB  1

TABLE  FCB  $31,$32,$33,$41	* keypad scan lookup table
       FCB  $34,$35,$36,$42
       FCB  $37,$38,$39,$43
       FCB  $2A,$30,$23,$44

* Start of program
MAIN   SEI                    	* Disable enable interrupts
       JSR  LCDSET            	* Setup LCD
       JSR  KEYSET            	* Setup Keypad

* Main Loop
M1     JSR  KEYIN             	* Get character from keypad
       CMPA #$2A              	* is keypad character '*' ?
       BNE  M2			* branch if no
       JSR  LCDSET              * yes, clear LCD screen
       BRA  M3                  * continue
M2     JSR  LCDOUT            	* Display key pressed on LCD
M3     JSR  ANYKEY            	* wait for key to be released
       BEQ  M1                	* if key released, go wait for another
       BRA  M3                	* continue waiting

* Keypad input subroutine
KEYIN
       JSR  ANYKEY            	* is any key pressed?
       BEQ  KEYIN		* wait if not

       JSR  KEYSCAN		* key pressed, figure out which one
       TSTA			* 0?
       BEQ  KEYIN		* ignore if yes
       PSHA			* save key value
       JSR  DELAY1		* wait a bit for debounce
       JSR  KEYSCAN		* scan again
       PULB			* get previous key
       CBA			* same key pressed
       BNE  KEYIN		* ignore if not
       RTS			* valid key pressed, return it

* figure out which key is being pressed
KEYSCAN
       CLRB                   	* CLEAR KEY NUMBER
       LDAA #$04              	* COLUMN 1 ON
       JSR  KEYCHK            	* TEST COLUMN 1
       BNE  KEYROW            	* KEY IS THIS ROW
       ADDB #4                	* UPDATE KEY COUNT
       LDAA #$08              	* COLUMN 2 ON
       JSR  KEYCHK            	* TEST COLUMN 2
       BNE  KEYROW            	* KEY IS THIS ROW
       ADDB #4                	* UPDATE KEY COUNT
       LDAA #$10              	* COLUMN 3 ON
       JSR  KEYCHK            	* TEST COLUMN 3
       BNE  KEYROW            	* KEY IS THIS ROW
       ADDB #4                	* UPDATE KEY COUNT
       LDAA #$20              	* COLUMN 4 ON
       JSR  KEYCHK            	* TEST COLUMN 4
       BEQ  NOKEY             	* NO KEY FOUND, START OVER
KEYROW
       LSRA                   	* next row
       BCS  KEYDONE		* if row found, finish
       INCB                     * incriment index
       LSRA                     * next row
       BCS  KEYDONE             * if row found, finish
       INCB                     * incriment index
       LSRA                     * next row
       BCS  KEYDONE             * if row found, finish
       INCB                     * incriment index
       LSRA			* next row
       BCC  NOKEY             	* NO KEY FOUND, START OVER

KEYDONE
       PSHX			* key found, save x
       CLRA			* clear a
       ADDD  #TABLE            	* get look up table
       XGDX			* prepare to get data
       LDAA 0,X			* get date at offset index
       PULX			* restore x
       RTS                      * return with key found in a

NOKEY  CLRA			* no key pressed, clear a
       RTS

* see if any key is pressed
ANYKEY
       LDX  #PORTD		* get port D
       LDAA #$3C              	* scann with ALL COLUMNS ON
KEYCHK
       STAA 0,X               	* OUTPUT KEY COLUMNS
       NOP
       NOP
       LDAA 2,X               	* INPUT KEY ROWS
       ANDA #$0F              	* MASK FOR KEY ROWS
       RTS                    	* WAIT FOR KEY

* This version adjusts for 4x20 keypad row addressing if you're expecting
* continuous rows 1,2,3,4
LCDOUT
	ldab	LCDBAS		* get current address

	CMPB 	#$13		* at end of first row
	beq     lcd_ad1		* jif yes
	CMPB 	#$53		* at end of 2nd row
	beq     lcd_ad2		* jif yes
	CMPB 	#$27		* at end of 3rd row
	beq     lcd_ad3		* jif yes

	STAA  LCDBAS+1		* write data to lcd output port
	RTS

lcd_ad1
	ldab	#$28+#$80	* set correct address
	bra	lcd_fix		* continue fix
lcd_ad2
	ldab	#$14+#$80	* set correct address
	bra	lcd_fix		* continue fix
lcd_ad3
	ldab	#$54+#$80	* set correct address
lcd_fix
	STAA	LCDBAS+1	* write data to lcd output port
	JSR	DELAY
	STAB	LCDBAS		* make address fix
	RTS

* configure LCD screen
LCDSET LDAA  #$3C             	* set 2x40 Display
       STAA  LCDBAS
       JSR   DELAY
       LDAA  #$01             	* Clear & Home
       STAA  LCDBAS
       JSR   DELAY
       LDAA  #$0F             	* Display on
       STAA  LCDBAS
       JSR   DELAY
       LDAA  #$06             	* Cursor shift on
       STAA  LCDBAS
       LDAA  #$14             	* Shift right
       STAA  LCDBAS
       LDAA  #$02             	* Cursor to Home
       STAA  LCDBAS
       JSR   DELAY
       RTS

* delay 1
DELAY  PSHB 		* save registers
       PSHA
       LDAB  #$F0	* set loop count 1
DEL1   LDAA  #$F0	* set loop count 2
DEL2   DECA             * decriment counter 2
       BNE   DEL2       * branch if not 0
       DECB		* decriment counter 1
       BNE   DEL1	* branch if not 0
       PULA		* restore registers
       PULB
       RTS

* delay 2
DELAY1
        PSHX		* save x
        LDX     #20000  * load count
DELLP   DEX		* decriment x
        BNE     DELLP	* loop if not 0
        PULX		* restore x
        RTS

KEYSET LDAA  #IO	* get port D direction
       STAA  PDDR	* set port D data direction register
       RTS