home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / screen / dscrnsav.arc / DSCRNSAV.ASM next >
Assembly Source File  |  1990-01-14  |  7KB  |  226 lines

  1. ; Program dscrnsav.asm
  2. ; David Markovitch 1/12/90
  3.  
  4. IDEAL
  5.  
  6. SEGMENT CODE
  7. ASSUME CS: CODE, DS: CODE
  8.  
  9. org 100h
  10.  
  11. start:
  12.   jmp init          ; jump to initialization
  13.  
  14. load_msg    db 13,10,"Dscrnsav screen saver resident - Delay is 5 min.",13,10
  15.             db "Options:  [d] disables, no parameter re-enables",13,10,"$"
  16. dsabl_msg   db 13,10,"Dscrnsav disabled",13,10,"$"
  17. enabl_msg   db 13,10,"Dscrnsav enabled",13,10,"$"
  18. err1_msg    db 13,10,"Invalid command line parameter",13,10,"$"
  19. err2_msg    db 13,10,"Dscrnsav not resident",13,10,"$"
  20.  
  21. maxcount    equ 5460 ; timer ticks for delay  5460 = 5 min
  22. shft_cnt    equ 40   ; ticks between screen shifts  40 = 2 sec
  23.  
  24. old9_ofs    dw ?     ; old int 9 address
  25. old9_seg    dw ?
  26. old1C_ofs   dw ?     ; old int 1C address
  27. old1C_seg   dw ?
  28. old_tail    dw ?     ; keyboard buffer tail
  29. off_flg     db 0     ; 1 = disable blanking  0 = normal operation    
  30. scr_offst   dw 0     ; offset for shifting screen
  31. blank       db 0     ; 1 = 'blank' screen  0 = normal screen
  32. turn_on     db 0     ; 1 = unblank screen  0 = nothing
  33. count       dw 0     ; tick counter for blanking
  34.  
  35. ;------------------------------------------------------------------------------
  36.  
  37. proc new9                 ; new int 9  (keyboard)
  38.   push es
  39.   push ds
  40.   push ax
  41.   push cs
  42.   pop ds
  43.   mov ax,40h
  44.   mov es,ax
  45.   mov ax,[word es: 1Ch]    ; save keyboard buffer tail pointer   
  46.   mov [old_tail],ax
  47.   pushf                    ; do bios keyboard handler
  48.   call [dword old9_ofs]
  49.   cmp [blank],0            ; check for blank screen
  50.   jne rest_scrn
  51.   mov [count],0            ; reset tick counter
  52.   jmp exit_9
  53.  
  54. rest_scrn:                 ; set flag to unblank screen
  55.   mov [turn_on],1
  56.   mov ax,[old_tail]        ; restore tail pointer to remove key from buffer
  57.   mov [word es: 1Ch],ax
  58. exit_9:
  59.   pop ax
  60.   pop ds
  61.   pop es
  62.   iret
  63. endp new9
  64.  
  65. ;------------------------------------------------------------------------------
  66.  
  67. proc new1C                 ; new int 1C  (timer tick)
  68.   sti                      ; enable interrupts
  69.   push es
  70.   push ds
  71.   push dx
  72.   push ax
  73.   push cs
  74.   pop ds
  75.   mov ax,40h
  76.   mov es,ax
  77.   cmp [turn_on],0          ; check if flag set to restore screen
  78.   je if_blank              ; jump to check for blank screen if flag not set
  79.  
  80.   mov [turn_on],0          ; restore original video buffer start
  81.   mov [blank],0
  82.   mov ax,[word es: 4Eh]    ; get bios video buffer start (bytes)
  83.   shr ax,1                 ; convert to words
  84.   push ax
  85.   jmp do_crt               ; set crt controller 
  86.  
  87. if_blank:                  
  88.   cmp [off_flg],0          ; exit if disabled
  89.   jne exit_1C
  90.   cmp [blank],0            ; check if screen already blank
  91.   jne chk_shift            ; if blank then jump to check if ready to shift 
  92.  
  93.   inc [count]              ; screen not blank - check if time to blank
  94.   cmp [count],maxcount
  95.   jne exit_1C              ; exit if not time to blank
  96.  
  97.   mov [blank],1            ; set blank screen flag
  98.   jmp do_shift             ; shift screen 
  99.  
  100. chk_shift:                 ; if screen blank - shift every shft_cnt ticks  
  101.   inc [count]
  102.   cmp [count],shft_cnt
  103.   jne exit_1C              ; exit if not time to shift
  104.  
  105. do_shift:                  
  106.   mov ax,[scr_offst]       ; get our video buffer offset (words)
  107.   add ax,1003              ; shift 1003 words
  108.   and ax,7FFh              ; limit to first 4K of video buffer
  109.   mov [scr_offst],ax       ; save our new video buffer offset
  110.   mov dx,[word es: 4Eh]    ; get bios video buffer start (bytes)
  111.   shr dx,1                 ; convert to words
  112.   add ax,dx                ; add our offset
  113.   push ax
  114.  
  115. do_crt:                    ; set crt controller
  116.   mov dx,[es: 63h]         ; crt controller base address
  117.   mov al,12                ; access register 12
  118.   out dx,al
  119.   inc dx
  120.   pop ax                   ; pop starting address 
  121.   xchg ah,al
  122.   out dx,al                ; write hi (start address) to register 12
  123.   dec dx
  124.   push ax                  ; push starting address
  125.   mov al,13                ; access register 13
  126.   out dx,al
  127.   inc dx
  128.   pop ax                   ; pop starting address
  129.   xchg ah,al
  130.   out dx,al                ; write lo (start address) to register 13
  131.   mov [count],0            ; reset tick counter
  132.  
  133. exit_1C:
  134.   pop ax
  135.   pop dx
  136.   pop ds
  137.   pop es
  138.   jmp [dword cs: old1C_ofs] 
  139.  
  140.  
  141.  
  142. endp new1C
  143.  
  144. ;------------------------------------------------------------------------------
  145.  
  146. init:                      ; initialization
  147.   mov si,81h
  148.   mov dx,offset err1_msg   ; "Invalid command line parameter"
  149. parse_loop:                ; check for 'd' on command line
  150.   lodsb
  151.   cmp al," "
  152.   je parse_loop            ; skip spaces
  153.   cmp al,13
  154.   je end_parse             ; jump if no parameter
  155.   or al,20h                ; convert to lower case
  156.   cmp al,"d"
  157.   jne out_err              ; invalid parameter
  158.   mov [off_flg],1          ; set disable flag
  159. end_parse:
  160.   cld                      ; search for a previous copy
  161.   mov [word start],0       ; fingerprint
  162.   mov bx,0                 ; bx = start segment
  163.   mov ax,cs                ; ax = current segment
  164. chk_prev:                  
  165.   inc bx                   ; increment segment
  166.   mov es,bx
  167.   cmp ax,bx                ; check if equals current segment
  168.   je no_copies             
  169.   mov si,offset start
  170.   mov di,si
  171.   mov cx,16                ; compare first 16 bytes of each segment
  172.   repe cmpsb
  173.   jne chk_prev             ; repeat if no match
  174.  
  175.   mov al,[off_flg]         ; copy found - change enable/disable flag
  176.   mov [es: off_flg],al
  177.   mov [es: count],0        ; reset tick count
  178.   mov dx,offset enabl_msg  ; "Dscrnsav enabled"
  179.   cmp al,0
  180.   je out_msg               ; copy enabled - errorlevel = 0
  181.  
  182.   mov dx,offset dsabl_msg  ; "Dscrnsav disabled"
  183.   mov al,0                 ; errorlevel = 0
  184.   jmp out_msg              ; copy disabled
  185.  
  186. no_copies:
  187.   mov dx,offset err2_msg   ; "Dscrnsav not resident"
  188.   cmp [off_flg],0  
  189.   je install               ; ok to install
  190.   
  191. out_err:
  192.   mov al,1
  193. out_msg:
  194.   mov ah,9                 ; display message
  195.   int 21h
  196.   mov ah,4Ch               ; terminate with errorlevel = al
  197.   int 21h
  198.  
  199. install:                   ; make program resident
  200.   mov ax,3509H             ; get old int 9 address
  201.   int 21H
  202.   mov ax,es
  203.   mov [old9_seg],ax        ; save old int 9 address  (keyboard)
  204.   mov [old9_ofs],bx
  205.   mov ax,351CH             ; get old int 1C address  (timer tick)
  206.   int 21H
  207.   mov ax,es
  208.   mov [old1C_seg],ax       ; save old int 1C address
  209.   mov [old1C_ofs],bx
  210.   mov dx,offset new9       ; set int 9 to point to our code
  211.   mov ax,2509H
  212.   int 21H
  213.   mov dx,offset new1C      ; set int 1C to point to our code
  214.   mov ax,251CH
  215.   int 21H
  216.   mov dx,offset load_msg   ; "Dscrnsav loaded"
  217.   mov ah,9
  218.   int 21h                  ; display message
  219.   mov dx,(init - start + 256 + 16)/16
  220.   mov ax,3100H             ; terminate and stay resident
  221.   int 21H
  222.  
  223. ends
  224. end start
  225.  
  226.