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
15 ; Revision 1.20 1994/01/18 10:58:55 john
\r
16 ; *** empty log message ***
\r
18 ; Revision 1.19 1993/12/22 13:28:40 john
\r
19 ; Added back changes Matt made in r1.14
\r
21 ; Revision 1.18 1993/12/22 13:18:32 john
\r
22 ; *** empty log message ***
\r
24 ; Revision 1.17 1993/12/20 16:48:47 john
\r
25 ; Put cli/sti around clear keybuffer in key_close
\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
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
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
39 ; Revision 1.13 1993/10/29 10:47:00 john
\r
40 ; *** empty log message ***
\r
42 ; Revision 1.12 1993/10/16 19:24:16 matt
\r
43 ; Added new function key_clear_times() & key_clear_counts()
\r
45 ; Revision 1.11 1993/10/15 10:16:49 john
\r
46 ; bunch of stuff, mainly with detecting debugger.
\r
48 ; Revision 1.10 1993/10/04 13:25:57 john
\r
49 ; Changed the way extended keys are processed.
\r
51 ; Revision 1.9 1993/09/28 11:35:32 john
\r
54 ; Revision 1.8 1993/09/23 18:09:23 john
\r
55 ; fixed bug checking for DBG
\r
57 ; Revision 1.7 1993/09/23 17:28:01 john
\r
58 ; made debug check look for DBG> instead of CONTROL
\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
66 ; Revision 1.5 1993/09/17 09:58:12 john
\r
67 ; Added checks for already installed, not installed, etc.
\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
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
75 ; Revision 1.2 1993/07/22 13:12:23 john
\r
79 ; Revision 1.1 1993/07/10 13:10:42 matt
\r
85 ;***************************************************************************
\r
86 ;***************************************************************************
\r
89 ;***** K E Y . A S M *****
\r
91 ;***** Contains routines to get, buffer, and check key presses. *****
\r
94 ;***** PROCEDURES *****
\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
105 ;***** VARIABLES *****
\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
116 ;***** CONSTANTS *****
\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
124 ;***************************************************************************
\r
125 ;***************************************************************************
\r
130 ;************************************************************************
\r
131 ;**************** FLAT MODEL DATA SEGMENT STUFF *************************
\r
132 ;************************************************************************
\r
134 _DATA SEGMENT BYTE PUBLIC USE32 'DATA'
\r
136 rcsid db "$Id: oldkey.asm,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $"
\r
138 PUBLIC _keyd_pressed ; Must start with a _ so C can see the variable.
\r
140 _keyd_pressed db 256 dup (?)
\r
142 keybuffer dw 256 dup (?) ; Use 256 so an inc wraps around
\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
151 PUBLIC _keyd_editor_mode
\r
153 _keyd_editor_mode db 0
\r
155 PUBLIC _keyd_use_bios
\r
157 _keyd_use_bios db 1
\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
164 PUBLIC _keyd_dump_key_array
\r
165 _keyd_dump_key_array db 0
\r
169 interrupted_cs dw ?
\r
170 interrupted_eip dd ?
\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
191 ;************************************************************************
\r
192 ;**************** FLAT MODEL CODE SEGMENT STUFF *************************
\r
193 ;************************************************************************
\r
195 _TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
\r
200 key_get_milliseconds:
\r
201 EXTERNDEF timer_get_stamp64:NEAR
\r
206 call timer_get_stamp64
\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
212 mov ebx, 2502279823 ; 2^21*1193180/1000
\r
220 ;************************************************************************
\r
221 ;************************************************************************
\r
223 ;***** K E Y _ T O _ A S C I I _ *****
\r
225 ;************************************************************************
\r
226 ;************************************************************************
\r
228 PUBLIC key_to_ascii_
\r
243 and ah, 01b ; take away ctrl and alt codes
\r
247 mov al, byte ptr key1[eax]
\r
257 public key_clear_times_,key_clear_counts_
\r
259 ;clear the array of key down times.
\r
267 lea edi,TimeKeyHeldDown
\r
268 rep stosd ;clear array
\r
275 ;clear the arrays of key down counts
\r
276 key_clear_counts_:
\r
284 rep stosd ;clear array
\r
287 rep stosd ;clear array
\r
295 PUBLIC key_down_time_
\r
308 cmp _keyd_pressed[ebx], 0
\r
312 cmp _keyd_editor_mode, 0
\r
315 call get_modifiers ;shift,alt,ctrl?
\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
327 add eax, TimeKeyHeldDown[ebx*4]
\r
328 mov TimeKeyHeldDown[ebx*4], 0
\r
336 PUBLIC key_down_count_
\r
341 mov eax, NumDowns[ebx*4]
\r
342 mov NumDowns[ebx*4], 0
\r
347 PUBLIC key_up_count_
\r
352 mov eax, NumUps[ebx*4]
\r
353 mov NumUps[ebx*4], 0
\r
360 ;************************************************************************
\r
361 ;************************************************************************
\r
363 ;***** K E Y _ F L U S H *****
\r
365 ;************************************************************************
\r
366 ;************************************************************************
\r
381 ; Clear the keyboard array
\r
382 mov edi, offset _keyd_pressed
\r
393 ;************************************************************************
\r
394 ;************************************************************************
\r
396 ;***** K E Y _ I N I T *****
\r
398 ;************************************************************************
\r
399 ;************************************************************************
\r
409 ;**************************************************************
\r
410 ;******************* INITIALIZE key QUEUE **********************
\r
411 ;**************************************************************
\r
413 mov _keyd_buffer_type,1
\r
417 ; Clear the keyboard array
\r
421 jne AlreadyInstalled
\r
423 ;**************************************************************
\r
424 ;******************* SAVE OLD INT9 HANDLER ********************
\r
425 ;**************************************************************
\r
429 mov eax, 03509h ; DOS Get Vector 09h
\r
431 mov org_int_sel, es ; Save old interrupt selector
\r
432 mov org_int_off, ebx ; Save old interrupt offset
\r
435 ;**************************************************************
\r
436 ;***************** INSTALL NEW INT9 HANDLER *******************
\r
437 ;**************************************************************
\r
439 mov eax, 02509h ; DOS Set Vector 09h
\r
440 mov edx, offset key_handler ; Point DS:EDX to new handler
\r
442 mov MyCodeSegment, bx
\r
457 ;************************************************************************
\r
458 ;************************************************************************
\r
460 ;***** K E Y _ C L O S E _ *****
\r
462 ;************************************************************************
\r
463 ;************************************************************************
\r
477 ;**************************************************************
\r
478 ;***************** RESTORE OLD INT9 HANDLER *******************
\r
479 ;**************************************************************
\r
483 ; Clear the BIOS buffer
\r
486 mov al, byte ptr [ebx]
\r
488 mov byte ptr [ebx], al
\r
491 mov eax, 02509h ; DOS Set Vector 09h
\r
492 mov edx, org_int_off
\r
493 mov ds, org_int_sel
\r
503 ;************************************************************************
\r
504 ;************************************************************************
\r
506 ;***** K E Y _ C H E C K _ *****
\r
508 ;************************************************************************
\r
509 ;************************************************************************
\r
511 PUBLIC key_checkch_ ; Must end with a _ so C can see the function.
\r
531 ;************************************************************************
\r
532 ;************************************************************************
\r
534 ;***** K E Y _ D E B U G *****
\r
536 ;************************************************************************
\r
537 ;************************************************************************
\r
545 ;************************************************************************
\r
546 ;************************************************************************
\r
548 ;***** K E Y _ G E T C H _ *****
\r
550 ;************************************************************************
\r
551 ;************************************************************************
\r
553 PUBLIC key_getch_ ; Must end with a _ so C can see the function.
\r
566 cli ; Critical section
\r
573 cli ; Critical section
\r
576 mov ax, word ptr keybuffer[ebx*2]
\r
577 inc BYTE PTR keyhead
\r
584 ;************************************************************************
\r
585 ;************************************************************************
\r
587 ;***** K E Y _ I N K E Y _ *****
\r
589 ;************************************************************************
\r
590 ;************************************************************************
\r
592 PUBLIC key_inkey_ ; Must end with a _ so C can see the function.
\r
603 cli ; Critical section
\r
610 cli ; Critical section
\r
612 mov ax, word ptr keybuffer[ebx*2]
\r
613 inc BYTE PTR keyhead
\r
619 PUBLIC key_peekkey_ ; Must end with a _ so C can see the function.
\r
627 cli ; Critical section
\r
636 mov ax, word ptr keybuffer[ebx*2]
\r
644 ;************************************************************************
\r
645 ;************************************************************************
\r
647 ;***** K E Y _ H A N D L E R *****
\r
649 ;************************************************************************
\r
650 ;************************************************************************
\r
652 PUBLIC key_handler ; Must end with a _ so C can see the function.
\r
656 pushfd ; Save flags in case we have to chain to original
\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
666 mov eax, (0b0000h+76*2)
\r
667 mov byte ptr [eax], '1'
\r
670 call CheckForDebugger
\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
676 @@: mov eax, 0b0000h+78*2
\r
677 mov byte ptr [eax], 'I'
\r
679 ; Clear the BIOS buffer
\r
681 ;**mov al, byte ptr [ebx]
\r
683 ;**mov byte ptr [ebx], al
\r
689 in al, 060h ; Get scan code from keyboard
\r
694 E0Code: mov E0Flag, 010000000b
\r
695 jmp LeaveHandler ; If garbage key, then don't buffer it
\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
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
706 ;**************************************************************
\r
707 ;****************** HANDLE A NEWLY PRESSED KEY ****************
\r
708 ;**************************************************************
\r
709 ;Marks the key press in EAX in the scancode array.
\r
712 ;cmp al, 0eh ; backspace
\r
713 ;je pause_execution
\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
720 ;------------------------------- Code for a key pressed for the first time ------------------------
\r
721 mov byte ptr _keyd_pressed[eax], 1
\r
726 call key_get_milliseconds
\r
729 mov TimeKeyWentDown[eax*4], edx
\r
732 inc NumDowns[eax*4]
\r
736 ;------------------------------- Code for a key that is already pressed ------------------------
\r
738 cmp _keyd_repeat, 0
\r
739 je DoneMarkingPressed
\r
742 cmp _keyd_buffer_type, 0
\r
743 je SkipBuffer ; Buffer = 0 means don't buffer anything.
\r
745 cmp al, 0AAh ; garbage key
\r
748 call get_modifiers ;returns ah
\r
755 ; If the buffer is full then don't buffer this key
\r
760 mov word ptr keybuffer[ebx*2], ax
\r
765 ;---------------------------------- Exit function -----------------------------
\r
766 DoneMarkingPressed:
\r
769 ;**************************************************************
\r
770 ;******************* HANDLE A RELEASED KEY ********************
\r
771 ;**************************************************************
\r
772 ; Unmarks the key press in EAX from the scancode array.
\r
775 mov _keyd_last_released, al
\r
776 mov byte ptr _keyd_pressed[eax], 0
\r
779 cmp _keyd_editor_mode, 0
\r
784 or ah,ah ;check modifiers
\r
791 call timer_get_stamp64
\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
797 mov ebx, 2502279823 ; 2^21*1193180/1000
\r
802 sub edx, TimeKeyWentDown[eax*4]
\r
803 add TimeKeyHeldDown[eax*4], edx
\r
805 skip_time: ;**jmp LeaveHandler
\r
807 ;**************************************************************
\r
808 ;*************** FINISH UP THE KEYBOARD INTERRUPT *************
\r
809 ;**************************************************************
\r
811 mov eax, (0b0000h+76*2)
\r
812 mov byte ptr [eax], '2'
\r
814 ;; cmp _keyd_dump_key_array, 0
\r
815 ;; je DontPassToBios
\r
821 showdown: mov al, _keyd_pressed[ebx]
\r
823 mov [ebx*2+ 0b0000h], al
\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
835 mov byte ptr [ eax+(0AAh*2+1) ], 07Fh
\r
836 mov byte ptr [ eax+(0E0h*2+1) ], 07Fh
\r
841 ; If in debugger, pass control to dos interrupt.
\r
843 PassToBios: pop ds ; Nothing left on stack but flags
\r
849 sub esp, 8 ; Save space for IRETD frame
\r
850 push ds ; Save registers we use.
\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
858 pop eax ; Restore registers
\r
860 iretd ; Chain to previous handler
\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
870 sti ; Reenable interrupts
\r
872 pop edx ; Restore all of the saved registers.
\r
877 sub esp, 8 ; Save space for IRETD frame
\r
878 push ds ; Save registers we use.
\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
886 pop eax ; Restore registers
\r
889 iretd ; Interrupt must return with IRETD
\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
901 sti ; Reenable interrupts
\r
903 pop edx ; Restore all of the saved registers.
\r
908 iretd ; Interrupt must return with IRETD
\r
910 ;returns ah=bitmask of shift,ctrl,alt keys
\r
911 get_modifiers: push ecx
\r
915 ; Check the shift keys
\r
916 mov cl, _keyd_pressed[ 036h ]
\r
917 or cl, _keyd_pressed[ 02ah ]
\r
920 ; Check the alt key
\r
921 mov cl, _keyd_pressed[ 038h ]
\r
922 or cl, _keyd_pressed[ 0b8h ]
\r
926 ; Check the ctrl key
\r
927 mov cl, _keyd_pressed[ 01dh ]
\r
928 or cl, _keyd_pressed[ 09dh ]
\r
937 ; Returns CF=0 if debugger isn't active
\r
938 ; CF=1 if debugger is active
\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
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
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
989 mov eax, 0b0000h ; 4096 = offset to mono video mem
\r
993 cmp BYTE PTR [eax+0],'D'
\r
995 cmp BYTE PTR [eax+2],'B'
\r
997 cmp BYTE PTR [eax+4],'G'
\r
999 cmp BYTE PTR [eax+6],'>'
\r
1002 ;Found DBG>, so consider debugger active:
\r
1003 jmp ActiveDebugger
\r
1006 cmp BYTE PTR [eax+14],'<'
\r
1008 cmp BYTE PTR [eax+16],'i'
\r
1010 cmp BYTE PTR [eax+18],'>'
\r
1012 cmp BYTE PTR [eax+20],' '
\r
1014 cmp BYTE PTR [eax+22],'-'
\r
1017 ; Found <i> - , so consider debugger active:
\r
1018 jmp ActiveDebugger
\r
1021 cmp BYTE PTR [eax+0], 200
\r
1023 cmp BYTE PTR [eax+2], 27
\r
1025 cmp BYTE PTR [eax+4], 17
\r
1028 ; Found either the help screen or view screen, so consider
\r
1030 jmp ActiveDebugger
\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
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