home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Author: Scott Hopson Mail: 76207,674
- ;
- ; If you like this program you don't have to pay me.
- ; If you don't like my comments go steal someone elses code
- ; In either case I hope you find this usefull
- ;
- ; This program revectors the timer and keyboard interrupts
- ; if a key has not been pressed after 15 minutes the timer routine
- ; saves the current screen into the buffer and clears video memory
- ; when a key is pressed the keyboard interrupt restores the screen to
- ; its previous state and resets the counter. The keystroke is not passed
- ; onto the system so the user can use any key to restore the screen without
- ; affecting the application.
- ;
- ; You could use int 8 instead of int 1c but it really doesn't matter
- ; int 8 calls int 1c which is normally vectored to an IRET unless you
- ; change it.
- ;
- ; Note: on some keyboards using the Left-Alt or Left-Ctrl keys to restore the
- ; screen does wierd stuff. Just press the opposite key to restore keyboard.
-
- .model tiny
-
- code segment para public 'CODE'
- assume cs:code
- org 100h ; this is going to be a .COM file
- start: jmp main ; skip passed data
-
- oldint9 dd ? ; previous keyboard vector (09h)
- oldint1c dd ? ; previous timer vector (1ch)
- video dw ? ; video memory location
- cursor dw ? ; current curso info
- count dw 0 ; count of ticks since keypress
- vflag db 0 ; just a flag
- _page db ? ; active page
- buffer dw 2000 dup(?) ; you could put this in EMS or just
- ; load the whole program high
-
- int9 proc far
- mov cs:[count],0 ; reset counter
- cmp cs:[vflag],1 ; is screen currently saved
- jne exit9 ; nope, he's going to hell
- push ax ; save those register like a good
- push bx ; little programmer
- push cx
- push ds
- push es
- push si
- push di
- in al,60h ; must read byte from keyboard
- ; or you'll just hang
- in al,61h ; get keyboard control lines
- mov ah,al ; save present settings
- or al,80h ; set enable keyboard bit
- out 61h,al ; write it out
- xchg ah,al ; get original values
- out 61h,al ; restore orginal bits
- mov al,20h ; signal End Of Interrupt (EOI)
- out 20h,al ; to Programmable Interrupt Controller (PIC)
- mov cs:[vflag],0 ; reset video saved flag
- mov bh,cs:[_page] ; set video page to active
- mov cx,cs:[cursor] ; get cursor info
- mov ah,01h ; restore cursor
- int 10h ; call bios video routine
- mov es,cs:[video] ; destination is address by es
- mov di,0 ; start at top of screen
- mov cx,2000 ; 2000 words = 4000 bytes = 80*25*2
- push cs ; setup source of saved info
- pop ds ; which is address by the data segment
- mov si,offset cs:buffer ; in buffer
- cld
- rep movsw ; move the data from buffer to screen fast
-
- pop di ; remember kiddies when your done playing
- pop si ; always put your toys back where you found
- pop es ; them or mommy DOS will spank you hard
- pop ds
- pop cx
- pop bx
- pop ax
- iret ; return from interrupt
- exit9: jmp cs:[oldint9] ; chain to previous vector
- int9 endp
-
- int1c proc near
- inc cs:[count] ; increment the counter
- cmp cs:[count],16200; has fifteen minutes passed
- jb exit1c ; no so just go on
- mov cs:[count],0 ; yes so reset counter
- cmp cs:[vflag],1 ; is screen saved already
- je exit1c ; praise the Lord he is
- push ax ; nope, well let's convert him
- push bx ; save all those little reggies
- push cx ; like we're supposed to
- push es
- push ds
- push si
- push di
- mov ah,0ffh ; get video state
- int 10h
- cmp al,7 ; need to check screen modes
- jbe mode4 ; can't mess with a graphics screen
- mode4: cmp al,4 ; modes 4,5,6 and anything above 7
- je exit1c ; are graphics modes
- cmp al,5
- je exit1c
- cmp al,6
- je exit1c
- mov cs:[vflag],1 ; screen is gettin saved
- mov cs:[_page],bh ; save active video page
- mov ah,03h ; get cursor info
- int 10h
- mov cs:[cursor],cx ; save for later
- or ch,20h ; turn it off for now
- mov ah,01h
- int 10h
- push cs
- pop es
- mov di,offset cs:buffer
- mov ds,cs:[video]
- mov si,0
- mov cx,2000
- cld
- rep movsw ; moving 2000 words is supposed to be
- mov cx,2000 ; faster than moving 4000 bytes
- mov ax,0700h ; setup video attributes
- mov es,cs:[video] ; get destination
- mov di,0
- cld
- rep stosw ; write words to clear screen
- pop di ; restore registers so system stays
- pop si ; happy...
- pop ds
- pop es
- pop cx
- pop bx
- pop ax
- exit1c: jmp cs:[oldint1c] ; chain to previous vector
- int1c endp
-
- LAST_BYTE db ? ; marker used for freeing memory
-
- message db 'Screen Saver Loaded...',13,10,24h
-
- main proc near
- push cs
- pop ds ; setup data segment
-
- mov es,word ptr cs:[2ch] ; free environment
- mov ah,49h ; we don't need it so why keep it?
- int 21h
-
- int 11h ; get video hardware info
- test al,30h ; check for monochrome video
- jz mono ; yes it is
-
- mov word ptr video,0b800h ; nope, a cga
- jmp getvect
- mono: mov word ptr video,0b000h
-
- getvect: mov ax,351ch ; get timer vector
- int 21h
- mov word ptr [oldint1c],bx ; save it
- mov word ptr [oldint1c+2],es
-
- mov ax,3509h ; get keyboard vector
- int 21h
- mov word ptr [oldint9],bx ; save it also
- mov word ptr [oldint9+2],es
-
- mov ax,251ch ; set new timer vector
- mov dx,offset int1c
- int 21h
- mov ax,2509h ; and new keyboard vector
- mov dx,offset int9
- int 21h
-
- mov ah,9 ; print message
- mov dx,offset message
- int 21h
-
- mov dx,offset LAST_BYTE ; point to end of memory to
- int 27h ; save and terminate but
- ; stay resident
- main endp
-
- code ends
- end start