OLDKEY.ASM 30 KB

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