home *** CD-ROM | disk | FTP | other *** search
- ;=============================================================================
- ; AllKeys- Returns popup stolen key combinations back to the applications.
- ; Load "ALLKEYS" before and after your pop-ups.
- ; Then press Ctrl-Alt-Z to toggle ALLKEYS on/off.
- ; "beep..BEEP" signals all keys on. "BEEP..beep" signals all keys off.
- ;=============================================================================
- CSEG SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
- ORG 100H
-
- FIRST: JMP INIT
-
- COPYRIGHT DB "ALLKEYS 1.0 (c) 1988 Ziff Communications Co.",13,10
- DB "PC Magazine ",254," Robert L. Morton",13,10
- DB "Low copy installed",13,10,"$"
-
- MESG1 DB "ALLKEYS high copy installed",13,10
- DB "Ctrl-Alt-Z to toggle tsr's on/off",13,10,"$"
-
- MESG2 DB "ALLKEYS already installed high and low",13,10,"$"
-
- MESG3 DB "Vectors could not be restored - ALLKEYS disabled",13,10,"$"
-
- MESG4 DB "ALLKEYS not loaded yet",13,10,"$"
-
- MESG5 DB "ALLKEYS un-installed",13,10,"$"
-
- ORIG_INT9 DW 0,0 ;The original int 9 vector
- ORIG_INT16 DW 0,0 ;The original int 16h vector
-
- USED_INT9 DW 0,0 ;The used int 9 vector
- USED_INT16 DW 0,0 ;The used int 16h vector
-
- HOTKEY DB 44 ;Our HOT key: "Z"
- SHIFT_MASK DB 0CH ;Our shift mask: "Ctrl-Alt"
-
- ALLKEYS DB 0 ;Allkeys on/off status flag.
-
- DISABLE DB 0 ;If set to 1, Allkeys will not respond
- ; to Ctrl-Alt-Z combination and all
- ; keystrokes will be processed normally.
-
- TONE_LOW DW 500 ;Low boundary "beep"
- TONE_HIGH DW 1500 ;High boundary "BEEP"
- TONE_STEP DW 500 ;Step between tones
- TONE_LENGTH DW 50 ;Length of each tone
-
- ;-----------------------------------------------------------------------------
- ; New interrupt 9 handling routine.
- ;-----------------------------------------------------------------------------
- NEW_INT9 PROC NEAR
- ASSUME CS:CSEG, DS:NOTHING, ES:NOTHING, SS:NOTHING
-
- STI ;Enable interrupts
- PUSH AX ;Save AX
-
- CMP CS:DISABLE,0 ;Are we disabled?
- JNE KB1 ;Jump out if so.
-
- IN AL,60H ;Get key just pressed
- CMP AL,CS:HOTKEY ;Was it our HOT key?
- JNE KB2 ;If not, jump KB2
-
- MOV AH,2 ;Get shift status.
- INT 16H
- AND AL,0FH ;Mask out shift keys
- CMP AL,CS:SHIFT_MASK ;Was it our shift mask?
- JNE KB2 ;If not, jump KB2
-
- CALL KB_RESET ;Reset keyboard
-
- XOR CS:ALLKEYS,0FFH ;Toggle request flag
-
- CALL BEEP_STATUS ;Beep Allkeys' status
-
- KB1: POP AX ;Restore AX
- JMP DWORD PTR CS:USED_INT9 ;Exit through popup chain
-
- KB2: CMP CS:ALLKEYS,0 ;Allkeys' request flag set?
- JE KB1 ;If not, jump KB1
- POP AX ;Restore AX
- JMP DWORD PTR CS:ORIG_INT9 ;Skip popup chain and exit
- ; directly to original.
- NEW_INT9 ENDP
-
- ;-----------------------------------------------------------------------------
- ; New interrupt 16h handling routine.
- ;-----------------------------------------------------------------------------
- NEW_INT16 PROC NEAR
- ASSUME CS:CSEG, DS:NOTHING, ES:NOTHING, SS:NOTHING
-
- STI ;Enable interrupts
- CMP CS:DISABLE,0 ;Are we disabled?
- JNE INT16_OUT ;Jump out if so.
-
- CMP CS:ALLKEYS,0 ;Allkeys' request flag set?
- JE INT16_OUT ;No - Leave through used 16h
- JMP DWORD PTR CS:ORIG_INT16 ;Yes- Leave through original
- INT16_OUT: JMP DWORD PTR CS:USED_INT16
-
- NEW_INT16 ENDP
-
- ;-----------------------------------------------------------------------------
- ; Routine to beep Allkeys' status through the speaker.
- ; If Allkeys is on, "beep..BEEP". If Allkeys is off, "BEEP..beep".
- ;-----------------------------------------------------------------------------
- BEEP_STATUS PROC NEAR
- ASSUME CS:CSEG, DS:NOTHING, ES:NOTHING, SS:NOTHING
-
- PUSH CX ;Save needed registers
- PUSH DS
-
- PUSH CS ;Point DS to our data
- POP DS
- ASSUME DS:CSEG
-
- CMP ALLKEYS,0 ;Allkeys off?
- JE BS2 ;If so, jump BS2
-
- ;Allkeys on - Ascend from a LOW tone to a HIGH tone.
-
- MOV CX,TONE_LOW ;Start at the bottom
- BS1: CALL SOUND ;Make the sound
- ADD CX,TONE_STEP ;Add the next step
- CMP CX,TONE_HIGH ;Are we over the top?
- JNA BS1 ;No - then keep on going
- JMP BS_OUT ;Yes- then jump out
-
- ;Allkeys off- Descend from a HIGH tone to a LOW tone.
-
- BS2: MOV CX,TONE_HIGH ;Start at the top
- BS3: CALL SOUND ;Make the sound
- SUB CX,TONE_STEP ;Subtract the next step
- CMP CX,TONE_LOW ;Are we below the bottom?
- JNB BS3 ;No, then keep on going
-
- BS_OUT: POP DS ;Restore used registers
- POP CX
- RET
-
- BEEP_STATUS ENDP
-
- ;-----------------------------------------------------------------------------
- ; Routine to produce a sound through the speaker.
- ; CX contains the frequency. Variable TONE_LENGTH contains the length.
- ;-----------------------------------------------------------------------------
- SOUND PROC NEAR
- ASSUME CS:CSEG, DS:CSEG, ES:NOTHING, SS:NOTHING
-
- PUSH AX ;Save needed registers
- PUSH CX
- PUSH DX
-
- ;Convert the frequency.
-
- MOV DX,12h ;Upper part
- MOV AX,34DEh ;Lower part
- DIV CX ;Divide by frequency
- MOV CX,AX ;to get quotient.
-
- ;Set the tone.
-
- MOV AL,CL ;Send low byte
- OUT 42h,AL ;out to the timer.
- MOV AL,CH ;Send high byte
- OUT 42h,AL ;out to the timer.
-
- ;Turn the tone on.
-
- IN AL,61h ;Get contents of system port B
- OR AL,3 ;Turn speaker and timer on
- OUT 61h,AL ;Send out new values to port B
-
- ;Delay
-
- MOV CX,TONE_LENGTH ;Put delay count in CX
- CALL DELAY ;Delay
-
- ;Turn the tone off.
-
- IN AL,61h ;Get port B again
- AND AL,0FCh ;Turn off timer and speaker
- OUT 61h,AL
- POP DX ;Restore used registers
- POP CX
- POP AX
- RET
-
- SOUND ENDP
-
- ;-----------------------------------------------------------------------------
- ; Routine to delay. CX contains the factor.
- ;-----------------------------------------------------------------------------
- DELAY PROC NEAR
-
- PUSH CX ;Save outside CX
- MOV CX,0FFH ;Move timing constant in CX
- DELAY1: LOOP DELAY1 ;Loop for inside
- POP CX ;Restore outside CX
- LOOP DELAY ;Loop for outside
- RET
-
- DELAY ENDP
-
- ;-----------------------------------------------------------------------------
- ; Routine to reset keyboard and 8259 interrupt controller.
- ;-----------------------------------------------------------------------------
- KB_RESET PROC NEAR
-
- IN AL,61H ;Get control port value
- MOV AH,AL ;Save in AH
- OR AL,80H ;Set bit 7
- OUT 61H,AL ;Output reset value
- MOV AL,AH ;Send original value...
- JMP SHORT $+2 ;Take your time
- OUT 61H,AL ;...to enable keyboard
- CLI ;No interrupts now
- MOV AL,20H ;Send end of interrupt
- OUT 20H,AL ;value to 8259.
- STI ;Re-enable interrupts
- RET
-
- KB_RESET ENDP
-
- ;-----------------------------------------------------------------------------
- ; Initialization for Allkeys....
- ;-----------------------------------------------------------------------------
- INIT PROC NEAR
- ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
-
- ;Check if the "/U" parameter was entered on the command line.
-
- MOV SI,80h ;Point to parm line
- CMP BYTE PTR [SI],0 ;Any chars entered?
- JNE INIT1 ;Yes-jump init1
- JMP INIT8 ;No -jump init8
-
- INIT1: MOV CL,[SI] ;Put parm length in CL
- XOR CH,CH ;Make 16 bit
- INC SI ;Point to next byte
- CLD ;Forward
-
- INIT2: LODSB ;Load a byte into AL
- CMP AL,"/" ;Is it our switch?
- JE INIT3 ;Jump if so
- LOOP INIT2 ;Keep on looking
- JMP INIT8 ;No switch found. Jump init8.
-
- INIT3: AND BYTE PTR [SI],0DFh ;Change char to uppercase
- CMP BYTE PTR [SI],"U" ;Is it a "U"?
- JE INIT4 ;Yes-jump init4
- JMP INIT8 ;No -jump init8
-
- ;"/U" parameter found. Make sure we're loaded.
-
- INIT4: CALL SEC_COPY ;Check for a second copy.
- JC INIT5 ;Jump if found.
-
- MOV DX,OFFSET MESG4 ;Print error message
- ERR_EXIT: MOV AH,9
- INT 21H
-
- MOV AX,4C01h ;Terminate with errorlevel 1
- INT 21H
-
- ;Modify resident copy to avoid future searches.
-
- INIT5: ASSUME DS:CSEG, ES:NOTHING
-
- PUSH ES ;Point DS at the resident
- POP DS ; copy of Allkeys.
- XOR AX,AX ;Point ES at the int vector
- MOV ES,AX ; table at bottom of memory.
-
- MOV WORD PTR [FIRST],0FFh ;This instruction modifies it
-
- ;Check if int 9 and 16h vectors point to the resident copy.
-
- MOV AX,DS ;Put seg of orig copy in AX
- CMP AX,ES:[ 9*4+2] ;Compare it to int 9 seg
- JNE INIT6 ;Jump if different
- CMP AX,ES:[16h*4+2] ;Compare it to int 16h seg
- JNE INIT6 ;Jump if different
-
- ;Int 9 and 16h vectors point to resident copy.
- ;Restore int 9 and 16h vectors and release resident copy from memory.
- ;Then terminate.
-
- ASSUME DS:NOTHING, ES:CSEG
-
- PUSH DS ;Point ES at the resident
- POP ES ; copy of Allkeys.
-
- MOV AX,2509H ;Restore interrupt 9
- MOV DX,ES:[USED_INT9 ]
- MOV DS,ES:[USED_INT9+2]
- INT 21H
-
- MOV AX,2516H ;Restore interrupt 16h
- MOV DX,ES:[USED_INT16 ]
- MOV DS,ES:[USED_INT16+2]
- INT 21H
-
- MOV AH,49H ;Have DOS release it from
- INT 21H ; memory.
-
- ASSUME DS:CSEG, ES:CSEG
- PUSH CS ;Point DS back at our data
- POP DS
-
- MOV DX,OFFSET MESG5 ;Display status message.
- OK_EXIT: MOV AH,9
- INT 21H
-
- MOV AX,4C00h ;Terminate with no errorlevel
- INT 21H
-
- ;Int 9 and 16h vectors do not point to resident copy.
- ;Check if resident copy was only installed LOW.
-
- INIT6: CMP USED_INT9,0 ;Only installed LOW?
- JNE INIT7 ;Jump if not
-
- ;Allkeys only installed LOW.
- ;Just simply release it from memory and terminate.
-
- ASSUME DS:CSEG, ES:CSEG
-
- PUSH DS ;Point ES at the resident
- POP ES ; copy of Allkeys.
- PUSH CS ;Point DS back to our data.
- POP DS
-
- MOV AH,49H ;Have DOS release it from
- INT 21H ; memory.
-
- MOV DX,OFFSET MESG5 ;Display OK message
- JMP OK_EXIT ; and terminate.
-
- ;Allkeys installed HIGH and LOW.
- ;Set DISABLE flag to disable Allkeys. Then terminate.
-
- INIT7: MOV DISABLE,1 ;Disable Allkeys
-
- MOV DX,OFFSET MESG3 ;Print error message
- JMP ERR_EXIT ; and terminate.
-
-
- ;"/U" parameter wasn't entered. Check to see if Allkeys already loaded.
-
- INIT8: ASSUME DS:CSEG, ES:CSEG
-
- CALL SEC_COPY ;Check for a second copy
- JC INIT9 ;Jump if found
-
- ;Second copy not found.
- ;Release the environment to conserve memory.
- ;Save the current interrupts 9 and 16h. Then TSR.
-
- ASSUME DS:CSEG, ES:NOTHING
-
- MOV AX,WORD PTR DS:[2CH] ;Release the environment.
- MOV ES,AX
- MOV AH,49H
- INT 21H
-
- MOV AX,3509H ;Get interrupt 9
- INT 21H
- MOV [ORIG_INT9 ],BX ;Save the offset
- MOV [ORIG_INT9+2],ES ;Save the segment
-
- MOV AX,3516H ;Get interrupt 16h
- INT 21H
- MOV [ORIG_INT16 ],BX ;Save the offset
- MOV [ORIG_INT16+2],ES ;Save the segment
-
- MOV DX,OFFSET COPYRIGHT ;Display copyright
- MOV AH,9
- INT 21H
-
- MOV AX,3100h ;Terminate and leave all
- MOV DX,(OFFSET INIT - OFFSET CSEG + 15) SHR 4
- INT 21H ; code but the init portion
- ; resident in memory. (TSR)
-
- ;Second copy was found.
- ;Make sure Allkeys not already installed high and low.
-
- INIT9: ASSUME DS:CSEG, ES:CSEG
-
- PUSH ES ;Point DS at the original
- POP DS ; copy of Allkeys.
-
- CMP USED_INT9,0 ;Already installed high & low?
- JE INIT10 ;Jump if not.
-
- MOV DX,OFFSET MESG2 ;Display error message
- JMP ERR_EXIT ; and terminate.
-
- ;Obtain and save the used interrupts 9 and 16h to the original copy.
-
- INIT10: ASSUME DS:CSEG, ES:NOTHING
-
- MOV AX,3509H ;Get used interrupt 9
- INT 21H
- MOV [USED_INT9 ],BX ;Save the offset
- MOV [USED_INT9+2],ES ;Save the segment
-
- MOV AX,3516H ;Get used interrupt 16h
- INT 21H
- MOV [USED_INT16 ],BX ;Save the offset
- MOV [USED_INT16+2],ES ;Save the segment
-
- ;Activate Allkeys by pointing interrupt vectors 9 and 16h
- ;to the resident copy's new interrupt 9 and 16h handlers.
-
- MOV AX,2509H ;Set interrupt 9
- MOV DX,OFFSET NEW_INT9
- INT 21H
-
- MOV AX,2516H ;Set interrupt 16h
- MOV DX,OFFSET NEW_INT16
- INT 21H
-
- MOV DX,OFFSET MESG1 ;Display ready message
- JMP OK_EXIT ; and terminate.
-
- INIT ENDP
-
-
- ;-----------------------------------------------------------------------------
- ; Routine to search through memory for a previous loaded copy of Allkeys.
- ; If found, on return, CF will be set and ES will point to previous copy.
- ;-----------------------------------------------------------------------------
- SEC_COPY PROC NEAR
- ASSUME CS:CSEG, DS:CSEG, ES:NOTHING, SS:CSEG
-
- MOV WORD PTR [FIRST],0 ;Modify to avoid false alarm
- MOV BX,600h ;BX= start of our search
- MOV AX,CS ;AX= end of our search
- CLD ;Forward
- NEXT_PARA:
- INC BX ;Next paragraph
- CMP AX,BX ;If current paragraph...
- MOV ES,BX ;Set search segment
- JE END_SEARCH ;...stop
-
- MOV SI,OFFSET FIRST ;Compare FIRST label
- MOV DI,SI ;Offset is same
- MOV CX,16 ;Only FIRST 16 bytes
- REP CMPSB ;Compare DS:SI TO ES:DI
- OR CX,CX ;All matched?
- JNZ NEXT_PARA ;No, keep on looking.
-
- STC ;Found a copy in memory.
- RET ; Set CF and RETurn.
-
- END_SEARCH: CLC ;Didn't find a copy.
- RET ; Clear CF and RETurn.
-
- SEC_COPY ENDP
-
- CSEG ENDS
- END FIRST
-