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