KEYBOARD.LST 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. Listing:
  2. 1 (* Release 3.10 *)
  3. 2 (*-------------------------------------------------------------------------*
  4. 3 * *
  5. 4 * KEYBOARD.MOD - COMMS Toolkit Keyboard interface *
  6. 5 * *
  7. 6 * COPYRIGHT (C) 1988..1992 Clarion Software Corporation. *
  8. 7 * All Rights Reserved *
  9. 8 * *
  10. 9 *--------------------------------------------------------------------------*)
  11. 10
  12. 11 IMPLEMENTATION MODULE Keyboard;
  13. 12
  14. 13 (*%F _OS2*)
  15. 14 IMPORT Lib,SYSTEM;
  16. 15
  17. 16 CONST
  18. 17 KbdDriverInstalled = FALSE;
  19. 18 KbdInterrupt = 09H; (* kbd interrupts handler consts *)
  20. 19 KbdDataPort = 60H;
  21. 20 KbdControlPort = 61H;
  22. 21 ClrKbdBit = 7;
  23. 22 KbdQueueSize = 16;
  24. 23 RightShiftActive = 0; (* kbd status word bit numbers *)
  25. 24 LeftShiftActive = 1;
  26. 25 ControlActive = 2;
  27. 26 AltActive = 3;
  28. 27 ScrollLockActive = 4;
  29. 28 NumLockActive = 5;
  30. 29 CapsLockActive = 6;
  31. 30 InsertActive = 7;
  32. 31 ScrollLockHeld = 12;
  33. 32 NumLockHeld = 13;
  34. 33 CapsLockHeld = 14;
  35. 34 InsertHeld = 15;
  36. 35 NumLock = 69; (* SCAN CODES FOR VARIOUS KEYS *)
  37. 36 BreakKey = 70;
  38. 37 ScrollLock = 70;
  39. 38 AltKey = 56;
  40. 39 CtlKey = 29;
  41. 40 CapsLock = 58;
  42. 41 LeftShift = 42;
  43. 42 RightShift = 54;
  44. 43
  45. 44 TYPE
  46. 45 Reg = RECORD
  47. 46 CASE : BOOLEAN OF
  48. 47 TRUE : X : CARDINAL; |
  49. 48 FALSE : H : SHORTCARD;
  50. 49 L : SHORTCARD; |
  51. 50 END; (*CASE*)
  52. 51 END; (*RECORD*)
  53. 52
  54. 53 VAR (* keyboard stuff *)
  55. 54 KbdFlags [40H:17H] : BITSET;
  56. 55 (*$W+*)
  57. 56 KbdQueue [40H:1AH] : RECORD
  58. 57 rptr,wptr : CARDINAL;
  59. 58 Buff : ARRAY[0..KbdQueueSize-1] OF
  60. 59 RECORD
  61. 60 key,scan : CHAR
  62. 61 END;
  63. 62 END;
  64. 63 (*$W-*)
  65. 64 Extended : BOOLEAN;
  66. 65 OldVect9,OldVect16 : FarADDRESS;
  67. 66 Continue : PROC;
  68. 67
  69. 68 (*.............................................*)
  70. 69
  71. 70 PROCEDURE SetVector(Int:WORD;Addr:FarADDRESS);
  72. 71 VAR
  73. 72 r : SYSTEM.Registers;
  74. 73 BEGIN
  75. 74 r.AH := 25H;
  76. 75 r.AL := BYTE(Int);
  77. 76 r.DS := SYSTEM.Seg(Addr^);
  78. 77 r.DX := SYSTEM.Ofs(Addr^);
  79. 78 Lib.Intr(r,21H); (* DOS Interrupt *)
  80. 79 END SetVector;
  81. 80
  82. 81 (*.............................................*)
  83. 82
  84. 83 PROCEDURE GetVector(Int:WORD):FarADDRESS;
  85. 84 VAR
  86. 85 r : SYSTEM.Registers;
  87. 86 BEGIN
  88. 87 r.AH := 35H;
  89. 88 r.AL := BYTE(Int);
  90. 89 Lib.Intr(r,21H); (* DOS Interrupt *)
  91. 90 RETURN [r.ES:r.BX];
  92. 91 END GetVector;
  93. 92
  94. 93 (*.............................................*)
  95. 94
  96. 95 PROCEDURE StoreKey(c:CHAR; code:CARDINAL);
  97. 96 VAR
  98. 97 newwptr,capc : CARDINAL;
  99. 98 BEGIN
  100. 99 WITH KbdQueue DO
  101. 100 newwptr := wptr+2;
  102. 101 IF newwptr=62 THEN
  103. 102 newwptr:=30;
  104. 103 END;
  105. 104 IF newwptr<>rptr THEN
  106. 105 capc := ORD(CAP(c));
  107. 106 IF (ControlActive IN KbdFlags) AND (capc>64) AND (capc<96) THEN
  108. 107 c := CHR(capc-64);
  109. 108 ELSIF (c>='a') AND (c<='z') AND (CapsLockActive IN KbdFlags) THEN
  110. 109 c := CHR(capc)
  111. 110 END;
  112. 111 Buff[(wptr-30)>>1].key := c;
  113. 112 Buff[(wptr-30)>>1].scan := CHR(code);
  114. 113 wptr := newwptr;
  115. 114 ELSE
  116. 115 Lib.Sound(200);
  117. 116 Lib.Delay(50);
  118. 117 Lib.NoSound;
  119. 118 END;
  120. 119 END;
  121. 120 END StoreKey;
  122. 121
  123. 122 (*.............................................*)
  124. 123
  125. 124 PROCEDURE Shifted():BOOLEAN;
  126. 125 BEGIN
  127. 126 RETURN KbdFlags*{LeftShiftActive,RightShiftActive}<>{};
  128. 127 END Shifted;
  129. 128
  130. 129 (*.............................................*)
  131. 130
  132. 131 (*# save, call(interrupt=>on,reg_saved=>(ax,bx,cx,dx,di,si,ds,es,st1,st2),reg_param=>(),same_ds=>off)*)
  133. 132 (* NB, The interrupt pragma sets up the registers as parameters to the *)
  134. 133 (* procedure in the order defined below. This ollows easy access to *)
  135. 134 (* the entry registers. *)
  136. 135 PROCEDURE KeyboardInterrupt;
  137. 136 CONST
  138. 137 Row1 = '1234567890-=';
  139. 138 Row1Shifted = '!"#$%^&*()_+';
  140. 139 Row2 = 'qwertyuiop[]';
  141. 140 Row2Shifted = 'QWERTYUIOP{}';
  142. 141 Row3 = "asdfghjkl;'`";
  143. 142 Row3Shifted = 'ASDFGHJKL:@~';
  144. 143 Row4 = '\zxcvbnm,./';
  145. 144 Row4Shifted = '|ZXCVBNM<>?';
  146. 145 KeyPad = '789-456+1230.';
  147. 146 VAR
  148. 147 code : CARDINAL;
  149. 148 ch,resetkb,
  150. 149 kbcontrol : CHAR;
  151. 150 BEGIN
  152. 151 ch := CHAR(SYSTEM.In(KbdDataPort)); (* read char *)
  153. 152 IF ORD(ch)<128 (* key press *) THEN
  154. 153 code := ORD(ch);
  155. 154 CASE code OF
  156. 155 1 : StoreKey(CHR(27),1); |
  157. 156 2..13 : IF AltActive IN KbdFlags THEN
  158. 157 StoreKey(0C,120+code-2);
  159. 158 ELSIF Shifted() THEN
  160. 159 StoreKey(Row1Shifted[code-2],code);
  161. 160 ELSE
  162. 161 StoreKey(Row1[code-2],code);
  163. 162 END; |
  164. 163 14 : IF Shifted() OR (ControlActive IN KbdFlags) THEN
  165. 164 StoreKey(CHR(127),14)
  166. 165 ELSE
  167. 166 StoreKey(CHR(8),14);
  168. 167 END; |
  169. 168 15 : IF Shifted() THEN
  170. 169 StoreKey(0C,15)
  171. 170 ELSE
  172. 171 StoreKey(CHR(9),15)
  173. 172 END; |
  174. 173 16..27 : IF AltActive IN KbdFlags THEN
  175. 174 StoreKey(0C,code)
  176. 175 ELSIF Shifted() THEN
  177. 176 StoreKey(Row2Shifted[code-16],code)
  178. 177 ELSE
  179. 178 StoreKey(Row2[code-16],code)
  180. 179 END; |
  181. 180 28 : IF ControlActive IN KbdFlags THEN
  182. 181 ch := CHR(10)
  183. 182 ELSE
  184. 183 ch := CHR(13)
  185. 184 END;
  186. 185 StoreKey(ch,28); |
  187. 186 CtlKey : INCL(KbdFlags,ControlActive) |
  188. 187 30..41 : IF AltActive IN KbdFlags THEN
  189. 188 StoreKey(0C,code)
  190. 189 ELSIF Shifted() THEN
  191. 190 StoreKey(Row3Shifted[code-30],code)
  192. 191 ELSE
  193. 192 StoreKey(Row3[code-30],code)
  194. 193 END; |
  195. 194 LeftShift : INCL(KbdFlags,LeftShiftActive); |
  196. 195 43..53 : IF AltActive IN KbdFlags THEN
  197. 196 StoreKey(0C,code)
  198. 197 ELSIF Shifted() THEN
  199. 198 StoreKey(Row4Shifted[code-43],code)
  200. 199 ELSE
  201. 200 StoreKey(Row4[code-43],code)
  202. 201 END; |
  203. 202 RightShift : INCL(KbdFlags,RightShiftActive); |
  204. 203 55 : StoreKey('*',55); |
  205. 204 AltKey : INCL(KbdFlags,AltActive); |
  206. 205 57 : StoreKey(' ',57); |
  207. 206 CapsLock : KbdFlags := KbdFlags/{CapsLockActive};
  208. 207 INCL(KbdFlags,CapsLockHeld); |
  209. 208 59..68 : IF AltActive IN KbdFlags THEN
  210. 209 StoreKey(0C,code+45)
  211. 210 ELSIF ControlActive IN KbdFlags THEN
  212. 211 StoreKey(0C,code+35)
  213. 212 ELSIF Shifted() THEN
  214. 213 StoreKey(0C,code+25)
  215. 214 ELSE
  216. 215 StoreKey(0C,code);
  217. 216 END; |
  218. 217 NumLock,
  219. 218 BreakKey : IF AltActive IN KbdFlags THEN
  220. 219 StoreKey(0C,code);
  221. 220 END; |
  222. 221 71..83 : IF KbdFlags*{AltActive,ControlActive}<>{} THEN
  223. 222 StoreKey(0C,code+62)
  224. 223 ELSIF Shifted() THEN
  225. 224 StoreKey(KeyPad[code-71],code)
  226. 225 ELSE
  227. 226 IF code=82 THEN
  228. 227 KbdFlags := KbdFlags/{InsertActive};
  229. 228 INCL(KbdFlags,InsertHeld);
  230. 229 END;
  231. 230 StoreKey(0C,code);
  232. 231 END; |
  233. 232 ELSE
  234. 233 StoreKey(0C,code);
  235. 234 END
  236. 235 ELSE
  237. 236 ch := CHR(ORD(ch)-128); (* KEY RELEASE *)
  238. 237 CASE ORD(ch) OF
  239. 238 AltKey : EXCL(KbdFlags,AltActive); |
  240. 239 CtlKey : EXCL(KbdFlags,ControlActive); |
  241. 240 LeftShift : EXCL(KbdFlags,LeftShiftActive); |
  242. 241 RightShift : EXCL(KbdFlags,RightShiftActive); |
  243. 242 CapsLock : EXCL(KbdFlags,CapsLockHeld); |
  244. 243 82 : EXCL(KbdFlags,InsertHeld); |
  245. 244 END;
  246. 245 END;
  247. 246 kbcontrol := CHAR(SYSTEM.In(KbdControlPort));
  248. 247 resetkb := CHR(CARDINAL(BITSET(ORD(kbcontrol))+{ClrKbdBit}));
  249. 248 SYSTEM.Out(KbdControlPort,SHORTCARD(resetkb));
  250. 249 SYSTEM.Out(KbdControlPort,SHORTCARD(kbcontrol));
  251. 250 SYSTEM.Out(20H,20H); (* send EOI to interrupt controller *)
  252. 251 END KeyboardInterrupt;
  253. 252 (*# restore *)
  254. 253
  255. 254 (*.............................................*)
  256. 255
  257. 256 PROCEDURE RdKey():CHAR;
  258. 257 VAR
  259. 258 c : CHAR;
  260. 259 R : SYSTEM.Registers;
  261. 260 BEGIN
  262. 261 IF Extended THEN
  263. 262 c := ScanCode;
  264. 263 Extended:=FALSE
  265. 264 ELSE
  266. 265 IF KbdDriverInstalled THEN
  267. 266 WITH KbdQueue DO
  268. 267 WHILE rptr=wptr DO
  269. 268 (* Wait for keypress *)
  270. 269 END;
  271. 270 WITH Buff[(rptr-30)>>1] DO
  272. 271 c := key;
  273. 272 ScanCode := scan;
  274. 273 END;
  275. 274 rptr := rptr+2;
  276. 275 IF rptr=62 THEN
  277. 276 rptr:=30;
  278. 277 END;
  279. 278 END;
  280. 279 ELSE
  281. 280 R.AH := 0;
  282. 281 Lib.Intr(R,16H);
  283. 282 IF R.AX=0 THEN END; (* break *) (* --- ??? --- *)
  284. 283 c := CHR(R.AL);
  285. 284 ScanCode := CHR(R.AH);
  286. 285 END;
  287. 286 END;
  288. 287 Extended := c=0C;
  289. 288 RETURN c;
  290. 289 END RdKey;
  291. 290
  292. 291 (*.............................................*)
  293. 292
  294. 293 PROCEDURE KeyPressed():BOOLEAN;
  295. 294 VAR
  296. 295 R : SYSTEM.Registers;
  297. 296 BEGIN
  298. 297 IF Extended THEN
  299. 298 RETURN TRUE;
  300. 299 END;
  301. 300 IF KbdDriverInstalled THEN
  302. 301 RETURN KbdQueue.rptr<>KbdQueue.wptr;
  303. 302 ELSE
  304. 303 R.AH := 1;
  305. 304 Lib.Intr(R,16H);
  306. 305 RETURN NOT (SYSTEM.ZeroFlag IN R.Flags) ;
  307. 306 END;
  308. 307 END KeyPressed;
  309. 308
  310. 309 (*.............................................*)
  311. 310
  312. 311 (*# save, call(interrupt=>on,reg_saved=>(ax,bx,cx,dx,di,si,ds,es,st1,st2),reg_param=>(),same_ds=>off)*)
  313. 312 (* NB, The interrupt pragma sets up the registers as parameters to the *)
  314. 313 (* procedure in the order defined below. This ollows easy access to *)
  315. 314 (* the entry registers. *)
  316. 315 PROCEDURE BiosKbd(Flags:BITSET;CS,IP:CARDINAL;A,C,D,B:Reg;SP,BP,SI,DI,DS,ES:CARDINAL);
  317. 316 BEGIN
  318. 317 SYSTEM.EI;
  319. 318 IF A.H = 0 THEN (* Read keyboard *)
  320. 319 A.L := SHORTCARD(RdKey());
  321. 320 A.H := SHORTCARD(ScanCode);
  322. 321 Extended := FALSE;
  323. 322 ELSIF A.H=1 THEN (* Keypressed *)
  324. 323 WITH KbdQueue DO
  325. 324 IF rptr=wptr THEN (* No key ready *)
  326. 325 INCL(Flags,SYSTEM.ZeroFlag);
  327. 326 ELSE
  328. 327 EXCL(Flags,SYSTEM.ZeroFlag);
  329. 328 WITH Buff[(rptr-30)>>1] DO
  330. 329 A.L := SHORTCARD(key);
  331. 330 A.H := SHORTCARD(scan);
  332. 331 END;
  333. 332 END;
  334. 333 END;
  335. 334 ELSIF A.H=2 THEN (* Get Shift Status *)
  336. 335 A.L := SHORTCARD(CARDINAL(KbdFlags) MOD 100H);
  337. 336 END;
  338. 337 END BiosKbd;
  339. 338 (*# restore *)
  340. 339
  341. 340 (*.............................................*)
  342. 341
  343. 342 PROCEDURE TermProc;
  344. 343 BEGIN
  345. 344 SYSTEM.DI;
  346. 345 SetVector(KbdInterrupt,OldVect9);
  347. 346 SetVector(16H,OldVect16);
  348. 347 SYSTEM.EI;
  349. 348 Continue();
  350. 349 END TermProc;
  351. 350
  352. 351 (*.............................................*)
  353. 352
  354. 353 BEGIN (* KeyBoard *)
  355. 354 Extended := FALSE;
  356. 355 IF KbdDriverInstalled THEN
  357. 356 OldVect9 := GetVector(KbdInterrupt);
  358. 357 OldVect16 := GetVector(16H);
  359. 358 SYSTEM.DI;
  360. 359 SetVector(KbdInterrupt,FarADR(KeyboardInterrupt));
  361. 360 SetVector(16H,FarADR(BiosKbd));
  362. 361 SYSTEM.EI;
  363. 362 Lib.Terminate(TermProc,Continue);
  364. 363 END;
  365. 364 END Keyboard.
  366. 365 (*%E*)
  367. 366 (*%T _OS2*)
  368. 367 (* OS/2 version *)
  369. 368 IMPORT Kbd;
  370. 369
  371. 370 VAR
  372. 371 Extended : BOOLEAN;
  373. 372
  374. 373 PROCEDURE RdKey() : CHAR;
  375. 374 VAR
  376. 375 k : Kbd.KEYINFO;
  377. ***** ^ not supported yet
  378. 376 r : CARDINAL;
  379. 377 BEGIN
  380. 378 IF Extended THEN
  381. 379 Extended := FALSE;
  382. 380 RETURN ScanCode;
  383. ***** ^ undeclared identifier
  384. 381 ELSE
  385. 382 r := Kbd.CharIn(k,Kbd.IO_WAIT,0);
  386. ***** ^ not supported yet
  387. ***** ^ not supported yet
  388. ***** ^ not supported yet
  389. ***** ^ not supported yet
  390. ***** ^ not supported yet
  391. ***** ^ not supported yet
  392. 383 IF (k.char=0C) OR (k.char=CHR(0E0H)) THEN
  393. ***** ^ not supported yet
  394. ***** ^ not supported yet
  395. ***** ^ not supported yet
  396. ***** ^ not supported yet
  397. ***** ^ undeclared identifier
  398. ***** ^ not supported yet
  399. 384 ScanCode := CHAR(k.scan);
  400. ***** ^ undeclared identifier
  401. ***** ^ not supported yet
  402. ***** ^ not supported yet
  403. 385 k.char := 0C;
  404. ***** ^ not supported yet
  405. ***** ^ not supported yet
  406. 386 Extended := TRUE;
  407. 387 END;
  408. 388 RETURN (k.char);
  409. ***** ^ not supported yet
  410. ***** ^ not supported yet
  411. 389 END;
  412. 390 END RdKey;
  413. ***** ^ not supported yet
  414. 391
  415. 392 PROCEDURE KeyPressed():BOOLEAN;
  416. 393 VAR
  417. 394 r : CARDINAL;
  418. 395 k : Kbd.KEYINFO;
  419. ***** ^ not supported yet
  420. 396 BEGIN
  421. 397 IF Extended THEN
  422. 398 RETURN TRUE;
  423. 399 ELSE
  424. 400 k.char := 0C;
  425. ***** ^ not supported yet
  426. ***** ^ not supported yet
  427. 401 k.scan := 0;
  428. ***** ^ not supported yet
  429. ***** ^ not supported yet
  430. 402 k.nlsShift := 0;
  431. ***** ^ not supported yet
  432. ***** ^ not supported yet
  433. 403 r := Kbd.Peek(k,0);
  434. ***** ^ not supported yet
  435. ***** ^ not supported yet
  436. ***** ^ not supported yet
  437. ***** ^ not supported yet
  438. 404 RETURN (k.scan#0) OR (k.char#0C);
  439. ***** ^ not supported yet
  440. ***** ^ not supported yet
  441. ***** ^ not supported yet
  442. ***** ^ not supported yet
  443. 405 END;
  444. 406 END KeyPressed;
  445. ***** ^ not supported yet
  446. 407
  447. 408 BEGIN
  448. 409 Extended := FALSE;
  449. 410 END Keyboard.
  450. ***** ^ not supported yet
  451. 411
  452. 412 (*%E*)
  453. 39 errors