Saturday 11 May 2019

grub4dos and non-USA keyboards

Together with Knyght, we have been working on supporting the Hungarian language and Hungarian keyboard for E2B.

E2B v1.B1c Beta includes the latest grub4dos version which adds even more Alt+ key support.

E2B uses grub4dos which, in turn, uses the BIOS to receive key codes from the keyboard. Unlike grub2, it does not have it's own keyboard interrupt handler.

A Hungarian 102-key keyboard produces the same keyboard scan codes as a USA 102-key keyboard or any other 102-key keyboard, the only difference is the engraved letters on the key tops.

This means that grub4dos must 'convert' the keyboard code it receives to generate the same character that is engraved on the key tops. For instance, when the key labelled " on a UK keyboard is pressed (shift+2), it should produce the " character and not the @ character that you would see if the keys had USA keyboard key tops.

grub4dos allows us to 'map' key codes using the setkey command. For instance, E2B uses a batch file to run a series of setkey commands to convert USA key codes to UK key codes:

errorcheck off
#clear all settings
#setkey [new character] [QWERTY-USA character]
#change key map for UK keyboard
setkey at doublequote
setkey doublequote at
setkey tilde bar
setkey numbersign backslash
echo UK KBD MAP SET %redir%

You can find these KBD_* files in the \_ISO\e2b\grub folder.

The KBD_LATIN_USA.g4b map file is new. If you would like an option for this in the Make_E2B.exe GUI, please let me know what language you would like to use it with (e.g. Spanish, Brazil-Portuguese, English?).

Alt key codes

Some keyboards, such as Hungarian and Latin-American, etc,  can only produce some of the 'standard' US ASCII key codes when the AltGr key is used together with another key.

For instance, the Latin-American (Spanish) keyboard requires you to press AltGr+q to produce the @ symbol. Note that under grub4dos, Alt+q, AltGr+q and Alt+Shift+q all produce the same key code of 1000 hex.

You can determine the grub4dos key code by using the commands at the grub4dos console (the first command 'setkey' clears all key code mapping, otherwise you may see the translated key code if one was set by a previous setkey command):
pause --test-key
(now press a key or key-chord to see the grub4dos key code)

Previous versions of grub4dos did not support the mapping of Alt+ keys, but the latest version in E2B v1.B1c now does if we precede the unshifted key name with an A (e.g. Aequal).

So we can use:
setkey at Aq
to produce the @ symbol when AltGr+q is pressed, and
setkey backslash Aminus
to produce the \ symbol when AltGr+- is pressed

The extra key between left-shift and the Z key is the 'oem102' key. We can now also change this key code using the key names oem102 and shiftoem102  (Aoem102 and Ashiftoem102 is not supported because the BIOS does not support it).

setkey less oem102
setkey greater shiftoem102

Grub4dos batch file to list KBD files

The latest E2B v1.B1c Beta contains a grub4dos batch file which lists all files in the \_ISO\e2b\grub folder which begin with "KBD_" and then allows the user to select and run any one of them. It is called by a new .mnu file which can be added into your menu system (the Pimp_my_Drive.cmd script will also add it in for you).

The batch file code was rather tricky because grubdos does not support the use of wildcards with the 'ls' command (e.g. ls KBD_* or ls KBD_*.g4b does not work). Also I wanted the user to be able to type in a number to select from the list of KBD files rather than have to type in the full name of the file.

ls /_ISO/e2b/grub/ > (md)0x220+5
#clear all variables
set *
set skip=0
set count=0
#don't abort if error so that endlocal is always run
errorcheck off

#get files beginning with KBD_ into variables K0, K1, K2, etc.
cat --locate=KBD_ --skip=%skip% --number=1 (md)0x220+5 > nul || goto :fin
set skip=%?%
cat --locate=\x20 --skip=%skip% --number=1 (md)0x220+5 > nul || goto :fin
set fend=%?%
set /a fl=%fend% - %skip% > nul
cat --skip=%skip% --length=%fl% (md)0x220+5 | set A=
call set K%count%=%A%
set skip=%fend%
set /a count=%count%+1 > nul
goto :lp1

echo -e =====================================\n
set K
set ask=
set /p /u ask=Choose a KBD file (e.g. "K0" or "0") : 
if "%ask%"=="" goto :EOF
if /i not "%ask:~0,1%"=="K" set ask=K%ask%
echo -e -n !BAT\nset f=\x25%ask%\x25 > (md)0x220+1
call (md)0x220+1
#assume keyboard is bad if user types a bad number and reset key map
if not exist /_ISO/e2b/grub/%f% pause --wait=2 ERROR: Resetting keyboard map... && setkey > nul && goto :fin1
if not exist /_ISO/e2b/grub/%f% pause ERROR: %ask% NOT FOUND! && goto :fin1
echo Running /_ISO/e2b/grub/%f%...
#ensure no error checking in case using older grub4dos
errorcheck off
call /_ISO/e2b/grub/%f%
pause --wait=3 > nul

Note that I use the 'set K' command to list all grub4dos environment variables that begin with 'K'. Since we used 'set *' after the 'setlocal' command, the only variables beginning with K will be the ones we have set as the keyboard file names.

Because grub4dos has a limit of about 60 variables, this code will only work correctly if there are less than about 50 KBD_* files. It also won't work correctly if there are spaces in the filenames.

If you have a non-USA keyboard, please test E2B v1.B1c Beta or later (use a real system - do NOT test under QEMU or VirtualBox as they produce the wrong key codes for some keys!).

No comments:

Post a Comment