; > adfs::TimsWini.arm.SourceDisc.!IKHG.Source.IntKeyBody ; ************************************************************ ; *** C h a n g e L i s t (better late than never!) *** ; ************************************************************ ; Date Description ; ---- ----------- ; 17-Feb-88 Modified Norway/Denmark, Sweden/Finland ; 19-Feb-88 Modified InkeyTran so that INKEY(-95) returns state of new key ; next to left shift key on international keyboards ; 19-Feb-88 Added code to select configured keyboard on initialisation ; 16-Mar-88 Conditional versioning between 1.20 and 2.00 ; Started modify AltCharTable mechanism ; 13-Apr-88 Fixed pound/backtick problem ; 14-Apr-88 Attempt to fix initialisation problem on A500s ; 28-Apr-88 Changed version string to "Int'l Keyboard" ; 20-Jul-88 Allow kbids from 1-31 ; 24-Oct-88 Modify for International Keyboard Handler Generator ; 18-Jul-89 Started to modify to allow Alt+key to give dead accents ; 31-Jul-89 Changed 'Dir', 'Hdr' etc to 'IKHG$Dir', 'IKHG$Hdr' etc ; 18-Oct-89 Corrected entry for shift-2 in TopBitSetTable1 ; 02-Feb-90 Added entries to IDD table, and changed Esperanto to 1100 ; 22-Nov-91 TMD Changed selection of keyboard structure to use ID rather ; than current keyboard country number, changed list of headers ; 26-Nov-91 TMD Changed initialisation to set keyboard to current keyboard, ; rather than default, so that it doesn't override what the ; Territory manager says. ; 16-Dec-91 OSS Corrected burnt in UK keyboard to match the spec. ; Added Mexico (and Israel) to IDD table. ; 22-Jan-92 OSS Corrected Perth layout to match Tim Caspell's spec, made ; ID 3 (PC) use Perth layout, enabled "WwYy" circumflex (Welsh). ; 16-Feb-92 OSS Added Tim's corrected Letters.Latin1, which tells !IKHG ; how to uppercase y and w circumflex. The module binary is ; unaffected. ; 04-Mar-92 TMD Removed Arthur120 conditionals. ; Removed references to non-existent keyboard id 3 (was PC at one stage). ; Tidied it up a bit. ; Made it not hang up if no keyboard attached (bug RP-1355). ; 27-Jun-94 Sorted out sources for international build. ; Added offsets in key structure so that keypad chars can be changed. ; 10-Aug-98 BJGA Added PC-style delete capability and Ursula service call table. ; 18-Aug-98 BJGA Fixed numerous layout bugs ; 31-Aug-98 Internals fully revised to use new UCS layout structures created ; by keygen. Alphabet adaptive, including UTF-8. ; 02-Sep-98 Hexadecimal keypad selection added. If the first digit is 0, ; then the number entered is read as hex. (Physical) keypad keys ; "/", "*", "-", "+", "." and "Enter" stand for digits A-F respectively. ; Also, logical keys A-F will work. ; 28-Sep-98 BJGA Merged in 10-Sep-98 and 24-Sep-98 changes to Ursula branch ; viz: updated layout drawfiles; added dialling codes for Wales, Wales2, ; DvorakUK and DvorakUSA; introduced quoted characters to !IKHG.Source.Chars; ; layout changes to Belgium, Denmark, France, Germany, Greece, Israel, ; LatinAm, Russia, Switzerland and Turkey; and Ctrl-Alt-F1/F2 use a callback. ; Also fixed Japan delete key to be special. ; 26-Aug-99 Software support for "FN" key. ; GBLL PCDel ; option to have Delete key return &8B (Copy) instead PCDel SETL {TRUE} GBLL Ursula ; add Ursula service call table Ursula SETL {TRUE} GET Hdr:ListOpts GET Hdr:Macros GET Hdr:System GET Hdr:ModHand GET Hdr:Services GET Hdr:Proc OsbyteSetCountry * &46 OsbyteSetAlphKey * &47 OsbyteFindOsbyteVars * &A6 OsbyteTABch * &DB OsbyteKeyBase * &EE OsbyteKeyOpt * &FE [ PCDel OsbyteReadCmos * &A1 CmosDelByte * &C3 CmosDelBit * 1 ] Country_UK * 1 Country_Master * 2 Country_Compact * 3 Country_Italy * 4 Country_Spain * 5 Country_France * 6 Country_Germany * 7 Country_Portugal * 8 Country_Esperanto * 9 Country_Greece * 10 Country_Sweden * 11 Country_Finland * 12 Country_Denmark * 14 Country_Norway * 15 Country_Iceland * 16 Country_Canada1 * 17 Country_Canada2 * 18 Country_Canada * 19 Country_Turkey * 20 Country_Arabic * 21 Country_Ireland * 22 Country_HongKong * 23 Country_Russia * 24 Country_Russia2 * 25 Country_Israel * 26 Country_Mexico * 27 Country_LatinAm * 28 Country_Australia * 29 Country_Austria * 30 Country_Belgium * 31 Country_Japan * 32 Country_MiddleEast * 33 Country_Netherlands * 34 Country_Switzerland * 35 Country_Wales * 36 Country_USA * 48 Country_Wales2 * 49 Country_ISO1 * 80 Country_ISO2 * 81 Country_ISO3 * 82 Country_ISO4 * 83 Country_ISO5 * 84 Country_ISO6 * 85 Country_ISO7 * 86 Country_ISO8 * 87 Country_ISO9 * 88 Country_DvorakUK * 70 Country_DvorakUSA * 71 Alphabet_Latin1 * 101 Alphabet_Latin2 * 102 Alphabet_Latin3 * 103 Alphabet_Latin4 * 104 Alphabet_Cyrillic * 105 Alphabet_Arabic * 106 Alphabet_Greek * 107 Alphabet_Hebrew * 108 Alphabet_Latin5 * 109 Alphabet_Welsh * 110 Alphabet_UTF8 * 111 Alphabet_Latin9 * 112 Alphabet_Latin6 * 113 Keyboard_A500 * 0 Keyboard_A1 * 1 Keyboard_Perth * 2 Keyboard_RCMM * 3 Keyboard_None * &FF MACRO IKT $A, $B, $C, $D, $E, $F, $G, $H IKT2 $A IKT2 $B IKT2 $C IKT2 $D IKT2 $E IKT2 $F IKT2 $G IKT2 $H MEND MACRO IKT2 $TE LCLA T T SETA $TE [ (T :AND: &FF00) = 0 T SETA T :OR: &FF00 ] [ (T :AND: &FF0000) = 0 T SETA T :OR: &FF0000 ] [ (T :AND: &FF000000) = 0 T SETA T :OR: &FF000000 ] & T MEND ; UK Keyboard keys K1Escape * &00 K1Function1 * &01 K1Function2 * &02 K1Function3 * &03 K1Function4 * &04 K1Function5 * &05 K1Function6 * &06 K1Function7 * &07 K1Function8 * &08 K1Function9 * &09 K1Function10 * &0A K1Function11 * &0B K1Function12 * &0C K1Print * &0D K1ScrollLock * &0E K1Break * &0F K1BackTick * &10 K1Digit1 * &11 K1Digit2 * &12 K1Digit3 * &13 K1Digit4 * &14 K1Digit5 * &15 K1Digit6 * &16 K1Digit7 * &17 K1Digit8 * &18 K1Digit9 * &19 K1Digit0 * &1A K1Minus * &1B K1Equals * &1C K1Pound * &1D K1BackSpace * &1E K1Insert * &1F K1Home * &20 K1PageUp * &21 K1NumLock * &22 K1NumPadSlash * &23 K1NumPadStar * &24 K1NumPadHash * &25 K1Tab * &26 K1LetterQ * &27 K1LetterW * &28 K1LetterE * &29 K1LetterR * &2A K1LetterT * &2B K1LetterY * &2C K1LetterU * &2D K1LetterI * &2E K1LetterO * &2F K1LetterP * &30 K1OpenSquare * &31 K1CloseSquare * &32 K1BackSlash * &33 K1Delete * &34 K1Copy * &35 K1PageDown * &36 K1NumPad7 * &37 K1NumPad8 * &38 K1NumPad9 * &39 K1NumPadMinus * &3A K1CtrlLeft * &3B K1LetterA * &3C K1LetterS * &3D K1LetterD * &3E K1LetterF * &3F K1LetterG * &40 K1LetterH * &41 K1LetterJ * &42 K1LetterK * &43 K1LetterL * &44 K1SemiColon * &45 K1Tick * &46 K1Return * &47 K1NumPad4 * &48 K1NumPad5 * &49 K1NumPad6 * &4A K1NumPadPlus * &4B K1ShiftLeft * &4C K1NotFittedLeft * &4D K1LetterZ * &4E K1LetterX * &4F K1LetterC * &50 K1LetterV * &51 K1LetterB * &52 K1LetterN * &53 K1LetterM * &54 K1Comma * &55 K1Dot * &56 K1Slash * &57 K1ShiftRight * &58 K1CursorUp * &59 K1NumPad1 * &5A K1NumPad2 * &5B K1NumPad3 * &5C K1CapsLock * &5D K1AltLeft * &5E K1Space * &5F K1AltRight * &60 K1CtrlRight * &61 K1CursorLeft * &62 K1CursorDown * &63 K1CursorRight * &64 K1NumPad0 * &65 K1NumPadDot * &66 K1NumPadEnter * &67 K1AcornLeft * &68 K1AcornRight * &69 K1Menu * &6A K1NoConvert * &6B K1Convert * &6C K1Kana * &6D K1NotFittedRight * &6E K1FN * &6F K1LeftMouse * &70 K1CentreMouse * &71 K1RightMouse * &72 ; Bits in pending ALT flag KBAlt_AccentMask * 31 KBAlt_AltDown * (1 :SHL: 5) KBAlt_DigitsPresent * (1 :SHL: 6) KBAlt_SelectKeyboard * (1 :SHL: 7) ; set after CTRL-ALT-F12 ; Kernel-referenced entries KVKeyTran * &0 KVKeyTranSize * &4 KVInkeyTran * &8 KVShiftingList * &C KVSpecialList * &10 KVSpecialCodeTable * &14 KVInit * &18 KVPendingAltCode * &1C ; Private entries KVPadNumTran * &20 ; offset from structure to new entry for keypad numerics KVPadCurTran * &24 ; offset from structure to new entry for keypad non-numerics KVFNTable * &28 KVUCSTable0 * &2C KVUCSTable1 * &30 KVSize * &34 ; size of key structure header KBStat_NoKanaLock * KBStat_NoShiftLock ; we've reassigned this bit ; Module workspace allocation ^ 0, R12 NewKeyStructWP # KVSize ; key structure header, must be first thing OldKeyHandler # 4 CurrentKeyboard # 4 ; current keyboard setting OsbyteVars # 4 AltDigitValue # 4 CurrentAlphabet # 4 AlphabetTable # 4 FallbackCode # 4 DeleteChar # 1 HexDigits # 1 A1Key_WorkspaceSize * :INDEX: @ ^ :INDEX: CurrentKeyboard, R0 R0CurrentKeyboard # 4 R0OsbyteVars # 4 R0AltDigitValue # 4 ; value of ALT+digits so far R0CurrentAlphabet # 4 R0AlphabetTable # 4 R0FallbackCode # 4 R0DeleteChar # 1 R0HexDigits # 1 ; User key workspace allocation ^ 0, R12 ShiftCount # 1 CtrlCount # 1 AltCount # 1 AltLeftDown # 1 ; for layouts where Left-Alt + Shift toggles layers FNDown # 1 MyMouseButtons # 1 ; bit0=R, bit1=C, bit2=L TempAction # 1 ; to remember the action in ProcessUCS KeyReturn # 2 ; length byte (1), value byte KeyNULReturn # 3 ; length byte (2), NUL, value byte NowtReturn * KeyNULReturn +1 ; zero length list KeyUTFReturn # 13 ; length byte (up to 12), 6 * (NUL, value) KeyUTFReturnEnd # 0 ; Handy macro to do the FN processing. Good for any non-modifier key. ; Corrupts R2 - this relies not only EVERY non-modifier handler not ; using R2, as if we end up calling a different handler, R2 will ; be corrupted. GBLA HandleFNsize MACRO HandleFN 01 LDRB R2, FNDown ; is FN down? TEQ R2, #0 ; if not, process as normal Push "R14", NE BLNE FindFN Pull "R14", NE HandleFNsize SETA . - %BT01 MEND ; **************** Module code starts here ********************** AREA |!!!Module|,CODE,READONLY Module_BaseAddr DCD 0 DCD A1Key_Init -Module_BaseAddr DCD A1Key_Die -Module_BaseAddr DCD A1Key_Service -Module_BaseAddr DCD A1Key_Title -Module_BaseAddr DCD A1Key_HelpStr -Module_BaseAddr DCD A1Key_HC_Table-Module_BaseAddr A1Key_Title = "InternationalKeyboard", 0 A1Key_HelpStr = "Int'l Keyboard", 9, "$Module_MajorVersion ($Module_Date)" [ Module_MinorVersion <> "" = " $Module_MinorVersion" ] [ Keyboard <> "All" = " $Keyboard" ] = 0 ALIGN ; ************************************************************************** A1Key_HC_Table * Module_BaseAddr ; ************************************************************************** ; ; A1Key_Init - Initialisation routine ; A1Key_Init Entry LDR r2, [r12] ; have we got workspace yet ? TEQ r2, #0 BNE %FT05 MOV r0, #ModHandReason_Claim MOV r3, #A1Key_WorkspaceSize SWI XOS_Module EXIT VS ; r2 -> workspace STR r2, [r12] ; save address in my workspace pointer, ; so Tutu can free it for me when I die 05 MOV wp, r2 MOV r0, #OsbyteSetAlphKey MOV r1, #&FF ; read current keyboard (as determined by Territory Mgr) SWI XOS_Byte ORRVC r1, r1, #128 ; and set current keyboard to that, to cause a kbd reset SWIVC XOS_Byte BLVC SetUpKeyStructureAndHandlerIfUs EXIT ; ************************************************************************** ; ; A1Key_Die - Die entry ; A1Key_Die Entry LDR wp, [r12] PHPSEI ; disable interrupts round this bit Push r14 ; (r14 contains previous I_bit status) MOV r0, #0 ; read current handler address SWI XOS_InstallKeyHandler TEQ r0, r12 BNE %FT10 ; key handler isn't us, so exit LDR r0, OldKeyHandler SWI XOS_InstallKeyHandler 10 Pull r14 PLP ; restore old IRQ state CLRV EXIT ; ************************************************************************** ; ; A1Key_Service - Main entry point for services ; ; in: R1 = service reason code ; R2 = parameter ; ; out: R1 = 0 if we claimed it ; R2 preserved ; [ Ursula ServiceTable DCD 0 ; flags DCD Service2 - Module_BaseAddr DCD Service_Reset ; &27 DCD Service_International ; &43 DCD Service_KeyHandler ; &44 DCD 0 ; terminator DCD ServiceTable - Module_BaseAddr A1Key_Service ROUT MOV R0, R0 | A1Key_Service ROUT ] TEQ r1, #Service_Reset TEQNE r1, #Service_KeyHandler TEQNE r1, #Service_International MOVNES pc, lr [ Ursula Service2 ] Entry "r1" LDR wp, [r12] ; point to workspace TEQ r1, #Service_KeyHandler ; if Service_KeyHandler BEQ %FT10 ; then branch TEQ r1, #Service_Reset ; else if Service_Reset TEQNE r2, #Inter_Keyboard ; or (the only other option) Service_International ; with reason code NewKeyboard BLEQ SetUpKeyStructureAndHandlerIfUs ; then call routine EXITS ; it's Service_KeyHandler, so claim service if kbid recognised 10 BL SetUpKeyStructureAndHandlerIfUs ; call setup routine STR r1, [sp] ; r1 on exit = 0 if it was us, else preserved EXITS ; ************************************************************************** ; ; SetUpKeyStructureAndHandlerIfUs - If suitable keyboard ID, set up ; the keyboard structure and claim handler ; ; in: r12 -> workspace ; SVC or IRQ mode ; ; out: r1 = 0 if we now own the handler ; Otherwise r1 preserved ; SetUpKeyStructureAndHandlerIfUs Entry "r0,r1" MOV r0, lr ORR r1, r0, #SVC_mode ; switch into SVC mode so we can issue SWIs TEQP r1, #0 NOP Push "r0-r4,lr" MOV r0, #1 SWI XOS_InstallKeyHandler TEQ r0, #Keyboard_A1 TEQNE r0, #Keyboard_Perth TEQNE r0, #Keyboard_RCMM TEQNE r0, #Keyboard_None BNE %FT50 MOV r0, #OsbyteFindOsbyteVars MOV r1, #0 MOV r2, #&FF SWI XOS_Byte ORR r1, r1, r2, LSL #8 STR r1, OsbyteVars ; set up osbyte vars address MOV r0, #OsbyteSetAlphKey MOV r1, #&FF ; read keyboard number SWI XOS_Byte STR r1, CurrentKeyboard MOV r0, #-1 STR r0, CurrentAlphabet STR r0, FallbackCode MOV r0, r12 BL GetAlphabetTable ADRL R0, KeyStructureTable MOV R4, R0 05 LDMIA R4!,{R2,R3} ; load keyboard number, offset pair CMP R2, #-1 ; if end of table TEQNE R1, R2 ; or numbers match then drop through BNE %BT05 ; else try next ADD R0, R0, R3 ; point to found table or default TEQP pc, #SVC_mode + I_bit ; disable IRQs round this bit NOP ; needed to get objasm to assemble cleanly MOV r2, #KVSize-4 SUB r1, r0, r12 ; offset from workspace to structure 10 LDR r3, [r0, r2] TEQ r2, #KVKeyTranSize ; is it KeyTranSize ? TEQNE r3, #0 ; or is it 0 ADDNE r3, r3, r1 ; if not then relative offset STR r3, [r12, r2] SUBS r2, r2, #4 BCS %BT10 ; now set up key handler to point to us, if it doesn't already MOV r0, #0 SWI XOS_InstallKeyHandler TEQ r0, r12 STRNE r0, OldKeyHandler MOVNE r0, r12 SWINE XOS_InstallKeyHandler [ PCDel ; scan CMOS to determine delete type MOV r0, #OsbyteReadCmos MOV r1, #CmosDelByte SWI XOS_Byte TST r2, #1 :SHL: CmosDelBit MOVEQ r0, #&7F MOVNE r0, #&8B STRB r0, DeleteChar ] Pull "r0-r4,lr" TEQP r0, #0 ; return to original mode and IRQ state MOV r0, #0 STR r0, [sp, #4] ; set stacked r1 to 0, so we claim the service EXITS ; the keyboard id is not recognised by us, so put back old handler if it's ; set to us at the moment 50 MOV r0, #0 SWI XOS_InstallKeyHandler TEQ r0, r12 ; if it's us LDREQ r0, OldKeyHandler ; then put back old one SWIEQ XOS_InstallKeyHandler Pull "r0-r4,lr" TEQP r0, #0 ; return to original mode and IRQ state NOP EXITS ; ************************************************************************** ; Find out what alphabet the system is using ; ; on entry: r0 -> my workspace ; on exit: r3 = CurrentAlphabet = alphabet number ; r4 = AlphabetTable = alphabet table or 0 GetAlphabetTable ROUT Entry "r0,r1,r12" MOV r12, r0 MOV r0, lr ; switch into SVC mode so we can issue SWIs ORR r1, r0, #SVC_mode TEQP r1, #0 NOP Push "r0-r2,lr" MOV r0, #OsbyteSetAlphKey MOV r1, #&7F ; read alphabet number SWI XOS_Byte LDR r3, CurrentAlphabet TEQ r1, r3 BNE %FT50 LDR r4, AlphabetTable 20 Pull "r0-r2,lr" TEQP r0, #0 ; return to original mode and IRQ state NOP EXITS 50 MOV r3, r1 STR r3, CurrentAlphabet TEQ r3, #Alphabet_UTF8 BEQ %BT20 MOV r4, #0 MOV r1, #Service_International MOV r2, #Inter_UCSTable SWI XOS_ServiceCall STR r4, AlphabetTable B %BT20 ; ************************************************************************** ; Now the code to handle it ; Initialise keyboard table handler ; ; in: R0 -> KeyStruct ; R1 = keyboard id ; R5 = KeyBdStatus ; R7 = PendingAltType ; R12 -> my workspace ; ; out: R5 = new KeyBdStatus ; R7 = new PendingAltType KeyStructInit ROUT MOV R0, #0 ; no shift or ctrl keys down STRB R0, ShiftCount STRB R0, CtrlCount STRB R0, AltCount STRB R0, AltLeftDown STRB R0, FNDown STRB R0, MyMouseButtons STRB R0, KeyNULReturn+1 ; NUL for NUL char return MOV R0, #1 ; string length for single key return STRB R0, KeyReturn+0 MOV R0, #2 ; length for NUL char return STRB R0, KeyNULReturn+0 BIC R5, R5, #(KBStat_ShiftEngaged :OR: KBStat_CtrlEngaged :OR: KBStat_PendingAlt) ORR R5, R5, #KBStat_NoKanaLock MOV R7, #0 ; 0 pending ALT MOV PC, R14 ProcessKShift ROUT LDRB R0, AltLeftDown ; is Left Alt down (where it switches layers?) TEQ R0, #1 LDREQB R0, ShiftCount TEQEQ R0, #0 ; if so, is Shift going down for the first time? TEQEQ R1, #1 EOREQ R5, R5, #KBStat_NoKanaLock ; if so, toggle layers, then proceed as normal ADR R0, ShiftCount MOV R2, #KBStat_ShiftEngaged ProcessShiftOrCtrl TEQ R1, #0 ; R1=1 => down, R1=0 => up LDRB R3, [R0] ADDNE R3, R3, #1 ; if down then increment (still NE) SUBEQS R3, R3, #1 ; if up then decrement and setup Z STRB R3, [R0] ORRNE R5, R5, R2 ; one or more shift/ctrl keys down BICEQ R5, R5, R2 ; zero shift/ctrl keys down MOV PC, R14 ProcessKCtrl ROUT ADR R0, CtrlCount MOV R2, #KBStat_CtrlEngaged B ProcessShiftOrCtrl ProcessKFN ROUT STRB R1, FNDown MOV PC, R14 ProcessKRight ROUT MOV R2, #1 ProcessMouseButton TEQ R1, #0 LDRB R0, MyMouseButtons ORRNE R0, R0, R2 ; button going down BICEQ R0, R0, R2 ; button going up STRB R0, MyMouseButtons MOV PC, R3 ; call his routine and exit ProcessKCentre ROUT MOV R2, #2 B ProcessMouseButton ProcessKLeft ROUT MOV R2, #4 B ProcessMouseButton ProcessKAltLeft ROUT STRB R1, AltLeftDown ; note new state of Left Alt TEQ R1, #0 ; are we going down? TSTNE R5, #KBStat_ShiftEngaged ; and is either Shift already down? EORNE R5, R5, #KBStat_NoKanaLock ; if so, toggle layers MOV PC, R14 ProcessKAlt ROUT LDRB R3, AltCount TEQ R3, #0 ; if no ALTs down so far, then must be STREQ R3, R0AltDigitValue ; going down, so zero cumulative digits STREQB R3, R0HexDigits TEQ R1, #0 ; 0 => up, 1 => down ADDNE R3, R3, #1 ; if down then increment SUBEQS R3, R3, #1 ; if up then decrement and setup Z STRB R3, AltCount BNE %FT10 TST R7, #KBAlt_DigitsPresent ; if no digits present BEQ %FT05 ; then skip LDR R1, R0AltDigitValue ; load digits TST R7, #KBAlt_SelectKeyboard ; selecting keyboard (CTRL-ALT-F12)? BNE SelectIDDKeyboard ; return either byte, or UCS character Push R14 BL GetAlphabetTable Pull R14 TEQ R3, #Alphabet_UTF8 BNE %FT02 BIC R1, R1, #&80000000 ; strip down to 31 bits BICS R7, R7, #(KBAlt_AltDown :OR: KBAlt_DigitsPresent) BICEQ R5, R5, #KBStat_PendingAlt B ReturnUCS 02 ADR R6, KeyNULReturn ; return 0 then byte STRB R1, [R6, #2] B %FT05 SelectIDDKeyboard ADR R0, IDDTable 03 LDMIA R0!, {R2, R3} ; load IDD number, country number CMP R2, #-1 ; end of table ? BEQ %FT05 ; then not recognised, so do nothing TEQ R2, R1 ; found match ? BNE %BT03 ORR R1, R3, #&80 Push R14 BL SelectKeyboard Pull R14 05 BICS R7, R7, #(KBAlt_AltDown :OR: KBAlt_DigitsPresent :OR: KBAlt_SelectKeyboard) B %FT15 10 ORRS R7, R7, #KBAlt_AltDown 15 ORRNE R5, R5, #KBStat_PendingAlt ; if NZ then still need bit set BICEQ R5, R5, #KBStat_PendingAlt ; else clear bit MOV PC, R14 IDDTable & 44, Country_UK & 39, Country_Italy & 34, Country_Spain & 33, Country_France & 49, Country_Germany & 351, Country_Portugal & 1100, Country_Esperanto & 30, Country_Greece & 46, Country_Sweden & 358, Country_Finland & 45, Country_Denmark & 47, Country_Norway & 354, Country_Iceland & 90, Country_Turkey & 353, Country_Ireland & 852, Country_HongKong & 7, Country_Russia & 972, Country_Israel & 52, Country_Mexico & 61, Country_Australia & 43, Country_Austria & 32, Country_Belgium & 81, Country_Japan & 31, Country_Netherlands & 41, Country_Switzerland & 1222, Country_Wales & 1, Country_USA & 2222, Country_Wales2 & 9944, Country_DvorakUK & 991, Country_DvorakUSA & 1001, Country_ISO1 & 1002, Country_ISO2 & 1003, Country_ISO3 & 1004, Country_ISO4 & 1005, Country_ISO5 & 1006, Country_ISO6 & 1007, Country_ISO7 & 1008, Country_ISO8 & 1009, Country_ISO9 & -1, -1 ProcessKCaps ROUT HandleFN HandleKCaps TEQ R1, #2 ; is it first press ? MOVNE PC, R14 ; don't auto-repeat TST R5, #KBStat_ShiftEngaged ; if shift down BICNE R5, R5, #KBStat_NoCapsLock ; then force CAPS on ORRNE R5, R5, #KBStat_ShiftEnable ; and SHIFT CAPS state EOREQ R5, R5, #KBStat_NoCapsLock ; else toggle caps lock state BICEQ R5, R5, #KBStat_ShiftEnable ; and cancel shift enable MOV PC, R14 ProcessKTab ROUT HandleFN HandleKTab LDR R3, R0OsbyteVars LDRB R3, [R3, #OsbyteTABch] ; TAB key code TST R3, #&80 ; top bit set ? BEQ ReturnOneCharAlt ; no, don't shift or ctrl it TST R5, #KBStat_ShiftEngaged EORNE R3, R3, #&10 ; modify for shift TST R5, #KBStat_CtrlEngaged EORNE R3, R3, #&20 ; modify for ctrl ReturnOneCharAlt TST R5, #KBStat_PendingAlt ; if no pending alt TSTNE R7, #KBAlt_AccentMask ; or its not an accent ADREQ R6, KeyReturn STREQB R3, [R6, #1] ; then return this MOVEQ PC, R14 LDR R4, [R0, #KVPendingAltCode] ADD PC, R0, R4 ; call PendingAltCode, as the Kernel would ProcessKDelete ROUT HandleFN HandleKDelete [ PCDel LDRB R1, R0DeleteChar ; get configured delete character | MOV R1, #&7F ] B ReturnOneChar ProcessKNum ROUT HandleFN HandleKNum TEQ R1, #2 ; is it first press ? EOREQ R5, R5, #KBStat_NoNumLock ; yes, then toggle num lock MOV PC, R14 ; (don't auto-repeat) ProcessKScroll ROUT HandleFN HandleKScroll TEQ R1, #2 ; is it first press ? EOREQ R5, R5, #KBStat_ScrollLock ; yes, then toggle scroll lock MOV PC, R14 ; (don't auto-repeat) ProcessKKana ROUT HandleFN HandleKKana TEQ R1, #2 ; is it first press ? EOREQ R5, R5, #KBStat_NoKanaLock ; yes, then toggle kana lock MOV PC, R14 ; (don't auto-repeat) ProcessKShiftCaps ROUT HandleFN HandleKShiftCaps TEQ R1, #2 ; is it first press ? MOVNE PC, R14 ; (don't auto-repeat) EOR R5, R5, #KBStat_NoCapsLock ; toggle caps lock TST R5, #KBStat_NoCapsLock ORREQ R5, R5, #KBStat_ShiftEnable ; set shift enable if caps lock on BICNE R5, R5, #KBStat_ShiftEnable MOV PC, R14 ProcessKBreak ROUT HandleFN ADD PC, R3, #4 ; offset for break routine ProcessK1Pad ROUT HandleFN TST R7, #KBAlt_AltDown BNE AltKeyPad BICS R7, R7, #KBAlt_AccentMask ; cancel accents BICEQ R5, R5, #KBStat_PendingAlt TST R5, #KBStat_NoNumLock ; test num lock LDREQ R3, [R0, #KVPadNumTran] ; num lock on LDRNE R3, [R0, #KVPadCurTran] ; num lock off ADD R3, R3, R0 LDRB R1, [R3, R4] ; get table entry TEQ R1, #&FF ; dummy key ? MOVEQ PC, R14 ; then exit LDR R6, R0OsbyteVars LDRB R2, [R6, #OsbyteKeyBase] ; add on numeric key base SUB R1, R1, #"0" ADD R1, R1, R2 LDRB R2, [R6, #OsbyteKeyOpt] ; zero => ctrl/shift modifies TEQ R2, #0 BNE %FT10 ; [don't modify] TST R1, #&80 ; top bit set ? BEQ %FT10 ; no, then don't modify TST R5, #KBStat_ShiftEngaged EORNE R1, R1, #&10 ; modify for shift TST R5, #KBStat_CtrlEngaged EORNE R1, R1, #&20 ; modify for ctrl 10 ReturnOneChar ADR R6, KeyReturn ; pass pointer back to MOS STRB R1, [R6, #1] ; having poked byte in MOV PC, R14 AltKeyPad ROUT LDR R3, [R0, #KVPadNumTran] LDRB R1, R0HexDigits ; are we doing hex? ADD R3, R3, R0 TEQ R1, #0 BNE AltKeyPadHex LDRB R3, [R3, R4] ; get value from PadK1NumTran SUB R3, R3, #"0" CMP R3, #10 ; if not in range 0-9 BICHS R7, R7, #(KBAlt_DigitsPresent :OR: KBAlt_SelectKeyboard) ; then get rid of digs + select ORRLO R7, R7, #KBAlt_DigitsPresent ; else indicate we have digits MOVHS R2, #0 ; if no digits STRHS R2, R0AltDigitValue ; then zero digits MOVHS PC, R14 ; and exit LDR R2, R0AltDigitValue MOV R1, #10 MLAS R3, R2, R1, R3 ; digits = digits*10+new digit TSTEQ R7, #KBAlt_SelectKeyboard STREQB R1, R0HexDigits ; 0 pressed first - switch to hex (not IDD) STR R3, R0AltDigitValue MOV PC, R14 AltKeyPadHex LDRB R1, [R3, R4] SUB R1, R1, #"0" ; check digits first - they're logical CMP R1, #10 BLO GotHex ADR R4, HexPadTable ; scan table of physical codes 05 LDRB R1, [R4], #2 TEQ R2, R1 LDREQB R1, [R4, #-1] BEQ GotHex TEQ R1, #0 BNE %BT05 GotHex LDR R2, R0AltDigitValue ADD R2, R1, R2, LSL #4 ; digits = digits*16+new digit STR R2, R0AltDigitValue MOV PC, R14 HexPadTable = K1NumPadSlash, &A = K1NumPadStar, &B = K1NumPadHash, &C = K1NumPadMinus, &C = K1NumPadPlus, &D = K1NumPadDot, &E = K1NumPadEnter, &F = 0 ALIGN ReturnNULChar ADR R6, KeyNULReturn STRB R1, [R6, #2] MOV PC, R14 ; ************************************************************************** ; ; In: R0->handler ; R1=action (shifting key:0,1=up,down; non-shifting:2=first,3=autorepeat) ; R2=low-level key number ; R3->table of exit points ; R4=special key number (eg 1 for first special key) ; R5=KeyBdStatus ; R6->a zero byte (so left unmodified -> no output) ; R7=PendingAltType ; R12->fixed workspace (allocated by kernel) - approx 170 bytes, not aligned ; ; Out: R0-R4 corrupted ; R5 updated ; R6->output (first byte=length, subsequent bytes to insert into buffer) ; R7 updated ProcessUCS ROUT HandleFN TST R5, #KBStat_NoKanaLock LDRNE R2, [R0, #KVUCSTable0] LDREQ R2, [R0, #KVUCSTable1] ADD R4, R4, R4, LSL #3 ; R4 = key * 9 ADD R2, R0, R2 ADD R2, R2, R4, LSL #2 ; R2 -> 36-byte entry for key TST R7, #KBAlt_DigitsPresent BNE CheckHexAtoF ; select the correct Shift/Ctrl/Alt variant. STRB R1, TempAction MOV R1, #0 TST R5, #KBStat_ShiftEngaged ORRNE R1, R1, #4 TST R5, #KBStat_CtrlEngaged ORRNE R1, R1, #8 TST R7, #KBAlt_AltDown ORRNE R1, R1, #16 02 TST R5, #KBStat_NoCapsLock BNE %FT05 ; process Caps Lock LDR R4, [R2, #32] ; get the capital-mapping word MOV R4, R4, LSR R1 AND R4, R4, #&F ; R4=alternate form for this character TST R4, #8 ; bit 3 of R4 set if only Shift-Caps changes BEQ %FT03 TST R5, #KBStat_ShiftEnable BEQ %FT05 AND R4, R4, #7 03 MOV R1, R4, LSL #2 05 LDR R1, [R2, R1] 06 TST R1, #&80000000 BNE FunnyUCS ReturnUCSAlt ANDS R2, R7, #KBAlt_AccentMask ; Check if we've got a pending accent MOVEQ R2, #-1 STREQ R2, R0FallbackCode ; clear "fallback" character BEQ ReturnUCS ; We have to apply a dead accent now. ADRL R4, AccentTable LDR R2, [R4, R2, LSL #2] ; offset to appropriate accent ADD R4, R4, R2 ; R4 now points to accent list BICS R7, R7, #KBAlt_AccentMask ; no more accents BICEQ R5, R5, #KBStat_PendingAlt ; if no more then zero status bit 07 LDR R3, [R4], #8 ; R3 = base character CMP R3, R1 BHI ReturnUCS ; we're not in the list - return char unmodified BNE %BT07 ; not found it yet STR R1, R0FallbackCode ; remember unaccented form, in case accented form ; not available LDR R1, [R4, #-4] ; R1 = accented form ; R1 = real UCS code ReturnUCS CMP R1, #&80 BLO ReturnOneOrNUL ; 00-7F always the same Push R14 BL GetAlphabetTable Pull R14 TEQ R3, #Alphabet_UTF8 BNE ReturnUCSForAlphabet ; Create the UTF-8 sequence Push R5 ADR R6, KeyUTFReturnEnd MOV R5, #2 MOV R4, #2_00100000 10 AND R2, R1, #2_00111111 ; continuation byte ORR R2, R2, #2_10000000 STRB R2, [R6, #-1]! MOV R2, #0 ; don't forget the 0 padding... STRB R2, [R6, #-1]! MOV R1, R1, LSR #6 CMP R1, R4 MOVHS R4, R4, LSR #1 ADDHS R5, R5, #1 BHS %BT10 ; and the leading byte... MOV R4, #&FF00 ORR R2, R1, R4, LSR R5 STRB R2, [R6, #-1]! MOV R2, #0 ; don't forget the 0 padding... STRB R2, [R6, #-1]! MOV R5, R5, LSL #1 STRB R5, [R6, #-1]! Pull R5 MOV PC, R14 ReturnUCSForAlphabet MOVS R3, R4 ; alphabet table BEQ ReturnUCSForNoAlphabet ; find which (if any) of codes &80-&FF is what we want MOV R6, #&80 13 LDR R2, [R3, R6, LSL #2] TEQ R1, R2 MOVEQ R1, R6 BEQ ReturnNULChar ADD R6, R6, #1 CMP R6, #&FF BLS %BT13 ; can't find it - do we have a fallback? 15 LDR R1, R0FallbackCode CMP R1, #-1 MOVNE R6, #-1 STRNE R6, R0FallbackCode ; clear fallback, else infinite loop BNE ReturnUCS ; give up - output nothing ADR R6, NowtReturn MOV PC, R14 ReturnUCSForNoAlphabet ; Assume pure ISO Latin 1 CMP R1, #&FF BHI %BT15 B ReturnNULChar FunnyUCS CMN R1, #1 ; Check for &FFFFFFFF - nothing ADREQ R6, NowtReturn BIC R1, R1, #&80000000 ; &800000xx - a raw buffer code CMP R1, #&100 ADRLO R6, KeyReturn STRLOB R1, [R6, #1] MOVLO PC, R14 ; Oooh - it's summat special CMP R1, #&10000 BLO %FT40 ; &8000xxxx - daft CMP R1, #&20000 BLO SpecialKey ; &8001xxxx - special key CMP R1, #&30000 BLO DeadKey ; &8002xxxx - dead key 40 ADRHI R6, NowtReturn MOV PC, R14 CheckHexAtoF ; We're doing something digitty - if it's hex we need to check for A-F. ; If it's not hex or A-F, we return immediately - it's not sensible to ; be outputting standard Alt symbols while doing a keypad sequence, although ; this is what pre 0.50 versions did. LDRB R4, R0HexDigits ; are we doing hex? TEQ R4, #0 MOVEQ PC, R14 LDR R4, [R2, #0] ; get the base symbol for this key BIC R4, R4, #&20 ; upper case the codes that matter CMP R4, #"A" MOVLO PC, R14 CMP R4, #"F" MOVHI PC, R14 SUB R1, R4, #"A"-10 B GotHex SpecialKey SUB R4, R1, #&10000 CMP R4, #10 LDRB R1, TempAction ADDLO PC, PC, R4, LSL #2 B %BT40 B HandleKScroll B HandleKNum B HandleKTab B HandleKCaps B HandleKKana B HandleKShiftCaps B HandleKDefaultKeyboard B HandleKConfiguredKeyboard B HandleKDialKeyboard B HandleKDelete DeadKey SUB R1, R1, #&20000 BIC R7, R7, #KBAlt_AccentMask ; clear accents ORR R7, R7, R1 ; put in new accent ORR R5, R5, #KBStat_PendingAlt ; and indicate it MOV PC, R14 ; Silly entry conditions here. Can return normally, ; preserving flags to carry on as normal, can pull PC from the stack ; to ignore the keypress altogether, or can call a new handler ; in the special table. ; ; Note that as in the HandleFN macro we're merrily scrambling R2. ; FindFN ROUT LDR R2, [R0, #KVFNTable] ; if no FN table at all TEQ R2, #0 MOVEQS PC,R14 Push "R1,R3" ADD R3, R0, R2 LDRB R2, [R3], #1 ; R2 = number of FN entries TEQ R2, #0 BEQ NoFN FNLoop LDRB R1, [R3], #2 ; R1 = base FN key, advance R3 to next entry CMP R1, R4 LDREQB R4, [R3, #-1] ; if R1 = this key, change R4 to new key BEQ FNContinue BHI NoFN ; if R1 > this key, its not there SUBS R2, R2, #1 BNE FNLoop NoFN Pull "R1,R3,PC" ; no FN entry - output nothing FNContinue ; Need to call the correct handler... LDR R2, [R0, #KVSpecialCodeTable] ADD R2, R2, R0 ; R2 -> special code table SUB R1, R2, #4 ; 0th entry is for 1st special LDR R1, [R1, R4, LSL #2] ; R1 = offset to code ADD R2, R1, R2 ; R2 = address of code ADD R2, R2, #HandleFNsize ; Skip past the FN handling code :) Pull "R1,R3,LR" MOV PC, R2 ; ************************************************************************** ; ; in: R0 -> key structure ; R1 = action (2=first,3=autorepeat) ; R2 = internal key number for char ; R3 = character which would be returned if not an ALT ; R5 = keyboard status ; R6 -> a zero byte ; R7 = pending alt type PendingAltCode ROUT TST R7, #KBAlt_AccentMask ; is it due to dead accent ? MOVEQ PC, R14 ; no, then must be Alt down - any real Alts are ; special - simple keys return nothing. ; called because of accented char MOV R1, R3 CMP R1, #&80 ; is it a Basic Latin character? BLO ReturnUCSAlt ; if so - get ProcessUCS to add the accent ; Boring - it's just a function key. Remove the dead accent and ; output the function key. BICS R7, R7, #KBAlt_AccentMask ; no more accents BICEQ R5, R5, #KBStat_PendingAlt ; if no more then zero status bit B ReturnOneChar ReturnOneOrNUL CMP R1, #0 ; if 0 then return 0 0 (C=1) CMPNE R1, #&80 ; elif -ve return 0 char BCS ReturnNULChar B ReturnOneChar ; else return 0 char HandleKDialKeyboard TST R7, #KBAlt_AltDown ; ensure Alt is down... ORRNE R7, R7, #KBAlt_SelectKeyboard ; set IDD selection flag MOV PC, R14 HandleKConfiguredKeyboard ROUT MOV R1, #&80 ; select default keyboard B SelectKeyboard HandleKDefaultKeyboard MOV R1, #&81 ; select UK keyboard SelectKeyboard MOV R3, PC AND R3, R3, #3 EOR R3, R3, #SVC_mode TEQP R3, PC ; select SVC mode NOP ; wait for it to happen Push R14 ADR R0, CallBack_SelectKeyboard SWI XOS_AddCallBack ; R1 already set up Pull R14 TEQP R3, PC ; reenter previous mode NOP ; wait for it to happen ReturnNowt ADR R6, NowtReturn ; return nowt MOV PC, R14 CallBack_SelectKeyboard Push "R0-R2,R14" MOV R0, #OsbyteSetAlphKey MOV R1, R12 ; R12 used to pass keyboard + &80 SWI XOS_Byte Pull "R0-R2,PC" ; ************************************************************************** ; ; Reverse table lookup for INKEY(-ve) ; ; For reference, here is the definitive internal key list. A number of codes ; are for BBC compatibility. For example, code 71 was the "@" key on the ; BBC micro - there was no separate @ key on the Archimedes UK layout, ; so the 2 key (Shift-2 was @) generates this internal code. These compatibility ; codes should not be used by new programs. ; ; Don't forget that these codes are supposed to be for _physical_ keys - ; the code for the key to the left of backspace never changes, no matter ; how it is marked. ; ; Internal code Key Low-level codes ; 0 Shift 4C or 58 ; 1 Ctrl 3B or 61 ; 2 Alt 5E or 60 ; 3 Left Shift 4C ; 4 Left Ctrl 3B ; 5 Left Alt 5E ; 6 Right Shift 58 ; 7 Right Ctrl 61 ; 8 Right Alt 60 ; 9 Select 70 ; 10 Menu 71 ; 11 Adjust 72 ; 12 FN 6F ; 13 (not defined) ; 14 (not defined) ; 15 (not defined) ; 16 Q 27 ; 17 3 13 ; 18 4 14 ; 19 5 15 ; 20 F4 04 ; 21 8 18 ; 22 F7 07 ; 23 - 1B ; 24 ^ 16 (BBC compatibility - see 52) ; 25 Left Arrow 62 ; 26 Keypad 6 4A ; 27 Keypad 7 37 ; 28 F11 0B ; 29 F12 0C ; 30 F10 0A ; 31 Scroll Lock 0E ; 32 Print 0D ; 33 W 28 ; 34 E 29 ; 35 T 2B ; 36 7 17 ; 37 I 2E ; 38 9 19 ; 39 0 1A ; 40 _ 1B (BBC compatibility - see 23) ; 41 Down Arrow 63 ; 42 Keypad 8 38 ; 43 Keypad 9 39 ; 44 Break 0F ; 45 ` 10 ; 46 Pound 1D (not fitted) ; 47 Backspace 1E ; 48 1 11 ; 49 2 12 ; 50 D 3E ; 51 R 2A ; 52 6 16 ; 53 U 2D ; 54 O 2F ; 55 P 30 ; 56 [ 31 ; 57 Up Arrow 59 ; 58 Keypad + 4B ; 59 Keypad - 39 ; 60 Keypad Enter 67 ; 61 Insert 1F ; 62 Home 20 ; 63 Page Up 21 ; 64 Caps Lock 5D ; 65 A 3C ; 66 X 4F ; 67 F 3F ; 68 Y 2C ; 69 J 42 ; 70 K 43 ; 71 @ 12 (BBC compatibility - see 49) ; 72 : 45 ; 73 Enter 47 ; 74 Keypad / 23 ; 75 Keypad Delete (not mapped) ; 76 Keypad . 66 ; 77 Num Lock 22 ; 78 Page Down 36 ; 79 ' 46 ; 80 Shift Lock (not mapped) ; 81 S 3D ; 82 C 50 ; 83 G 40 ; 84 H 41 ; 85 N 53 ; 86 L 44 ; 87 ; 45 (BBC compatibility - see 72) ; 88 ] 32 ; 89 Delete 34 ; 90 Keypad # 25 (not normally fitted) ; 91 Keypad * 24 ; 92 Keypad , (not mapped) ; 93 = 1C ; 94 \ 4D ; 95 Not fitted (R) 6E (between / and Shift on Japanese keyboard) ; 96 Tab 26 ; 97 Z 4E ; 98 Space 5F ; 99 V 51 ; 100 B 52 ; 101 M 54 ; 102 , 55 ; 103 . 56 ; 104 / 57 ; 105 End 35 ; 106 Keypad 0 65 ; 107 Keypad 1 5A ; 108 Keypad 3 5C ; 109 No Convert 6B ; 110 Convert 6C ; 111 Kana 6D ; 112 Escape 00 ; 113 F1 01 ; 114 F2 02 ; 115 F3 03 ; 116 F5 05 ; 117 F6 06 ; 118 F8 08 ; 119 F9 09 ; 120 # (\ on BBC+Arch) 33 ; 121 Right Arrow 64 ; 122 Keypad 4 48 ; 123 Keypad 5 49 ; 124 Keypad 2 5B ; 125 Left Acorn 68 ; 126 Right Acorn 69 ; 127 Menu 6A InkeyTran IKT &6A, &69, &68, &5B, &49, &48, &64, &33 ; 80-87 IKT &09, &08, &06, &05, &03, &02, &01, &00 ; 88-8F IKT &6D, &6C, &6B, &5C, &5A, &65, &35, &57 ; 90-97 IKT &56, &55, &54, &52, &51, &5F, &4E, &26 ; 98-9F IKT &6E, &4D, &1C, &FF, &24, &25, &34, &32 ; A0-A7 IKT &45, &44, &53, &41, &40, &50, &3D, &FF ; A8-AF IKT &46, &36, &22, &66, &FF, &23, &47, &45 ; B0-B7 IKT &12, &43, &42, &2C, &3F, &4F, &3C, &5D ; B8-BF IKT &21, &20, &1F, &67, &3A, &4B, &59, &31 ; C0-C7 IKT &30, &2F, &2D, &16, &2A, &3E, &12, &11 ; C8-CF IKT &1E, &1D, &10, &0F, &39, &38, &63, &1B ; D0-D7 IKT &1A, &19, &2E, &17, &2B, &29, &28, &0D ; D8-DF IKT &0E, &0A, &0C, &0B, &37, &4A, &62, &16 ; E0-E7 IKT &1B, &07, &18, &04, &15, &14, &13, &27 ; E8-EF IKT &FF, &FF, &FF, &6F, &72, &71, &70, &60 ; F0-F7 IKT &61, &58, &5E, &3B, &4C, &5E60, &3B61, &4C58 ; F8-FF ; ************************************************************************** ShiftingKeyList = ShiftingKeyListEnd-ShiftingKeyList-1 = K1ShiftLeft, K1ShiftRight, K1CtrlLeft, K1CtrlRight = K1AltLeft, K1AltRight, K1FN = K1RightMouse, K1CentreMouse, K1LeftMouse, K1Break ShiftingKeyListEnd ALIGN ; ************************************************************************** ; ; A general purpose special code list used by most UCS keyboard drivers - ; long enough for lots of keys, every one special. ; SpecialCodeTable & ProcessKShift - SpecialCodeTable & ProcessKShift - SpecialCodeTable & ProcessKCtrl - SpecialCodeTable & ProcessKCtrl - SpecialCodeTable & ProcessKAlt - SpecialCodeTable & ProcessKAlt - SpecialCodeTable & ProcessKFN - SpecialCodeTable & ProcessKLeft - SpecialCodeTable & ProcessKCentre - SpecialCodeTable & ProcessKRight - SpecialCodeTable & ProcessKBreak - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessK1Pad - SpecialCodeTable & ProcessKScroll - SpecialCodeTable & ProcessKNum - SpecialCodeTable & ProcessKTab - SpecialCodeTable & ProcessKCaps - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable & ProcessUCS - SpecialCodeTable SpecialCodeTableEnd ; And the default keypad layout. PadKNumTran = "/*#789-456+1230.",&0D PadKCurTran = "/*#",&1E,&8F,&9F,"-",&8C,&FF,&8D,"+",&8B,&8E,&9E,&CD,&7F,&0D ALIGN END