home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sampler0 / dimmer.asm < prev    next >
Assembly Source File  |  1990-01-21  |  41KB  |  958 lines

  1.                 page    66,132
  2.  
  3. ; This file was modified by Ben Diss (CIS 71270,341) to fix the ALT key
  4. ; bug and to provide the following inmprovements:
  5. ;
  6. ; 1. The hot key to increase or decrease intensity is CTRL-ALT plus the
  7. ;    arrow key.
  8. ; 2. The replaced ISRs are now called at the beginning of all ISRs
  9. ;    rather than JMPed to at the end.  This eliminates some problems with a
  10. ;    few clone systems.
  11. ; 3. Hot-key blanking has been added via SHIFT-SHIFT.
  12. ; 4. Hot-key disabling has been added via CTRL-ALT-D and re-enabling via
  13. ;    CTRL-ALT-E.
  14. ; 5. Mouse support has been added, so that any use of the mouse will
  15. ;    reset the time-out blanker.
  16. ; 6. The version number has been changed to 1.01 to relect the changes.
  17. ;
  18. ; Although I have used this program on my system since it was published,
  19. ; I cannot promise that it will work on yours, as I have not done any
  20. ; in-depth testing.  This program is provided "as-is" without any
  21. ; warrenty of any kind.  The original version was written for PC
  22. ; Magazine and is Copyright 1989, Ziff Communications Co.  I hereby
  23. ; release all claims to rights for the modifications I have made.
  24. ;
  25. ;      --- Ben
  26. ;
  27. ;-------------------------------------------------------------------------
  28. ; On 1-17-90, version 1.02:
  29. ;
  30. ; I rewrote the mouse routines so that all mouse drivers will be
  31. ;supported on all types of systems.  The old method only worked for
  32. ;serial mouses.  Also, when no mouse driver was loaded with certain
  33. ;programs that did use a mouse, the system would go into orbit.
  34. ;
  35. ; The method used now, polls the mouse driver twice a second for any
  36. ;change in the status.  I did it this way to reduce the overhead of the
  37. ;polling routine.  The side effect is that it is almost impossible to
  38. ;detect the press of a button using this method.
  39. ;
  40. ;----------------------------------------------------------------------------
  41. ; On 1-18-90, version 1.02:
  42. ;
  43. ;  Commented out the interval timer for the mouse polling routine.  I
  44. ;found no difference with and without the delay using a number of
  45. ;benchmark programs.  To retore them, simply delete the comments in from
  46. ;of those lines.
  47. ;
  48. ;----------------------------------------------------------------------------
  49. ; On 1-20-90, version 1.03:
  50. ;
  51. ;  WHOOPS!  I forgot to bypass the INT 33 monitoring routine when there
  52. ;is no mouse driver installed.
  53. ;
  54. ;============================================================================
  55. ; DIMMER.COM allows VGA users to interactively brighten or dim the screen.
  56. ; Syntax is:
  57. ;
  58. ;       DIMMER [/U] [/V[+|-]] [/D mmm [+|-]xx] [[+|-]xx]
  59. ;
  60. ; where /U = Uninstall the program
  61. ;       /D = Adjust intensity by xx after mmm minutes of inactivity
  62. ;       xx = Numeric code from -63 to +63 representing relative
  63. ;            amount by which to adjust the intensity
  64. ;       /V = Reset delay timer on call to BIOS video interrupt. The
  65. ;         default is V-.
  66. ;
  67. ; COMMAND LINE INTENSITY CONTROL
  68. ;
  69. ;       DIMMER /D 1 -63 causes the screen to blank after 1 minute of
  70. ;       inactivity.  DIMMER /D 0 cancels any time delay previously entered.
  71. ;       DIMMER -20 causes the screen to immediately dim 20 intensity levels.
  72. ;       DIMMER 0 restores the screen intensity to what it was when DIMMER
  73. ;       was installed.  In all cases, DIMMER becomes RAM-resident so that
  74. ;       intensity levels can also be adjusted interactively.
  75. ;       DIMMER /D 1 -63 /V causes the screen to blank after 1 minute of
  76. ;       inactivity.  If a program calls any BIOS video routines, the
  77. ;       screen is reset to its original brightness.
  78. ;
  79. ; INTERACTIVE INTENSITY CONTROL
  80. ;
  81. ;       With DIMMER installed, Ctrl-Alt-UpArrow increases the display intensity
  82. ;       by 1 level, Ctrl-Alt-DnArrow decreases the intensity by 1 level, and
  83. ;       Ctrl-Alt-Home restores the screen intensity to what it was when DIMMER
  84. ;       was installed.
  85. ;============================================================================
  86.  
  87.                 code    segment
  88.                 assume  cs:code
  89.  
  90.                 org     2Ch
  91. env_segment     dw      ?                       ;Address of environment block
  92.                 org     80h
  93. command_tail    dw      ?                       ;Address of command tail
  94.  
  95.                 org     100h
  96. main:           jmp     initialize              ;Go to initialization code
  97.  
  98. program         db      "Dimmer 1.03 "
  99. copyright       db      "(c) 1989 Ziff Communications Co.",13,10
  100. authors         db      "PC Magazine ",254," Doug Boling and Jeff Prosise"
  101.                 db      "$",1Ah
  102.  
  103. dimmer_val    db      0                       ;Relative dimmer value
  104. delaydimval    db      0                       ;Delayed dimmer value
  105. wait_time    dw      -1                      ;Delay until screen blank
  106. dim_counter    dw      -1                      ;Number of minutes to delay
  107. second_cnt    dw      1092                    ;Timer ticks per minute
  108. restorebyvid    db    0            ;1 = delay reset by video call
  109. vid_function    dw      0                       ;Saved video function
  110. int08h          dd      ?                       ;Int 8 vector (Timer)
  111. int09h          dd      ?                       ;Int 9 vector (Keyboard)
  112. int10h          dd      ?                       ;Int 10 vector (Video)
  113. INT33H          dd      ?                       ;Int 33 vector (Mouse)
  114. MOUSE_INST      db      ?                       ;0 if no mouse , -1 if present
  115. MOUSE_BUZY      DB      0                       ;0=not buzy, -1=buzy
  116.  
  117. ;============================================================================
  118. ; RESET_DELAY reset the delay counter
  119. ;============================================================================
  120.  
  121. RSHIFT  =       000000001B      ; Right Shift Key is Depressed
  122. LSHIFT    =    000000010B    ; Left Shift Key is Depressed
  123. CTRL    =    000000100B    ; Ctrl Key is Depressed
  124. ALT    =    000001000B    ; Alt Key is Depressed
  125.  
  126. KEYS_UP DB      1               ;0=keys not up since blank
  127. SAVE_WAIT    DW    ?    ;saves the wait_time
  128.  
  129. reset_delay    proc    near 
  130.  
  131.         CMP     CS:[KEYS_UP],1          ;keys released since last
  132.         JNE     done_reset              ;  forced blank?
  133.     mov     cs:[second_cnt],1092    ;Reset delay counters
  134.     mov     ax,cs:[wait_time]
  135.     xchg    cs:[dim_counter],ax
  136.         or      ax,ax                   ;If counter was 0, reset the
  137.         jne     done_reset              ;  screen intensity
  138.     mov     ah,cs:[dimmer_val]
  139.     call    adj_palette_2
  140. done_reset:
  141.     ret
  142.  
  143. reset_delay    endp
  144.  
  145. ;============================================================================
  146. ; MOUSEINT monitors the mouse driver for activity
  147. ;============================================================================
  148.  
  149.         EVEN                            ; word align to assist prefetch que
  150.  
  151. MOUSEINT        PROC    NEAR
  152.  
  153.         MOV     MOUSE_BUZY,-1           ; mouse driver is now buzy
  154.         PUSHF                           ; push flags
  155.         CALL    INT33H                  ; call the driver
  156.         MOV     MOUSE_BUZY,0            ; mouse is now free
  157.         IRET                            ; return
  158.  
  159. MOUSEINT        ENDP
  160.  
  161. ;============================================================================
  162. ; CHECK_MOUSE polls the mouse driver to check for movement
  163. ;============================================================================
  164.  
  165. MOUSE_BX        DW      ?
  166. MOUSE_CX        DW      ?
  167. MOUSE_DX        DW      ?
  168.  
  169.         EVEN                            ; word align to assist prefetch que
  170.  
  171. CHECK_MOUSE     PROC    NEAR
  172.  
  173.         PUSH    BX                      ; save registers
  174.         PUSH    CX
  175.         PUSH    DX
  176.  
  177.         MOV     AX,3                    ; Get mouse position and status
  178.         PUSHF                           ; push the flags and
  179.         CALL    INT33H                  ;   call the mouse driver
  180.  
  181.         CMP     BX,MOUSE_BX             ; if button status has changed
  182.         JNE     MOUSE_MOVED             ;   then reset the delay
  183.         CMP     CX,MOUSE_CX             ; if the horiz position has changed
  184.         JNE     MOUSE_MOVED             ;   then reset the delay
  185.         CMP     DX,MOUSE_DX             ; if the vert position has changed
  186.         JNE     MOUSE_MOVED             ;   then reset the delay
  187.         JMP     SHORT SAVE_MOUSE        ; else just save the status
  188.  
  189. MOUSE_MOVED:
  190.         CALL    RESET_DELAY             ; reset the delay counter and restore
  191.                                         ;  the screen if necessary
  192. SAVE_MOUSE:
  193.         MOV     MOUSE_BX,BX             ; save the mouse driver status
  194.         MOV     MOUSE_CX,CX
  195.         MOV     MOUSE_DX,DX
  196.  
  197.         POP     DX                      ; restore the registers
  198.         POP     CX
  199.         POP     BX
  200.         RET
  201.  
  202. CHECK_MOUSE     ENDP
  203.  
  204.  
  205. ;============================================================================
  206. ; TIMERINT services the BIOS timer interrupt.
  207. ;============================================================================
  208.  
  209. ;COUNTER DB      9                       ; mouse polling interval counter
  210.  
  211.         EVEN                            ; word align to assist prefetch que
  212.  
  213. timerint        proc    far
  214.         pushf                           ;Push flags
  215.         call    int08h                  ;Call BIOS timer routine
  216.         sti                             ;Enable interrupts
  217.  
  218.         push    ax                      ;Save AX
  219.  
  220.         CMP     MOUSE_INST,-1           ; if mouse not installed
  221.         JNE     TIMER_1                 ;   then skip mouse check
  222. ;
  223. ; Check the mouse driver only once per second.  This saves CPU time, but
  224. ; also makes detecting a button press very unlikely.
  225. ;
  226. ;        DEC     COUNTER                 ; decrement the interval timer
  227. ;        JNZ     TIMER_1                 ; if not zero, then skip mouse check
  228. ;        MOV     COUNTER,9               ; reset the interval timer
  229.  
  230.         CMP     MOUSE_BUZY,-1           ; if the mouse driver is buzy
  231.         JE      TIMER_1                 ;   then skip the mouse check
  232.  
  233.         CALL    CHECK_MOUSE             ;   else check for mouse movement
  234.  
  235. TIMER_1:
  236.         mov     ax,cs:[dim_counter]     ;Get delay counter
  237.         cmp     ax,0FFFFh               ;See if timer enabled
  238.         je      timer_exit              ;Exit if not enabled
  239.         or      ax,ax                   ;Exit if timer at 0 to
  240.         je      timer_exit              ;  prevent rollover.
  241.  
  242.         dec     cs:[second_cnt]         ;Decrement seconds and exit
  243.         jnz     timer_exit              ;  if not zero
  244.     mov     word ptr cs:[second_cnt],1092
  245.         dec     ax                      ;Decrement minute counter
  246.     mov     cs:[dim_counter],ax    ;Update delay counter
  247.         or      ax,ax                   ;Exit if timer hasn't
  248.         jne     timer_exit              ;  reached zero
  249.  
  250.     mov     ah,cs:[delaydimval]    ;Get dimmer value
  251.         call    adj_palette_2           ;Modify color registers
  252. timer_exit:
  253.     pop    ax    ;Restore AX and exit
  254.     iret
  255. timerint    endp
  256.  
  257. ;============================================================================
  258. ; KBINT services the keyboard interrupt.
  259. ;============================================================================
  260.  
  261.         EVEN                            ; word align to assist prefetch que
  262.  
  263. kbint   proc    far
  264.  
  265.     PUSHF
  266.         CALL    INT09H                  ;BIOS keyboard handler
  267.         sti                             ;Enable interrupts
  268.         push    ax                      ;Save AX
  269.  
  270.         call    reset_delay             ; reset the delay counter
  271.  
  272.         MOV     AH,2                    ;Get keyboard shift status
  273.     INT    16H
  274.  
  275.         and     al,0Fh                  ;Mask upper 4 bits
  276.         cmp     al,ALT+CTRL             ;Check for Alt key
  277.         je      alt_found               ;Continue if Alt is pressed
  278.  
  279.     CMP    AL,LSHIFT+RSHIFT    ;Check for our hot-key
  280.     JNE    kbint0a
  281.  
  282.     MOV     AH,CS:[DELAYDIMVAL]    ;else get dimmer value
  283.         CALL    ADJ_PALETTE_2           ;Modify color registers
  284.     MOV    CS:[DIM_COUNTER],0    ;Set counter dimmed screen
  285.         MOV     CS:[KEYS_UP],0          ;Set key_up to 'not yet'
  286.     JMP    SHORT kbint_done
  287. kbint0a:
  288.     CMP    AL,0
  289.     JNE    KBINT_DONE
  290.     MOV    CS:[KEYS_UP],1
  291. kbint_done:
  292.     POP    AX
  293.     IRET
  294.  
  295. alt_found:
  296.     in    al,60h
  297.  
  298.         CMP     AL,20H                  ;Check for 'D' to disable
  299.     JNE    kbint0b
  300.     MOV    AX,CS:[WAIT_TIME]
  301.     MOV    CS:[SAVE_WAIT],AX    ;Save the wait_time
  302.     MOV    CS:[DIM_COUNTER],0FFFFH    ;Disable dim_counter
  303.     MOV    CS:[WAIT_TIME],0FFFFH    ;DIsable wait_time
  304.     MOV    AX,0E07H
  305.     INT    10H
  306.     JMP    SHORT kbint4
  307.  
  308. kbint0b:
  309.         CMP     AL,12H                  ;Check for 'E' to enable
  310.     JNE    kbint0c
  311.     MOV    AX,CS:[SAVE_WAIT]
  312.     MOV    CS:[WAIT_TIME],AX
  313.     MOV    CS:[DIM_COUNTER],AX
  314.     MOV    CS:[SECOND_CNT],1092    ;Reset delay counters
  315.     MOV    AX,0E07H
  316.     INT    10H
  317.     MOV    AX,0E07H
  318.     INT    10H
  319.     JMP    SHORT kbint4
  320. kbint0c:
  321.         cmp     al,72                   ;Check for UpArrow
  322.     jne     kbint1
  323.     cmp     cs:[dimmer_val],63    ;Increment color registers
  324.         jge     kbint3                  ;  by 1 if dimmer value
  325.         inc     cs:[dimmer_val]         ;  isn't maxed out
  326.     jmp     short kbint3
  327. kbint1:
  328.         cmp     al,80                   ;Check for DnArrow
  329.     jne     kbint2
  330.     cmp     cs:[dimmer_val],-63    ;Decrement color registers
  331.         jle     kbint3                  ;  by 1 if dimmer value
  332.         dec     cs:[dimmer_val]         ;  isn't zeroed out
  333.     jmp     short kbint3
  334. kbint2:
  335.         cmp     al,71                   ;Reset color registers if
  336.         jne     kbint_done              ;  Alt-Home was pressed
  337.     mov     cs:[dimmer_val],0
  338. kbint3:
  339.     mov     ah,cs:[dimmer_val]    ;Get dimmer value
  340.         call    adj_palette_2           ;Modify color registers
  341.  
  342. kbint4:
  343.     MOV    AH,1
  344.     INT    16H
  345.     JZ    KBINT_EXIT
  346.  
  347.     MOV    AH,0
  348.     INT    16H
  349.     JMP    SHORT kbint4
  350.  
  351. KBINT_EXIT:
  352.     pop    ax    ;Restore AX and exit
  353.     iret
  354.  
  355. kbint    endp
  356.  
  357.  
  358. ;============================================================================
  359. ; VIDEOINT services the BIOS video interrupt.
  360. ;============================================================================
  361.  
  362.         EVEN                            ; word align to assist prefetch que
  363.  
  364. videoint        proc    far
  365.         mov     cs:[vid_function],ax    ;Save function number
  366.         pushf                           ;Push flags
  367.         call    int10h                  ;Call video BIOS routine
  368.         sti                             ;Enable interrupts
  369.         push    ax                      ;Save AX
  370.  
  371.     cmp    cs:[restorebyvid],0    ;If video checking enabled,
  372.         je      video_1                 ;  check delay counter.
  373.         cmp     word ptr cs:[dim_counter],0
  374.         jne     video_1                 ;Restore color register
  375.         mov     ah,cs:[dimmer_val]      ;  values if timed delay
  376.         call    adj_palette_2           ;  has dimmed the screen
  377.         mov     cs:[second_cnt],1092    ;Reset delay counters
  378.         mov     ax,cs:[wait_time]
  379.         mov     cs:[dim_counter],ax
  380.  
  381. video_1:
  382.         mov     ax,cs:[vid_function]    ;See what function was called
  383.         or      ah,ah                   ;Check for mode change
  384.         je      refresh_palette
  385.         cmp     ah,11h                  ;Check for mode reset
  386.         je      refresh_palette
  387.  
  388.         cmp     ax,1010h                ;Check for changes to the
  389.         je      refresh_buffer          ;  VGA color registers
  390.         cmp     ax,1012h                ;  made thru the video
  391.         je      refresh_buffer          ;  BIOS
  392.         cmp     ax,101Bh
  393.         jne     video_exit
  394. refresh_buffer:
  395.         call    get_palette             ;Reload register array
  396.         jmp     short video_exit
  397.  
  398. refresh_palette:
  399.         mov     ah,cs:[dimmer_val]      ;Get dimmer adjust value
  400.         call    adj_palette_2           ;Modify palette
  401. video_exit:
  402.         pop     ax                      ;Restore AX and exit
  403.         iret
  404. videoint        endp
  405.  
  406. ;----------------------------------------------------------------------------
  407. ; ADJ_PALETTE_1 adjusts the VGA color registers to their original values
  408. ; plus the current dimmer value.
  409. ;   Entry:  AH - Dimmer value
  410. ;           DS - Segment where color register values are stored
  411. ;----------------------------------------------------------------------------
  412. adj_palette_1   proc    near
  413.                 cld                             ;Clear direction flag
  414.                 push    cx                      ;Save registers
  415.                 push    dx
  416.                 push    si
  417.  
  418.                 mov     si,offset end_res       ;Point SI to buffer
  419.                                                 ;  containing original values
  420.                 mov     dx,03C8h                ;Write address register
  421.                 xor     al,al                   ;Set beginning address
  422.                 cli                             ;Disable interrupts
  423.                 out     dx,al
  424.                 mov     cx,256 * 3              ;256 color registers
  425.                 mov     dx,03C9h                ;Write data register
  426. adj_loop1:
  427.                 lodsb                           ;Get color value
  428.                 call    mod64_add               ;Add dimmer value
  429.                 out     dx,al                   ;Write data to color register
  430.                 loop    adj_loop1               ;Loop until done
  431.  
  432.                 sti                             ;Enable interrupts
  433.                 pop     si                      ;Restore registers and exit
  434.                 pop     dx
  435.                 pop     cx
  436.                 ret
  437. adj_palette_1   endp
  438.  
  439. ;----------------------------------------------------------------------------
  440. ; ADJ_PALETTE_2 adjusts the VGA color registers to their original values
  441. ; plus the current dimmer value.
  442. ;   Entry:  AH - Dimmer value
  443. ;----------------------------------------------------------------------------
  444. adj_palette_2   proc    near
  445.                 push    ds                      ;Save DS
  446.                 push    cs                      ;Point DS to code segment
  447.                 pop     ds
  448.                 call    adj_palette_1           ;Modify color registers
  449.                 pop     ds                      ;Restore DS and exit
  450.                 ret
  451. adj_palette_2   endp
  452.  
  453. ;----------------------------------------------------------------------------
  454. ; MOD64_ADD adds AH to AL using modulo 64 math.
  455. ;----------------------------------------------------------------------------
  456. mod64_add       proc    near
  457.                 or      al,al                   ;If 0, don't brighten
  458.                 je      mod2
  459.                 add     al,ah
  460.                 cmp     al,0                    ;See if underflow
  461.                 jg      mod1
  462.                 mov     al,0                    ;If so, set at minimum
  463.                 jmp     short mod2
  464. mod1:
  465.                 cmp     al,63                   ;See if overflow
  466.                 jbe     mod2
  467.                 mov     al,63                   ;If so, set at maximum
  468. mod2:
  469.                 ret
  470. mod64_add       endp
  471.  
  472. ;----------------------------------------------------------------------------
  473. ; GET_PALETTE buffers the current values of the VGA color registers.
  474. ;----------------------------------------------------------------------------
  475. get_palette     proc    near
  476.                 cld                             ;Clear direction flag
  477.                 push    ax                      ;Save registers
  478.                 push    cx
  479.                 push    dx
  480.                 push    di
  481.                 push    es
  482.  
  483.                 mov     cx,cs                   ;Point ES to the code segment
  484.                 mov     es,cx
  485.                 mov     di,offset end_res       ;Point DI to save buffer
  486.                 mov     dx,03C7h                ;Read address register
  487.                 xor     al,al                   ;Begin with register 0
  488.                 cli                             ;Disable interrupts
  489.                 out     dx,al
  490.                 mov     cx,256 * 3              ;256 color registers
  491.                 mov     dx,03C9h                ;Read data register
  492. getp_loop1:
  493.                 in      al,dx                   ;Get color register value
  494.                 and     al,3Fh                  ;Mask off the upper 2 bits
  495.                 stosb                           ;Store it
  496.                 loop    getp_loop1              ;Loop until done
  497.  
  498.                 sti                             ;Enable interrupts
  499.                 pop     es                      ;Restore registers and exit
  500.                 pop     di
  501.                 pop     dx
  502.                 pop     cx
  503.                 pop     ax
  504.                 ret
  505. get_palette     endp
  506.  
  507. ;----------------------------------------------------------------------------
  508. ; FINAL_INSTALL is the last of the resident code.
  509. ;----------------------------------------------------------------------------
  510. final_install:
  511.                 assume  ds:code
  512.                 call    get_palette             ;Get color register values
  513.                 mov     ah,dimmer_val           ;Adjust color registers and
  514.                 call    adj_palette_2           ;  terminate
  515.                 mov     dx,(offset end_res-offset code+768+15) SHR 4
  516.                 mov     ax,3100h
  517.                 int     21h
  518. end_res         =       $                       ;End of resident code
  519.  
  520. ;============================================================================
  521. ; Start of non-resident section.
  522. ;============================================================================
  523.  
  524. alrdy_installed db      0                       ;Installed flag
  525. other_seg       dw      0                       ;Segment of installed code
  526. change_flag     db      0                       ;Set if dimmer or delay
  527.                                                 ;  value is modified
  528. infomsg1        db      "Program uninstalled$"
  529. errmsg1         db      "Program not installed$"
  530. errmsg2         db      "Syntax: DIMMER [/U] [/V[+|-]] [/D mmm [+|-]xx]"
  531.                 db      " [[+|-]xx]$"
  532. errmsg3         db      "Can",39,"t uninstall$"
  533. errmsg4         db      "VGA required$"
  534. errmsg5         db      "Intensity value must be between -63 and +63$"
  535. errmsg6         db      "Invalid delay value$"
  536. errmsg7         db      "Program already installed$"
  537. errmsg8         db      "Invalid intensity value$"
  538.  
  539. initialize      proc    near
  540.                 assume  cs:code,ds:code
  541. ;
  542. ;See if a copy of DIMMER is already resident in memory.
  543. ;
  544.                 cld                             ;Clear direction flag
  545.                 mov     word ptr [main],0       ;Initialize fingerprint
  546.                 xor     bx,bx                   ;Zero BX for start
  547.                 mov     ax,cs                   ;Keep CS value in AX
  548. find_copy:
  549.                 inc     bx                      ;Increment search segment
  550.                 mov     es,bx
  551.                 cmp     ax,bx                   ;Not installed if current
  552.                 je      find_copy1              ;  segment is found
  553.                 mov     si,offset main          ;Search this segment for ASCII
  554.                 mov     di,si                   ;  fingerprint.
  555.                 mov     cx,16
  556.                 repe    cmpsb
  557.                 jne     find_copy               ;Loop back if not found
  558.                 inc     alrdy_installed         ;Set installed flag
  559. find_copy1:
  560.                 mov     other_seg,es            ;Save segment value
  561. ;
  562. ;Check to see if a mouse is present
  563. ;
  564.                 MOV     AX,0                    ; check for mouse driver
  565.                 INT     33H
  566.                 MOV     MOUSE_INST,AH           ;0=no mouse, -1=mouse installed
  567. ;
  568. ;Verify that a VGA is installed.
  569. ;
  570.                 mov     ax,1A00h                ;BIOS read display function
  571.                 int     10h
  572.                 mov     dx,offset errmsg4
  573.                 cmp     al,1Ah                  ;See if VGA present
  574.                 jne     disp_error              ;Exit on error if no VGA
  575. ;
  576. ;Parse the command line for switches.
  577. ;
  578.                 mov     si,offset command_tail+1        ;Point SI to command
  579. parse_line_loop:                                        ;  tail in PSP
  580.                 lodsb                           ;Scan command line for / or a
  581.                 cmp     al,32                   ;  number.  Continue scanning
  582.                 je      parse_line_loop         ;  until a carriage return is
  583.                 cmp     al,13                   ;  found.
  584.                 je      parse_line_end
  585.  
  586.                 cmp     al,"/"                  ;Is this a / character?
  587.                 jne     check_numeric           ;No, then check for numeric
  588.                 lodsb                           ;Get next character
  589.                 or      al,20h                  ;Convert to lower case
  590.                 cmp     al,"u"                  ;Check for uninstall switch
  591.                 je      uninstall_found
  592.                 cmp     al,"d"                  ;Check for delay switch
  593.                 je      delay_found
  594.                 cmp     al,"v"                  ;Check for reset delay by
  595.                 je      vidflag_found        ;  video call switch.
  596. parse_line_error:
  597.                 mov     dx,offset errmsg2       ;Syntax error
  598.                 jmp     short disp_error        ;Display message and exit
  599. ;
  600. ;Read the dimmer value from the command line if entry is numeric.
  601. ;
  602. check_numeric:
  603.                 cmp     al,"-"                  ;Convert ASCII number into
  604.                 je      numeric_start           ;  binary.  Check for leading
  605.                 cmp     al,"+"                  ;  sign.
  606.                 je      numeric_start
  607.                 cmp     al,"0"
  608.                 jb      parse_line_error
  609.                 cmp     al,"9"
  610.                 ja      parse_line_error
  611.                 dec     si
  612. numeric_start:
  613.                 or      change_flag,1           ;Set bit 0 in change flag
  614.                 call    setdim                  ;Read and set dimmer value
  615.                 jmp     short chk_err_and_loop  ;Check for error return
  616. ;
  617. ;Read the time delay and dimmer values from the command line.
  618. ;
  619. vidflag_found:
  620.                 call    setvidflag              ;Modify the state of video flg
  621.                 jmp     short chk_err_and_loop  ;Check for error return
  622. delay_found:
  623.                 or      change_flag,2           ;Set bit 1 in change flag
  624.                 call    setdelay                ;Read and set delay value
  625. chk_err_and_loop:
  626.                 jc      disp_error
  627.                 jmp     short parse_line_loop
  628. ;
  629. ;Uninstall the program from memory.
  630. ;
  631. uninstall_found:
  632.                 mov     dx,offset errmsg1       ;Make sure program is
  633.                 cmp     alrdy_installed,0       ;  installed and signal
  634.                 je      disp_error              ;  error if it is not
  635.                 call    remove                  ;Remove program from memory
  636.                 mov     dx,offset errmsg3
  637.                 jc      disp_error              ;Error if can't remove
  638.                 mov     dx,offset infomsg1      ;Acknowledge if removed
  639.                 call    print_string
  640. exit:
  641.                 mov     ax,4C00h                ;Exit with RC = 0
  642.                 int     21h
  643. ;
  644. ;Process new dimmer and/or delay values now if DIMMER is already resident.
  645. ;
  646. parse_line_end:
  647.                 cmp     alrdy_installed,0       ;Program already installed?
  648.                 je      install                 ;No, then install it
  649.                 cmp     change_flag,0           ;Changes to resident copy?
  650.                 jne     check_dimmer_change     ;Yes, then process them
  651.                 mov     dx,offset errmsg7
  652. disp_error:
  653.                 call    print_string            ;No, then display error
  654.                 mov     ax,4C01h                ;  message and exit
  655.                 int     21h                     ;  with RC = 1
  656. check_dimmer_change:
  657.                 test    change_flag,1           ;Adjust color registers if
  658.                 jz      check_delay_change      ;  dimmer value was changed
  659.                 push    ds
  660.                 mov     ds,other_seg            ;Point DS to installed
  661.                 assume  ds:nothing              ;  segment
  662.                 mov     ah,ds:[dimmer_val]
  663.                 call    adj_palette_1
  664.                 pop     ds
  665.                 assume  ds:code
  666.                 jmp     exit                    ;Terminate
  667. check_delay_change:
  668.                 test    change_flag,2           ;Exit now if delay value
  669.                 jnz     exit                    ;  was modified
  670. ;
  671. ;Install a copy of DIMMER.
  672. ;
  673. install:
  674.                 mov     ax,3508h                ;Hook into interrupt 8
  675.                 int     21h
  676.                 mov     word ptr int08h,bx
  677.                 mov     word ptr int08h[2],es
  678.                 mov     ax,2508h
  679.                 mov     dx,offset timerint
  680.                 int     21h
  681.  
  682.                 mov     ax,3509h                ;Hook into interrupt 9
  683.                 int     21h
  684.                 mov     word ptr int09h,bx
  685.                 mov     word ptr int09h[2],es
  686.                 mov     ax,2509h
  687.                 mov     dx,offset kbint
  688.                 int     21h
  689.  
  690.                 mov     ax,3510h                ;Hook into interrupt 10h
  691.                 int     21h
  692.                 mov     word ptr int10h,bx
  693.                 mov     word ptr int10h[2],es
  694.                 mov     ax,2510h
  695.                 mov     dx,offset videoint
  696.                 int     21h
  697.  
  698.         CMP     MOUSE_INST,-1           ; if mouse not installed
  699.         JNE     INIT_1                  ;   then skip mouse install
  700.  
  701.                 mov     ax,3533h                ;Hook into interrupt 33h
  702.                 int     21h
  703.                 mov     word ptr int33h,bx
  704.                 mov     word ptr int33h[2],es
  705.                 mov     ax,2533h
  706.                 mov     dx,offset MOUSEINT
  707.                 int     21h
  708.  
  709. INIT_1:
  710.                 mov     dx,offset program       ;Display copyright notice
  711.                 call    print_string            ;  and jump to final
  712.                 jmp     final_install           ;  install code
  713. initialize      endp
  714.  
  715. ;-----------------------------------------------------------------------------
  716. ; PRINT_STRING displays a DOS "$"-delimited text string with leading and
  717. ; trailing CRLFs.
  718. ;   Entry: DS:DX - String address
  719. ;-----------------------------------------------------------------------------
  720. crlf            db      13,10,"$"
  721.  
  722. print_string    proc    near
  723.                 push    dx                      ;Save entry-level value of DX
  724.                 mov     ah,9                    ;Print leading CRLF
  725.                 mov     dx,offset crlf
  726.                 int     21h
  727.                 mov     ah,9                    ;Print text string
  728.                 pop     dx
  729.                 int     21h
  730.                 mov     ah,9                    ;Print trailing CRLF
  731.                 mov     dx,offset crlf
  732.                 int     21h
  733.                 ret                             ;Exit to caller
  734. print_string    endp
  735.  
  736. ;-----------------------------------------------------------------------------
  737. ; SETVIDFLAG modifies the video reset flag.
  738. ;   Entry: DS:SI - Address of optional sign value.
  739. ;-----------------------------------------------------------------------------
  740. setvidflag      proc    near
  741.                 mov     al,1                    ;Assume video flag enable
  742.                 cmp     byte ptr [si],"-"       ;Check for video flag disable
  743.                 jne     setvidflag_1
  744.                 dec     al
  745. setvidflag_1:
  746.                 mov     es,other_seg            ;Point ES to installed seg
  747.                 mov     es:[restorebyvid],al    ;Set/Reset video flag
  748.                 clc
  749.                 ret
  750. setvidflag      endp
  751.  
  752. ;-----------------------------------------------------------------------------
  753. ; SETDIM sets the dimmer value.
  754. ;   Entry: DS:SI - Address of first digit
  755. ;   Exit:  CF set on error (DX points to error message text)
  756. ;-----------------------------------------------------------------------------
  757. setdim          proc    near
  758.                 mov     di,si                   ;Copy command line pointer
  759.                 call    asc2bin                 ;Convert ASCII to binary
  760.                 mov     dx,offset errmsg8       ;Exit on error
  761.                 jc      setdim_error
  762.                 cmp     byte ptr [di-1],"-"     ;Negate value if negative
  763.                 jne     setdim_1
  764.                 neg     ax
  765. setdim_1:
  766.                 mov     dx,offset errmsg5
  767.                 cmp     ax,63                   ;Error if value is less than
  768.                 jg      setdim_error            ;  -63 or greater than +63
  769.                 cmp     ax,-63
  770.                 jl      setdim_error
  771.  
  772.                 mov     es,other_seg            ;Point ES to installed seg
  773.                 mov     es:[dimmer_val],al      ;Record dimmer value
  774.                 clc
  775. setdim_exit:
  776.                 ret
  777. setdim_error:
  778.                 stc
  779.                 jmp     short setdim_exit
  780. setdim          endp
  781.  
  782. ;-----------------------------------------------------------------------------
  783. ; SETDELAY sets the delay counter.
  784. ;   Entry: DS:SI - Address of first character past /D switch
  785. ;   Exit:  CF set on error (DX points to error message text)
  786. ;-----------------------------------------------------------------------------
  787. setdelay        proc    near
  788. setdelay_l1:
  789.                 lodsb
  790.                 cmp     al,32                   ;Skip spaces
  791.                 je      setdelay_l1
  792.                 mov     dx,offset errmsg2       ;Error if no delay value
  793.                 cmp     al,13                   ;  was specified
  794.                 je      setdelay_error
  795.  
  796.                 dec     si                      ;Back up to first character
  797.                 call    asc2bin                 ;Convert ASCII to binary
  798.                 mov     dx,offset errmsg6       ;Exit on error
  799.                 jc      setdelay_error
  800.                 mov     bx,0FFFFh               ;If delay value 0, disable
  801.                 or      ax,ax                   ;  delay counter with FFFFh
  802.                 je      delay_2
  803.                 mov     bx,ax                   ;Save delay value
  804. setdelay_l2:
  805.                 lodsb                           ;Get next character
  806.                 cmp     al,32                   ;Skip spaces
  807.                 je      setdelay_l2
  808.                 mov     dx,offset errmsg2       ;Error if no delay value
  809.                 cmp     al,13                   ;  was specified
  810.                 je      setdelay_error
  811.  
  812.                 mov     di,si                   ;Copy pointer to number
  813.                 cmp     al,"-"                  ;Check for leading sign
  814.                 je      setdelay_1              ;  identifier
  815.                 cmp     al,"+"
  816.                 je      setdelay_1
  817.                 dec     si                      ;Back up to first character
  818. setdelay_1:
  819.                 push    bx                      ;Save delay value
  820.                 call    asc2bin                 ;ASCII --> binary
  821.                 pop     bx                      ;Retrieve delay value
  822.                 mov     dx,offset errmsg8       ;Exit on error
  823.                 jc      setdelay_error
  824.                 cmp     byte ptr [di-1],"-"     ;Negate value if negative
  825.                 jne     delay_1
  826.                 neg     ax
  827. delay_1:
  828.                 mov     dx,offset errmsg5       ;Check to see if the value
  829.                 cmp     ax,63                   ;  is out of range
  830.                 jg      setdelay_error
  831.                 cmp     ax,-63
  832.                 jl      setdelay_error
  833. delay_2:
  834.                 mov     es,other_seg            ;Load new delay and dimmer
  835.                 mov     es:[delaydimval],al     ;  values into the
  836.                 mov     es:[wait_time],bx       ;  program
  837.                 MOV     ES:[SAVE_WAIT],BX
  838.                 mov     es:[dim_counter],bx
  839.                 mov     es:[second_cnt],1092
  840.                 clc
  841. setdelay_exit:
  842.                 ret
  843. setdelay_error:
  844.                 stc
  845.                 jmp     short setdelay_exit
  846. setdelay        endp
  847.  
  848. ;-----------------------------------------------------------------------------
  849. ; REMOVE removes a resident copy of the program from memory.
  850. ;   Exit: CF set on error
  851. ;-----------------------------------------------------------------------------
  852.  
  853. remove_error:
  854.                 stc
  855.                 jmp     remove_exit1
  856.  
  857. remove          proc    near
  858.                 cmp     alrdy_installed,0       ;See if installed
  859.                 je      remove_error            ;No, error
  860.  
  861.                 mov     ax,3508h                ;Get timer vector
  862.                 int     21h
  863.                 mov     ax,es                   ;Check to make sure timer
  864.                 cmp     ax,other_seg            ;  vector not modified
  865.                 jne     remove_error
  866.  
  867.                 mov     ax,3509h                ;Get keyboard vector
  868.                 int     21h
  869.                 mov     ax,es                   ;Check to make sure keyboard
  870.                 cmp     ax,other_seg            ;  vector not modified
  871.                 jne     remove_error
  872.  
  873.                 mov     ax,3510h                ;Get video vector
  874.                 int     21h
  875.                 mov     ax,es                   ;Check to make sure video
  876.                 cmp     ax,other_seg            ;  vector not modified
  877.                 jne     remove_error
  878.  
  879.         CMP     MOUSE_INST,-1           ; if mouse not installed
  880.         JNE     REMOVE_1                ;   then skip mouse segment check
  881.  
  882.                 mov     ax,3533h                ;Get mouse vector
  883.                 int     21h
  884.                 mov     ax,es                   ;Check to make sure video
  885.                 cmp     ax,other_seg            ;  vector not modified
  886.                 jne     remove_error
  887.  
  888. REMOVE_1:
  889.                 push    ds
  890.                 lds     dx,es:[int08h]          ;Get old interrupt 8 vector
  891.                 mov     ax,2508h                ;Set interrupt
  892.                 int     21h
  893.                 lds     dx,es:[int09h]          ;Get old interrupt 9 vector
  894.                 mov     ax,2509h                ;Set interrupt
  895.                 int     21h
  896.                 lds     dx,es:[int10h]          ;Get old interrupt 10 vector
  897.                 mov     ax,2510h                ;Set interrupt
  898.                 int     21h
  899.  
  900.         CMP     MOUSE_INST,-1           ; if mouse not installed
  901.         JNE     REMOVE_2                ;   then skip mouse remove
  902.  
  903.                 lds     dx,es:[int33h]          ;Get old interrupt 33 vector
  904.                 mov     ax,2533h                ;Set interrupt
  905.                 int     21h
  906. REMOVE_2:
  907.                 pop     ds
  908.  
  909.                 mov     cx,es:[env_segment]
  910.                 mov     ah,49h                  ;Free PSP block
  911.                 int     21h
  912.                 mov     es,cx                   ;Free environment block
  913.                 mov     ah,49h
  914.                 int     21h
  915. remove_exit:    
  916.                 clc
  917. remove_exit1:
  918.                 ret
  919.  
  920. remove          endp
  921.  
  922. ;-----------------------------------------------------------------------------
  923. ; ASC2BIN Converts an ASCII number pointed to by SI to a hex value.
  924. ;   Entry: SI = pointer to ASCII number
  925. ;   Exit:  AX = binary value
  926. ;          CF set on error
  927. ;-----------------------------------------------------------------------------
  928. ten             dw      10
  929.  
  930. asc2bin         proc near
  931.                 xor     ax,ax                   ;Clear accumulator
  932.                 xor     bx,bx                   ;Clear BX
  933. asc_loop:
  934.                 mov     bl,[si]                 ;Get ASCII character
  935.                 cmp     bl,13                   ;Done if carriage return or
  936.                 je      asc_exit                ;  space encountered
  937.                 cmp     bl,32
  938.                 je      asc_exit
  939.                 inc     si
  940.                 sub     bl,"0"                  ;ASCII --> binary
  941.                 jb      asc_error               ;Error if binary value is
  942.                 cmp     bl,9                    ;  less than 0 or greater
  943.                 ja      asc_error               ;  than 9
  944.                 mul     ten                     ;Multiply accumulator by 10
  945.                 add     ax,bx                   ;Add last digit to sum
  946.                 jmp     short asc_loop          ;Loop until done
  947. asc_exit:
  948.                 clc
  949. asc_exit1:
  950.                 ret
  951. asc_error:
  952.                 stc
  953.                 jmp     short asc_exit1
  954. asc2bin         endp
  955.  
  956. code            ends
  957.                 end     main
  958.