I developed this code for a vertical debounce counter for the PIC micro (PIC16F57). The code is called every 512 microseconds. It takes 5 bits from PORTB and compares it to a last known debounced state. If an active input has been stable for 64 calls it is accepted as changed. Though it is sufficiently good for the current application, I am interested in possible improvements to speed up overall execution time. I am not interested in prematurely leaving the loop in case there is nothing to update.
cblock 0x08 gpcounter:1 ; general purpose counter debstate:1 delta:1 toggle:1 vcounter:6 endc ; Button debounce ; A button state is considered stable if it has not changed in 64 polls each 512 usec debounce ; Read input state. Only bits 0-4 are inputs movf PORTB, W andlw 0x1f ; Any input bits that have changed with respect to the last known state ; will be set to 1's in delta and toggle. ; delta remains fixed, toggle will act as a carry while looping ; Because toggle bits will be reset only, toggle will always be a subset of delta. xorwf debstate, W movwf delta movwf toggle ; Load first counter row in index register movlw vcounter movwf FSR ; Counter has 6 rows movlw 0x06 movwf gpcounter debounceloop ; Reset row for all bits which have not changed states movf delta, W andwf INDF, F ; Flip row bits according to toggle mask. ; Because the 1's in toggle are a subset of those in delta, ; any reset counter bits can never be toggled back to 1 movf toggle, W xorwf INDF, F ; If any bits were toggled from 1 to 0, retain carry bit, else discard it comf INDF, W andwf toggle, F ; We're done with this row incf FSR, F decfsz gpcounter, F goto debounceloop ; toggle will now contain 1's for any counters ; that have overflown, so it can be used as xor mask ; to update the last known debounced state movf toggle, W xorwf debstate, F retlw 0x00