Phantom keypresses on Oric keyboards

If you want to ask questions about how the machine works, peculiar details, the differences between models, here it is !
How to program the oric hardware (VIA, FDC, ...) is also welcome.
User avatar
Chema
Game master
Posts: 3020
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Phantom keypresses on Oric keyboards

Post by Chema »

Hi again,

Fabrice Frances detected a strange behaviour in the Oric keyboard when testing 1337 and our keyboard scanning routine.

I am sure he would not mind if I post here his conclusions
Fabrice Frances wrote:On the real keyboard, when you press 3 random keys on the keyboard matrix, you might sometimes get 4 bits set to 1 in your display.

This happens when the 3 keys are 3 points of a rectangle in the keyboard matrix.

So, if 3 and Q are pressed simultaneously, no problem, they are detected.
Now, if X is added, we detect 3, Q, X and D. And if we press D instead of X, both are detected too.
Same thing if 3 and D are pressed first (they are correctly detected) : as soon as we add X or Q, both X and Q are also detected.

And the same behavior happens if you take 3 keys on any other rectangle in the matrix : for example if you press X, G and 5, you will also detect S.
The explanation:
Fabrice Frances wrote:When you press a key, this has the effect to put in contact the row and the column. And when you test a key, you put a 0 (ground) to the desired column, and you sense the row level (the level is inversed by a transistor before reaching the PB3 input).
Now imagine that I simultaneously press keys 3, 1 and C, and that I want to test if Z is pressed: I apply a zero level to column PA5, and I sense row #2... Z is not pressed so there's no direct contact between column 5 and row 2, but... there's a contact between column 5 and row #0 (because key 1 is pressed), so row #0 is also at ground level... and there's a contact between row #0 and column PA7 (because key 3 is pressed), so column #7 is forced to ground level **even though you have put a 1 in this column bit** (bit 7 of the PSG IO port) ! You can now see the end of the story : since column #7 is forced to ground, and since there's a contact between column #7 and row #2 (key C is pressed), you sense row #2 and see a zero level... and thus wrongly conclude Z is pressed...
So basically it is something that cannot be avoided by software. Furure programs should select carefuly the keys to use.

The other interesting bit is that the routine posted here:
http://miniserve.defence-force.org/svn/ ... /keyboard/
works perfectly as is, with no extra waiting cycles or something, tested on Symoon's oric and also on Fabrice's atmos and oric-1.
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte »

Chema wrote:Furure programs should select carefuly the keys to use.
I would amend that slightly and say "Furure programs(such as a ZXSpectrum emulator) that require multiple keypresses should select carefuly the keys to use." because in general practice its never an issue 8)

Note the ZXSpectrum rubber keys model was a classic machine for expecting you to be able to stretch fingers to 2,3 or even 4 key combinations in one keypress in order to select keywords or commands.

I never had this issue when i wrote zipnzap all those years ago. Though that set all the columns to zero and had qazx for left player and ./]' for right player simultaneously :P

Also afaik the PC keyboard can only detect up to 3 simultaneous keys down regardless the emulator reading it.
This was confirmed by Fabrice years ago when i was working on the keys for Wave and wanted to use Shift + Funct(Alt) + Key and stuff like that.
User avatar
Chema
Game master
Posts: 3020
Joined: Tue Jan 17, 2006 10:55 am
Location: Gijón, SPAIN
Contact:

Post by Chema »

Twilighte wrote:
Chema wrote:Furure programs should select carefuly the keys to use.
I would amend that slightly and say "Furure programs(such as a ZXSpectrum emulator) that require multiple keypresses should select carefuly the keys to use." because in general practice its never an issue 8)
Of course, I meant when you want to detect multiple keypresses (for example jump+left+fire, you don't want the game to detect also the pause or abort key...). In 1337 you can press several keys a the same time (you can be rotating in two or three axes while firing for instance). There is a combination that also produces the ESC key to be detected, which would launch the escape pod ruining your current game. Fortunately, the ESC key (same as others) are detected differently (not simultaneously) and this never happens...
Also afaik the PC keyboard can only detect up to 3 simultaneous keys down regardless the emulator reading it.
This was confirmed by Fabrice years ago when i was working on the keys for Wave and wanted to use Shift + Funct(Alt) + Key and stuff like that.
Mmmm... not sure. I have tested my keyboard virtual matrix demonstration program and under DosBox+Euphoric you can detect more than five simultaneous keys for sure...

Anyway, just an interesting bit of info, more than something really useful.
User avatar
Twilighte
Game master
Posts: 819
Joined: Sat Jan 07, 2006 12:07 am
Location: Luton, UK
Contact:

Post by Twilighte »

Chema wrote:Of course, I meant when you want to detect multiple keypresses (for example jump+left+fire, you don't want the game to detect also the pause or abort key...).
True however cannot some logic take place here?
For example Pause and Abort should actually have the lowest priority and therefore should sit at the end of the key comparison code.

For me if i'm expecting lots of keys i will place their codes in a table and match the index to two more tables with a vector to jump to when detected. If small number of keys then i'll use code instead to check each key code in turn.
Either way its possible to put the check for Abort or Pause at the end.

Also if your program is expecting different key combinations to do different things then detect the actual keypresses themselves by embedding the keys into a matrix or single byte.
For example on occasions i've stored the joystick controls in a single byte where left is bit0, right bit1, fire bit2 etc.
Then when your looking for Jump+Left+Fire you'll look for say %01000110.
Now Pause and Abort is only likely to be pressed with all other keys up so look specifically for it.
For example if pause was bit 5 (00100000) then we'd do a comparison on exactly that with all other keys expected to be up.

Take for example a game that requires 11 keys. We represent each key as a single bit so 2 bytes are needed.
Byte0
Bit 7 Abort
Bit 6 Pause
Bit 5 Jump
Bit 4 Down
Bit 3 Up
Bit 2 Fire
Bit 1 Right
Bit 0 Left
Byte1
Bit 7 Drop
Bit 6 Pickup
Bit 5 Secondary fire

Assuming that Fire+Left+Jump also falsely indicates Abort as in the example given by Chema a while ago, we should only detect as follows

Code: Select all

LDA Byte0
AND #%00100101
CMP #%00100101
BNE NotFound
FoundFireLeftJump
Thats what i would do anyway 8)
Post Reply