Classic Computer Magazine Archive COMPUTE! ISSUE 95 / APRIL 1988 / PAGE 43

Redefining The ST Keyboard

I'm an Atari 520ST owner from Sweden and I wish I could print the characters å, ä and ö. I wonder if there is any way to redefine three keys, for instance [,], and \, so when I press one of these keys, å, ä and ö will appear.

Johan Melander

It's certainly possible to redefine the keyboard map. Within the ST ROMs is an XBIOS function called Keytbl(), which resets the pointers to the translation tables used to convert keyscan codes into ASCII character codes. To use it, first set up three arrays of 128 characters, one array each for normal characters, Shift characters, and Caps Lock characters. Next, call Keytbl(), passing the addresses of the three arrays. The keys will be redefined from that point forward.

One small problem is that when the keyboard redefinition program ends, the conversion table is normally erased, which locks up the keyboard or causes it to print strange characters when you type. The solution is the Ptermres() function, which tells the operating system that the current program is to "terminate but stay resident." The program ends, but it's not erased from memory.

The keyscan codes for the keys labeled [,], and \ are 91, 93, and 92 respectively. The ST's character codes for å, ä, and ö are 143, 142, and 153 for the uppercase versions of these characters, and 134, 132, and 148 for the lowercase versions.

You can use virtually any language except ST BASIC to write the program that calls Keytbl() and Ptermres(). Here's an example written in C:

#include <stdio.h>
#include <osbind.h>
static char nk[3][128];
struct table{
   char *norm;
   char *shift;
   char *caplock;
} *keys;
main(){
int i, j;
char *(m[3]);
long mem;
  appl_init();
  keys = (struct table *) Keytbl(-1L, -1L, -1L);
  m[0] = keys->norm;
  m[1] = keys->shift;
  m[2] = keys->caplock;
  for(i = 0; i < 3; i++)
    for(j = 0; j < 128; j++)
      nk[i][j] = *(m[i] + j);
  nk[0][26] = 134;
  nk[0][27] = 132;
  nk[0][43] = 148;
  nk[1][26] = nk[2][26] = 143;
  nk[1][27] = nk[2][27] = 142;
  nk[1][43] = nk[2][43] = 153;
  Keytbl(nk[0], nk[1], nk[2]);
  appl_exit();
  Ptermres(12000L,0);
}

The 12,000 bytes reserved for the program and variables in the last line should be sufficient. If your version of C allows you to determine the actual memory used, you could calculate the size of the program and its variables and substitute that value in the Ptermres() function. Once the keys are redefined, they'll stay that way for word processors, languages, games, and so on, until you reset or reboot your ST.