6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 09, 2024 8:22 am

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Thu Feb 02, 2023 10:15 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 443
Hi Forum,

I wrote a whole post. I'm going to go ahead and share it, as a kind of tribute. Because I had my target audience in mind (you guys) while writing it I took some trouble to rewrite it a few times, and go back and double check what I was saying. While doing that, I looked at what I wrote about the key repeat sequence ($75, $75, $75) and thought "boy, things sure would be easier if it resent the '$E0' code every time instead of just at the beginning and the end. Then I thought "wait, does it actually do that? You just *wrote* that, you didn't actually check for sure." So I went to check it for sure. And Lo! It sends $E0 with every key-repeat! Hot dog. My cursor keys are now working with one extra flag bit and a few extra instructions in the "key release" routine. Plus, it's extensible if I want to add some other $E0 keys in the future (like CTRL and ALT) that I'm not currently using.

So... thanks for being you guys! Just being present in my imagination helped me clear up a problem without actually having to pester you.

At Ed's suggestion, here's what an extended key repeat sequence really sends:

Code:
$E0, $75,<$E0, $75, $E0, $75, $E0, $75...>,$E0, $F0, $75
^    ^    ^                                ^    ^    ^
|    |    |                                |    |    |
|    |    |                                |    |    +-- scan code
|    |    |                                |    +------- break code
|    |    |                                +------------ extended code
|    |    +--------------------------------------------- key repeat
|    +-------------------------------------------------- scan code (make code)
+------------------------------------------------------- extended code



=-=-=-=-= ORIGINAL POST BELOW =-=-=-=-=

Ben Eater's keyboard driver isn't very good. Let's let him off the hook... his code is suppose to be a starting point to get people thinking and making their own better versions. I did that. For example, Ben's version does a lot of processing in the ISR; I didn't want that, so my ISR just grabs the scan-code from the keyboard and saves it in a buffer for later dispatching. I bet most other people also made this change - it's kind of low hanging fruit.

Another thing about Ben's version is the way it handles the SHIFT keys. It has a SHIFT flag. The handler routine for SHIFT sets the flag on make and clears it on break. At least, that's what you would think. Actually what it does is that it *flips* (eor) the flag on make *or* break. This would work fine if there was only one SHIFT key, but since there are two the make/break sequences can overlap and you can get weird effects. In my version there's a separate flag for each SHIFT so overlapping sequences don't interpret <RSHIFT DOWN>,<LSHIFT DOWN> as <SHIFT DOWN, SHIFT UP>.

I just got to the point in my code review that I want to add cursor / arrow key functionality. Here's how this works:

When you push a key, let's say numpad key scan-code $75, the PS2 keyboard sends a make code (that scan-code). If you hold the key down it will send it again (key repeat) until you let go the key. Then it will send a break code ($F0) followed by the scan code again. So a typical key-press is 3 bytes: $75, $F0, $75.

For some keys - the cursor keys in particular - the keyboard re-uses certain scan-codes and prepends them with a special "extended" code: $E0. The cursor keys are just the numpad key scancodes for '2,' '4,' '6,' and '8' sent following the E code. The thing is, on key release the keyboard sends the modifier code before it sends the break code. This seems backwards to me; the break code means "release what comes next," so shouldn't it be $F0 (release) $E0 (the extended) $75 (numpad key)? Anyway.

Code:
$E0, $75,<$75, $75, $75...>,$E0, $F0, $75
^    ^    ^                 ^    ^    ^
|    |    |                 |    |    |
|    |    |                 |    |    +-- scan-code
|    |    |                 |    +------- break
|    |    |                 +------------ extended
|    |    +------------------------------ key repeat
|    +----------------------------------- scan-code
+---------------------------------------- modifier


You can probably see the difficulty. If you are pushing a lot of arrow keys, say, quickly navigating around a text screen (or playing a game... ha!) it's likely that key-presses will overlap with key-releases. So you will get, e.g.:
Code:
$E0, $75, $E0, $72, $E0, $F0, $75, $E0, $F0 $72
^         ^         ^              ^
|         |         |              |
|         |         |              +-- E OFF
|         |         +----------------- E ON
|         +--------------------------- E OFF
+------------------------------------- E ON


For any particular $E0, there's no way to tell on the spot if it means "interpret the next scan code as extended" or "release the previously extended scancode."

I could set flag on the first $E0, then ignore all subsequent $E0s, until $E0 is cleared. Then have a separate "key-down" flag for each key that sends $E0, just like I do with SHIFTs. The key-release routine would check ALL of those flags, and only clear the $E0 flag once every extended key has been released. Of course, then there's a new problem to solve... what happens when a keypress that should never be extended [*] (say, numpad 8) but that shares a scancode with one that is extended overlaps with some extended keypress (say, cursor right)? You will get "right, up" instead of "right, 8." It's the opposite problem.

Another try that almost works is to clear the E flag every time you test it. That handles both kinds of overlapping key-presses, but it breaks key-repeat.

Thinking about the amount of code involved in handling just these 4 keys makes my morale sink. I can't help but wonder if there's a more elegant way to do this.

[*] Actually, numpad keys can be modified by num-lock, but let's save that for later!

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Last edited by Paganini on Fri Feb 03, 2023 5:21 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 03, 2023 7:17 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
That's quite the result - rubber-duck debugging.

The only comment I'd make, is that your diagrams show what you feared, rather than what you subsequently found. Because many readers will skim, your head post will be a much better landing page if you added the what-actually-happens picture in your preamble.

(It's a good title, and a good subject, and might well be a top search result for years. Make it live up to that possibility!)


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 03, 2023 5:15 pm 
Offline

Joined: Fri Mar 18, 2022 6:33 pm
Posts: 443
Good idea Ed! I'll do that.

_________________
"The key is not to let the hardware sense any fear." - Radical Brad


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: