home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
screen
/
dscrnsav.arc
/
DSCRNSAV.ASM
next >
Wrap
Assembly Source File
|
1990-01-14
|
7KB
|
226 lines
; Program dscrnsav.asm
; David Markovitch 1/12/90
IDEAL
SEGMENT CODE
ASSUME CS: CODE, DS: CODE
org 100h
start:
jmp init ; jump to initialization
load_msg db 13,10,"Dscrnsav screen saver resident - Delay is 5 min.",13,10
db "Options: [d] disables, no parameter re-enables",13,10,"$"
dsabl_msg db 13,10,"Dscrnsav disabled",13,10,"$"
enabl_msg db 13,10,"Dscrnsav enabled",13,10,"$"
err1_msg db 13,10,"Invalid command line parameter",13,10,"$"
err2_msg db 13,10,"Dscrnsav not resident",13,10,"$"
maxcount equ 5460 ; timer ticks for delay 5460 = 5 min
shft_cnt equ 40 ; ticks between screen shifts 40 = 2 sec
old9_ofs dw ? ; old int 9 address
old9_seg dw ?
old1C_ofs dw ? ; old int 1C address
old1C_seg dw ?
old_tail dw ? ; keyboard buffer tail
off_flg db 0 ; 1 = disable blanking 0 = normal operation
scr_offst dw 0 ; offset for shifting screen
blank db 0 ; 1 = 'blank' screen 0 = normal screen
turn_on db 0 ; 1 = unblank screen 0 = nothing
count dw 0 ; tick counter for blanking
;------------------------------------------------------------------------------
proc new9 ; new int 9 (keyboard)
push es
push ds
push ax
push cs
pop ds
mov ax,40h
mov es,ax
mov ax,[word es: 1Ch] ; save keyboard buffer tail pointer
mov [old_tail],ax
pushf ; do bios keyboard handler
call [dword old9_ofs]
cmp [blank],0 ; check for blank screen
jne rest_scrn
mov [count],0 ; reset tick counter
jmp exit_9
rest_scrn: ; set flag to unblank screen
mov [turn_on],1
mov ax,[old_tail] ; restore tail pointer to remove key from buffer
mov [word es: 1Ch],ax
exit_9:
pop ax
pop ds
pop es
iret
endp new9
;------------------------------------------------------------------------------
proc new1C ; new int 1C (timer tick)
sti ; enable interrupts
push es
push ds
push dx
push ax
push cs
pop ds
mov ax,40h
mov es,ax
cmp [turn_on],0 ; check if flag set to restore screen
je if_blank ; jump to check for blank screen if flag not set
mov [turn_on],0 ; restore original video buffer start
mov [blank],0
mov ax,[word es: 4Eh] ; get bios video buffer start (bytes)
shr ax,1 ; convert to words
push ax
jmp do_crt ; set crt controller
if_blank:
cmp [off_flg],0 ; exit if disabled
jne exit_1C
cmp [blank],0 ; check if screen already blank
jne chk_shift ; if blank then jump to check if ready to shift
inc [count] ; screen not blank - check if time to blank
cmp [count],maxcount
jne exit_1C ; exit if not time to blank
mov [blank],1 ; set blank screen flag
jmp do_shift ; shift screen
chk_shift: ; if screen blank - shift every shft_cnt ticks
inc [count]
cmp [count],shft_cnt
jne exit_1C ; exit if not time to shift
do_shift:
mov ax,[scr_offst] ; get our video buffer offset (words)
add ax,1003 ; shift 1003 words
and ax,7FFh ; limit to first 4K of video buffer
mov [scr_offst],ax ; save our new video buffer offset
mov dx,[word es: 4Eh] ; get bios video buffer start (bytes)
shr dx,1 ; convert to words
add ax,dx ; add our offset
push ax
do_crt: ; set crt controller
mov dx,[es: 63h] ; crt controller base address
mov al,12 ; access register 12
out dx,al
inc dx
pop ax ; pop starting address
xchg ah,al
out dx,al ; write hi (start address) to register 12
dec dx
push ax ; push starting address
mov al,13 ; access register 13
out dx,al
inc dx
pop ax ; pop starting address
xchg ah,al
out dx,al ; write lo (start address) to register 13
mov [count],0 ; reset tick counter
exit_1C:
pop ax
pop dx
pop ds
pop es
jmp [dword cs: old1C_ofs]
endp new1C
;------------------------------------------------------------------------------
init: ; initialization
mov si,81h
mov dx,offset err1_msg ; "Invalid command line parameter"
parse_loop: ; check for 'd' on command line
lodsb
cmp al," "
je parse_loop ; skip spaces
cmp al,13
je end_parse ; jump if no parameter
or al,20h ; convert to lower case
cmp al,"d"
jne out_err ; invalid parameter
mov [off_flg],1 ; set disable flag
end_parse:
cld ; search for a previous copy
mov [word start],0 ; fingerprint
mov bx,0 ; bx = start segment
mov ax,cs ; ax = current segment
chk_prev:
inc bx ; increment segment
mov es,bx
cmp ax,bx ; check if equals current segment
je no_copies
mov si,offset start
mov di,si
mov cx,16 ; compare first 16 bytes of each segment
repe cmpsb
jne chk_prev ; repeat if no match
mov al,[off_flg] ; copy found - change enable/disable flag
mov [es: off_flg],al
mov [es: count],0 ; reset tick count
mov dx,offset enabl_msg ; "Dscrnsav enabled"
cmp al,0
je out_msg ; copy enabled - errorlevel = 0
mov dx,offset dsabl_msg ; "Dscrnsav disabled"
mov al,0 ; errorlevel = 0
jmp out_msg ; copy disabled
no_copies:
mov dx,offset err2_msg ; "Dscrnsav not resident"
cmp [off_flg],0
je install ; ok to install
out_err:
mov al,1
out_msg:
mov ah,9 ; display message
int 21h
mov ah,4Ch ; terminate with errorlevel = al
int 21h
install: ; make program resident
mov ax,3509H ; get old int 9 address
int 21H
mov ax,es
mov [old9_seg],ax ; save old int 9 address (keyboard)
mov [old9_ofs],bx
mov ax,351CH ; get old int 1C address (timer tick)
int 21H
mov ax,es
mov [old1C_seg],ax ; save old int 1C address
mov [old1C_ofs],bx
mov dx,offset new9 ; set int 9 to point to our code
mov ax,2509H
int 21H
mov dx,offset new1C ; set int 1C to point to our code
mov ax,251CH
int 21H
mov dx,offset load_msg ; "Dscrnsav loaded"
mov ah,9
int 21h ; display message
mov dx,(init - start + 256 + 16)/16
mov ax,3100H ; terminate and stay resident
int 21H
ends
end start