list p=12F683 ; list directive to define processor
#include <p12F683.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _FCMEN_ON & _IESO_OFF & _CP_OFF & _CPD_OFF & _BOD_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.
cblock 0x20
InBuffer
combo1
combo2
combo3
combo4
dbctr
swlatch
NoGo
d1
d2
endc
org 0x0000 ; org sets the origin, 0x0000
goto Start ; go to beginning of program
org 0x0004 ;interrupt vector
goto Start
Start
movlw 07h ; Set GPIO <2:0) to
movwf CMCON0 ; digital I/O
clrf ANSEL ; digital I/0
movlw b'001111'
banksel TRISIO
movwf TRISIO
banksel GPIO
clrf GPIO
getinput
movlw InBuffer ; 4 character input buffer address
movwf FSR ; FSR = &InBuffer
getnext
call getbutton ; get a button press
movwf INDF ; add to buffer (1, 2, 4, or 8)
incf FSR,F ;
movlw InBuffer+4 ;
xorwf FSR,W ; all 4 buttons added?
bnz getnext ; no, branch, else,
chkcombo
movf InBuffer+0 ; W = InBuffer[0]
xorlw combo1 ; same as combination key 1?
bnz NoGo ; no, branch, else
movf InBuffer+1 ; W = InBuffer[1]
xorlw combo2 ; same as combination key 2?
bnz NoGo ; no, branch, else
movf InBuffer+2 ; W = InBuffer[2]
xorlw combo3 ; same as combination key 3?
bnz NoGo ; no, branch, else
movf InBuffer+3 ; W = InBuffer[3]
xorlw combo4 ; same as combination key 4?
bnz NoGo ; no, branch, else
;
; we've got a good combo
;
getbutton
movlw 20 ; reset debounce counter
movwf dbctr ; to 20 msecs
dbdelay
call DelayCy ; use 1 msec sample interval
comf GPIO,W ; sample active low switches
andlw 0x0F ; sample only b3..b0 bits
xorwf swlatch,W ; a difference (press or release)?
bz getbutton ; no, branch (reset), else
decfsz dbctr,f ; debounced? yes, skip, else
goto dbdelay ; sample again
xorwf swlatch,F ; update debounced switch state latch
andwf swlatch,W ; a debounced "new press"?
bz getbutton ; no, branch (a "new release"), else
return ; returns W = 1, 2, 4, or 8
DelayCy ;998 cycles
movlw 0xC7
movwf d1
movlw 0x01
movwf d2
Delay_0
decfsz d1, f
goto $+2
decfsz d2, f
goto Delay_0
;2 cycles
goto $+1
END ; directive 'end of program'