performance – Debounce counter for PIC micro – Suggestions for improvement


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