home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / bios / key2.asm < prev    next >
Assembly Source File  |  1998-06-08  |  30KB  |  1,047 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.         keyhead      db  ?
  154.         keytail      db  ?
  155. PUBLIC  _keyd_buffer_type
  156. PUBLIC  _keyd_repeat
  157.         _keyd_buffer_type db  ?   ; 0=No buffer, 1=buffer ASCII, 2=buffer scans
  158.         _keyd_repeat      db  ?
  159.  
  160.         E0Flag      db     0
  161.  
  162.         Installed   db  0
  163.  
  164. INCLUDE KEYS.INC
  165.  
  166.  
  167. _DATA   ENDS
  168.  
  169. DGROUP  GROUP _DATA
  170.  
  171.  
  172. ;************************************************************************
  173. ;**************** FLAT MODEL CODE SEGMENT STUFF *************************
  174. ;************************************************************************
  175.  
  176. _TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
  177.  
  178.         ASSUME  ds:_DATA
  179.         ASSUME  cs:_TEXT
  180.  
  181. key_get_milliseconds:
  182.         EXTERNDEF   timer_get_stamp64:NEAR
  183.  
  184.         push    ebx
  185.         push    edx
  186.  
  187.         call    timer_get_stamp64
  188.  
  189.         ; Timing in milliseconds
  190.         ; Can be used for up to 1000 hours
  191.         shld    edx, eax, 21            ; Keep 32+11 bits
  192.         shl     eax, 21
  193.         mov     ebx, 2502279823         ; 2^21*1193180/1000
  194.         div     ebx
  195.  
  196.         pop     edx
  197.         pop     ebx
  198.  
  199.         ret
  200.  
  201. ;************************************************************************
  202. ;************************************************************************
  203. ;*****                                                              *****
  204. ;*****                   K E Y _ T O _ A S C I I _                  *****
  205. ;*****                                                              *****
  206. ;************************************************************************
  207. ;************************************************************************
  208.  
  209. PUBLIC  key_to_ascii_
  210.  
  211. key_to_ascii_:
  212.  
  213.         ; EAX = scancode
  214.         push    ebx
  215.  
  216.         mov     bl, ah
  217.         and     bl, 011111110b
  218.         cmp     bl, 0
  219.         jne     CantDoKey
  220.  
  221.         cmp     al, 127
  222.         jae     CantDoKey
  223.  
  224.         and     ah, 01b        ; take away ctrl and alt codes
  225.         shl     al, 1
  226.         shr     eax, 1
  227.         and     eax, 0ffh
  228.         mov     al, byte ptr key1[eax]
  229.         pop     ebx
  230.         ret
  231.  
  232. CantDoKey:
  233.         pop     ebx
  234.         mov     eax, 255
  235.         ret
  236.  
  237.  
  238. public key_clear_times_,key_clear_counts_
  239.  
  240. ;clear the array of key down times.
  241. key_clear_times_:    
  242.     cli
  243.     push    eax
  244.     push    ecx
  245.     push    edi
  246.     xor    eax,eax
  247.     mov    ecx,256
  248.     lea    edi,TimeKeyHeldDown
  249.     rep    stosd    ;clear array
  250.     pop    edi
  251.     pop    ecx
  252.     pop    eax
  253.     sti
  254.     ret
  255.  
  256. ;clear the arrays of key down counts
  257. key_clear_counts_:    
  258.     cli
  259.     push    eax
  260.     push    ecx
  261.     push    edi
  262.     xor    eax,eax
  263.     mov    ecx,256
  264.     lea    edi,NumDowns
  265.     rep    stosd    ;clear array
  266.     mov    ecx,256
  267.     lea    edi,NumUps
  268.     rep    stosd    ;clear array
  269.     pop    edi
  270.     pop    ecx
  271.     pop    eax
  272.     sti
  273.     ret
  274.  
  275.  
  276. PUBLIC  key_down_time_
  277.  
  278. key_down_time_:
  279.         cli
  280.  
  281.         push    edx
  282.         push    ecx
  283.         push    ebx
  284.  
  285.  
  286.         mov     ebx, eax
  287.         xor     eax, eax
  288.  
  289.         cmp     _keyd_pressed[ebx], 0
  290.         je      NotPressed
  291.  
  292.         
  293.         cmp    _keyd_editor_mode, 0
  294.         je    read_time
  295.  
  296.         call    get_modifiers    ;shift,alt,ctrl?
  297.         or      ah,ah
  298.         jz      read_time
  299.         xor     eax,eax
  300.         jmp     NotPressed
  301.  
  302. read_time:    mov     ecx, TimeKeyWentDown[ebx*4]
  303.         call    key_get_milliseconds
  304.         mov     TimeKeyWentDown[ebx*4], eax
  305.         sub     eax, ecx        ; EAX = time held since last
  306.  
  307. NotPressed:
  308.         add     eax, TimeKeyHeldDown[ebx*4]
  309.         mov     TimeKeyHeldDown[ebx*4], 0
  310.  
  311.         pop     ebx
  312.         pop     ecx
  313.         pop     edx
  314.         sti
  315.         ret
  316.  
  317. PUBLIC  key_down_count_
  318. key_down_count_:
  319.         cli
  320.         push    ebx
  321.         mov     ebx, eax
  322.         mov     eax, NumDowns[ebx*4]
  323.         mov     NumDowns[ebx*4], 0
  324.         pop     ebx
  325.         sti
  326.         ret
  327.  
  328. PUBLIC  key_up_count_
  329. key_up_count_:
  330.         cli
  331.         push    ebx
  332.         mov     ebx, eax
  333.         mov     eax, NumUps[ebx*4]
  334.         mov     NumUps[ebx*4], 0
  335.         pop     ebx
  336.         sti
  337.         ret
  338.  
  339.  
  340.  
  341. ;************************************************************************
  342. ;************************************************************************
  343. ;*****                                                              *****
  344. ;*****                   K E Y _ F L U S H                          *****
  345. ;*****                                                              *****
  346. ;************************************************************************
  347. ;************************************************************************
  348.  
  349. PUBLIC  key_flush_
  350.  
  351. key_flush_:
  352.         cli
  353.  
  354.         push    eax
  355.         push    ecx
  356.         push    edi
  357.  
  358.         mov     keyhead,0
  359.         mov     keytail,255
  360.         mov     E0Flag, 0
  361.  
  362.         ; Clear the keyboard array
  363.         mov     edi, offset _keyd_pressed
  364.         mov     ecx, 32
  365.         mov     eax,0
  366.         rep     stosd
  367.  
  368.         pop     edi
  369.         pop     ecx
  370.         pop     eax
  371.         sti
  372.         ret
  373.  
  374. ;************************************************************************
  375. ;************************************************************************
  376. ;*****                                                              *****
  377. ;*****                   K E Y _ I N I T                            *****
  378. ;*****                                                              *****
  379. ;************************************************************************
  380. ;************************************************************************
  381.  
  382. PUBLIC  key_init_
  383.  
  384. key_init_:
  385.         push    eax
  386.         push    ebx
  387.         push    ds
  388.         push    es
  389.  
  390.         ;**************************************************************
  391.         ;******************* INITIALIZE key QUEUE **********************
  392.         ;**************************************************************
  393.  
  394.         mov     _keyd_buffer_type,1
  395.         mov     _keyd_repeat,1
  396.         mov     E0Flag, 0
  397.  
  398.         ; Clear the keyboard array
  399.         call    key_flush_
  400.  
  401.         cmp     Installed, 0
  402.         jne     AlreadyInstalled
  403.  
  404.         ;**************************************************************
  405.         ;******************* SAVE OLD INT9 HANDLER ********************
  406.         ;**************************************************************
  407.  
  408.         mov     Installed, 1
  409.  
  410.         mov     eax, 03509h             ; DOS Get Vector 09h
  411.         int     21h                     ; Call DOS
  412.         mov     org_int_sel, es         ; Save old interrupt selector
  413.         mov     org_int_off, ebx        ; Save old interrupt offset
  414.  
  415.  
  416.         ;**************************************************************
  417.         ;***************** INSTALL NEW INT9 HANDLER *******************
  418.         ;**************************************************************
  419.  
  420.         mov     eax, 02509h             ; DOS Set Vector 09h
  421.         mov     edx, offset key_handler  ; Point DS:EDX to new handler
  422.         mov     bx, cs
  423.         mov     MyCodeSegment, bx
  424.         mov     ds, bx
  425.         int     21h
  426.  
  427.  
  428. AlreadyInstalled:
  429.  
  430.         pop     es
  431.         pop     ds
  432.         pop     ebx
  433.         pop     eax
  434.  
  435.         ret
  436.  
  437.  
  438. ;************************************************************************
  439. ;************************************************************************
  440. ;*****                                                              *****
  441. ;*****                   K E Y _ C L O S E _                          *****
  442. ;*****                                                              *****
  443. ;************************************************************************
  444. ;************************************************************************
  445.  
  446. PUBLIC  key_close_
  447.  
  448. key_close_:
  449.         push    eax
  450.         push    ebx
  451.         push    edx
  452.         push    ds
  453.  
  454.  
  455.         cmp     Installed, 0
  456.         je      @f
  457.  
  458.         ;**************************************************************
  459.         ;***************** RESTORE OLD INT9 HANDLER *******************
  460.         ;**************************************************************
  461.  
  462.         mov     Installed, 0
  463.  
  464.         ; Clear the BIOS buffer
  465.         cli
  466.         mov     ebx, 041ch
  467.         mov     al, byte ptr [ebx]
  468.         mov     ebx, 041ah
  469.         mov     byte ptr [ebx], al
  470.         sti
  471.  
  472.         mov     eax, 02509h         ; DOS Set Vector 09h
  473.         mov     edx, org_int_off
  474.         mov     ds, org_int_sel
  475.         int     21h
  476.  
  477. @@:         pop     ds
  478.         pop     edx
  479.         pop     ebx
  480.         pop     eax
  481.  
  482.         ret
  483.  
  484. ;************************************************************************
  485. ;************************************************************************
  486. ;*****                                                              *****
  487. ;*****                   K E Y _ C H E C K _                          *****
  488. ;*****                                                              *****
  489. ;************************************************************************
  490. ;************************************************************************
  491.  
  492. PUBLIC  key_checkch_       ; Must end with a _ so C can see the function.
  493.  
  494. key_checkch_:
  495.         cli
  496.         push    ebx
  497.  
  498.         xor     eax, eax
  499.         cmp     Installed, 0
  500.         je      NoKey
  501.  
  502.         mov     bl, keytail
  503.         inc     bl
  504.         cmp     bl, keyhead
  505.         je      Nokey
  506.         mov     eax, 1
  507. Nokey:
  508.         pop     ebx
  509.         sti
  510.         ret
  511.  
  512. ;************************************************************************
  513. ;************************************************************************
  514. ;*****                                                              *****
  515. ;*****                 K E Y _ D E B U G                              *****
  516. ;*****                                                              *****
  517. ;************************************************************************
  518. ;************************************************************************
  519.  
  520. PUBLIC  key_debug_
  521. key_debug_:
  522.         int 3h
  523.         ret
  524.  
  525.  
  526. ;************************************************************************
  527. ;************************************************************************
  528. ;*****                                                              *****
  529. ;*****                   K E Y _ G E T C H _                        *****
  530. ;*****                                                              *****
  531. ;************************************************************************
  532. ;************************************************************************
  533.  
  534. PUBLIC  key_getch_       ; Must end with a _ so C can see the function.
  535.  
  536. key_getch_:
  537.         push    ebx
  538.  
  539.         xor     eax, eax
  540.         xor     ebx, ebx
  541.         cmp     Installed, 0
  542.         jne     StillNoKey
  543.         pop     ebx
  544.         ret
  545.  
  546. StillNoKey:
  547.         cli             ; Critical section
  548.         mov     bl, keytail
  549.         inc     bl
  550.         cmp     bl, keyhead
  551.         sti
  552.         je      StillNoKey
  553.  
  554.         cli             ; Critical section
  555.         xor     ebx, ebx
  556.         mov     bl, keyhead
  557.         mov     ax, word ptr keybuffer[ebx*2]
  558.         inc     BYTE PTR keyhead
  559.         sti
  560.  
  561.         pop     ebx
  562.         ret
  563.  
  564.  
  565. ;************************************************************************
  566. ;************************************************************************
  567. ;*****                                                              *****
  568. ;*****                   K E Y _ I N K E Y _                        *****
  569. ;*****                                                              *****
  570. ;************************************************************************
  571. ;************************************************************************
  572.  
  573. PUBLIC  key_inkey_       ; Must end with a _ so C can see the function.
  574.  
  575. key_inkey_:
  576.         push    ebx
  577.  
  578.         xor     eax, eax
  579.         xor     ebx, ebx
  580.  
  581.         cmp     Installed, 0
  582.         je      NoInkey
  583.  
  584.         cli             ; Critical section
  585.         mov     bl, keytail
  586.         inc     bl
  587.         cmp     bl, keyhead
  588.         sti
  589.         je      NoInkey
  590.  
  591.         cli             ; Critical section
  592.         mov     bl, keyhead
  593.         mov     ax, word ptr keybuffer[ebx*2]
  594.         inc     BYTE PTR keyhead
  595.         sti
  596. NoInkey:
  597.         pop     ebx
  598.         ret
  599.  
  600. PUBLIC  key_peekkey_       ; Must end with a _ so C can see the function.
  601.  
  602. key_peekkey_:
  603.         push    ebx
  604.  
  605.         xor     eax, eax
  606.         xor     ebx, ebx
  607.  
  608.         cli             ; Critical section
  609.  
  610.         cmp     Installed, 0
  611.         je      NoPeek
  612.         mov     bl, keytail
  613.         inc     bl
  614.         cmp     bl, keyhead
  615.         je      NoPeek
  616.         mov     bl, keyhead
  617.         mov     ax, word ptr keybuffer[ebx*2]
  618.         
  619. NoPeek:        sti
  620.         pop     ebx
  621.         ret
  622.  
  623.  
  624.  
  625. ;************************************************************************
  626. ;************************************************************************
  627. ;*****                                                              *****
  628. ;*****                   K E Y _ H A N D L E R                      *****
  629. ;*****                                                              *****
  630. ;************************************************************************
  631. ;************************************************************************
  632.  
  633. PUBLIC  key_handler      ; Must end with a _ so C can see the function.
  634.  
  635. key_handler:
  636.  
  637.         pushfd              ; Save flags in case we have to chain to original
  638.         push    eax
  639.         push    ebx
  640.         push    ecx
  641.         push    edx
  642.         push    ds
  643.  
  644.         mov     ax, DGROUP  ; Point to our data segment, since this is an
  645.         mov     ds, ax      ; interrupt and we don't know where we were.
  646.  
  647. IFDEF DEBUG
  648.         call    CheckForDebugger
  649.         jnc     @f
  650. ;****        mov eax, 0b0000h+78*2
  651. ;****        mov byte ptr [eax], 'D'
  652.         jmp      PassToBios      ; If debugger is active, then skip buffer
  653.  
  654. @@:
  655. ;****         mov eax, 0b0000h+78*2
  656. ;****        mov byte ptr [eax], 'I'
  657.  
  658.         ; Clear the BIOS buffer
  659.         mov     ebx, 041ch
  660.         mov     al, byte ptr [ebx]
  661.         mov     ebx, 041ah
  662.         mov     byte ptr [ebx], al
  663. ENDIF
  664.  
  665.         xor     eax, eax
  666.         xor    ebx, ebx
  667.  
  668.         in      al, 060h                ; Get scan code from keyboard
  669.         cmp     al, 0E0h
  670.         jne     NotE0Code
  671.  
  672. E0Code:        mov     E0Flag, 010000000b
  673.         jmp    LeaveHandler        ; If garbage key, then don't buffer it
  674.  
  675. NotE0Code:    mov    bl, al            ; Put break bit into bl    ; 0 = pressed, 1=released
  676.         and    al, 01111111b        ; AL = scancode
  677.         or    al, E0Flag        ; AL = extended scancode
  678.         mov     E0Flag,0        ; clear E0 flag
  679.         shl    bl, 1            ; put upper bit into carry flag
  680.         jc    key_mark_released    ; if upper bit of bl was set, then it was a release code
  681.  
  682. ;**************************************************************
  683. ;****************** HANDLE A NEWLY PRESSED KEY ****************
  684. ;**************************************************************
  685. ;Marks the key press in EAX in the scancode array.
  686.  
  687. key_mark_pressed:
  688.         ;cmp    al, 0eh    ; backspace
  689.         ;je    pause_execution
  690.         
  691.         mov     _keyd_last_pressed, al
  692.         ; Check if the key is repeating or if it just got pressed.
  693.         cmp     byte ptr _keyd_pressed[eax], 1
  694.         je      AlreadyDown
  695.  
  696. ;------------------------------- Code for a key pressed for the first time ------------------------
  697.         mov     byte ptr _keyd_pressed[eax], 1    
  698.         ; Set the time
  699.  
  700.         push    edx
  701.         push    eax
  702.         call    key_get_milliseconds
  703.         mov     edx, eax
  704.         pop     eax
  705.         mov     TimeKeyWentDown[eax*4], edx
  706.         pop     edx
  707.  
  708.         inc     NumDowns[eax*4]
  709.  
  710.         jmp    BufferAX
  711.  
  712. ;------------------------------- Code for a key that is already pressed ------------------------
  713. AlreadyDown:
  714.         cmp     _keyd_repeat, 0
  715.         je      DoneMarkingPressed
  716.  
  717. BufferAX:
  718.     cmp     _keyd_buffer_type, 0
  719.     je      SkipBuffer          ; Buffer = 0 means don't buffer anything.
  720.  
  721.     cmp     al, 0AAh        ; garbage key
  722.     je      SkipBuffer
  723.  
  724.     call    get_modifiers      ;returns ah
  725.     
  726.     xor     ebx, ebx
  727.     mov     bl, keytail
  728.     inc     bl
  729.     inc     bl
  730.  
  731.     ; If the buffer is full then don't buffer this key
  732.     cmp     bl, keyhead
  733.     je      SkipBuffer
  734.     dec     bl
  735.  
  736.     mov     word ptr keybuffer[ebx*2], ax
  737.     mov     keytail, bl
  738.  
  739. SkipBuffer:    
  740.         
  741. ;---------------------------------- Exit function -----------------------------
  742. DoneMarkingPressed:
  743.     jmp    LeaveHandler
  744.  
  745. ;**************************************************************
  746. ;******************* HANDLE A RELEASED KEY ********************
  747. ;**************************************************************
  748. ; Unmarks the key press in EAX from the scancode array.
  749. key_mark_released:
  750.  
  751.         mov     _keyd_last_released, al
  752.         mov     byte ptr _keyd_pressed[eax], 0
  753.         inc     NumUps[eax*4]
  754.  
  755.         cmp    _keyd_editor_mode, 0
  756.         je    NotInEditorMode
  757.         push    eax
  758.         xor     ah,ah
  759.         call    get_modifiers
  760.         or      ah,ah    ;check modifiers
  761.         pop     eax
  762.         jnz     skip_time
  763.  
  764. NotInEditorMode:    
  765.         push    eax
  766.  
  767.         call    timer_get_stamp64
  768.  
  769.         ; Timing in milliseconds
  770.         ; Can be used for up to 1000 hours
  771.         shld    edx, eax, 21            ; Keep 32+11 bits
  772.         shl     eax, 21
  773.         mov     ebx, 2502279823         ; 2^21*1193180/1000
  774.         div     ebx
  775.  
  776.         mov     edx, eax
  777.         pop     eax
  778.         sub     edx, TimeKeyWentDown[eax*4]
  779.         add     TimeKeyHeldDown[eax*4], edx
  780.  
  781. skip_time:    ;**jmp    LeaveHandler
  782.  
  783. ;**************************************************************
  784. ;*************** FINISH UP THE KEYBOARD INTERRUPT *************
  785. ;**************************************************************
  786. LeaveHandler:
  787.         ;jmp    DontPassToBios
  788.         jmp    PassToBios
  789.  
  790. ;****        cmp    _keyd_dump_key_array, 0
  791. ;****        je    DontPassToBios
  792. ;****        mov    ecx, 256
  793. ;****        mov    ebx, 0
  794. ;****
  795. ;****showdown:    mov    al, _keyd_pressed[ebx]
  796. ;****        add    al, '0'
  797. ;****        mov    [ebx*2+ 0b0000h], al
  798. ;****        inc    ebx
  799. ;****        loop    showdown
  800. ;****
  801. ;****        mov    eax, 0b0000h
  802. ;****        mov     byte ptr [ eax+(036h*2+1) ], 070h
  803. ;****        mov     byte ptr [ eax+(02Ah*2+1) ], 070h
  804. ;****        mov     byte ptr [ eax+(038h*2+1) ], 070h
  805. ;****        mov     byte ptr [ eax+(0B8h*2+1) ], 070h
  806. ;****        mov     byte ptr [ eax+(01Dh*2+1) ], 070h
  807. ;****        mov     byte ptr [ eax+(09dh*2+1) ], 070h
  808. ;****
  809. ;****        mov     byte ptr [ eax+(0AAh*2+1) ], 07Fh
  810. ;****        mov     byte ptr [ eax+(0E0h*2+1) ], 07Fh
  811. ;****
  812. ;****        jmp    DontPassToBios
  813. ;****
  814.  
  815. ; If in debugger, pass control to dos interrupt.
  816.  
  817. PassToBios:    pop     ds          ; Nothing left on stack but flags
  818.         pop     edx
  819.         pop     ecx
  820.         pop     ebx
  821.         pop     eax
  822.  
  823.         sub     esp, 8              ; Save space for IRETD frame
  824.         push    ds                  ; Save registers we use.
  825.         push    eax
  826.         mov     ax, DGROUP
  827.         mov     ds, ax              ; Set DS to our data segment
  828.         mov     eax, org_int_off   ; put original handler address
  829.         mov     [esp+8], eax        ;   in the IRETD frame
  830.         movzx   eax, org_int_sel
  831.         mov     [esp+12], eax
  832.         pop     eax                 ; Restore registers
  833.         pop     ds
  834.         iretd                       ; Chain to previous handler
  835.  
  836. pause_execution:
  837.         in      al, 61h         ; Get current port 61h state
  838.         or      al, 10000000b   ; Turn on bit 7 to signal clear keybrd
  839.         out     61h, al         ; Send to port
  840.         and     al, 01111111b   ; Turn off bit 7 to signal break
  841.         out     61h, al         ; Send to port
  842.         mov     al, 20h         ; Reset interrupt controller
  843.         out     20h, al
  844.         sti                     ; Reenable interrupts
  845.         pop     ds
  846.         pop     edx             ; Restore all of the saved registers.
  847.         pop     ecx
  848.         pop     ebx
  849.         pop     eax
  850.         popfd
  851.  
  852.         iretd                   ; Interrupt must return with IRETD
  853.  
  854. DontPassToBios:    
  855.  
  856. ; Resets the keyboard, PIC, restores stack, returns.
  857.         in      al, 61h         ; Get current port 61h state
  858.         or      al, 10000000b   ; Turn on bit 7 to signal clear keybrd
  859.         out     61h, al         ; Send to port
  860.         and     al, 01111111b   ; Turn off bit 7 to signal break
  861.         out     61h, al         ; Send to port
  862.         mov     al, 20h         ; Reset interrupt controller
  863.         out     20h, al
  864.         sti                     ; Reenable interrupts
  865.         pop     ds
  866.         pop     edx             ; Restore all of the saved registers.
  867.         pop     ecx
  868.         pop     ebx
  869.         pop     eax
  870.         popfd
  871.         iretd               ; Interrupt must return with IRETD
  872.  
  873. ;returns ah=bitmask of shift,ctrl,alt keys
  874. get_modifiers:        push    ecx
  875.  
  876.         xor     ah,ah
  877.  
  878.         ; Check the shift keys
  879.         mov     cl, _keyd_pressed[ 036h ]
  880.         or      cl, _keyd_pressed[ 02ah ]
  881.         or      ah, cl
  882.  
  883.         ; Check the alt key
  884.         mov     cl, _keyd_pressed[ 038h ]
  885.         or      cl, _keyd_pressed[ 0b8h ]
  886.         shl     cl, 1
  887.         or      ah, cl
  888.  
  889.         ; Check the ctrl key
  890.         mov     cl, _keyd_pressed[ 01dh ]
  891.         or      cl, _keyd_pressed[ 09dh ]
  892.         shl     cl, 2
  893.         or      ah, cl
  894.  
  895.         pop     ecx
  896.         ret
  897.  
  898. IFDEF DEBUG
  899. CheckForDebugger:
  900.     ; Returns CF=0 if debugger isn't active
  901.     ;         CF=1 if debugger is active
  902.  
  903.         ;*************************** DEBUG ******************************
  904.         ; When we're in the VIDEO debugger, we want to pass control to
  905.         ; the original interrupt.  So, to tell if the debugger is active,
  906.         ; I check if video page 1 is the active page since that is what
  907.         ; page the debugger uses, and if that works, I check the top of
  908.         ; the screen to see if the texxt "Control" is there, which should
  909.         ; only be there when we're in the debugger.
  910.  
  911.     
  912.  
  913.         push    eax
  914.         ;mov     eax, 0462h          ; Address 0462 stores BIOS current page
  915.         ;cmp     BYTE PTR [eax], 1
  916.         ;jne     NoDebuggerOnColor
  917.         ;mov     eax, 0b8000h+4096   ; 4096 = offset to 2nd video mem page
  918.         ;cmp     BYTE PTR [eax+2],'C'
  919.         ;jne     NoDebuggerOnColor
  920.         ;cmp     BYTE PTR [eax+4],'o'
  921.         ;jne     NoDebuggerOnColor
  922.         ;cmp     BYTE PTR [eax+6],'n'
  923.         ;jne     NoDebuggerOnColor
  924.         ;cmp     BYTE PTR [eax+8],'t'
  925.         ;jne     NoDebuggerOnColor
  926.         ;cmp     BYTE PTR [eax+10],'r'
  927.         ;jne     NoDebuggerOnColor
  928.         ;cmp     BYTE PTR [eax+12],'o'
  929.         ;jne     NoDebuggerOnColor
  930.         ;cmp     BYTE PTR [eax+14],'l'
  931.         ;jne     NoDebuggerOnColor
  932.         ;jmp     ActiveDebugger
  933.         ;NoDebuggerOnColor:
  934.         ; First, see if there is a mono debugger...
  935.  
  936.         ;mov     eax, 0b0000h        ; 4096 = offset to mono video mem
  937.         ;cmp     BYTE PTR [eax+2],'C'
  938.         ;jne     NoActiveDebugger
  939.         ;cmp     BYTE PTR [eax+4],'o'
  940.         ;jne     NoActiveDebugger
  941.         ;cmp     BYTE PTR [eax+6],'n'
  942.         ;jne     NoActiveDebugger
  943.         ;cmp     BYTE PTR [eax+8],'t'
  944.         ;jne     NoActiveDebugger
  945.         ;cmp     BYTE PTR [eax+10],'r'
  946.         ;jne     NoActiveDebugger
  947.         ;cmp     BYTE PTR [eax+12],'o'
  948.         ;jne     NoActiveDebugger
  949.         ;cmp     BYTE PTR [eax+14],'l'
  950.         ;jne     NoActiveDebugger
  951.  
  952.         mov     eax, 0b0000h        ; 4096 = offset to mono video mem
  953.         add     eax, 24*80*2
  954.  
  955.  
  956.         cmp     BYTE PTR [eax+0],'D'
  957.         jne     NextTest
  958.         cmp     BYTE PTR [eax+2],'B'
  959.         jne     NextTest
  960.         cmp     BYTE PTR [eax+4],'G'
  961.         jne     NextTest
  962.         cmp     BYTE PTR [eax+6],'>'
  963.         jne     NextTest
  964.  
  965.         ;Found DBG>, so consider debugger active:
  966.         jmp     ActiveDebugger
  967.  
  968. NextTest:
  969.         cmp     BYTE PTR [eax+14],'<'
  970.         jne     NextTest1
  971.         cmp     BYTE PTR [eax+16],'i'
  972.         jne     NextTest1
  973.         cmp     BYTE PTR [eax+18],'>'
  974.         jne     NextTest1
  975.         cmp     BYTE PTR [eax+20],' '
  976.         jne     NextTest1
  977.         cmp     BYTE PTR [eax+22],'-'
  978.         jne     NextTest1
  979.  
  980.         ; Found <i> - , so consider debugger active:
  981.         jmp     ActiveDebugger
  982.  
  983. NextTest1:
  984.         cmp     BYTE PTR [eax+0], 200
  985.         jne     NextTest2
  986.         cmp     BYTE PTR [eax+2], 27
  987.         jne     NextTest2
  988.         cmp     BYTE PTR [eax+4], 17
  989.         jne     NextTest2
  990.  
  991.         ; Found either the help screen or view screen, so consider
  992.         ; debugger active
  993.         jmp     ActiveDebugger
  994.  
  995. NextTest2:
  996.         ; Now we see if its active by looking for the "Executing..."
  997.         ; text on the bottom of the mono screen
  998.         ;mov     eax, 0b0000h        ; 4096 = offset to mono video mem
  999.         ;add     eax, 24*80*2
  1000.         ;cmp     BYTE PTR [eax+0],'E'
  1001.         ;je      NoActiveDebugger
  1002.         ;cmp     BYTE PTR [eax+2],'x'
  1003.         ;je      NoActiveDebugger
  1004.         ;cmp     BYTE PTR [eax+4],'e'
  1005.         ;je      NoActiveDebugger
  1006.         ;cmp     BYTE PTR [eax+6],'c'
  1007.         ;je      NoActiveDebugger
  1008.  
  1009. NoActiveDebugger:
  1010.         pop     eax
  1011.         clc
  1012.         ret
  1013.  
  1014. ActiveDebugger:
  1015.         pop     eax
  1016.         stc
  1017.         ret
  1018.  
  1019. ENDIF
  1020.  
  1021. _TEXT   ENDS
  1022.  
  1023.         END
  1024.  
  1025.  
  1026. 
  1027.