Documentation of: nkcc.s Date: Friday 28.02.1992 15.48 **************************************************************************** * * NORMALIZED KEY CODE CONVERTER * * Release 2.81 * *--------------------------------------------------------------------------- * * Edition : 53 * Author : Harald Siegmund * Assembler: MadMac 1.05 * Notes : Definition of the symbol NKCNOGEM will suppress inclusion * of the GEM part, which saves about 3.5 KByte of memory. * The functions nkc_multi()/nkc_amulti() and the GEM parameter * block are not available then. * * Definition of the symbol NKCOWNPB will NKCC force to use its * own GEM parameter blocks (they won't be exported and shared * with the Turbo C library). The symbol is ignored if NKCNOGEM * is defined. * *--------------------------------------------------------------------------- * * History : * * 1989: * May 14: creation of file (NKCC 1.00) * Jun 07/15-16/19/21/Jul 11: improvements, changes, debugging * 1990: * Jan 13: global functions now available in two versions: * parameters passed via registers (e.g. for Turbo C) * parameters passed via stack (underscore before label name) * * May 23-24/26-28: creation of NKCC 2.00 (almost every function rewritten) * Jun 16/27: assembler-entry added by Gerd Knops * Jun 30/Jul 02: return shift key flags in nkc_multi()/amulti() as NKF?_... * Jul 09: nkc_kstate() * Aug 03: nkc_cmp() * Aug 18: fatal bug in nkc_kstate() fixed * Sep 15: nkc_timer() * Sep 15-17/30: own button event handler * Oct 03: debugging * nkc_vlink()/vunlink() * documentation syntax changed (LRef/XRef removed; Reg: changed) * Oct 05: debugging mouse button handler (problems with menu bar) * Oct 07: Control/Alternate + character always returns capital characters * changing key code comparism rules in nkc_cmp() * Oct 22: debugging nkc_cmp() (did sometimes recognize unique key codes) * debugging ASCII code input in nkc_amulti() * Dec 11/15/17: MU_XTIMER * 1991: * Jan 11: don't call AES with set MU_XTIMER flag * Mar 31: ensure that evnt_multi() parameters are restored when being * corrupted by a bug in AES!! * Apr 01: debugging * Apr 13: nkc_conv() renamed to nkc_tconv() * Apr 13-14: nkc_gconv() * May 10: debugging (nk_beend()) * May 29: debugging (double shift key compare) * export nkc_toupper and nkc_tolower * Jul 05: completing history * Jul 31: version number before XBRA header * Aug 06: " is now a deadkey! * Aug 07: more deadkeys... * Aug 22: deadkeys can now be enabled/disabled separately * nkc_set() changed * nkc_init() returns version # * bug fixed: nkc_cmp() corrupted high words of D3 and D4 * Sep 07/14: nkc_cmp() improved; NKF?_RESVD now in use * Nov 05: adjustments to ASCII input feature of TOS 3.06 * Nov 16: bug fixed in nkc_cmp() mechanism * Control key emulation * Dec 29: small corrections and extensions of the documentation * source documentation syntax now in extra file * 1992: * Jan 03: changing documentation of nkc_init() * revising info lines in function headers * Jan 12: adjusting nkc_init() to its new documentation! * appending .b respectively .l to all instructions with a default * operand size which is not .w * changing macro XBRA_HD * Feb 11: adjusting button event handler to MINT * Feb 28: NKCOWNPB switch * *--------------------------------------------------------------------------- * * Features to come (in future versions...): * * - when receiving key codes from AES, NKCC uses the *current* state of * the Alternate/Control/Shift keys because the original state was lost * (forgotten by AES!). Wrong key codes may be the result. This will be * fixed some time. * * - NKCC will support additional (and more complex) deadkeys, such like * Arabian ones. A communication interface between NKCC and a text editor * will be built in for that purpose (Arabian languages' deadkeys can * affect existing text!). * * - when NKCC finds itself in memory (perhaps installed by an accessory), * interrupts and variables will be shared between both NKCCs (preventing * the installation of lots of interrupts and thus saving processor time). * **************************************************************************** *KEY _NAME "NKCC" **************************************************************************** * ASSEMBLER CONTROL SECTION * **************************************************************************** *KEY =NKCNOGEM * if defined (on the assembler's command line), this symbol will supress * inclusion of the GEM part of NKCC (see comment in file header) * *KEY =NKCOWNPB * if defined, NKCC will use its own GEM parameter blocks .include "nkcc.sh" ; NKCC definitions **************************************************************************** * EXPORT * **************************************************************************** ; functions .globl nkc_init ; init NKCC .globl nkc_exit ; exit NKCC .globl nkc_set ; set special key flags .globl nkc_conin ; NKCC key input via GEMDOS .globl nkc_cstat ; console input status via GEMDOS .globl nkc_tconv ; TOS key code converter .globl nkc_gconv ; GEM key code converter .globl nkc_kstate ; return shift key state .globl nkc_timer ; return 200 Hz system clock .globl nkc_cmp ; compare two key codes .globl nkc_vlink ; link function to XBRA vector list .globl nkc_vunlink ; unlink function from XBRA list .globl nkc_toupper ; upper case conversion table .globl nkc_tolower ; lower case conversion table .if !(^^defined NKCNOGEM) .globl nkc_multi ; NKCC multi event .globl nkc_amulti ; multi event, assembler binding .if !(^^defined NKCOWNPB) .globl _GemParBlk ; TC compatible GEM param'block .globl _contrl ; sub-arrays of GPB .globl _global .globl _intin .globl _intout .globl _ptsin .globl _ptsout .globl _addrin .globl _addrout .endif .endif **************************************************************************** * GLOBAL TEXT SECTION * **************************************************************************** **************************************************************************** * * nkc_init: initialize NKCC * # G U * * This function initializes NKCC. It must be called once before any other * NKCC routine. It performs some tasks that may be important for you to * know: * * - the state of bit 3 of the system variable ($484.B) is saved, * then the bit is set; nkc_exit() restores it * - a 200 Hz clock interrupt is installed, using the XBRA method (ID is * "NKCC") * * nkc_init() gets some flags which configure NKCC and enable some special * functions: * * NKI?_BUTHND install NKCC's button event handler (see documentation * NKCC.DOC for details) * NKI?_BHTOS additional flag: install only, if TOS has mouse click bug * NKI?_NO200HZ don't install the 200 Hz timer interrupt * * Notes: * * - if NKCC is assembled as TOS-only version (symbol NKCNOGEM was defined), * both NKI?_BUTHND and NKI?_BHTOS flags are ignored. * * - if the button event handler is installed, the NKI?_NO200HZ flag is * ignored (because the 200 Hz clock is needed by the handler). Besides, * the initialization continues: * * - an own GEM trap handler (trap #2) is installed, using the XBRA method * (to be up to date when a new double click time is set via the AES * function evnt_dclick()) * * - a vex_butv() call (VDI) is made to install a mouse button exchange * handler * * In: R D0.L miscellaneous flags (NKI?_...); see above * R D1.w handle of an open VDI workstation * (must only be valid if the button handler is * installed) * Out: W D0.w NKCC's version number as 4 digit BCD * (main # in high byte, sub # in low byte) * * Reg: D:01234567 A:01234567 CCR * U**..... **...... * * **************************************************************************** **************************************************************************** * * nkc_exit: exit NKCC * # G U * * nkc_exit() must be called before the program is quit. It restores * , which has been modified by nkc_init() and removes all * handlers installed in the system. * * In: - * Out: W D0.W status flag: * 0 OK * -1 can't remove 200 Hz clock interrupt * -2 can't remove trap #2 handler * -3 can't remove both handlers * An error can happen if somebody corrupted the * XBRA vector list. This is fatal! * * Reg: D:01234567 A:01234567 CCR * ***..... **...... =D0.W * **************************************************************************** **************************************************************************** * * nkc_set: set special key flags * # G * * This function is used to enable/disable special key handling procedures. * The features which can be set are: * * - direct input of ASCII codes; when switched on, pressing the Alternate * key plus one of the numbers on the numeric keypad will start the input * of a decimal ASCII number. The input is finished either when 3 digits * are typed in or the Alternate key is released. NKCC will return the * corresponding character with the entered ASCII code. This feature makes * it possible to use the whole range of the character set (from 0 ... 255). * * - deadkey management; when switched on, NKCC will combine some combi- * nations of two key strokes to one character. This is used to generate * characters with accents which are not on the keyboard. The supported * deadkeys are: * * ^ + aeiou = ƒˆŒ“– (NKS?_D_CIRCUM) * ~ + nNaoAo = คฅฐฑทธ (NKS?_D_TILDE) * ' + eEaiou = ‚ กขฃ (NKS?_D_AGUI) * ` + aeiouA = …Š•—ถ (NKS?_D_GRAVE) * น + aeiouyAOU = „‰‹”˜Ž™š (NKS?_D_UMLAUT) * " + aeiouyAOU = „‰‹”˜Ž™š (NKS?_D_QUOTE) * ๘ + aA = † (NKS?_D_SMOERE) * , + cC = ‡€ (NKS?_D_CEDIL) * / + oO = ณฒ (NKS?_D_SLASH) * * The quote character as synonym for umlaut is e.g. needed on the Dutch * keyboard, where neither umlaut characters nor the umlaut itself are * available. * * Each deadkey can be enabled/disabled separately. * * - Control key emulation: Control plus an ASCII code in the range of * $40...$5F (characters @, A...Z, [, \, ], ^ and _) is converted * to an ASCII code of $00...$1F. * * * In: R D0.L new key flags (bit set = feature on): * NKS?_ALTNUM ASCII input * NKS?_D_... deadkey ... * (NKSf_DEADKEY: all deadkeys) * NKS?_CTRL control key emulation * Out: - * * Reg: D:01234567 A:01234567 CCR * ***..... **...... * * **************************************************************************** **************************************************************************** * * nkc_conin: raw console character input * # G * * This routine replaces the Gemdos function Crawcin. However, it returns * a WORD with the key code in normalized format rather than a LONG with * the key code in the language dependend TOS format. * * In: - * Out: W D0.w key code in normalized format * for details see nkc_tconv() * W CCR set according content of D0.w * * Reg: D:01234567 A:01234567 CCR * W**..... **...... =D0.w * **************************************************************************** **************************************************************************** * * nkc_cstat: return console character input status * # G * * This function checks, if a key is in the key input buffer or not. * * In: - * Out: W D0.W flag: * 0 no key in buffer * -1 at least one key in buffer * W CCR set according content of D0.W * * Reg: D:01234567 A:01234567 CCR * W**..... **...... =D0.W * **************************************************************************** **************************************************************************** * * nkc_multi: NKCC multi event * # G U * * nkc_multi() is a binding function to the AES multi event handler. The * only differences are the keyboard events and the shift key state: the key * codes are returned in normalized format (see nkc_tconv()), the shift key * state is compatible to the NKF?_... flags. For a detailed description of * the whole mass of parameters consult your AES manual or compiler handbook! * * In: R 4(SP).w event mask (MU_...) * R 6(SP).w MU_BUTTON: max # of clicks to wait for * R 8(SP).w MU_BUTTON: mask of buttons to check * R 10(SP).w MU_BUTTON: button states to wait for * R 12(SP).w MU_M1: area enter/leave flag * R 14(SP).w MU_M1: x position of area * R 16(SP).w MU_M1: y position of area * R 18(SP).w MU_M1: width of area * R 20(SP).w MU_M1: height of area * R 22(SP).w MU_M2: area enter/leave flag * R 24(SP).w MU_M2: x position of area * R 26(SP).w MU_M2: y position of area * R 28(SP).w MU_M2: width of area * R 30(SP).w MU_M2: height of area * R 32(SP).L MU_MESAG: ^8 words of message buffer * R 36(SP).w MU_TIMER: low word of time to wait * R 38(SP).w MU_TIMER: high word of time to wait * ^W 40(SP).L MU_BUTTON/M1/M2: ^word for mouse x * ^W 44(SP).L MU_BUTTON/M1/M2: ^word for mouse y * ^W 48(SP).L MU_BUTTON/M1/M2: ^word for button state * ^W 52(SP).L MU_BUTTON/M1/M2: ^word for shift state * ^W 56(SP).L MU_KEYBD: ^word for key code in normalized format * ^W 60(SP).L MU_BUTTON: ^word for # of mouse clicks * Out: W D0.w mask of occured events (MU_...) * * Reg: D:01234567 A:01234567 CCR * W**..... **...... * * **************************************************************************** **************************************************************************** * * nkc_amulti: NKCC multi event called by Assembler *** added by Gerd Knops * # G U * * See description of nkc_multi()! * * usage: instead of move.l #aespb,d1 * move #$c8,d0 * trap #2 * * do jsr nkc_amulti * * In: all parameters for evnt_multi in the AES parameter arrays * Out: values in intout and message buffer * * Reg: D:01234567 A:01234567 CCR * ***..... **...... * * **************************************************************************** **************************************************************************** * * nkc_tconv: TOS key code converter * # G R * * This is the most important function within NKCC: it takes a key code * returned by TOS and converts it to the sophisticated normalized format. * * Note: the raw converter does no deadkey handling, ASCII input or * Control key emulation. * * In: R D0.L key code in TOS format: * 0 1 * bit 31: ignored ignored * bit 30: ignored ignored * bit 29: ignored ignored * bit 28: no CapsLock CapsLock * bit 27: no Alternate Alternate pressed * bit 26: no Control Control pressed * bit 25: no left Shift key left Shift pressed * bit 24: no right Shift key right Shift pressed * * bits 23...16: scan code * bits 15...08: ignored * bits 07...00: ASCII code (or rubbish in most cases * when Control or Alternate is pressed ...) * * Out: W D0.w normalized key code: * bits 15...08: flags: * 0 1 * NKF?_FUNC printable char "function key" * NKF?_RESVD ignore it ignore it * NKF?_NUM main keypad numeric keypad * NKF?_CAPS no CapsLock CapsLock * NKF?_ALT no Alternate Alternate pressed * NKF?_CTRL no Control Control pressed * NKF?_LSH no left Shift key left Shift pressed * NKF?_RSH no right Shift key right Shift pressed * * bits 07...00: key code * function (NKF?_FUNC set): * < 32: special key (NK_...) * >=32: printable char + Control and/or Alternate * no function (NKF?_FUNC not set): * printable character (0...255!!!) * * W CCR set according content of D0.w * * Reg: D:01234567 A:01234567 CCR * U**..... **...... =D0.w * **************************************************************************** **************************************************************************** * * nkc_gconv: GEM key code converter * # G R * * Why a second key code converter, you ask? Well, in some cases it might * happen that the key status byte of the original key code (with states * of both Shift keys, Control, Alternate and CapsLock) is lost. Then * this converter function must be called, which uses another algorithm * to construct the normalized key code. * * Notes: * - the raw converter does no deadkey handling, ASCII input or Control * key emulation. * - NKCC does not use this function at all for its own purposes! * - some key combinations cannot be distinguished without the flag byte! * For example, "Alternate A" and "Shift Alternate A" produce the same * result. Whenever possible, use nkc_tconv()! * * In: R D0.w key code in GEM format: * bits 15...08: scan code * bits 07...00: ASCII code * * Out: W D0.w normalized key code (see nkc_tconv() for details) * W CCR set according content of D0.w * * Reg: D:01234567 A:01234567 CCR * U**..... **...... =D0.w * **************************************************************************** **************************************************************************** * * nkc_kstate: return state of Shift/Control/Alternate/CapsLock in * normalized format * # G R * * This is a very *FAST* function which returns the state of the Shift/ * Control/Alternate and CapsLock keys in normalized format. * * In: - * Out: W D0.w normalized key flags: * 0 1 * NKF?_CAPS no CapsLock CapsLock * NKF?_ALT no Alternate Alternate pressed * NKF?_CTRL no Control Control pressed * NKF?_LSH no left Shift key left Shift pressed * NKF?_RSH no right Shift key right Shift pressed * * W CCR set according content of D0.w * * Reg: D:01234567 A:01234567 CCR * w**..... **...... =D0.w * **************************************************************************** **************************************************************************** * * nkc_timer: return current value of 200 Hz system clock * # G R * * This is a very *FAST* function which returns the content of the 200 Hz * system clock. * * In: - * Out: W D0.L current 200 HZ system clock value * * Reg: D:01234567 A:01234567 CCR * w**..... **...... * * **************************************************************************** **************************************************************************** * * nkc_cmp: compare two key codes * # G R * * nkc_cmp() compares key codes. What for, you ask? A simple "if key_code1 * = key_code2" would also do it? No! This function follows some specific * rules, which improve the flexibility of key code comparism. * * One of the key codes passed to nkc_cmp() is called the "reference key * code". The other is the "test key code", which is got from nkc_conin() * or nkc_multi(). Some flags of the reference code are treated a special * way: * * NKF?_IGNUM (same as NKF?_RESVD) * if set, the numeric keypad flag doesn't matter * * NKF?_CAPS (CapsLock) * if set, the case of the ASCII code doesn't matter * * NKFf_SHIFT (both Shift key flags) * if BOTH shift flags are set, the combination of shift key flags in * the test key code doesn't matter: only one shift flag has to be set, * no matter which one. * * In: W D0.w reference key code * W D1.w key code to test * Out: W D0.W flag: 1 = key codes match * 0 = key codes don't match * W CCR set according content of D0.W * * Reg: D:01234567 A:01234567 CCR * u**..... **...... =D0.w * **************************************************************************** **************************************************************************** * * nkc_vlink: link function to XBRA vector list * # G U * * This function can be used to change system vectors and let them point * to own functions, using a standard method. The vector, which should be * changed, is described by the contents of D0.L and D1.W. It can be * either a standard vector number, e.g. 2 for the bus error exception * vector, or the absolute address of the vector, e.g. $502 for the screen * dump vector. The function to install must have the following header: * * .dc.b "XBRA" magic longword * .dc.b "myID" four ASCII character ID of the function * (NKCC uses "NKCC", for example) * .dc.l 0 buffer for the old vector content * function: ... start of the function code * * The function should end with: * * move.l function-4(pc),-(sp) * rts * * * Note: in NKXM_ADR mode, this function automatically switches (temporary) * to Supervisor mode to prevent bus errors * * * In: R D0.L vector descriptor * R D1.W mode: * NKXM_NUM = D0.L contains a vector number * NKXM_ADR = D0.L contains a vector address * R A0.L ^function to install (NOT ^XBRA header!) * Out: W -4(A0.L).L old content of vector * * Reg: D:01234567 A:01234567 CCR * ***..... **...... * * **************************************************************************** **************************************************************************** * * nkc_vunlink: unlink function from XBRA vector list * # G U * * nkc_vunlink() removes a function which was installed using the XBRA method. * For details see nkc_link(). If the XBRA list was corrupted, the function * aborts with an error code. This happens, when a non-XBRA routine is * installed on the same vector after the nkc_vlink() call of the function * to remove. * * Note: the function automatically switches (temporary) to Supervisor mode * to prevent bus errors * * In: R D0.L vector descriptor * R D1.W mode: * NKXM_NUM = D0.L contains a vector number * NKXM_ADR = D0.L contains a vector address * R A0.L ^function to remove (NOT ^XBRA header!) * Out: W D0.w status: * 0 = OK * -1 = can't remove (XBRA list corrupted) * W CCR set according content of D0.w * * Reg: D:01234567 A:01234567 CCR * U**..... **...... =D0.w * **************************************************************************** **************************************************************************** * GLOBAL DATA SECTION * **************************************************************************** * lower case to upper case conversion table * (array of 256 unsigned bytes) nkc_toupper: * upper case to lower case conversion table * (array of 256 unsigned bytes) nkc_tolower: **************************************************************************** * GLOBAL BSS SECTION * **************************************************************************** * GEM parameter block * (structure GEMPARBLK) .if !(^^defined NKCNOGEM) .if !(^^defined NKCOWNPB) _GemParBlk: ; GEM parameter block .endif _contrl: .ds.w 11 ; control array _global: .ds.w 80 ; global array _intin: .ds.w 128 ; integer input array _ptsin: .ds.w 128 ; pointers input array _intout: .ds.w 128 ; integer output array _ptsout: .ds.w 128 ; pointers output array _addrin: .ds.l 128 ; address input array _addrout: .ds.l 6 ; address output array * note: the original TC declaration of _GemParBlk defined the size of the * array _addrout to be 128 longs. I examined the GEM library (module * _GEMPARB.O) and found out the real size - only six longs! Maybe * this changes in future versions of TC, so you better check it * (I tested versions 1.10, 2.0 and 2.05). End of file