koreth@ssyx.ucsc.edu (Steven Grimm) (02/25/89)
Submitted-by: uunet!mcvax!cwi.nl!eddy (Eddy Boeve) Posting-number: Volume 2, Issue 14 Archive-name: keyfix Here is a program to fix the 'gulam.prg' binary for non-american keyboards. You do not have to edit the program, just run it. The program does the rest. The binary is also being posted in comp.binaries.atari.st. /* * keyfix.c -- Utility for Gulam * * Original version: copyright (c) 1986, 1987 pm@cwru.edu * * Rewrite : eddyright (e) 1989 eddy@cwi.nl * * This is an utility for GULAM to patch the default key bindings * in the 'gulam.prg' binary. It was originally created by * 'pm@cwru.edu' to change the USA key bindings for us Europeans * and contained a 3*128 table with the desired new bindings. * * This version is different because you don't have to edit it for * your own machine. It works out for itself what keys produce what * characters. * * This program takes your default key translation tables via the * XBIOS function 'Keytbl' and adds the GULAM function, arrow and * keypad key translations. (Why Gulam doesn't do this is unclear). * If you already have a USA key binding, everything will stay the * same. Otherwise the '@~#\|$' keys will hopefully appear under the * right button. * * Compile 'kmpfix.c'. Run the resulting program from the directory * that contains the 'gulam.prg'. * The new version of 'gulam.prg' (with the new key mapping) will be * written out as 'gulamnew.prg' in the current directory. * * Below we define ST520/1040 keynames; the values are the ascii codes * returned by ST BIOS. * * The values below are chosen to have certain patterns: * * to SHIFT add 0040 * F1-10 0201 to 0212 * keypad 0-9 0260 to 0272 (subtract -0200 to get ascii digits) * keypad()/ *-+.cr add 0300 to the ascii ()/ *-+.cr * * Other choices may be better, I don't know. However, I think it is * unwise to use numbers in the range 0000 to 0177, because they are * regular ascii codes. * * If you want to change some bindings, do it in the routine * 'copy_map': * kn['scan_code'] = 'ascii_code'; * * Exit values: * 0 : No errors, * -1 : Error in finding key map in binary, * -2 : Error in memory allocation, * -3 : Error in file reading/writing. */ #include <osbind.h> #include <xbios.h> #include <bios.h> #define GULAM_SIZE (100000L) /* Number larger than size gulam * program (in bytes) */ /* * These 'KC_' scan code values are not defined in <bios.h> */ #define KC_KLP 0x63 /* Keypad ( */ #define KC_KRP 0x64 /* Keypad ) */ #define KC_KSTAR 0x66 /* Keypad * */ #define KC_KPLUS 0x4E /* Keypad + */ #define KC_KENT 0x72 /* Keypad Enter */ #define KC_KMINUS 0x4A /* Keypad - */ #define KC_KDOT 0x71 /* Keypad . */ #define KC_KSLASH 0x65 /* Keypad / */ #define KC_K0 0x70 /* Keypad 0 */ #define KC_K1 0x6D /* Keypad 1 */ #define KC_K2 0x6E /* Keypad 2 */ #define KC_K3 0x6F /* Keypad 3 */ #define KC_K4 0x6A /* Keypad 4 */ #define KC_K5 0x6B /* Keypad 5 */ #define KC_K6 0x6C /* Keypad 6 */ #define KC_K7 0x67 /* Keypad 7 */ #define KC_K8 0x68 /* Keypad 8 */ #define KC_K9 0x69 /* Keypad 9 */ /* * ST520/1040 keynames */ #define F1 0201 #define F2 0202 #define F3 0203 #define F4 0204 #define F5 0205 #define F6 0206 #define F7 0207 #define F8 0210 #define F9 0211 #define F10 0212 #define HELP 0213 #define UNDO 0214 #define INSERT 0215 #define HOME 0216 #define UPARRO 0273 #define DNARRO 0274 #define LTARRO 0275 #define RTARRO 0276 #define KLP 0300 #define KRP 0301 #define KSTAR 0302 #define KPLUS 0303 #define KENTER 0304 #define KMINUS 0305 #define KDOT 0306 #define KSLASH 0307 #define K0 0260 #define K1 0261 #define K2 0262 #define K3 0263 #define K4 0264 #define K5 0265 #define K6 0266 #define K7 0267 #define K8 0270 #define K9 0271 /* * The above are the unshifted values. Shifted, as well as * 'capslocked' (for only these keys) values that I use are these +0040. */ #define SHIFTED 0040 #define UNSHIFTED_MODE 0 /* Normal (unshifted) mode */ #define SHIFTED_MODE 1 /* With shift key pressed */ #define CAPSLOCK_MODE 2 /* With capslock key pressed */ static char *mode_string [] = { "Unshifted Mode", /* Mode_string[UNSHIFTED_MODE] */ "Shifted Mode", /* Mode_string[SHIFTED_MODE] */ "Capslock Mode" /* Mode_string[CAPSLOCK_MODE] */ }; /* * Error ( string, ec) * * Write string and exit (ec). */ Error (str, ec) char *str; int ec; { printf ("Error: ** %s **\n", str); exit (ec); } /* error */ /* * copy_map (mode, k_orig, k_new) * * This routine will copy the contents of 'k_orig' (the original * keyboard's translation table for mode 'mode', obtained by the * xbios function 'Keytbl') to the new defined translation table * 'k_new'. Also the function/arrow/keypad key entries in 'k_new' * will be changed to the preferred Gulam settings. */ void copy_map (mode, k_orig, k_new) register short mode; char *k_orig, /* Pointer to original key table for 'mode' */ *k_new; /* New defined key table for Gulam */ { register char *ko = k_orig, *kn = k_new; register int i, offset = 0; /* If shifted mode, add this */ printf ("Changing keyboard translation table (%s) at %06lx.\n", mode_string[mode], k_orig); for (i=0; i<128; i++) kn[i] = ko[i]; /* * Change Function/Arrow/Keypad keys * Here you can add/change entries. */ if (mode == SHIFTED_MODE) offset = SHIFTED; kn[KC_F1] = F1 + offset; kn[KC_F2] = F2 + offset; kn[KC_F3] = F3 + offset; kn[KC_F4] = F4 + offset; kn[KC_F5] = F5 + offset; kn[KC_F6] = F6 + offset; kn[KC_F7] = F7 + offset; kn[KC_F8] = F8 + offset; kn[KC_F9] = F9 + offset; kn[KC_F10] = F10 + offset; kn[KC_HELP] = HELP + offset; kn[KC_UNDO] = UNDO + offset; kn[KC_INS] = INSERT + offset; kn[KC_CLR] = HOME + offset; kn[KC_CUP] = UPARRO + offset; kn[KC_CDOWN] = DNARRO + offset; kn[KC_CLEFT] = LTARRO + offset; kn[KC_CRIGHT] = RTARRO + offset; kn[KC_KLP] = KLP + offset; kn[KC_KRP] = KRP + offset; kn[KC_KSLASH] = KSLASH + offset; kn[KC_KSTAR] = KSTAR + offset; kn[KC_KPLUS] = KPLUS + offset; kn[KC_KENT] = KENTER + offset; kn[KC_KMINUS] = KMINUS + offset; kn[KC_KDOT] = KDOT + offset; kn[KC_K0] = K0 + offset; kn[KC_K1] = K1 + offset; kn[KC_K2] = K2 + offset; kn[KC_K3] = K3 + offset; kn[KC_K4] = K4 + offset; kn[KC_K5] = K5 + offset; kn[KC_K6] = K6 + offset; kn[KC_K7] = K7 + offset; kn[KC_K8] = K8 + offset; kn[KC_K9] = K9 + offset; } /* copy_map */ /* * Return offset in the binary file gulam.prg where the keymap[] begins. * 80336 (decimal) is this number valid for beta-version * 1.03.04.05 (121887). */ char * kmpbgn(buf, n) register char *buf; register long n; { /* kmp[] is extracted from Gulam's src; do NOT change it. */ static char kmp[16] = { /* -------scan codes: 0x00-0x0f --------------- */ '\000' /*nul*/, '\033' /*esc*/, '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' , '-' , '=' , '\010' /* bs*/, '\011' /* ht*/ }; register long i; register int j; register char *p, *q; for (i = 0L; i < n; i++) { p = &buf[i]; q = kmp; for (j = 0; j < 16; j++) if (*p++ != *q++) break; if (j == 16) goto found; } Error ("key map begin not found!", -1); found: printf("Key map begins at byte %ld\r\n", i); return &buf[i]; } main() { struct keytbl *kp; register char *buf, *q; register int i; register long n, m; register unsigned long lsz; lsz = GULAM_SIZE; /* Enough space to hold entire * gulam.prg! */ buf = (char *) Malloc(lsz); if (buf == 0L) Error ("can't Malloc", -2); /* read all of gulam.prg into buf */ i = Fopen("gulam.prg", 0); if (i <= 0) Error ("gulam.prg not found", -3); n = Fread(i, lsz, buf); if (n <= 0L) Error ("error reading file", -3); else if (n == GULAM_SIZE) Error ("gulam.prg probably bigger", -3); Fclose(i); /* * Get the keymap beginning in 'gulam.prg' */ q = kmpbgn(buf, n); /* * Fix the keymap tables */ kp = Keytbl (-1L,-1L,-1L); /* Get keytable structure */ copy_map (UNSHIFTED_MODE, kp->kt_normal, (char *) q ); copy_map (SHIFTED_MODE, kp->kt_shifted, (char *) (q + 128) ); copy_map (CAPSLOCK_MODE, kp->kt_capslock, (char *) (q + 256) ); /* write the new gulam.prg out */ i = Fcreate("gulamnew.prg", 0); if (i <= 0) Error ("could not create gulamnew.prg", -3); m = Fwrite(i, n, buf); if (m != n) Error ("error writing file", -3); Fclose(i); printf("new version of gulam is gulamnew.prg\n\n"); } /* main */