home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / bios / key1.asm < prev    next >
Assembly Source File  |  1998-06-08  |  31KB  |  1,069 lines

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