KEY1.ASM 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/bios/rcs/key.asm $
  13. ; $Revision: 1.20 $
  14. ; $Author: john $
  15. ; $Date: 1994/01/18 10:58:55 $
  16. ;
  17. ; Contains routines to get, buffer, and check key presses.
  18. ;
  19. ; $Log: key.asm $
  20. ; Revision 1.20 1994/01/18 10:58:55 john
  21. ; *** empty log message ***
  22. ;
  23. ; Revision 1.19 1993/12/22 13:28:40 john
  24. ; Added back changes Matt made in r1.14
  25. ;
  26. ; Revision 1.18 1993/12/22 13:18:32 john
  27. ; *** empty log message ***
  28. ;
  29. ; Revision 1.17 1993/12/20 16:48:47 john
  30. ; Put cli/sti around clear keybuffer in key_close
  31. ;
  32. ; Revision 1.16 1993/12/20 15:39:13 john
  33. ; Tried to neaten handler code... also, moved some cli's and sti's around
  34. ; trying to find bug. Made the code call key_get_milliseconds instead
  35. ; of timer_get_milliseconds, because we don't want the cli and sti
  36. ; stuff in the interrupt handler.
  37. ;
  38. ; Revision 1.15 1993/12/02 10:54:48 john
  39. ; Made the Ctrl,Shift,Alt keys buffer like all the other keys.
  40. ;
  41. ; Revision 1.14 1993/10/29 11:25:18 matt
  42. ; Made key_down_time() not accumulate time if shift,alt,ctrl down
  43. ;
  44. ; Revision 1.13 1993/10/29 10:47:00 john
  45. ; *** empty log message ***
  46. ;
  47. ; Revision 1.12 1993/10/16 19:24:16 matt
  48. ; Added new function key_clear_times() & key_clear_counts()
  49. ;
  50. ; Revision 1.11 1993/10/15 10:16:49 john
  51. ; bunch of stuff, mainly with detecting debugger.
  52. ;
  53. ; Revision 1.10 1993/10/04 13:25:57 john
  54. ; Changed the way extended keys are processed.
  55. ;
  56. ; Revision 1.9 1993/09/28 11:35:32 john
  57. ; added key_peekkey
  58. ;
  59. ; Revision 1.8 1993/09/23 18:09:23 john
  60. ; fixed bug checking for DBG
  61. ;
  62. ; Revision 1.7 1993/09/23 17:28:01 john
  63. ; made debug check look for DBG> instead of CONTROL
  64. ;
  65. ; Revision 1.6 1993/09/20 17:08:19 john
  66. ; Made so that keys pressed in debugger don't get passed through to
  67. ; the keyboard handler. I also discovered, but didn't fix a error
  68. ; (page fault) caused by jumping back and forth between the debugger
  69. ; and the program...
  70. ;
  71. ; Revision 1.5 1993/09/17 09:58:12 john
  72. ; Added checks for already installed, not installed, etc.
  73. ;
  74. ; Revision 1.4 1993/09/15 17:28:00 john
  75. ; Fixed bug in FlushBuffer that used CX before a REP instead of ECX.
  76. ;
  77. ; Revision 1.3 1993/09/08 14:48:00 john
  78. ; made getch() return an int instead of a char that has shift states, etc.
  79. ;
  80. ; Revision 1.2 1993/07/22 13:12:23 john
  81. ; fixed comment
  82. ; ,.
  83. ;
  84. ; Revision 1.1 1993/07/10 13:10:42 matt
  85. ; Initial revision
  86. ;
  87. ;
  88. ;
  89. ;***************************************************************************
  90. ;***************************************************************************
  91. ;***** *****
  92. ;***** *****
  93. ;***** K E Y . A S M *****
  94. ;***** *****
  95. ;***** Contains routines to get, buffer, and check key presses. *****
  96. ;***** *****
  97. ;***** *****
  98. ;***** PROCEDURES *****
  99. ;***** *****
  100. ;***** key_init() - Activates the keyboard package. *****
  101. ;***** key_close() - Deactivates the keyboard package. *****
  102. ;***** key_check() - Returns 1 if a buffered key is waiting. *****
  103. ;***** key_getch() - Waits for and returns a buffered keypress. *****
  104. ;***** key_flush() - Clears buffers and state array. *****
  105. ;***** key_time() - Index by scan code. Contains the time key has been *****
  106. ;***** held down. NOT DONE YET. *****
  107. ;***** *****
  108. ;***** *****
  109. ;***** VARIABLES *****
  110. ;***** *****
  111. ;***** keyd_buffer_type -Set to 0 and key_getch() always returns 0. *****
  112. ;***** Set to 1 to so that ASCII codes are returned *****
  113. ;***** by key_getch(). Set to 2 and key_getch() returns*****
  114. ;***** the buffered keyboard scan codes. *****
  115. ;***** keyd_repeat - Set to 0 to not allow repeated keys in the *****
  116. ;***** keyboard buffer. Set to 1 to allow repeats. *****
  117. ;***** keyd_pressed[] -Index by scan code. Contains 1 if key down else 0*****
  118. ;***** *****
  119. ;***** *****
  120. ;***** CONSTANTS *****
  121. ;***** *****
  122. ;***** Setting the DEBUG to 1 at compile time passes SysReq through *****
  123. ;***** to the debugger, and when the debugger is active, it will give *****
  124. ;***** the debugger any keys that are pressed. Note that this only *****
  125. ;***** works with the Watcom VIDEO debugger at this time. Setting *****
  126. ;***** DEBUG to 0 takes out all the debugging stuff. *****
  127. ;***** *****
  128. ;***************************************************************************
  129. ;***************************************************************************
  130. DEBUG EQU 1
  131. .386
  132. ;************************************************************************
  133. ;**************** FLAT MODEL DATA SEGMENT STUFF *************************
  134. ;************************************************************************
  135. _DATA SEGMENT BYTE PUBLIC USE32 'DATA'
  136. rcsid db "$Id: key.asm 1.20 1994/01/18 10:58:55 john Exp $"
  137. PUBLIC _keyd_pressed ; Must start with a _ so C can see the variable.
  138. _keyd_pressed db 256 dup (?)
  139. keybuffer dw 256 dup (?) ; Use 256 so an inc wraps around
  140. TimeKeyWentDown dd 256 dup(0)
  141. TimeKeyHeldDown dd 256 dup(0)
  142. NumDowns dd 256 dup(0)
  143. NumUps dd 256 dup(0)
  144. MyCodeSegment dw ?
  145. PUBLIC _keyd_editor_mode
  146. _keyd_editor_mode db 0
  147. PUBLIC _keyd_use_bios
  148. _keyd_use_bios db 1
  149. PUBLIC _keyd_last_pressed
  150. _keyd_last_pressed db 0
  151. PUBLIC _keyd_last_released
  152. _keyd_last_released db 0
  153. PUBLIC _keyd_dump_key_array
  154. _keyd_dump_key_array db 0
  155. org_int_sel dw ?
  156. org_int_off dd ?
  157. interrupted_cs dw ?
  158. interrupted_eip dd ?
  159. keyhead db ?
  160. keytail db ?
  161. PUBLIC _keyd_buffer_type
  162. PUBLIC _keyd_repeat
  163. _keyd_buffer_type db ? ; 0=No buffer, 1=buffer ASCII, 2=buffer scans
  164. _keyd_repeat db ?
  165. E0Flag db 0
  166. Installed db 0
  167. INCLUDE KEYS.INC
  168. _DATA ENDS
  169. DGROUP GROUP _DATA
  170. ;************************************************************************
  171. ;**************** FLAT MODEL CODE SEGMENT STUFF *************************
  172. ;************************************************************************
  173. _TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
  174. ASSUME ds:_DATA
  175. ASSUME cs:_TEXT
  176. key_get_milliseconds:
  177. EXTERNDEF timer_get_stamp64:NEAR
  178. push ebx
  179. push edx
  180. call timer_get_stamp64
  181. ; Timing in milliseconds
  182. ; Can be used for up to 1000 hours
  183. shld edx, eax, 21 ; Keep 32+11 bits
  184. shl eax, 21
  185. mov ebx, 2502279823 ; 2^21*1193180/1000
  186. div ebx
  187. pop edx
  188. pop ebx
  189. ret
  190. ;************************************************************************
  191. ;************************************************************************
  192. ;***** *****
  193. ;***** K E Y _ T O _ A S C I I _ *****
  194. ;***** *****
  195. ;************************************************************************
  196. ;************************************************************************
  197. PUBLIC key_to_ascii_
  198. key_to_ascii_:
  199. ; EAX = scancode
  200. push ebx
  201. mov bl, ah
  202. and bl, 011111110b
  203. cmp bl, 0
  204. jne CantDoKey
  205. cmp al, 127
  206. jae CantDoKey
  207. and ah, 01b ; take away ctrl and alt codes
  208. shl al, 1
  209. shr eax, 1
  210. and eax, 0ffh
  211. mov al, byte ptr key1[eax]
  212. pop ebx
  213. ret
  214. CantDoKey:
  215. pop ebx
  216. mov eax, 255
  217. ret
  218. public key_clear_times_,key_clear_counts_
  219. ;clear the array of key down times.
  220. key_clear_times_:
  221. cli
  222. push eax
  223. push ecx
  224. push edi
  225. xor eax,eax
  226. mov ecx,256
  227. lea edi,TimeKeyHeldDown
  228. rep stosd ;clear array
  229. pop edi
  230. pop ecx
  231. pop eax
  232. sti
  233. ret
  234. ;clear the arrays of key down counts
  235. key_clear_counts_:
  236. cli
  237. push eax
  238. push ecx
  239. push edi
  240. xor eax,eax
  241. mov ecx,256
  242. lea edi,NumDowns
  243. rep stosd ;clear array
  244. mov ecx,256
  245. lea edi,NumUps
  246. rep stosd ;clear array
  247. pop edi
  248. pop ecx
  249. pop eax
  250. sti
  251. ret
  252. PUBLIC key_down_time_
  253. key_down_time_:
  254. cli
  255. push edx
  256. push ecx
  257. push ebx
  258. mov ebx, eax
  259. xor eax, eax
  260. cmp _keyd_pressed[ebx], 0
  261. je NotPressed
  262. cmp _keyd_editor_mode, 0
  263. je read_time
  264. call get_modifiers ;shift,alt,ctrl?
  265. or ah,ah
  266. jz read_time
  267. xor eax,eax
  268. jmp NotPressed
  269. read_time: mov ecx, TimeKeyWentDown[ebx*4]
  270. call key_get_milliseconds
  271. mov TimeKeyWentDown[ebx*4], eax
  272. sub eax, ecx ; EAX = time held since last
  273. NotPressed:
  274. add eax, TimeKeyHeldDown[ebx*4]
  275. mov TimeKeyHeldDown[ebx*4], 0
  276. pop ebx
  277. pop ecx
  278. pop edx
  279. sti
  280. ret
  281. PUBLIC key_down_count_
  282. key_down_count_:
  283. cli
  284. push ebx
  285. mov ebx, eax
  286. mov eax, NumDowns[ebx*4]
  287. mov NumDowns[ebx*4], 0
  288. pop ebx
  289. sti
  290. ret
  291. PUBLIC key_up_count_
  292. key_up_count_:
  293. cli
  294. push ebx
  295. mov ebx, eax
  296. mov eax, NumUps[ebx*4]
  297. mov NumUps[ebx*4], 0
  298. pop ebx
  299. sti
  300. ret
  301. ;************************************************************************
  302. ;************************************************************************
  303. ;***** *****
  304. ;***** K E Y _ F L U S H *****
  305. ;***** *****
  306. ;************************************************************************
  307. ;************************************************************************
  308. PUBLIC key_flush_
  309. key_flush_:
  310. cli
  311. push eax
  312. push ecx
  313. push edi
  314. mov keyhead,0
  315. mov keytail,255
  316. mov E0Flag, 0
  317. ; Clear the keyboard array
  318. mov edi, offset _keyd_pressed
  319. mov ecx, 32
  320. mov eax,0
  321. rep stosd
  322. pop edi
  323. pop ecx
  324. pop eax
  325. sti
  326. ret
  327. ;************************************************************************
  328. ;************************************************************************
  329. ;***** *****
  330. ;***** K E Y _ I N I T *****
  331. ;***** *****
  332. ;************************************************************************
  333. ;************************************************************************
  334. PUBLIC key_init_
  335. key_init_:
  336. push eax
  337. push ebx
  338. push ds
  339. push es
  340. ;**************************************************************
  341. ;******************* INITIALIZE key QUEUE **********************
  342. ;**************************************************************
  343. mov _keyd_buffer_type,1
  344. mov _keyd_repeat,1
  345. mov E0Flag, 0
  346. ; Clear the keyboard array
  347. call key_flush_
  348. cmp Installed, 0
  349. jne AlreadyInstalled
  350. ;**************************************************************
  351. ;******************* SAVE OLD INT9 HANDLER ********************
  352. ;**************************************************************
  353. mov Installed, 1
  354. mov eax, 03509h ; DOS Get Vector 09h
  355. int 21h ; Call DOS
  356. mov org_int_sel, es ; Save old interrupt selector
  357. mov org_int_off, ebx ; Save old interrupt offset
  358. ;**************************************************************
  359. ;***************** INSTALL NEW INT9 HANDLER *******************
  360. ;**************************************************************
  361. mov eax, 02509h ; DOS Set Vector 09h
  362. mov edx, offset key_handler ; Point DS:EDX to new handler
  363. mov bx, cs
  364. mov MyCodeSegment, bx
  365. mov ds, bx
  366. int 21h
  367. AlreadyInstalled:
  368. pop es
  369. pop ds
  370. pop ebx
  371. pop eax
  372. ret
  373. ;************************************************************************
  374. ;************************************************************************
  375. ;***** *****
  376. ;***** K E Y _ C L O S E _ *****
  377. ;***** *****
  378. ;************************************************************************
  379. ;************************************************************************
  380. PUBLIC key_close_
  381. key_close_:
  382. push eax
  383. push ebx
  384. push edx
  385. push ds
  386. cmp Installed, 0
  387. je @f
  388. ;**************************************************************
  389. ;***************** RESTORE OLD INT9 HANDLER *******************
  390. ;**************************************************************
  391. mov Installed, 0
  392. ; Clear the BIOS buffer
  393. cli
  394. mov ebx, 041ch
  395. mov al, byte ptr [ebx]
  396. mov ebx, 041ah
  397. mov byte ptr [ebx], al
  398. sti
  399. mov eax, 02509h ; DOS Set Vector 09h
  400. mov edx, org_int_off
  401. mov ds, org_int_sel
  402. int 21h
  403. @@: pop ds
  404. pop edx
  405. pop ebx
  406. pop eax
  407. ret
  408. ;************************************************************************
  409. ;************************************************************************
  410. ;***** *****
  411. ;***** K E Y _ C H E C K _ *****
  412. ;***** *****
  413. ;************************************************************************
  414. ;************************************************************************
  415. PUBLIC key_checkch_ ; Must end with a _ so C can see the function.
  416. key_checkch_:
  417. cli
  418. push ebx
  419. xor eax, eax
  420. cmp Installed, 0
  421. je NoKey
  422. mov bl, keytail
  423. inc bl
  424. cmp bl, keyhead
  425. je Nokey
  426. mov eax, 1
  427. Nokey:
  428. pop ebx
  429. sti
  430. ret
  431. ;************************************************************************
  432. ;************************************************************************
  433. ;***** *****
  434. ;***** K E Y _ D E B U G *****
  435. ;***** *****
  436. ;************************************************************************
  437. ;************************************************************************
  438. PUBLIC key_debug_
  439. key_debug_:
  440. int 3h
  441. ret
  442. ;************************************************************************
  443. ;************************************************************************
  444. ;***** *****
  445. ;***** K E Y _ G E T C H _ *****
  446. ;***** *****
  447. ;************************************************************************
  448. ;************************************************************************
  449. PUBLIC key_getch_ ; Must end with a _ so C can see the function.
  450. key_getch_:
  451. push ebx
  452. xor eax, eax
  453. xor ebx, ebx
  454. cmp Installed, 0
  455. jne StillNoKey
  456. pop ebx
  457. ret
  458. StillNoKey:
  459. cli ; Critical section
  460. mov bl, keytail
  461. inc bl
  462. cmp bl, keyhead
  463. sti
  464. je StillNoKey
  465. cli ; Critical section
  466. xor ebx, ebx
  467. mov bl, keyhead
  468. mov ax, word ptr keybuffer[ebx*2]
  469. inc BYTE PTR keyhead
  470. sti
  471. pop ebx
  472. ret
  473. ;************************************************************************
  474. ;************************************************************************
  475. ;***** *****
  476. ;***** K E Y _ I N K E Y _ *****
  477. ;***** *****
  478. ;************************************************************************
  479. ;************************************************************************
  480. PUBLIC key_inkey_ ; Must end with a _ so C can see the function.
  481. key_inkey_:
  482. push ebx
  483. xor eax, eax
  484. xor ebx, ebx
  485. cmp Installed, 0
  486. je NoInkey
  487. cli ; Critical section
  488. mov bl, keytail
  489. inc bl
  490. cmp bl, keyhead
  491. sti
  492. je NoInkey
  493. cli ; Critical section
  494. mov bl, keyhead
  495. mov ax, word ptr keybuffer[ebx*2]
  496. inc BYTE PTR keyhead
  497. sti
  498. NoInkey:
  499. pop ebx
  500. ret
  501. PUBLIC key_peekkey_ ; Must end with a _ so C can see the function.
  502. key_peekkey_:
  503. push ebx
  504. xor eax, eax
  505. xor ebx, ebx
  506. cli ; Critical section
  507. cmp Installed, 0
  508. je NoPeek
  509. mov bl, keytail
  510. inc bl
  511. cmp bl, keyhead
  512. je NoPeek
  513. mov bl, keyhead
  514. mov ax, word ptr keybuffer[ebx*2]
  515. NoPeek: sti
  516. pop ebx
  517. ret
  518. ;************************************************************************
  519. ;************************************************************************
  520. ;***** *****
  521. ;***** K E Y _ H A N D L E R *****
  522. ;***** *****
  523. ;************************************************************************
  524. ;************************************************************************
  525. PUBLIC key_handler ; Must end with a _ so C can see the function.
  526. key_handler:
  527. pushfd ; Save flags in case we have to chain to original
  528. push eax
  529. push ebx
  530. push ecx
  531. push edx
  532. push ds
  533. mov ax, DGROUP ; Point to our data segment, since this is an
  534. mov ds, ax ; interrupt and we don't know where we were.
  535. mov eax, (0b0000h+76*2)
  536. mov byte ptr [eax], '1'
  537. IFDEF DEBUG
  538. call CheckForDebugger
  539. jnc @f
  540. mov eax, 0b0000h+78*2
  541. mov byte ptr [eax], 'D'
  542. jmp PassToBios ; If debugger is active, then skip buffer
  543. @@: mov eax, 0b0000h+78*2
  544. mov byte ptr [eax], 'I'
  545. ; Clear the BIOS buffer
  546. ;**mov ebx, 041ch
  547. ;**mov al, byte ptr [ebx]
  548. ;**mov ebx, 041ah
  549. ;**mov byte ptr [ebx], al
  550. ENDIF
  551. xor eax, eax
  552. xor ebx, ebx
  553. in al, 060h ; Get scan code from keyboard
  554. cmp al, 0E0h
  555. jne NotE0Code
  556. E0Code: mov E0Flag, 010000000b
  557. jmp LeaveHandler ; If garbage key, then don't buffer it
  558. NotE0Code: mov bl, al ; Put break bit into bl ; 0 = pressed, 1=released
  559. and al, 01111111b ; AL = scancode
  560. or al, E0Flag ; AL = extended scancode
  561. mov E0Flag,0 ; clear E0 flag
  562. cmp al, 029h
  563. je pause_execution
  564. shl bl, 1 ; put upper bit into carry flag
  565. jc key_mark_released ; if upper bit of bl was set, then it was a release code
  566. ;**************************************************************
  567. ;****************** HANDLE A NEWLY PRESSED KEY ****************
  568. ;**************************************************************
  569. ;Marks the key press in EAX in the scancode array.
  570. key_mark_pressed:
  571. ;cmp al, 0eh ; backspace
  572. ;je pause_execution
  573. mov _keyd_last_pressed, al
  574. ; Check if the key is repeating or if it just got pressed.
  575. cmp byte ptr _keyd_pressed[eax], 1
  576. je AlreadyDown
  577. ;------------------------------- Code for a key pressed for the first time ------------------------
  578. mov byte ptr _keyd_pressed[eax], 1
  579. ; Set the time
  580. push edx
  581. push eax
  582. call key_get_milliseconds
  583. mov edx, eax
  584. pop eax
  585. mov TimeKeyWentDown[eax*4], edx
  586. pop edx
  587. inc NumDowns[eax*4]
  588. jmp BufferAX
  589. ;------------------------------- Code for a key that is already pressed ------------------------
  590. AlreadyDown:
  591. cmp _keyd_repeat, 0
  592. je DoneMarkingPressed
  593. BufferAX:
  594. cmp _keyd_buffer_type, 0
  595. je SkipBuffer ; Buffer = 0 means don't buffer anything.
  596. cmp al, 0AAh ; garbage key
  597. je SkipBuffer
  598. call get_modifiers ;returns ah
  599. xor ebx, ebx
  600. mov bl, keytail
  601. inc bl
  602. inc bl
  603. ; If the buffer is full then don't buffer this key
  604. cmp bl, keyhead
  605. je SkipBuffer
  606. dec bl
  607. mov word ptr keybuffer[ebx*2], ax
  608. mov keytail, bl
  609. SkipBuffer:
  610. ;---------------------------------- Exit function -----------------------------
  611. DoneMarkingPressed:
  612. jmp LeaveHandler
  613. ;**************************************************************
  614. ;******************* HANDLE A RELEASED KEY ********************
  615. ;**************************************************************
  616. ; Unmarks the key press in EAX from the scancode array.
  617. key_mark_released:
  618. mov _keyd_last_released, al
  619. mov byte ptr _keyd_pressed[eax], 0
  620. inc NumUps[eax*4]
  621. cmp _keyd_editor_mode, 0
  622. je NotInEditorMode
  623. push eax
  624. xor ah,ah
  625. call get_modifiers
  626. or ah,ah ;check modifiers
  627. pop eax
  628. jnz skip_time
  629. NotInEditorMode:
  630. push eax
  631. call timer_get_stamp64
  632. ; Timing in milliseconds
  633. ; Can be used for up to 1000 hours
  634. shld edx, eax, 21 ; Keep 32+11 bits
  635. shl eax, 21
  636. mov ebx, 2502279823 ; 2^21*1193180/1000
  637. div ebx
  638. mov edx, eax
  639. pop eax
  640. sub edx, TimeKeyWentDown[eax*4]
  641. add TimeKeyHeldDown[eax*4], edx
  642. skip_time: ;**jmp LeaveHandler
  643. ;**************************************************************
  644. ;*************** FINISH UP THE KEYBOARD INTERRUPT *************
  645. ;**************************************************************
  646. LeaveHandler:
  647. mov eax, (0b0000h+76*2)
  648. mov byte ptr [eax], '2'
  649. ;; cmp _keyd_dump_key_array, 0
  650. ;; je DontPassToBios
  651. jmp PassToBios
  652. mov ecx, 256
  653. mov ebx, 0
  654. showdown: mov al, _keyd_pressed[ebx]
  655. add al, '0'
  656. mov [ebx*2+ 0b0000h], al
  657. inc ebx
  658. loop showdown
  659. mov eax, 0b0000h
  660. mov byte ptr [ eax+(036h*2+1) ], 070h
  661. mov byte ptr [ eax+(02Ah*2+1) ], 070h
  662. mov byte ptr [ eax+(038h*2+1) ], 070h
  663. mov byte ptr [ eax+(0B8h*2+1) ], 070h
  664. mov byte ptr [ eax+(01Dh*2+1) ], 070h
  665. mov byte ptr [ eax+(09dh*2+1) ], 070h
  666. mov byte ptr [ eax+(0AAh*2+1) ], 07Fh
  667. mov byte ptr [ eax+(0E0h*2+1) ], 07Fh
  668. jmp DontPassToBios
  669. ; If in debugger, pass control to dos interrupt.
  670. PassToBios: pop ds ; Nothing left on stack but flags
  671. pop edx
  672. pop ecx
  673. pop ebx
  674. pop eax
  675. sub esp, 8 ; Save space for IRETD frame
  676. push ds ; Save registers we use.
  677. push eax
  678. mov ax, DGROUP
  679. mov ds, ax ; Set DS to our data segment
  680. mov eax, org_int_off ; put original handler address
  681. mov [esp+8], eax ; in the IRETD frame
  682. movzx eax, org_int_sel
  683. mov [esp+12], eax
  684. pop eax ; Restore registers
  685. pop ds
  686. iretd ; Chain to previous handler
  687. pause_execution:
  688. in al, 61h ; Get current port 61h state
  689. or al, 10000000b ; Turn on bit 7 to signal clear keybrd
  690. out 61h, al ; Send to port
  691. and al, 01111111b ; Turn off bit 7 to signal break
  692. out 61h, al ; Send to port
  693. mov al, 20h ; Reset interrupt controller
  694. out 20h, al
  695. sti ; Reenable interrupts
  696. pop ds
  697. pop edx ; Restore all of the saved registers.
  698. pop ecx
  699. pop ebx
  700. pop eax
  701. sub esp, 8 ; Save space for IRETD frame
  702. push ds ; Save registers we use.
  703. push eax
  704. mov ax, DGROUP
  705. mov ds, ax ; Set DS to our data segment
  706. mov eax, org_int_off ; put original handler address
  707. mov [esp+8], eax ; in the IRETD frame
  708. movzx eax, org_int_sel
  709. mov [esp+12], eax
  710. pop eax ; Restore registers
  711. pop ds
  712. iretd ; Interrupt must return with IRETD
  713. DontPassToBios:
  714. ; Resets the keyboard, PIC, restores stack, returns.
  715. in al, 61h ; Get current port 61h state
  716. or al, 10000000b ; Turn on bit 7 to signal clear keybrd
  717. out 61h, al ; Send to port
  718. and al, 01111111b ; Turn off bit 7 to signal break
  719. out 61h, al ; Send to port
  720. mov al, 20h ; Reset interrupt controller
  721. out 20h, al
  722. sti ; Reenable interrupts
  723. pop ds
  724. pop edx ; Restore all of the saved registers.
  725. pop ecx
  726. pop ebx
  727. pop eax
  728. popfd
  729. iretd ; Interrupt must return with IRETD
  730. ;returns ah=bitmask of shift,ctrl,alt keys
  731. get_modifiers: push ecx
  732. xor ah,ah
  733. ; Check the shift keys
  734. mov cl, _keyd_pressed[ 036h ]
  735. or cl, _keyd_pressed[ 02ah ]
  736. or ah, cl
  737. ; Check the alt key
  738. mov cl, _keyd_pressed[ 038h ]
  739. or cl, _keyd_pressed[ 0b8h ]
  740. shl cl, 1
  741. or ah, cl
  742. ; Check the ctrl key
  743. mov cl, _keyd_pressed[ 01dh ]
  744. or cl, _keyd_pressed[ 09dh ]
  745. shl cl, 2
  746. or ah, cl
  747. pop ecx
  748. ret
  749. IFDEF DEBUG
  750. CheckForDebugger:
  751. ; Returns CF=0 if debugger isn't active
  752. ; CF=1 if debugger is active
  753. ;*************************** DEBUG ******************************
  754. ; When we're in the VIDEO debugger, we want to pass control to
  755. ; the original interrupt. So, to tell if the debugger is active,
  756. ; I check if video page 1 is the active page since that is what
  757. ; page the debugger uses, and if that works, I check the top of
  758. ; the screen to see if the texxt "Control" is there, which should
  759. ; only be there when we're in the debugger.
  760. push eax
  761. ;mov eax, 0462h ; Address 0462 stores BIOS current page
  762. ;cmp BYTE PTR [eax], 1
  763. ;jne NoDebuggerOnColor
  764. ;mov eax, 0b8000h+4096 ; 4096 = offset to 2nd video mem page
  765. ;cmp BYTE PTR [eax+2],'C'
  766. ;jne NoDebuggerOnColor
  767. ;cmp BYTE PTR [eax+4],'o'
  768. ;jne NoDebuggerOnColor
  769. ;cmp BYTE PTR [eax+6],'n'
  770. ;jne NoDebuggerOnColor
  771. ;cmp BYTE PTR [eax+8],'t'
  772. ;jne NoDebuggerOnColor
  773. ;cmp BYTE PTR [eax+10],'r'
  774. ;jne NoDebuggerOnColor
  775. ;cmp BYTE PTR [eax+12],'o'
  776. ;jne NoDebuggerOnColor
  777. ;cmp BYTE PTR [eax+14],'l'
  778. ;jne NoDebuggerOnColor
  779. ;jmp ActiveDebugger
  780. ;NoDebuggerOnColor:
  781. ; First, see if there is a mono debugger...
  782. ;mov eax, 0b0000h ; 4096 = offset to mono video mem
  783. ;cmp BYTE PTR [eax+2],'C'
  784. ;jne NoActiveDebugger
  785. ;cmp BYTE PTR [eax+4],'o'
  786. ;jne NoActiveDebugger
  787. ;cmp BYTE PTR [eax+6],'n'
  788. ;jne NoActiveDebugger
  789. ;cmp BYTE PTR [eax+8],'t'
  790. ;jne NoActiveDebugger
  791. ;cmp BYTE PTR [eax+10],'r'
  792. ;jne NoActiveDebugger
  793. ;cmp BYTE PTR [eax+12],'o'
  794. ;jne NoActiveDebugger
  795. ;cmp BYTE PTR [eax+14],'l'
  796. ;jne NoActiveDebugger
  797. mov eax, 0b0000h ; 4096 = offset to mono video mem
  798. add eax, 24*80*2
  799. cmp BYTE PTR [eax+0],'D'
  800. jne NextTest
  801. cmp BYTE PTR [eax+2],'B'
  802. jne NextTest
  803. cmp BYTE PTR [eax+4],'G'
  804. jne NextTest
  805. cmp BYTE PTR [eax+6],'>'
  806. jne NextTest
  807. ;Found DBG>, so consider debugger active:
  808. jmp ActiveDebugger
  809. NextTest:
  810. cmp BYTE PTR [eax+14],'<'
  811. jne NextTest1
  812. cmp BYTE PTR [eax+16],'i'
  813. jne NextTest1
  814. cmp BYTE PTR [eax+18],'>'
  815. jne NextTest1
  816. cmp BYTE PTR [eax+20],' '
  817. jne NextTest1
  818. cmp BYTE PTR [eax+22],'-'
  819. jne NextTest1
  820. ; Found <i> - , so consider debugger active:
  821. jmp ActiveDebugger
  822. NextTest1:
  823. cmp BYTE PTR [eax+0], 200
  824. jne NextTest2
  825. cmp BYTE PTR [eax+2], 27
  826. jne NextTest2
  827. cmp BYTE PTR [eax+4], 17
  828. jne NextTest2
  829. ; Found either the help screen or view screen, so consider
  830. ; debugger active
  831. jmp ActiveDebugger
  832. NextTest2:
  833. ; Now we see if its active by looking for the "Executing..."
  834. ; text on the bottom of the mono screen
  835. ;mov eax, 0b0000h ; 4096 = offset to mono video mem
  836. ;add eax, 24*80*2
  837. ;cmp BYTE PTR [eax+0],'E'
  838. ;je NoActiveDebugger
  839. ;cmp BYTE PTR [eax+2],'x'
  840. ;je NoActiveDebugger
  841. ;cmp BYTE PTR [eax+4],'e'
  842. ;je NoActiveDebugger
  843. ;cmp BYTE PTR [eax+6],'c'
  844. ;je NoActiveDebugger
  845. NoActiveDebugger:
  846. pop eax
  847. clc
  848. ret
  849. ActiveDebugger:
  850. pop eax
  851. stc
  852. ret
  853. ENDIF
  854. _TEXT ENDS
  855. END
  856.