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