• Please review our updated Terms and Rules here

Apple II emulator keypress handling

mechaniputer

Experienced Member
Joined
May 23, 2015
Messages
59
Hi folks,

I'm working on my Apple II emulator and writing my own monitor ROM from scratch. I have some doubts about how key repeat was done on a real Apple II. Did the hardware prevent too-fast repeats (and take care of debouncing) or was this something that the ROM had to take care of (for instance by timing how long a key is held before starting to repeat it)? In any case, my ROM can do that now, but I wonder if it is really supposed to. I've looked at original ROM listings to try to see how it was done, but I haven't seen the answer jump out at me yet. Which is why I suspect some hardware measures were involved. If that is the case, I'll go back and do it in (simulated) hardware instead. Saves some bytes.

In case it matters, my emulator is intended to match the behaviors of the original 1977 Apple II.

Thanks.
 
Key repeat on the Apple II was done by the keyboard encoder (dedicated microcontroller), not in the Apple II ROM.
 
Key repeat on the Apple II was done by the keyboard encoder (dedicated microcontroller), not in the Apple II ROM.
That's what I suspected, but then my question is what about games that needed a key held down for movement? They don't seem to be affected by repeat delay. Was there a way for software to disable repeat delay?
 
That's what I suspected, but then my question is what about games that needed a key held down for movement? They don't seem to be affected by repeat delay. Was there a way for software to disable repeat delay?
I just looked at the monitor ROM listing, looks like key repeat is a function of holding the key down and the keyboard strobe being reset when the key is read. So the keyboard will still show a key being held down, but the strobe won't be enabled, allowing software to read held down keys.
The repeat key (REPT) likely pulses the keyboard strobe to repeat the key being held down on the apple II.
 
So in summary:

When a key is held (any "normal" key including alphanumeric, space, CR, etc), the keyboard hardware will write the value to $C000 with strobe once. The value at $C000 will not be cleared unless the key is released, except that the strobe bit may be cleared if $C010 has been read. After a human-perceptible "moment", it goes into repeat mode, in which it will resume setting both the key value and the strobe at a sane interval for key repeat.

This permits the software to always check whether a key is still held, even when the strobe is not being refreshed (during the repeat pause).

Is that what you mean? It makes sense. Just want to confirm.
 
Here's a book that details much of the behavior of the Apple II system. Chapter 7 has a pretty complete description of how the Apple II's keyboard scan works, including what the AY3600 keyboard controller was doing.

I've only scanned it, but it looks like "debounce" was mostly taken care of by the keyboard controller, which had an 8ms key-held-down delay before it would fire the keyboard strobe for a key. As for detecting whether a keyboard key is just constantly held down (without REPT)... I know this is a dumb question, but can the original Apple II even *do* that ? The documentation in the book and for the AY3600 implies that once a strobe has been fired for a keypress event that key is locked out from triggering strobe again *and* the same value stays set on the output pins. (Unless you hit REPT, in which case the strobe is fired at the rate determined by a 555 timer pulse.) For laughs I fired up an Apple II emulator and ran a loop peeking $C000 and it looks to me as if you're going to see the last key pressed there whether or not you're still holding it down. (Clearing the probe just unsets bit 7, it doesn't change the value on the lower 7 pins.)

I remember a lot of Apple 2 games you played with a keyboard did a thing where instead of holding down a key to move a direction you'd hit a key to *start* movement and a different key to stop, *or* you'd have to pound the key repeatedly. From this book I'm not sure just watching a hold down is even a thing you can do.

(Digging around you *may* be able to do it on the IIe and up, because there's a way to read an "any key is held down" signal?)
 
Here's a book that details much of the behavior of the Apple II system. Chapter 7 has a pretty complete description of how the Apple II's keyboard scan works, including what the AY3600 keyboard controller was doing.

I've only scanned it, but it looks like "debounce" was mostly taken care of by the keyboard controller, which had an 8ms key-held-down delay before it would fire the keyboard strobe for a key.

So that's debounce, but what about key repeat delay? Like if you hold "A", there's a brief pause before it goes into full speed repeat, right? Was that in hardware? Or did the original only support manual use of the "REPT" key? I only have IIe's in my collection, which have automatic key repeat without a dedicated key.

For laughs I fired up an Apple II emulator and ran a loop peeking $C000 and it looks to me as if you're going to see the last key pressed there whether or not you're still holding it down. (Clearing the probe just unsets bit 7, it doesn't change the value on the lower 7 pins.)

Alright. Does anyone have an original 1977 Apple II they could try this out on? Just to confirm that $C000 always shows the key last pressed even if it has been released and the strobe has been cleared by accessing $C010?
 
Like if you hold "A", there's a brief pause before it goes into full speed repeat, right?

I don’t think there was, no. Why would they have a repeat button on the keyboard if they had auto-repeat?

I don’t have an original 1977 II but I do have a II+, it’s just kind of a pain to set it up at the moment.
 
I don’t think there was, no. Why would they have a repeat button on the keyboard if they had auto-repeat?

This is a good point...

Thanks for the advice. I plan to do the following:

On a keypress event, the emulator frontend will set $C000 with key value and strobe, and will not take further action until another key is pressed or the current key is released and pressed again. REPT key will reset bit 7 (at 15Hz) without changing the other bits. Maybe I'll map the alt key as REPT.

The emulator backend will only clear bit 7 of $C000 when $C010 is read, but the other 7 bits stay as they were.

And the ROM code will be ignorant of all of this, merely watching for the strobe bit to achieve sane behavior.

Perhaps someday I'll try my ROM on real hardware to see if I got it all right.
 
Back
Top