CoolKey.pas 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. {$G+}
  2. UNIT CoolKey; {“¤®¡­ ï,   £« ¢­®¥ ¡ëáâà ï à ¡®â  á ª« ¢¨ âãன.
  3. �®«ì訥 ¢®§¬®¦­®áâ¨}
  4. INTERFACE
  5. {$C FIXED PRELOAD PERMANENT}
  6. Uses Dos;
  7. {$F+,S-,W-}
  8. Var
  9. ifCaps,ifScroll,ifNum : boolean;
  10. CodeBuffer : array [0..255] of byte;
  11. PressBuffer : array [0..255] of boolean;
  12. BufB,BufE : byte;
  13. Type
  14. EScanCode = (SC_BUFFULL, SC_ESCAPE, SC_1, SC_2, SC_3, SC_4, SC_5 ,SC_6, SC_7,
  15. SC_8, SC_9, SC_0, SC_MINUS, SC_EQUAL, SC_BACKSPACE, SC_TAB,
  16. SC_Q,SC_W,SC_E,SC_R,SC_T,SC_Y,SC_U,SC_I,SC_O,SC_P,SC_LBR,SC_RBR,
  17. SC_ENTER,SC_LCTRL,SC_A,SC_S,SC_D,SC_F,SC_G,SC_H,SC_J,SC_K,SC_L,
  18. SC_SEMICOLON,SC_AMPERSAND,SC_TILDE,SC_LSHIFT,SC_BACKSLASH,
  19. SC_Z,SC_X,SC_C,SC_V,SC_B,SC_N,SC_M,SC_COMMA,SC_PERIOD,SC_SLASH,
  20. SC_RSHIFT,SC_GREY_MUL,SC_LALT,SC_SPACE,SC_CAPSLOCK,SC_F1,SC_F2,
  21. SC_F3,SC_F4,SC_F5,SC_F6,SC_F7,SC_F8,SC_F9,SC_F10,SC_NUMLOCK,
  22. SC_SCROLLLOCK,SC_PAD_HOME,SC_PAD_UP,SC_PAD_PGUP,SC_GRAY_SUB,
  23. SC_PAD_LEFT,SC_PAD_5,SC_PAD_RIGHT,SC_GRAY_ADD,SC_PAD_END,
  24. SC_PAD_DOWN,SC_PAD_PGDN,SC_PAD_INS,SC_PAD_DEL, {Primary over}
  25. SC_SYSREQ,SC_NOTE1_F11,SC_L102,SC_F11,SC_F12,SC_NOTE1_F15,
  26. SC_PA1,SC_LWin,SC_RWIN,SC_MENU,SC_5E,SC_5F,SC_60,SC_61,SC_62,
  27. SC_F16,SC_F17,SC_F18,SC_F19,SC_F20,SC_F21,SC_F22,SC_F23,SC_F24,
  28. SC_6C,SC_ERASEOEF,SC_6E,SC_COPYPLAY,SC_70,SC_71,SC_CrSel,SC_DELTA,
  29. SC_EXSEL,SC_75,SC_CLEAR,SC_77,SC_78,SC_79,SC_7A,SC_7B,SC_7C,SC_7D,
  30. SC_7E,SC_7F,
  31. {ADDITION TO TABLE, prefixed by 0E0h }
  32. SC_80,SC_81,SC_82,SC_83,SC_84,SC_85,SC_86,SC_87,SC_88,SC_89,SC_8A,SC_8B,SC_8C,SC_8D,SC_8E,SC_8F,
  33. SC_90,SC_91,SC_92,SC_93,SC_94,SC_95,SC_96,SC_97,SC_98,SC_99,SC_9A,SC_9B,SC_PAD_ENTER,SC_RCTRL,SC_9E,SC_9F,
  34. SC_A0,SC_A1,SC_A2,SC_A3,SC_A4,SC_A5,SC_A6,SC_A7,SC_A8,SC_A9,SC_PREFIX,SC_AB,SC_AC,SC_AD,SC_AE,SC_AF,
  35. SC_B0,SC_B1,SC_B2,SC_B3,SC_B4,SC_PAD_DIV,SC_B6,SC_PRINTSCREEN,SC_RALT,SC_B9,SC_BA,SC_BB,SC_BC,SC_BD,SC_BE,SC_BF,
  36. SC_C0,SC_C1,SC_C2,SC_C3,SC_C4,SC_C5,SC_C6,SC_HOME,SC_UP,SC_PGUP,SC_CA,SC_LEFT,SC_CC,SC_RIGHT,SC_CE,SC_END,
  37. SC_DOWN,SC_PGDN,SC_INSERT,SC_DELETE,SC_D4,SC_D5,SC_D6,SC_D7,SC_D8,SC_D9,SC_DA,SC_DB,SC_DC,SC_DD,SC_DE,SC_DF,
  38. SC_E0,SC_E1,SC_E2,SC_E3,SC_E4,SC_E5,SC_E6,SC_E7,SC_E8,SC_E9,SC_EA,SC_EB,SC_EC,SC_ED,SC_EE,SC_EF,
  39. SC_F0,SC__F1,SC__F2,SC__F3,SC__F4,SC__F5,SC__F6,SC__F7,SC__F8,SC__F9,SC_FA,SC_FB,SC_FC,SC_FD,SC_FE,SC_FF);
  40. TKeyTable = array [EScanCode] of boolean;
  41. PKeyTable = ^TKeyTable; {ƒ« ¢­ë© ⨯ ¬®¤ã«ï, ¬ áᨢ ­ ¦ âëå ª­®¯®ª}
  42. CONST
  43. SC_NAME : array [EScanCode] of string [15] =
  44. ('','Escape','1','2','3','4','5','6','7','8','9','0','Substract',
  45. 'Equal','Backspace','Tab','Q','W','E','R','T','Y','U','I','O','P',
  46. 'Left Bracket','Right Bracket','Enter', 'Left Ctrl','A','S','D','F','G','H',
  47. 'J','K','L','Semicolon','Ampersand','Tilde','Left Shift','Back Slash','Z',
  48. 'X','C','V','B','N','M',
  49. 'Comma','Period','Slash','Right Shift','Grey *','Left Alt',
  50. 'SpaceBar','CapsLock','F1','F2','F3','F4','F5','F6','F7','F8','F9','F10',
  51. 'NumLock','ScrollLock','Pad Home','Pad Up','Pad PgUp','Gray -','Pad Left',
  52. 'Pad 5','Pad Right','Gray +','Pad End','Pad Down','Pad PgDn','Pad Ins',
  53. 'Pad Del','','','','F11','F12','','','Left Win','Right Win','Menu','5E','5F',
  54. '60','61','62','63','64','65','66','67','68','69','6A','6B','6C','6D','6E',
  55. '6F','70','71','72','73','74','75','76','77','78','79','7A','7B','7C','7D',
  56. '7E','7F', {Full Original PC/XT Keyboard}
  57. {Begining of 101-key}
  58. '80','81','!','@','#','$','%','^','&','*','(',')','_','+','8E','8F','90','91',
  59. '92','93','94','96','96','97','98','99','9A','9B','Pad Enter', 'Right Ctrl',
  60. '9E','9F','A0','A1','A2','A3','A4','A5','A6','A7','A8','A9','Prefix1','AB',
  61. 'AC','AD','AE','AF','B0','B1','B2','B3','B4','Pad Div','Prefix2','Printscreen',
  62. 'Right Alt','B9','BA','BB','BC','BD','BE','BF','C0','C1','C2','C3','C4','C5',
  63. 'C6','Home','Up','PgUp','CA','Left','CC','Right','CE','End','Down','PgDn',
  64. 'Insert','Delete','D4','D5','D6','D7','D8','D9','DA','Left Win','Right Win',
  65. 'Menu','DE','DF','E0','E1','E2','E3','E4','E5','E6','E7','E8','E9','EA',
  66. 'EB','EC','ED','EE','EF','F0','F1','F2','F3','F4','F5','F6','F7','F8','F9',
  67. 'FA','FB','FC','FD','FE','FF');
  68. Function InitKeyboard : PKeyTable; {�¥à¥å¢ â INT09. ‚®§¢à. 㪠­  â ¡«¨æã}
  69. Function GetChar(aSC : byte):Char;
  70. Function GetScanCode(var aC:EScanCode; var Pressed:Boolean):Boolean;
  71. Procedure CloseKeyboard; {‚®§¢à â ¯à¥à뢠­¨ï. ‚ë室}
  72. IMPLEMENTATION
  73. const
  74. gInited : boolean = false;
  75. lastPref : byte = 0;
  76. var
  77. KeyTable : TKeyTable;
  78. OldINT09 : Pointer;
  79. Procedure NewInt09;far;assembler;
  80. asm
  81. push ax
  82. push bx
  83. push si
  84. push es
  85. push cx
  86. push dx
  87. xor bx, bx
  88. xor ax, ax
  89. in al, 60h
  90. cmp al, 0E0h
  91. jz @@SETPREF
  92. mov cl, al
  93. mov bl, al {Save real value}
  94. and bl, 7Fh
  95. add bl, lastPref {Calculate table offset}
  96. mov si, offset KeyTable {Load table}
  97. add si, bx {Add index}
  98. shr al, 7
  99. not al
  100. and al, 1
  101. mov ds:[si], al
  102. mov si, offset CodeBuffer
  103. xor dx, dx
  104. mov dl, BufE
  105. cmp dl, 255
  106. jz @@HERE
  107. add si, dx
  108. mov ds:[si], bl
  109. mov si, offset PressBuffer
  110. add si, dx
  111. mov ds:[si], al
  112. inc dx
  113. mov byte ptr BufE, dl
  114. @@HERE:
  115. mov lastPref, 0
  116. cmp cl, 3Ah
  117. jz @@CAPS
  118. cmp cl, 45h
  119. jz @@NUM
  120. cmp cl, 46h
  121. jz @@SCROLL
  122. jmp @@OUT2
  123. @@CAPS:
  124. mov al, ifCaps
  125. not al
  126. and al, 1
  127. mov byte ptr ifCaps, al
  128. jmp @@OUT
  129. @@NUM:
  130. mov al, ifNum
  131. not al
  132. and al, 1
  133. mov byte ptr ifNum, al
  134. jmp @@OUT
  135. @@SCROLL:
  136. mov al, ifScroll
  137. not al
  138. and al, 1
  139. mov byte ptr ifScroll, al
  140. jmp @@OUT
  141. @@SETPREF:
  142. mov lastPref, 80h {This equals offset of extended keys}
  143. jmp @@out2
  144. @@OUT:
  145. mov ah, byte ptr ifCaps {Create lights}
  146. shl ah, 1 {bits}
  147. mov al, byte ptr ifNum
  148. or ah, al
  149. shl ah, 1
  150. mov al, byte ptr ifScroll
  151. or ah, al
  152. mov al, ah
  153. shl al, 4
  154. push 0
  155. pop es
  156. mov byte ptr es:[417h], al
  157. mov cx, 0 {Wait controller}
  158. @@WL1: {}
  159. in al, 64h {}
  160. and al, 2h {}
  161. loopnz @@WL1 {}
  162. mov al, 0edh {We are going to change lights}
  163. out 60h, al {}
  164. mov cx, 0
  165. @@WL2:
  166. in al, 64h
  167. and al, 2h
  168. loopnz @@WL2
  169. mov al, ah {Here we got our lights}
  170. out 60h, al
  171. @@OUT2:
  172. pop dx
  173. pop cx
  174. pop es
  175. pop si
  176. pop bx
  177. in al, 61h { Get value of keyboard control lines}
  178. mov ah, al { save it }
  179. or al, 80h { set the "enable kbt" bit }
  180. out 61h, al { and write it out the contorl port }
  181. xchg ah, al { fetch the original value }
  182. out 61h, al { and write it back }
  183. mov al, 20h { Send End-Of-Interrupt signal }
  184. out 20h, al { to the 8259 Interrupt Controller }
  185. pop ax
  186. iret
  187. end;{NewInt09}
  188. {-------------------------------}
  189. Function GetScanCode(var aC:EScanCode; var Pressed:Boolean):Boolean;
  190. begin
  191. if BufB <> BufE then
  192. begin
  193. aC := EScanCode(CodeBuffer[BufB]);
  194. Pressed := PressBuffer[BufB];
  195. inc(BufB);
  196. GetScanCode := true;
  197. end
  198. else
  199. begin
  200. BufB:=0;
  201. BufE:=0;
  202. GetScanCode := false;
  203. end;
  204. end;
  205. Function InitKeyboard : PKeyTable; {�¥à¥å¢ â INT09. ‚®§¢à. 㪠­  â ¡«¨æã}
  206. begin
  207. if gInited then Exit;
  208. FillChar(KeyTable,256,0); {Zeroes keys table}
  209. FillChar(CodeBuffer,256,0); {Zeroes keys table}
  210. FillChar(PressBuffer,256,0); {Zeroes keys table}
  211. BufB:=0;
  212. BufE:=0;
  213. GetIntVec($09,OldINT09);
  214. SetIntVec($09,Addr(NewINT09));
  215. gInited := true;
  216. InitKeyBoard := @KeyTable;
  217. end;{Init keyboard}
  218. {------------------------}
  219. Procedure CloseKeyboard; {‚®§¢à â ¯à¥à뢠­¨ï. ‚ë室}
  220. begin
  221. if not gInited then exit;
  222. SetIntVec($09,OldInt09);
  223. gInited := false;
  224. end;{CloseKeyboard}
  225. Function GetChar(aSC : byte):Char;
  226. begin
  227. GetChar := #0;
  228. if EScanCode(aSC) in [SC_Q..SC_P,SC_A..SC_L,SC_Z..SC_M] then
  229. begin
  230. if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] or ifCaps then
  231. GetChar := SC_NAME[EScanCode(aSC)][1]
  232. else
  233. GetChar := chr(ord(SC_NAME[EScanCode(aSC)][1]) + $20);
  234. exit;
  235. end;
  236. if EScanCode(aSC) in [SC_1..SC_0] then
  237. begin
  238. if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  239. GetChar := SC_NAME[EScanCode(aSC + ord(SC_80))][1]
  240. else
  241. GetChar := SC_NAME[EScanCode(aSC)][1];
  242. exit;
  243. end;
  244. case EScanCode(aSC) of
  245. SC_MINUS: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  246. GetChar := '_' else GetChar := '-';
  247. SC_EQUAL: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  248. GetChar := '+' else GetChar := '=';
  249. SC_BACKSLASH: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  250. GetChar := '|' else GetChar := '\';
  251. SC_LBR: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  252. GetChar := '{' else GetChar := '[';
  253. SC_RBR: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  254. GetChar := '}' else GetChar := '}';
  255. SC_SEMICOLON: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  256. GetChar := ':' else GetChar := ';';
  257. SC_AMPERSAND: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  258. GetChar := ':' else GetChar := '''';
  259. SC_COMMA: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  260. GetChar := '<' else GetChar := ',';
  261. SC_PERIOD: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  262. GetChar := '>' else GetChar := '.';
  263. SC_SLASH: if KeyTable[SC_LSHIFT] or KeyTable[SC_RSHIFT] then
  264. GetChar := '?' else GetChar := '/';
  265. SC_SPACE: GetChar := ' ';
  266. end;
  267. end;
  268. END.