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