Category : Windows 3.X Files
Archive   : WINBLANK.ZIP
Filename : BLANK.ASM

 
Output of file : BLANK.ASM contained in archive : WINBLANK.ZIP
page 60,132
title blank -- blank out idle screen
comment *
This is a routine that is loaded and stays resident. It
intercepts hardware clock, keyboard, and video interrupts,
and controls the video chip enable to blank the screen after
extended inactivity. It also intercepts the reserved
interrupt used in some systems for the mouse.

About the mouse. The mouse hardware interrupt is the wrong thing;
the Microsoft mouse seems to generate regular interrupts that
inhibit blanking at all times. The mouse driver software interrupt
is another choice, but it fails to make the mouse light up the
screen under mouse menu, and inhibits blanking under Word. So it goes.

I modified it 3 July, 1987 to add a flag that would let a Windows
program indicate that it wanted the screen kept lit/lit up. It
works by the Windows program setting the flag when something
interesting happens. Whenever a clock interrupt happens, it
first checks that flag, and if non-zero it does the normal
processing in blank as if a key had been hit. The string
"WindowsHook\0" precedes the byte that contains the flag.

*

subttl macros and equates
.xlist
include macros.mac
.list

limit equ 5*60 ;number of seconds before blank screen
ega equ true ;if ega board
mdacga equ true ;if mono or cga board
winhook equ true ;if windows hook code wanted

mouse equ false ;trap mouse interrupts?

intv_kbd equ 09h ;interrupt vector number for keyboard input
intv_mse equ 33h ;used on some systems for mouse
intv_vid equ 10h ;interrupt vector number for video output
intv_clk equ 1Ch ;interrupt vector number for timer tick

onesec equ 18 ;interrupts about 18 per second
timer equ limit * onesec ;video timer to turnoff

bios_data equ 0040h ;segment of the bios data area
base_6845 equ 63H ;offset to port for 6845 chip
port_mode equ 4 ;delta to mode port in chip
mode_6845 equ 65h ;offset to where bios keeps the mode value

abs0 segment at 0
org 4A8h
save_ptr dd ? ;EGA save area pointer
abs0 ends

save_area struc
dd ?
psave dd ?
dd 5 dup (?)
save_area ends

subttl code
begin_com run ;start of code for a com file

old_kbd dd ? ;storage for old interrupt vector address
old_mse dd ? ;storage for old interrupt vector address
old_vid dd ? ;storage for old interrupt vector address
old_clk dd ? ;storage for old interrupt vector address
keyflag db 0 ;set to 1 when enable is required
count dw 0 ;starts at zero, controls turn-off
onflag db 1 ;set to 1 if video enabled
busy db 0 ;set to 1 if in clk interrupt already

if winhook
db "WindowsHook",0
winflag db 0 ;set non-zero if windows wants screen on
endif

if ega
new_save save_area <> ;new EGA save area
work_palette db 256 dup (?) ;EGA working palette
save_palette db 17 dup (?) ;Saved palette
off_palette db 17 dup (0) ;Turn off palette
endif

assume cs:cseg,ds:nothing,es:nothing

if mdacga
;
; This routine gets the mda/cga controller mode I/O port into dx,
; then loads the current mode value into al.
;
; Modifies ax, dx
;
get_port proc near
if ega
mov dx,03B8h ;assume values for ega, since likely
mov al,3 ;not in mode 7.

else

push ds
mov ax,bios_data ;setup addressability
mov ds,ax
mov dx,ds:base_6845 ;get base controller port,
add dx,port_mode ;offset to mode port.
mov al,ds:mode_6845 ;get current mode value
pop ds
endif
ret
get_port endp
endif

; This is the routine that checks the WindowsHook flag and, if it
; has been set will reset the flag and let the rest of the blanker
; act as if a key had been hit or screen output made.
;
if winhook
winchk proc near
cmp winflag,0 ;see if Windows wants the screen
je short wc1 ;jump if not
mov keyflag,1 ;do the normal things that would
mov count,0 ;happen if key/screen stuff found
mov winflag,0 ;and get ready for next Windows hit
wc1:
ret
winchk endp
endif

;
; This is the handler for the keyboard interrupt. It sets the
; flag to request the video be re-enabled, then passes on control
; of the interrupt.
;
int_kbd proc far ;handler for keyboard interrupt
mov keyflag,1 ;signal that video enable is required,
mov count,0 ;clear the turn-off counter, then
jmp old_kbd ;simply invoke the saved vector
int_kbd endp
;
; This is the handler for the mouse interrupt. It sets the
; flag to request the video be re-enabled, then passes on control
; of the interrupt.
;
; It is not enabled, since it does not work -- the mouse seems to be
; polled.
;
if mouse
int_mse proc far ;handler for mouse interrupt
mov keyflag,1 ;signal that video enable is required,
mov count,0 ;clear the turn-off counter, then
jmp old_mse ;simply invoke the saved vector
int_mse endp
endif
;
; This is the handler for the video output interrupt. It sets the
; flag to request the video be re-enabled, then passes on control
; of the interrupt.
;
int_vid proc far ;handler for vid interrupt
mov keyflag,1 ;signal that video enable is required,
mov count,0 ;clear the turn-off counter, then
jmp old_vid ;simply invoke the saved vector
int_vid endp
;
; This is the handler for the timer interrupt. It verifies that
; we are not entering recursively, and if not looks at the video state.
; If video is off, it looks to see if re-enable is wanted. If video
; is on, it counts down, and if the timer has expired it shuts down
; the video.
;
int_clk proc far ;handler for clk interrupt
cmp busy,0 ;see if already running
je short ic1 ;if not
jmp old_clk ;if so
ic1:
mov busy,1 ;show in routine
sti ;re-enable interrupts, then see what the
push ds ;current video state is.
push ax
push dx

if winhook ;do check for Windows, then normal timer
call winchk ;processing.
endif

cmp onflag,0
je short ic_off ;jump if video off
inc count ;video is on, so bump count and
cmp count,timer ;see if time to turn off
jna ic_exit ;nothing more if not there

if mdacga
; turn off mono/cga board
call get_port ;setup dx, al
and al,11110111b ;clear enable bit,
out dx,al ;shove into port to turn off the video.

endif
if ega

; turn off ega
push es
push si
push di
push cx
xor ax,ax
mov es,ax ;es is abs0 base
les si,es:save_ptr ;es:si is save area pointer
lds si,es:save_area.psave[si] ;ds:si is current palette address
mov ax,cs
mov es,ax
assume es:cseg
lea di,save_palette ;es:di is palette save area
mov cx,17
cld
rep movsb ;make copy of palette
lea dx,off_palette
mov ax,1002h
pushf
call old_vid ;reload palette registers with zeroes
pop cx
pop di
pop si ;to make everything black
pop es
assume es:nothing
endif

xor al,al ;get a zero
mov onflag,al ;note we are off
mov keyflag,al ;and clear wanted flag
jmp short ic_exit
ic_off:
cmp keyflag,0 ;see if need to turn on
je short ic_exit ;if not, all done

if mdacga
; turn on mono/cga board
call get_port ;setup dx, al
or al,00001000b ;turn on enable bit
out dx,al ;shove to port

endif
if ega

; turn on ega board
push es
mov ax,cs
mov es,ax
assume es:cseg
lea dx,save_palette
mov ax,1002h
pushf
call old_vid ;reload palette registers with saved
pop es
assume es:nothing
endif

mov count,0 ;reset counter
mov onflag,1 ;note we are on
ic_exit:
pop dx
pop ax ;restore registers, then
pop ds ;simply invoke the saved vector
cli ;after restoring all initial entry stuff
mov busy,0 ;show not in routine
jmp old_clk
int_clk endp
;
; ***** end of resident code area *****
;
end_keep label byte

;
; ***** invocation routine *****
;
if ega
no_ega: db "EGA not present, wrong version of BLANK",cr,lf,eom
endif
run: ;procedure to initialize
if ega
xor ax,ax ;set up palette save area if needed
mov ds,ax
assume ds:abs0
les si,save_ptr ;get current save area pointer
mov ax,es
or ax,si
jnz short r1 ;ok if have one
mov ax,cs
mov ds,ax
dos dos_vstr,,no_ega
dos dos_terminate
r1:
lds bx,es:save_area.psave[si] ;get palette pointer
assume ds:nothing
mov ax,ds
or ax,bx
jnz short r2 ;jump if have palette already
mov ax,es
mov ds,ax ;set ds:si as save area source address
mov ax,cs
mov es,ax ;set es:di as save area destination address
lea di,new_save
mov cx,7*4
cld
rep movsb ;copy save area
mov ax,cs ;put work palette address into save area
mov ds,ax
assume ds:cseg
mov word ptr new_save.psave+2,ax
lea ax,work_palette
mov word ptr new_save.psave,ax
cli
xor ax,ax ;set in new save area
mov ds,ax
assume ds:abs0
mov ax,offset new_save
mov word ptr save_ptr,ax
mov ax,cs
mov word ptr save_ptr+2, ax
sti
assume ds:nothing
r2:
mov ah,0Fh ;get video state
int intv_vid ;get current video mode to al
and al,7Fh ;clear regen buffer (odd effects
xor ah,ah ;happen if you don't).
int intv_vid ;reset mode, setup palette
xor dx,dx
xor bx,bx
mov ah,2
int intv_vid ;reset cursor position
endif ;EGA

mov ax,cs
mov ds,ax
assume ds:cseg
intercept intv_kbd,old_kbd,int_kbd ;get control of hooks
if mouse
intercept intv_mse,old_mse,int_mse
les si,old_mse
mov ax,es
or si,ax
jnz short r3
revert intv_mse,old_mse
r3:
endif
intercept intv_vid,old_vid,int_vid
intercept intv_clk,old_clk,int_clk
resident end_keep ;exit with handlers kept
end_com


  3 Responses to “Category : Windows 3.X Files
Archive   : WINBLANK.ZIP
Filename : BLANK.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/