Category : Files from Magazines
Archive   : VOL7N12.ZIP
Filename : ALLKEYS.ASM

 
Output of file : ALLKEYS.ASM contained in archive : VOL7N12.ZIP
;=============================================================================
; 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


  3 Responses to “Category : Files from Magazines
Archive   : VOL7N12.ZIP
Filename : ALLKEYS.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/