;************************************************************************** ;* KEYLCD-E ;* Simple program to read the Axiom CME11A8 or CMM SS: keypad and ;* echo the keys to the LCD screen. ;* ;* Modified by D.Kohn for use with MiniIDE 01/18/04 ;************************************************************************** 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 #$A8 ; set correct address bra lcd_fix ; continue fix lcd_ad2 ldab #$94 ; set correct address bra lcd_fix ; continue fix lcd_ad3 ldab #$D4 ; 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