Well, we are not in the habbit of doing people's homework for them, but without actually writing the whole program, we can give you the steps that need to take place so you'll understand it better than if someone just gave you the completed code.
First, it sounds like the 4 rows and 4 columns of the keypad are connected to PB. Is that right? If they are, the only reason to read PA is to turn off the CA2 interrupt, not to get any info about what key is being pressed. When the time comes, you'll read PA, but discard the information. Otherwise, leave PA available for something else, which you can still do without affecting the keypad job. Actually, with a few tricks, you can use a sigle 6522 VIA for more things simultaneously than I'm sure you imagine.
Without external ICs (like the keypad encoder mentioned above), 4 bits of PB will be connected to the keypad columns, and 4 bits to the rows. Let's say PB0-PB3 go to the columns, and PB4-PB7 go to the rows. Each row will have a pull-up resistor to Vcc so it will be in a high logic state unless a key on that row is pressed to connect it to a column whose voltage is low.
Next you need a way to generate the interrupt from CA2. The most straight forward way to take care of the hardware part of that would be to connect each row to one input of a 4-input NAND gate. (A second choice would be to connect each row to the cathode of a diode, and all the anodes to CA2. Then put a pull-up resistor on CA2.)
You'll need to do a few things to set up the VIA. First set the data direction for the port B bits by writing to DDRB (VIA register 2). To do it as mentioned above, you'll make the columns outputs by writing 1's to the four column bits, and make the rows to be inputs by writing 0's to the four row bits. If PB0-PB3 go to the columns as mentioned above, you'll write 00001111B (0FH) to DDRB. Then when you write to PB, it will only affect the 4 least-significant bits, and you can read the 4 most-significant ones as needed.
To set up CA2, you'll need to write to the PCR (VIA register 12). The figure in the data sheet is self-explanatory there. Set it up to generate an interrupt on a falling edge (PCR=XXXX0010B). After your interrupt-service routine (ISR) is in place (more on that in a minute), you will also need to enable the interrupt by writing to the IER (VIA register 14), a 1 to bits 7 and 0, and at this point, you'll probably want 0's in the other bits.
For the interupt service, once you have verified (by reading the IFR, or VIA register 13) that CA2 is indeed the source of the interrupt, you will need to scan the keypad. First set the first column low (XXXX1110B) while keeping the others high, and then read the rows to see if any one of them is low. If they're all high (1111XXXXB, verified by ANDing with 11110000B and seeing if the result is 11110000B), you move on to set the next column low and again read the rows, and so on, until you find which one of them shows a key being pressed. It's possible that keybounce would make it appear that even though there was an interrupt, no key was pressed. Just keep scanning and the keypress will show up. From your description, it sounds like that when a keypress shows up, the value you read at PB (not PA) will be the key value itself that you will put in a key buffer that starts at 0050.
You must use a delay for debouncing so that the normal switch contact bounce does not register dozens of keypresses when there was only one. You can avoid looking for further keypresses until there has been perhaps a tenth of a second of continuous no-key-pressed status. Keeping the computer tied up in the ISR for this long however is generally not something you want to do. It is usually preferable to do something like using a VIA timer to generate an interrupt every so many milliseconds to go back and check the keypad status again and record what it found, so the computer can get on with its work. For example, do you want the computer to do something when you press a key (instead of waiting until you release it)? That's more user-friendly. The computer will have to be freed up to be able to do that. This is one of the many things a real-time clock, or RTC, even done in software using the VIA's T1, is valuable for, even if you don't care about keeping the time of day. The RTC will come in even more valuable if you want to have auto-repeat, and be able to set the repeat speed as well as the delay before repeating begins. I've done this many times over the years. It's not super complicated, but probably beyond the scope of your project. You don't need to implement that, but de-bouncing is mandatory if you are storing keypresses in a key buffer. So far we have not gotten into muli-key combinations either, like shifted keys where you hold the shift key down while pressing another key, or doing 2-key rollover.
After the ENTER key is pressed (which you verify by comparing the PB value to that of the ENTER key), it sounds like you can disable the interrupts (either with the IER or by making all the columns high), then, when the background program is ready, have it turn off the CA2 interrupt by doing a dummy read of PA, and re-enable the CA2 interrupt in the IER. If the end of the key buffer in memory is reached before ENTER has been pressed, you will probably want to turn off the interrupts then as well.
Each time a key is pressed, you will record its value (read from PB-- again, not PA) with an STA ZP,X instruction, and increment X each time. When the background program is ready to re-enable interrupts after the ENTER key is pressed, it will set the X value back to the beginning of your key buffer so the first subsequent keypress gets recorded at 0050. Note that the ISR will need to keep its own record of the X value somewhere in memory since the background program would also need X and overwrite it.
|