Debouncing switches

;***********************************************************
; CheckSwitches is called every clock tick to check
; for switch action.
; The T-flag should be clear during init.  It is used to store a
; change from the previous state
;
; for best (startup) behavior, STATE should be initialized to PIND

.def tmp = r0	; temp register, either in lower or upper half
.def STATE = r1	; STATE of pressed switches

.include "C:\usr\atmel\include\1200def.inc"

main:
	; ************** init required for CheckSwitches ************
	clt			; clear T-flag
	in STATE,PIND		; init current STATE to PIN registers
	; ***********************************************************

	ser r16			; init PORT B to output
	out DDRB,r16

loop:
	rcall CheckSwitches
	rjmp loop


;********************************************************************
CheckSwitches:
	in	tmp,PIND		; read PINs
	cp 	tmp,STATE		; equal to previous STATE
	breq	equal			; no:
	mov	STATE,tmp		; save new STATE
	bld	tmp,0			; toggle T-flag
	com	tmp
	bst	tmp,0
return:	ret
equal:
	brtc	return		; if T-flag set
	clt					;  clear T-flag, so we take
							;  action only once
	rjmp 	SwitchAction	;  process switch state
						;  pressed values in DEBOUNCE
	;  changed "rcall SwitchAction" to rjmp for 	;  tail-optimization
;********************************************************************


SwitchAction:
	out PORTB,STATE
	ret
Thanks to Ron Kreymborg for this.