Alright, for starters let's think about the polling driver. In order to know "when the action is" it actually reads I/O. But the interrupt version I'm imagining (based on option c) will instead examine a byte in memory (which I'll call the Status Byte) which is a simple message that gets updated by the ISR. The message has two parts, each just a single bit:
- a bit (let's say it's Bit7) that says a new interrupt has occurred, and...
- a bit (let's say it's Bit0) that equals the 1 or 0 just received by the new interrupt
Upon initialization of the SBC, Bit7 gets set to 0; you'll also want to set the 65C22 control registers as required.
Later, every time the driver goes to fetch a keypress, the process is as follows:
- to act as a bit counter, set a register or memory location to zero
- keep examining Bit7 of the status byte and wait until it equals 1.
- get Bit0 of the status byte and shift it into a register or memory location.
- set Bit7 of the status byte back to 0. (Or clear the entire byte.)
- increment the counter to see if all bits have been received yet. If not, loop back to 2.
- set the bit counter location to zero
- get the finished scan code that's now fully present in the shifter location
The silent partner on the team is the ISR. As you can probably guess, its job is simply to input the bit from I/O and copy it into Bit0 of the status byte. Then it sets Bit7 of the status byte and exits. As much as possible, we try to avoid putting a lot of smarts into the ISR -- we want it to execute as quickly as possible.
I've left some details for you to sort out, for example the CLI you'll need before the ball can get rolling. You'll also want a CLI somewhere near the beginning of the refresh ISR so that ISR can in turn be interrupted. And probably some other stuff I've forgotten.
To get the code built and working, it might be best to start with just a simple ISR which merely sets a bit. Then flesh things out from there.
Finally, I notice Daryl's driver includes features that involve
outputting to the keyboard. I've ignored all that -- presumably these code snippets needn't be interrupt driven (or perhaps the features can be omitted).
-- Jeff
EDIT: Instead of passing along the bits one at a time (and relying on foreground code to do the shifting), it'd be better to have the ISR also do a one-bit shift with each of the 8 interrupts. It would also update the bit count. By watching the count, the foreground code would know when all bits have arrived -- it would then grab the complete scan code and do what's necessary to digest it. I suggest this approach because it may occasionally happen that two scan codes arrive in close succession, and using the one-bit-at-a-time approach there's a risk the program may still be digesting the first scan code when the first bits of the second scan code begin arriving. So, better to let the ISR shift those bits to ensure they'll be saved rather than getting ignored.
(Carrying this one step further, the ISR could enter completed scan codes into a circular FIFO buffer, and this would allow even more protection in case your application program is VERY slow digesting scan codes.)
_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html