home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
utils
/
kylock.zip
/
KYLOCK.ASM
next >
Wrap
Assembly Source File
|
1987-06-16
|
30KB
|
564 lines
;
page 66,132
;
;KYLOCK.ASM for the IBM PC/XT & PCJR - 1987 by Ocean
;
;This is part 2 of a 2 part utilities set consisting of -----------------------
;SCRNOFF3.ASM & KYLOCK.ASM. -----------------------THEY MUST BE USED TOGETHER!
; -----------------------
;
kb_data equ 60h ;keyboard data port
kb_ctrl equ 61h ;keyboard control port
k_key equ 37 ;scan code of k key
o_key equ 24 ;scan code of o key
del_key equ 83 ;scan code of Del key
ins_key equ 82 ;scan code of Ins key
alt_key equ 8 ;shift code for Alt key
ctrl_key equ 4 ;shift code for Ctrl key
eoi equ 20h ;end-of-interrupt signal
int_ctrl_port equ 20h ;8259 interrupt controller port
;
code segment para public 'code'
assume cs:code
org 0
seg_org equ $
;
bios_data segment at 40h ;bios data area
org 063h
addr_6845 dw ? ;define location that holds
;word address of active display
org 065h
crt_mode_set db ? ;define location that holds
;byte loaded into pc active
;display port or pcjr's vga
bios_data ends
;
org 0100h
begin: jmp initialize ;goto initialization routine
;
adapter db 0 ;0 = EGA, 1 = CGA or MDA, and
;2 = PCJR
pcjr_mode db ? ;current setting of PCJR video
pc_mode db ? ;current setting of 6845 mode
;control register of the pc
kylock_status db 0 ;interrupt routine status flag
char_count dw ? ;length of password
hotky_val db 00h,44h,2fh,2eh,2dh ;hotkey make scan code table -
db 20h,1eh,16h,11h ;filler,F10,v,c,x,d,a,u, and w
msr_address dw ? ;address of mode select register
pcjr_signature db 0fdh ;PCJR BIOS signature
ibm_signature db 'IBM' ;EGA BIOS signature
errmsg db 13,10,'KYLOCK ALREADY LOADED!',13,10,'$'
;
old_int_9h label dword ;holding area for INT 9h vector
int_9h_ptr dw 2 dup (?)
old_int_16h label dword ;holding area for INT 16h vector
int_16h_ptr dw 2 dup (?)
old_int_5h label dword ;holding area, INT 5h vector
int_5h_ptr dw 2 dup (?)
;
;------------------------------------------------------------------------------
;All calls to INT 5 will henceforth be routed thru here. On the PCJR, the
;Print Screen Function is processed by INT 48h (This interrupt translates the
;PCJR 62 key keyboard scan codes to be compatible with the 83 key keyboard of
;the PC and then INT 9 occurs.) which activates INT 5 before INT 9 is called.
;To insure that a copy of the screen cannot be printed out on the PCJR while
;the keyboard is supposedly locked, therefore, requires that the bios print
;screen service be intercepted and nulled while KYLOCK is active.
;------------------------------------------------------------------------------
;
new_int_5h proc near
test kylock_status,01 ;kylock routine active?
jnz print_not ;yes, block PRTSCR function
jmp old_int_5h ;no, goto normal INT 5h handler
print_not: iret ;exit, nulling INT 5h
new_int_5h endp
;
;------------------------------------------------------------------------------
;All calls to INT 16h will henceforth be routed thru here. If ah = 255 on
;entry, bh is set to 255 to signal the caller that this routine was indeed
;invoked.
;------------------------------------------------------------------------------
new_int_16h proc near
cmp ah,255 ;ah = 255?
jne newint1 ;no, then jump
mov bh,ah ;yes, set bh to 255 and exit
iret
newint1: jmp old_int_16h ;goto normal 16h handler
new_int_16h endp
;
;------------------------------------------------------------------------------
;Execution comes here every time an interrupt 9 is generated from the keyboard.
;------------------------------------------------------------------------------
;
kylock proc near
sti ;restore interrupts
push ax ;save registers
push bx
push cx
push dx
push si
push di
push ds
push es
in al,kb_data ;read keypress (or break)
cmp kylock_status,0 ;kylock routine active?
je kylock0 ;no, then check for Alt-O/Alt-K
;
;The kylock routine is already in progress. Check for a press of one of the
;POPUP DESKSET "hot-keys" and block it out if it just occured. (This routine
; may be omitted if this program is not used with POPUP DESKSET.)
;
and al,7fh ;strip the break bit
mov dl,al ;load keypress make scan code
mov cx,8 ;number of hotkeys to check
lea bx,hotky_val ;address of table of hotkeys
next1: mov ax,cx ;sequential pointer to hotkey
xlat hotky_val ;load value of hotkey to al
cmp dl,al ;keypress match this "hotkey"?
jne loop ;no, how about next one?
mov ah,2 ;yes, get shift status
int 16h ;
cmp al,alt_key ;alt pressed?
jne exit1 ;no, goto old int 9 routine
call kb_reset ;alt-"hotkey" pressed; reset kb
jmp unlck1 ;exit
loop: loop next1 ;get next value from table
mov al,dl ;no match - continue
;
;The kylock routine is already in progress. Check for a press of Ctrl-Alt-Del
;or Ctrl-Alt-Ins (On the PCJR, this combination invokes diagnostic routines
;from which a Ctrl-Alt-Del can reset the machine.) and block it out if it just
;occurred.
;
cmp al,ins_key ;was Ins Key pressed?
je sh_stat ;get shift status
cmp al,del_key ;was the Del key pressed?
jne exit1 ;no, goto old INT 9 routine
sh_stat: mov ah,2 ;Int 16h - get shift status
int 16h ;get status of shift keys
and al,alt_key+ctrl_key ;ctrl-alt pressed?
cmp al,alt_key+ctrl_key
jne exit1 ;no, goto old int 9 routine
call kb_reset ;ctrl-alt-del press - reset kb
jmp unlck1 ;exit
;
;The kylock routine is not already active. If Alt-O was pressed, toggle timer
;on/off, then block it out.
;
kylock0: cmp al,o_key ;o key pressed?
jne strp_brk ;no, jump
mov ah,2 ;yes, get shift status
int 16h
test al,alt_key ;Alt pressed when o key press?
jnz toggle ;Alt-o key press --- toggle
jmp strp_brk ;Alt-o key not pressed --- jump
;
;Int 16h is called here with ah set to 158. Int 16h is a chained interrupt
;hooked into by SCRNOFF3. When it is SCRNOFF3's turn in the chain, it tests
;the value of the register AH. If it has been set to 158, then it toggles its
;timer on/off.
;
toggle: mov ah,158 ;Place 158 into AH
int 16h ;Call INT with AH set to 158
call kb_reset ;reset kybrd, throw away alt-o
jmp unlck1 ;exit, skip normal kybrd route
strp_brk: and al,7fh ;strip the break bit
;
;The kylock routine is not already active. See if Alt-K was pressed.
;
cmp al,k_key ;is it the k key?
jne exit ;no, goto old int 9 routine
mov ah,2 ;int 16h - get shift status
int 16h
test al,alt_key ;is the alt key pressed?
jne kylock2 ;yes, goto kylock routine
;
;Exit routine restores registers and, if screen is blanked, enables the video
;& resets count before exiting thru normal keyboard interrupt handler.
;
exit: pop es ;pop registers off stack
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
;
;Call user interrupt 4dh (created by scrnoff3.com) to unblank screen if the
;timer within scrnoff3.com is 0.
;
int 4dh ;user interrupt 4dh
jmp old_int_9h ;exit to normal interrupt
;handler
;
;Exit1 routine restores registers before exiting thru normal keyboard interrupt
;handler and bypasses video enable and count reset routines since kylock is in
;progress.
;
exit1: pop es ;pop registers off stack
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
jmp old_int_9h ;exit to normal interrupt
;handler
;
;Trigger keys are pressed. Reset the keyboard, send an EOI signal to the 8259,
;and execute our kylock routine.
;
kylock2: call kb_reset ;reset keyboard and issue EOI
mov kylock_status,1 ;set status byte
push cs ;set ds and es to the code
;segment
pop ds
push cs
pop es
assume ds:code
;
;Begin kylock routine by disabling video and getting a password from the user.
;
call video_disable ;disable video display
xor di,di ;point DI to start of PSP
call get_password ;get the password
or cx,cx ;any characters input?
je unlock ;no, exit this interrupt
cmp al,27 ;was input terminated with ESC
je unlock ;yes, then exit
mov char_count,cx ;save length of password
;
;The password is now entered and the keyboard 'locked', awaiting input of a
;matching password. Accept input from the keyboard but continue to loop until
;the password is correctly re-entered.
;
kylock3: mov di,80h ;point DI to upper storage
call get_password ;get password
cmp cx,char_count ;same number of characters?
jne kylock3 ;no, then paswords don't match
cmp al,27 ;was input ended with ESC key?
je kylock3 ;yes, start input loop over
xor si,si ;point SI to first password
mov di,80h ;point DI to second password
cld ;clear DF for string operations
repe cmpsw ;compare the two passwords
jne kylock3 ;not equal, continue looping
;
;Exit kylock routine by clearing the status flag, enabling the video display,
;and executing an IRET instruction.
;
unlock: mov kylock_status,0 ;reset status byte
push ax ;save ax & dx
push dx
call video_enable ;re-enable video display
pop dx ;restore dx & ax
pop ax
unlck1: pop es ;restore register values
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret ;exit kylock routine
kylock endp
;
;------------------------------------------------------------------------------
;VIDEO ENABLE and VIDEO DISABLE enable and disable the VIDEO output to the
;screen of the PCJR
;------------------------------------------------------------------------------
;
video_disable proc near ;disable the video display
cmp adapter,0 ;is video adapter an EGA?
je ega_disable ;yes, then jump
test adapter,2 ;is computer a PCJR?
jnz jr_disable ;yes, then jump
;
;Disable video of PC with CGA or MDA adapter.
;
push ds ;save ds
mov ax,bios_data ;set es to bios data area
mov ds,ax
assume ds:bios_data
mov al,crt_mode_set ;get current value (dynamic) of
;6845 mode control register
mov pc_mode,al ;save it
mov ax,addr_6845 ;get active display address
add ax,4 ;add 4 to get MSR address
mov msr_address,ax ;save address
mov al,0ah ;out 6845 index register...
mov dx,03b4h ;points to 6845 data reg. 10
out dx,al
mov al,2bh ;value to turn off cursor
mov dx,03b5h ;6845 data registers port
out dx,al ;disable cursor
mov dx,msr_address ;6845 mode control register
mov al,pc_mode ;get current value of 6845 mode
and al,37h ;strip enable bit
out dx,al ;disable video display
pop ds ;restore ds
ret
;
;Disable video of PC with an EGA card.
;
ega_disable: xor al,al ;zero al (clear bit 5)
call set_ega ;disable EGA
ret
;
;Disable video of PCJR.
;
jr_disable: push ds ;save ds register
mov ax,bios_data ;set es to bios data area
mov ds,ax ;
assume ds:bios_data ;
mov al,crt_mode_set ;get current value (dynamic) of
;PCJR VGA mode control register
mov pcjr_mode,al ;store current value, VGA mode
mov dx,03dah ;PCJR VGA I/O port
in al,dx ;addr/data f/f to proper state
mov al,02h ;VGA border color register
out dx,al ;set VGA to border color cont.
mov al,00h ;color black
out dx,al ;set border color black
mov al,00 ;VGA mode control 1 register
out dx,al ;set VGA to mode control 1
mov al,pcjr_mode ;get current value of VGA mode
and al,0f7h ;toggle enable/disable bit
out dx,al ;disable video display
pop ds ;restore ds register
ret
video_disable endp
;
video_enable proc near ;enable the video display
cmp adapter,0 ;is video adapter an EGA?
je ega_enable ;yes,then jump
test adapter,2 ;is the computer a PCJR?
jnz jr_enable ;yes, then jump
;
;Enable video of PC with CGA or MDA adapter card.
;
mov al,0ah ;out to 6845 index register...
mov dx,03b4h ;points to 6845 data reg. 10
out dx,al
mov al,0bh ;value to turn cursor on
mov dx,03b5h ;6845 data registers port
out dx,al ;enable cursor
mov dx,msr_address ;6845 mode control register
mov al,pc_mode ;get stored value 6845 mode
out dx,al ;enable pc display
ret
;
;Enable video of PC with an EGA adapter card.
;
ega_enable: mov al,20h ;set bit 5 of al
call set_ega ;enable EGA video
ret
;
;Enable video of PCJR.
;
jr_enable: mov dx,03dah ;set PCJR VGA address
in al,dx ;addr/data f/f to proper state
mov al,00h ;VGA mode control 1 register
out dx,al ;set VGA to mode control 1
mov al,pcjr_mode ;get stored value VGA mode
out dx,al ;enable PCJR video display ...
;border remains black
ret
video_enable endp
;
;-----------------------------------------------------------------------------
;SET_EGA is called by VIDEO_ENABLE and VIDEO_DISABLE routines to selectively
;set or clear bit 5 of the EGA Attribute Address Register.
;Entry: AL - value to OUT to Attribute Address Register
;-----------------------------------------------------------------------------
;
set_ega proc near
push ax ;save AL
mov dx,3bah ;reset monochrome flip-flop...
in al,dx ;for write to Address Register
mov dx,3dah ;reset color flip-flop
in al,dx
mov dx,3c0h ;set DX to Attr Addr Register
pop ax ;retrieve entry value of AL
out dx,al ;write value to register
ret
set_ega endp
;
;------------------------------------------------------------------------------
;KB RESET subroutine resets the keyboard and issues an EOI to the 8259 PIC.
;------------------------------------------------------------------------------
;
kb_reset proc near
test adapter,2 ;Is this computer a PCJR?
jnz jr_kbd ;yes,then jump
;
;Reset standard PC keyboard.
;
std_kbd: in al,kb_ctrl ;get current control port value
mov ah,al ;save it
or al,80h ;set the keyboard clear bit
out kb_ctrl,al ;send reset value to port
mov al,ah ;get the original value
out kb_ctrl,al ;enable the keyboard
jmp kbd1 ;jump to disable interrupts
;and send EOI signal to 8259
;
;Reset PCJR keyboard.
;
jr_kbd: in al,0a0h ;yes, then read NMI mask
;register to clear PCJR
;keyboard NMI latch
kbd1: cli ;disable interrupts
mov al,eoi ;get eoi value
out int_ctrl_port,al ;send eoi signal to the 8259
sti ;enable interrupts
ret ;return to caller
kb_reset endp
;
;------------------------------------------------------------------------------
;GET PASSWORD subroutine reads up to 50 characters entered from the keyboard
;and stores them in the designated buffer. Backspace key is active as an
;editing key.
;Entry: ES:DI - buffer address | EXIT: CX - character count
;------------------------------------------------------------------------------
;
get_password proc near
cld ;clear DF for string operations
xor cx,cx ;zero CX - initial char count
getpas1: mov ah,0 ;INT 16h funct. - get keypress
int 16h ;get character from keyboard
cmp al,13 ;ENTER key?
je done ;yes, then exit
cmp al,27 ;ESC key?
je done ;yes, then exit
cmp al,8 ;BACKSPACE key?
je backspace ;yes,goto backspace routine
cmp cx,40h ;is the buffer full?
je buffer_full ;yes, then don't accept entry
inc cx ;char entered - increment count
stosw ;deposit character in buffer
jmp getpas1 ;return for more input
backspace: or cx,cx ;any characters to delete?
je getpas1 ;no,then goto input loop
sub di,2 ;decrement buffer pointer
dec cx ;decrement character count
jmp getpas1 ;return to input loop
buffer_full: mov ah,14 ;INT 10h function - Write TTY
mov al,7 ;ASCII code for beep
int 10h ;sound the beep
jmp getpas1 ;and return for more input
done: ret ;return to calling routine
get_password endp
;
;------------------------------------------------------------------------------
;INITIALIZE routine checks to see if KYLOCK has already been loaded. If so,
;execution aborts with an error message. If it hasn't, then the value of
;ADAPTER is set according to the type of display adapter present in the system
;and the vectors in low memory pointing to the INT 9h and 16h routines are set
;to point to our own newly installed code.
;------------------------------------------------------------------------------
;
initialize proc near
;
;See if KYLOCK has been previously loaded by calling INT 16h with AH set to
;255 and BH set to 0. If BH comes back unchanged, then KYLOCK is NOT
;currently resident in memory; if BH = 255, then KYLOCK has been loaded.
;
mov ah,255 ;set AH and BH
xor bh,bh
int 16h ;call interrupt routine
or bh,bh ;is BH = 0?
je init1 ;yes, then continue
lea dx,errmsg ;no, print error message & exit
mov ah,09h
int 21h
ret
;
;Check the computer's ID to see if its a PC or PCJR.
;
init1: mov ax,0f000h ;es to BIOS segment holding
mov es,ax ;computer ID value
mov al,byte ptr es:[0fffeh] ;offset address and load to al
sub al,0fch ;
or al,al ;al = 0?
jz pc ;AT, try the pc routine...
dec al ;al = 1?
jz pcjr ;yes, then computer is a PCJR
dec al ;al = 2?
jz pc ;XT, try the pc routine...
dec al ;al = 3?
jz pc ;PC
jnz pc ;unidentified computer, try PC
ret
;
;The computer is a PCJR.
;
pcjr: mov adapter,2 ;set adapter to PCJR
jmp init2 ;jump to install program
;
;The computer is a PC. Check for the presence of an Enhanced Graphics Adapter
;by looking for an 'IBM'signature in the EGA Bios area.
;
pc: mov ax,0c000h ;set ES to EGA BIOS segment
mov es,ax
mov di,1eh ;starting address of signature
lea si,ibm_signature ;point si to 'IBM' text
mov cx,3 ;three characters to check
cld ;clear df
repe cmpsb ;compare the three bytes
je init2 ;signature found - EGA present
;
;The computer is a PC, but the display adapter is not an EGA. It must be
;either a CGA or an MDA.
;
mov adapter,1 ;set ADAPTER for CGA or MDA
;
;Save the current interrupt 16h vector and replace it with our own.
;
init2: mov ah,35h ;DOS function - get vector
mov al,16h ;interrupt 16h
int 21h ;get the vector
mov int_16h_ptr,bx ;save offset of vector
mov int_16h_ptr[2],es ;save segment of vector
mov ah,25h ;DOS function - set vector
mov al,16h ;interrupt 16h
lea dx,new_int_16h ;pointer to new routine
int 21h ;set vector
;
;Now save the old interrupt 9 vector, replace it with the new one, and exit.
;
mov ah,35h ;DOS function - get vector
mov al,9h ;interrupt 9
int 21h ;get vector
mov int_9h_ptr,bx ;save offset
mov int_9h_ptr[2],es ;save segment
mov ah,25h ;DOS function - set vector
mov al,9h ;interrupt 9
lea dx,kylock ;point to our freeze routine
int 21h ;set vector
;
;Save the current interrupt 5h vector and replace it with a new routine.
;
mov ah,35h ;DOS function - get vector
mov al,5h ;interrupt 5h
int 21h ;get the vector
mov int_5h_ptr,bx ;save offset of vector
mov int_5h_ptr[2],es ;save segment of vector
mov ah,25h ;DOS function - set vector
mov al,5h ;interrupt 5h
lea dx,new_int_5h ;pointer to new routine
int 21h ;set vector
mov dx,(offset initialize - seg_org + 15) shr 4 ;...
;prepare DX for exit
mov ah,31h ;terminate-but-stay-resident
int 21h ;dos function call
initialize endp
;
code ends
end begin