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