home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
utils
/
kylock.zip
/
SCRNOFF3.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-06-16
|
18KB
|
337 lines
;
page 66,132
;
;SCRNOFF3.ASM for the IBM PC/XT & PCJR - 1987 by Ocean
;
;This is part 1 of a 2 part utilities set consisting of -----------------------
;SCRNOFF3.ASM & KYLOCK.ASM. --------------------- THEY MUST BE USED TOGETHER!
; -----------------------
;
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
count dw 0cc8h ;initial 3 min. to blank screen
timer_stat db 01h ;initialize timer - on
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,'SCRNOFF3 ALREADY LOADED!',13,10,'$'
;
old_int_1ch label dword ;holding area for INT 8h vector
int_1ch_ptr dw 2 dup (?)
old_int_16h label dword ;holding area for INT 16h vector
int_16h_ptr dw 2 dup (?)
;
;------------------------------------------------------------------------------
;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,127 ;ah = 127?
jne switch ;no, then jump
mov bh,ah ;yes, set bh to 255 and exit
iret
switch: cmp ah,158 ;INT called by ALT O keypress?
jne newint1 ;no, then jump
add timer_stat,01h ;yes, toggle timer on/off
iret
newint1: jmp old_int_16h ;goto normal 16h handler
new_int_16h endp
;
;------------------------------------------------------------------------------
;User timer INT 1Ch is now routed through here.
;------------------------------------------------------------------------------
;
countdown3 proc near
test timer_stat,01h ;timer activated?
jz do_nothing ;no, exit
cmp count,00 ;yes, check if count has zeroed
jz do_nothing ;already zero, exit
dec count ;active & not zero, tick & ...
jnz do_nothing ;not zero, exit ... else ...
;
;Time has run out, call the video_disable routine to blank the screen only.
;The rest of the program is still ready to lock the keyboard with a password if
;desired.
;
push ax ;save ax register
push dx ;save dx register
cli ;disable all interrupts
call video_disable ;time is up - disable the video
mov al,eoi ;get eoi value
out int_ctrl_port,al ;send eoi signal to the 8259
pop dx ;restore dx register
pop ax ;restore ax register
sti
do_nothing: jmp old_int_1ch ;iret thru old_int_1Ch
countdown3 endp
;
;------------------------------------------------------------------------------
;This routine is user vector interrupt 4dh!
;------------------------------------------------------------------------------
unblank proc near
cmp count,00 ;if timer is not 0 the screen
;is still visible - jump to
jnz reset_count ;reset count to 3 min., since
;a keypress has occured
push ax ;save ax register
push dx ;save dx register
call video_enable ;timer was 0 when a keypress
;occured, so make the screen
;visible
pop dx ;restore dx register
pop ax ;restore ax register
reset_count: mov count,0cc8h ;reset timer to 3 min. then
;return to caller (KYLOCK.COM)
iret
unblank 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 ;strip enable 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 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
;
;------------------------------------------------------------------------------
;INITIALIZE routine checks if SCRNOFF3 has already been loaded. If it has,
;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 SCRNOFF3 has been previously loaded by calling INT 16h with AH set to
;254 and BH set to 0. If BH comes back unchanged, then SCRNOFF3 is NOT
;currently resident in memory; if BH = 255, then SCRNOFF3 has been loaded.
;
mov ah,127 ;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 1Ch vector and replace it with a new routine.
;
init2: mov ah,35h ;DOS function - get vector
mov al,1ch ;interrupt 1ch
int 21h ;get the vector
mov int_1ch_ptr,bx ;save offset of vector
mov int_1ch_ptr[2],es ;save segment of vector
mov ah,25h ;DOS function - set vector
mov al,1ch ;interrupt 1ch
lea dx,countdown3 ;point - countdown3 routine
int 21h ;set vector
;
;Save the current interrupt 16h vector and replace it with a new routine.
;
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
;
;Set user vector interrupt 4dh to unblank routine.
;
mov ah,25h ;DOS function - set vector
mov al,4dh ;interrupt 4dh
lea dx,unblank ;point to unblank 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