Hi Rob,
I have something that might help a little.
I have a module that scans two ports for button press/release (sixteen buttons). It uses an interrupt to "que" the scan "task" subroutine at some interval. I typically use 200 microseconds per scan, but sometimes piggie-back the scheduling of the scan off of some other periodic interrupt, like the ADC, to save a timer.
The scan task has a debounce counter that you can set. It will not register a change until the IO-input has been stable for N sample periods. It then sticks the button "events" in a queue, for another "task" to extract and process.
The button events are:
KeyPressed: the key was pressed down
KeyClicked: the key was pressed and released quickly
KeyHeld: the key has been pressed long enough to be 'Held'
KeyRepeat: the key has been down for an additional 1/4 second
KeyHoldEnd: the key was 'Held', but is now released
KeyReleased: the key was let back up
For your application, the "KeyHeld" and "KeyRepeat" code might be able to be used as is, or modified to suit your needs.
I know this might be more than you need, but let me know if you want to try it. I use a little pico-scheduler for my "tasks", and can include that if you would like.