tmk / tmk_keyboard

Keyboard firmwares for Atmel AVR and Cortex-M
3.98k stars 1.7k forks source link

[ibmpc/xt] Firmware incorrectly maps < & > to ' * for XT keyboards #702

Closed Drag0nFly closed 3 years ago

Drag0nFly commented 3 years ago

The TMK firmware (tested several versions) appears to re-map the "<" key (to the right of the Left shift) as ' (tick). This only occurs when the keyboard is in XT mode. If it's in AT mode the mapping is correct.

Conversely, the | and § key (on the top-left, next to 1) outputs "<" & ">". (A common problem is that these are switched, but this is not completely true with the TMK, which outputs ' & * instead, meaning there are two keys which outputs identical characters on "extended" ANSI layouts)

With the Soarer, the keys are mapped correctly (i.e, < > and | §)

Output from hid_listen showing which keycodes are registered; for the < + > (shift + <): (which outputs ' *

Waiting for device:
Listening:
r56 'rD6 r36 r36 r56 *rD6 rB6

Output from hid_listen when pressing the | + § keys (which outputs < >)

r29 <rA9 r36 r29 >rA9 rB6

Note that | and § are not switched (common mistake, ref. OSX, maybe other OS-es), but that ' * are output (which there is a dedicated key for on this keyboard, on row 2 due to the “big ass Enter” key.

tmk commented 3 years ago

What keyboard are you refering to? Can you post a pic or a link? And let me know your OS and keyboard layout on computer?

As far as I know IBM didn't define XT scan codes for those international keys officially. So internatioanl keyboard support is likely to dependent on manufacturer.

TMK firmware is basically compliant with this old 'scan code translation table' published by Microsoft. https://web.archive.org/web/20090206085854/http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf

In TMK converter XT scan code(Set 1) 0x29 is handled as ` ~ key(on US layout) and 0x56 as Non-US \and |.

IBM XT key XT code(Set1) USB HID key USB HID code Desc
~ # 0x29 `~ 0x35 located near Enter on IBM XT
\ | 0x2B \ | 0x31 located near Left Shift key on IBM XT
< > 0x56 Non-US \and | 0x64 Not exist on IBM XT

Refer this for IBM XT keyboard layout: https://www.seasip.info/VintagePC/ibm_1501105.html

Drag0nFly commented 3 years ago

Hasu–this is the issue I referred to on geekhack. The layout is probably not official, as it is a combination of US ANSI (big-ass enter) and ISO. The keyboard is a NTC KB-6252EA – https://images.finncdn.no/dynamic/960w/2021/7/vertical-0/26/4/226/105/014_2034820777.jpg

It works with the same extended layout on multiple OSes – Linux, OSX.

The keys affected is the 0x56 XT code in your table above, and the | & § key (which is on the upper left-hand side, right under Escape on ISO keyboards)

It must be adhering to some kind of standard, as the Soarer firmware handled it without issues, as well as a PS2-to-USB keyboard+mouse dongle (Aten branded).

I mentioned IBM as this is the firmware on the TMK adapter, not based on the layout. Hopefully the picture above makes it clearer. :)

tmk commented 3 years ago

Thanks for the pic. It is useful for future reference.

Is there the problem on Windows or Linux also? only on MacOS? I have heard key swapping problem like this on MacOS from some users.

Please share Soarer's coverter hid_listen log to see how it converter the keys. I don't know how Soarer's handle the keys but Aten is not related here because it is PS/2(AT) converter, not XT. Are you sure that you are using default keyamp and you didn't edit or load keymap on Soarer's before? On Soarer's converter keymap data is stored in EEPROM and is not removed even if you flash TMK or other firmware.

Again, what's your keyboard layout on computer? I'm using US keyboard layout on Linux, the | § key(USB HID: 0x35) would register `~ there. Like that, which charactor a key registers depends on your keyboard layout setting and OS. So I want to know those informations.

And do you know what language the keyboard was designed for ? I guess Danish or Swedish?

Drag0nFly commented 3 years ago

The issue is the same on Linux and OSX, except that OSX switches the | § and < > keys for every non-ANSI keyboard (it has a bug which defaults to ANSI) (in this case the ' * and < > are switched)

The behaviour above is from Linux, where it works as it should. The layout is extended ISO 105-key (Norwegian).

I'll include a hid_listen capture when using the Soarer (sorry–thought I did this, but apparently the above output is from using the TMK.)

Lastly, I am only using default keymaps, nothing has been edited. (Not really an option as I would have to do this on a number of systems.)

tmk commented 3 years ago

That is exactly what I expected. Thanks for the explanation. I just found a bug in my code and the Microsoft translation table is not useful for ISO keyboards. I think I got a clue to solution now. (EDIT: Microsoft table is correct. 2021-08-16)

As for key next to backspace on the keyboard, what XT scan code it sends and what charactor it register?

Translation in current implementation:

XT key XT code USB HID key USB HID code Desc
~ # 0x29 `~ 0x35 near Enter on IBM XT keyboard
\ | 0x2B \ | 0x31 near Left Shift key on IBM XT keyboard
| § 0x29 `~ 0x35 near 1 on other ISO keyboards
< > 0x56 Non-US # ~ 0x32* near Left shift key on other ISO keyboards

*: this is a bug and should be 0x64.

Translation ISO-preferable :

XT key XT code USB HID key USB HID code Desc
~ # 0x29 Non-US # \~ `~ 0x32 0x35 near Enter on IBM XT keyboard
\ | 0x2B Non-US \ | 0x64 0x31 near Left Shift key on IBM XT keyboard
| § 0x29 Non-US # \~ `~ 0x32 0x35 near 1 on other ISO keyboards
< > 0x56 Non-US \ | 0x64 near Left shift key on other ISO keyboards

(EDIT: I was confused. Microsoft table is correct in the end. 2021-08-16)

This translation may not work for US layout users by default. I'll look into a bit more.

Drag0nFly commented 3 years ago

Here's the hid_listen debug output when the keyboard is in XT mode connected to the Soarer:

Key next to backspace: (outputs ' and * with Shift)

\'

r2B +31 d31 '
rAB -31 u31

* (w/ shift)

r36 +E5 dE5
*r2B +31 d31
rAB -31 u31
rB6 -E5 uE

< (right of left shift)

r56 +64 d64 <
rD6 -64 u64

> (w/ shift)

r36 +E5 dE5
>r56 +64 d64
rD6 -64 u64
rB6 -E5 uE5

| (below Escape):

r29 +35 d35 |
rA9 -35 u35

§ (w/ Shift):

r36 +E5 dE5
§r29 +35 d35
rA9 -35 u35
rB6 -E5 uE5
tmk commented 3 years ago

I assmume that the Soarer's behaviour tested on Windows or Linux, right?

So Soarer's translation is like below. XT key XT code USB HID key USB HID code Desc
# ~ (| §) 0x29 ` ~ (| §) 0x35 near Enter on IBM XT
near 1 on Norwegian
\ | (' *) 0x2B US \ | (' *) 0x31 near Left Shift on IBM XT
near Backspace on Norwegian keyboard
(< >) 0x56 Non-US \ | (< >) 0x64 Not exist on IBM XT
near Left Shift on Norwegian keyboards
And I believe this is current TMK translation. XT key XT code USB HID key USB HID code Desc
# ~ (| §) 0x29 ` ~ (| §) 0x35 near Enter on IBM XT
near 1 on Norwegian
\ | (' *) 0x2B US \ | (' *) 0x31 near Left Shift on IBM XT
near Backspace on Norwegian keyboard
(< >) 0x56 Non-US # ~ (? ?) 0x32 Not exist on IBM XT
near Left Shift on Norwegian keyboards

So TMK problem is the <> key only(on Linux or Windows), right? What character does the <> key register on Windows or Linux using TMK converter?

I think I was confused with MacOS swap problem you refered at same time. Let's forget MacOS temporarily here.

Drag0nFly commented 3 years ago

I think you were right the first time (your first table), as it only affects the "<" key (which should send USB HID code 64). I did another test now with the most recent (AFAIK) TMK firmware. (and yes, let's definitely forget OSX–I mentioned it as this issue is somewhat similar)

All tests are done on Linux.

So with your firmware, the "<" key (to the right of the left shift), outputs ' (tick). With shift, it outputs (asterisk). As you noticed earlier, there is also a dedicated key for ' & on this layout (next to backspace), and it works as expected with the TMK firmware in XT mode.

hid_listen capture when using your adapter / TMK firmware:

Device disconnected.
Waiting for new device:.......................
Listening:

TMK:44ee4f/LUFA:d6a7df

USB configured.

Loop start.
I336
338 PRT:22 ISR:AAC0 rAA A3337 wFF R R R R R R R R R R
3729 ERR:11 ISR:0000 X4230 rAA W4232 wF2 R R R R R R R R R R R5125
ID:FFFF(XT)
5125 ERR:11 ISR:AAC0 S5126 L5126

r56 'rD6

r36 r*56 rD6 rB6

r29 |rA9

r36 r29 §rA9 rB6

As you see, r29 and r36 are correct. I am unsure why | § was not registering correctly with the initial capture. But hopefully this clears things up a bit.

tmk commented 3 years ago

That result is reasonable for current TMK implementation, which has a bug on the <> key.

Just fixed code for the <> key. Try this firmware. https://github.com/tmk/tmk_keyboard/blob/copam_k430_test/converter/ibmpc_usb/binary/ibmpc_usb_atmega32u4.hex

New TMK firmware should behave like below, as same as Soarer's does and Microsoft describes.

XT key XT code USB HID key USB HID code Desc
# ~ (| §) 0x29 ` ~ (| §) 0x35 near Enter on IBM XT
near 1 on Norwegian
\ | (' *) 0x2B US \ | (' *) 0x31 near Left Shift on IBM XT
near Backspace on Norwegian keyboard
(< >) 0x56 Non-US \ | (< >) 0x64 Not exist on IBM XT
near Left Shift on Norwegian keyboards
Drag0nFly commented 3 years ago

Sorry for the late update; I can confirm that your commit fixes the issue and that "<" / ">" is now properly output in XT mode for the key next to the left shift on this ISO (NO) layout keyboard – thanks!

Verified the other keys as well, and everything appears to be correctly mapped.

btw., there is a (cosmetic) error in the table above showing backtick instead of tick (` ) vs. (' )

It is only cosmetic, as the correct character is output with your firmware – i.e, ' (tick). :) Just thought I'd mention it to avoid future mixups.

Anyway, I think the ticket can be closed. Thanks for your assistance as always! 👍

tmk commented 3 years ago

Thank you for the test.

I'll update main repo and prebuilt firmware files of IBMPC converter soon later.