home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol9n15.zip / CONCEAL.ASM < prev    next >
Assembly Source File  |  1990-07-01  |  72KB  |  2,035 lines

  1. _TEXT          SEGMENT PUBLIC 'CODE'
  2.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  3.  
  4.                ORG     80H
  5. DTA            LABEL   BYTE
  6.  
  7.                ORG     100H
  8. START:         JMP     INITIALIZE
  9.  
  10. ;              DATA AREA
  11. ;              ---------
  12. CR             EQU     13
  13. LF             EQU     10
  14. FF             EQU     12
  15. CTRL_Z         EQU     26
  16. SPACE          EQU     32
  17. BOX            EQU     254
  18. BELL           EQU     7
  19. TAB            EQU     9
  20.  
  21. SIGNATURE      DB      SPACE,CR,CR,LF
  22. COPYRIGHT      DB      "CONCEAL 1.0 (c) 1990 Ziff Communications Co.",CR,LF
  23. PROGRAMMER     DB      "PC Magazine ",BOX," Michael J. Mefford",CR,LF,LF,"$"
  24.                DB      CTRL_Z
  25.  
  26. KB_FLAG        EQU     17H
  27. BUFFER_HEAD    EQU     1AH
  28. BUFFER_TAIL    EQU     1CH
  29. CTRL_STATE     EQU     4
  30. ALT_STATE      EQU     8
  31.  
  32. COMBO          DB      "Z"
  33. HOT_KEY_SCAN   DB      2CH                     ;"Z"
  34. HOT_SHIFT_KEY  DB      ALT_STATE
  35.  
  36. OLD8           DW      ?,?                     ;Old interrupt addresses.
  37. OLD9           DW      ?,?
  38. OLD21          DW      ?,?
  39.  
  40.  
  41. PORT_A         EQU     60H
  42. PORT_B         EQU     61H
  43. COMMAND_PORT   EQU     20H
  44. EOI            EQU     20H
  45.  
  46. MATCHING       STRUC
  47. RESERVED       DB      21 DUP (?)
  48. ATTRIBUTE      DB              ?
  49. FILE_TIME      DW              ?
  50. FILE_DATE      DW              ?
  51. SIZE_LOW       DW              ?
  52. SIZE_HIGH      DW              ?
  53. FILE_NAME      DB      13 DUP (?)
  54. MATCHING       ENDS
  55.  
  56. PASS_CODE      EQU     95H
  57. PASSWORD       DB      "S" XOR 95H, "H" XOR 96H, "A" XOR 97H, "Z" XOR 98H
  58.                DB      "A" XOR 99H, "M" XOR 9AH
  59. PASS_LEN       EQU     $ - PASSWORD
  60.                DB      50 DUP (?)
  61. PASSWORD_LEN   EQU     $ - PASSWORD
  62. PASS_CNT       DW      PASS_LEN
  63. PASS_MASK      DB      PASS_CODE
  64. PASS_POINTER   DW      OFFSET DTA
  65.  
  66. TRAP_FUNCS     LABEL   BYTE
  67. FCB_FUNCS      DB      0FH, 13H, 17H ;Open, Delete, Rename.
  68. HANDLE_FUNCS   DB      3DH, 41H, 56H
  69. TRAP_CNT       EQU     $ - TRAP_FUNCS
  70.  
  71. BOGUS_ARG      DB      12 DUP (0)
  72. FILESPEC       DB      13 DUP (?)
  73.  
  74. EGA_INFO       EQU     87H
  75. EGA_ACTIVE     EQU     00001000B
  76. ADDR_6845      EQU     63H
  77. CRT_MODE_SET   EQU     65H
  78. VIDEO_SIGNAL   EQU     00001000B
  79. CRT_MODE       EQU     49H
  80. SAVE_MODE      DB      ?
  81. CRT_PALETTE    EQU     66H
  82. SAVE_PALETTE   DB      ?
  83. CRT_COLS       EQU     4AH
  84. ACTIVE_PAGE    EQU     62H
  85. CURSOR_ADDR    DW      ?
  86. CURSOR_POSN    EQU     50H
  87. CURSOR_POS     DW      ?
  88. CURSOR_MODE    DW      ?
  89.  
  90. ON             EQU     1
  91. OFF            EQU     0
  92. SOFT_BLANK     EQU     1
  93. HARD_BLANK     EQU     2
  94.  
  95. CONCEAL_FLAG   DW      OFF              ; ON if files have been secured.
  96. BLANK_FLAG     DB      OFF              ; ON if /G ON or /B ON.
  97. CGA_MONO       EQU     0
  98. EGA_VGA        EQU     1
  99. SOFTWARE       EQU     2
  100. BLANK_TYPE     DB      ?                ; CGA_MONO, EGA_VGA or SOFTWARE blanked.
  101. BLANK_SCREEN   DB      OFF              ; ON if screen is blanked.
  102. UNBLANK_FLAG   DB      OFF              ; ON if password required to unblank.
  103. BLANK_IT       DB      OFF              ; ON if Hotkey pressed; timer will blank
  104. UNBLANK_IT     DB      OFF              ; ON if key pressed; timer will unblank
  105. GRAPHIC_APPS   DB      OFF              ; ON if Don't blank graphic apps.
  106. BUFFER_FLAG    DB      OFF              ; ON if installed with /G.
  107. CHANGE_FLAG    DB      OFF              ; ON if attribute to be changed.
  108. CONCEAL_STATS  EQU     0
  109. ATTR_STATS     EQU     1
  110. STATS_FLAG     DB      ?
  111.  
  112. DEFAULT_TIME   EQU     3 * 1092
  113. TIMER_BUSY     DB      0
  114. TIME_OUT       DW      DEFAULT_TIME
  115. COUNTER        DW      DEFAULT_TIME
  116.  
  117. CONCEAL_BUSY   DB      0                       ;=1 if DOS hook entered.
  118.  
  119. ;----------------------------------------------;
  120.  
  121. DOS            PROC    FAR
  122.  
  123.                CMP     CS:CONCEAL_FLAG,ON
  124.                JNZ     SKIP_CONCEAL2
  125.                CMP     CONCEAL_BUSY,1
  126.                JZ      SKIP_CONCEAL2
  127.                MOV     CS:CONCEAL_BUSY,1
  128.  
  129.                PUSH    DS
  130.                PUSH    ES
  131.                PUSH    BX
  132.                PUSH    CX
  133.                PUSH    DX
  134.                PUSH    SI
  135.                PUSH    DI
  136.                PUSH    AX
  137.  
  138.                CMP     AX,4301H                ;Change file mode.
  139.                JNZ     TRAP
  140.                PUSH    AX
  141.                PUSH    CX
  142.                MOV     AX,4300H
  143.                INT     21H
  144.                MOV     BX,CX
  145.                POP     CX
  146.                POP     AX
  147.                JC      SKIP_CONCEAL1
  148.                TEST    BX,4
  149.                JZ      SKIP_CONCEAL1
  150.                TEST    CX,4
  151.                JZ      MAKE_CONCEAL
  152.                JMP     SHORT SKIP_CONCEAL1
  153.  
  154. TRAP:          CLD
  155.                MOV     SI,DS                   ;Segment.
  156.                MOV     CX,CS
  157.                MOV     DS,CX
  158.                MOV     ES,CX
  159.                XCHG    AH,AL
  160.                MOV     DI,OFFSET TRAP_FUNCS
  161.                MOV     CX,TRAP_CNT
  162.                REPNZ   SCASB
  163.                JNZ     SKIP_CONCEAL1
  164.                MOV     CX,DX                   ;Offset.
  165.                CMP     DI,OFFSET HANDLE_FUNCS + 1
  166.                JAE     DO_CONCEAL
  167.                CALL    CONVERT_FCB
  168.  
  169. DO_CONCEAL:    CALL    CK_CONCEAL              ;See if filespec has System attr.
  170.                JC      MAKE_CONCEAL
  171.  
  172. SKIP_CONCEAL1: POP     AX
  173.                POP     DI
  174.                POP     SI
  175.                POP     DX
  176.                POP     CX
  177.                POP     BX
  178.                POP     ES
  179.                POP     DS
  180.                MOV     CS:CONCEAL_BUSY,0
  181. SKIP_CONCEAL2: JMP     DWORD PTR CS:OLD21      ;Call keyboard handling routine.
  182.  
  183. MAKE_CONCEAL:  PUSH    CS
  184.                POP     DS
  185.                MOV     DX,OFFSET BOGUS_ARG     ;To fail, pass the call with
  186.                POP     AX                      ; an invalid argument.
  187.                PUSHF
  188.                CALL    DWORD PTR CS:OLD21
  189.                POP     DI
  190.                POP     SI
  191.                POP     DX
  192.                POP     CX
  193.                POP     BX
  194.                POP     ES
  195.                POP     DS
  196.                MOV     CS:CONCEAL_BUSY,0
  197.                RET     2                       ;Return with flags intact.
  198.  
  199. DOS            ENDP
  200.  
  201. ;----------------------------------------------;
  202. ; INPUT: SI:CX -> FCB; OUTPUT: SI:CX -> FILESPEC
  203.  
  204. CONVERT_FCB:   XCHG    SI,CX                   ;Convert a FCB format to
  205.                MOV     DS,CX                   ; a handle format.
  206.                MOV     DI,OFFSET FILESPEC
  207.  
  208.                LODSB
  209.                CMP     AL,-1                   ;Extended FCB?
  210.                JNZ     DRIVE
  211.                ADD     SI,6
  212.                LODSB
  213. DRIVE:         OR      AL,AL
  214.                JNZ     STORE_DRIVE
  215.                MOV     AH,19H                  ;Current disk.
  216.                PUSHF
  217.                CALL    DWORD PTR CS:OLD21
  218.                INC     AL
  219.  
  220. STORE_DRIVE:   ADD     AL,"A" - 1
  221.                STOSB
  222.                MOV     AL,":"
  223.                STOSB
  224.                PUSH    SI
  225.                MOV     CX,8
  226.  
  227. NEXT_NAME:     LODSB
  228.                CMP     AL,SPACE
  229.                JBE     EXTENSION
  230.                STOSB
  231.                LOOP    NEXT_NAME
  232.  
  233. EXTENSION:     MOV     AL,"."
  234.                STOSB
  235.                POP     SI
  236.                ADD     SI,8
  237.                MOV     CX,3
  238. NEXT_EXT:      LODSB
  239.                CMP     AL,SPACE
  240.                JBE     ASCIIZ
  241.                STOSB
  242.                LOOP    NEXT_EXT
  243.  
  244. ASCIIZ:        XOR     AL,AL
  245.                STOSB
  246.                MOV     SI,CS
  247.                MOV     CX,OFFSET FILESPEC
  248.                RET
  249.  
  250. ;----------------------------------------------;
  251. ; INPUT: SI:CX -> FILESPEC;  OUTPUT: CF = 1 if FILESPEC has system attribute.
  252.  
  253. CK_CONCEAL:    MOV     AH,2FH                  ;Get disk transfer address
  254.                PUSHF
  255.                CALL    DWORD PTR CS:OLD21
  256.                PUSH    ES                      ; and save.
  257.                PUSH    BX
  258.  
  259.                PUSH    CS
  260.                POP     DS
  261.                MOV     DX,OFFSET DTA
  262.                MOV     AH,1AH                  ;Set disk transfer address
  263.                PUSHF                           ; to our DTA.
  264.                CALL    DWORD PTR CS:OLD21
  265.  
  266.                MOV     DS,SI
  267.                MOV     DX,CX
  268.                MOV     CX,1 OR 2 OR 4          ;Read-only, hidden and system
  269.                MOV     AH,4EH                  ; attributes.
  270.                PUSHF
  271.                CALL    DWORD PTR CS:OLD21
  272.                CMC
  273.                JNC     CK_CONCEAL_END
  274.                TEST    CS:DTA.ATTRIBUTE,4      ;System attribute?
  275.                STC
  276.                JNZ     CK_CONCEAL_END
  277.                CLC
  278.  
  279. CK_CONCEAL_END: POP     DX
  280.                POP     DS
  281.                PUSHF
  282.                MOV     AH,1AH                  ;Restore DTA.
  283.                PUSHF
  284.                CALL    DWORD PTR CS:OLD21
  285.                POPF
  286.                RET
  287.  
  288. ;------------------------------------------------------------------------------
  289. ;Execution comes here thru interrupt 9 every time a key is pressed or released.
  290. ;------------------------------------------------------------------------------
  291.  
  292. KEYBOARD       PROC    NEAR
  293.                STI
  294.                PUSH    AX
  295.                IN      AL,PORT_A               ;Get scan code.
  296.  
  297.                PUSHF
  298.                CALL    CS:DWORD PTR OLD9
  299.  
  300.                CMP     CS:BLANK_FLAG,OFF       ;Blanking active?
  301.                JNZ     CK_STATE
  302.                JMP     KEYBOARD_END
  303.  
  304. CK_STATE:      PUSH    BX
  305.                PUSH    SI
  306.                PUSH    DI
  307.                PUSH    DS
  308.                PUSH    ES
  309.  
  310.                MOV     BX,CS
  311.                MOV     DS,BX
  312.                MOV     BX,40H
  313.                MOV     ES,BX
  314.                CMP     AL,HOT_KEY_SCAN         ;Our hot key?
  315.                JNZ     CK_DISABLED
  316.  
  317.                MOV     AL,ES:[KB_FLAG]         ;Get keyboard shift status
  318.                TEST    AL,HOT_SHIFT_KEY
  319.                JZ      CK_DISABLED
  320.  
  321.                CLI
  322.                MOV     AX,ES:BUFFER_HEAD       ;Flush keyboard buffer.
  323.                MOV     ES:BUFFER_TAIL,AX
  324.                CMP     BLANK_SCREEN,ON         ;Screen already blanked?
  325.                JZ      LILLY_JMP
  326.                MOV     BLANK_IT,ON             ;If no, request blank.
  327. LILLY_JMP:     JMP     KEYBOARD_DONE
  328.  
  329. CK_DISABLED:   CMP     BLANK_SCREEN,ON
  330.                JNZ     RESET_TIMER
  331.                TEST    AL,80H                  ;Key release?
  332.                JNZ     KEYBOARD_DONE           ;If yes, ignore.
  333.                CMP     UNBLANK_FLAG,ON         ;Password required?
  334.                JNZ     DO_UNBLANK
  335.  
  336.                MOV     BX,CS
  337.                MOV     ES,BX
  338.                CLD
  339.                MOV     AH,1
  340.                INT     16H
  341.                JZ      KEYBOARD_DONE
  342.                XOR     AH,AH                   ;Get password.
  343.                INT     16H
  344.                MOV     DI,PASS_POINTER
  345.                CMP     AL,CR                   ;If carriage return, decode.
  346.                JZ      DECODE
  347.                CMP     DI,OFFSET DTA + PASSWORD_LEN
  348.                JAE     KEYBOARD_DONE
  349.  
  350.                CMP     AL,"a"                  ;Capitalize.
  351.                JB      DO_STORE
  352.                CMP     AL,"z"
  353.                JA      DO_STORE
  354.                AND     AL,5FH
  355.  
  356. DO_STORE:      XOR     AL,PASS_MASK            ;Encode.
  357.                STOSB
  358.                MOV     PASS_POINTER,DI
  359.                INC     PASS_MASK
  360.                JMP     SHORT KEYBOARD_DONE
  361.  
  362. DECODE:        STOSB                           ;Carriage return.
  363.                MOV     PASS_MASK,PASS_CODE
  364.                MOV     DI,OFFSET DTA
  365.                MOV     PASS_POINTER,DI
  366.                MOV     SI,OFFSET PASSWORD
  367.                PUSH    CX
  368.                MOV     CX,PASS_CNT
  369.                REPZ    CMPSB
  370.                POP     CX
  371.                JNZ     KEYBOARD_DONE           ;Valid password?
  372.                CMP     BYTE PTR [DI],CR
  373.                JNZ     KEYBOARD_DONE
  374.  
  375. DO_UNBLANK:    MOV     UNBLANK_IT,ON           ;Request unblank.
  376.                MOV     BX,40H
  377.                MOV     DS,BX
  378.                CLI
  379.                MOV     AX,DS:BUFFER_HEAD       ;Flush keyboard buffer.
  380.                MOV     DS:BUFFER_TAIL,AX
  381.                JMP     SHORT KEYBOARD_DONE
  382.  
  383. RESET_TIMER:   MOV     AX,TIME_OUT             ;Reset time-out.
  384.                MOV     COUNTER,AX
  385.  
  386. KEYBOARD_DONE: POP     ES
  387.                POP     DS
  388.                POP     DI
  389.                POP     SI
  390.                POP     BX
  391. KEYBOARD_END:  POP     AX
  392.                IRET
  393.  
  394. KEYBOARD       ENDP
  395.  
  396. ;------------------------------------------------------------------------------
  397. ;Interrupt 8 handling routine.
  398. ;------------------------------------------------------------------------------
  399.  
  400. TIMER          PROC    NEAR
  401.                CLI
  402.                PUSHF
  403.                CALL    CS:DWORD PTR OLD8
  404.                CMP     CS:BLANK_FLAG,OFF       ;Blanking active?
  405.                JZ      TIMER_END
  406.  
  407.                PUSH    AX
  408.                PUSH    DS
  409.                MOV     AX,CS
  410.                MOV     DS,AX
  411.  
  412.                CMP     TIMER_BUSY,0
  413.                JNZ     TIMER_DONE
  414.                INC     TIMER_BUSY
  415.  
  416.                CLD
  417.                CMP     UNBLANK_IT,ON           ;Request to unblank?
  418.                JZ      ENABLE
  419.                CMP     BLANK_IT,ON             ;Request to blank?
  420.                JZ      DO_BLANK
  421.  
  422.                CMP     COUNTER,0               ;If timed-out, keep blanked.
  423.                JZ      KEEP_BLANK
  424.                DEC     COUNTER                 ;Else, decrement counter.
  425.                JNZ     TIMER_EXIT
  426.  
  427. DO_BLANK:      CALL    BLANK
  428.                JMP     SHORT TIMER_EXIT
  429.  
  430. ENABLE:        CALL    UNBLANK
  431.                JMP     SHORT TIMER_EXIT
  432.  
  433. KEEP_BLANK:    CALL    BLANK_MODE
  434.  
  435. TIMER_EXIT:    CLI
  436.                DEC     TIMER_BUSY
  437.  
  438. TIMER_DONE:    POP     DS
  439.                POP     AX
  440.  
  441. TIMER_END:     IRET
  442.  
  443. TIMER          ENDP
  444.  
  445. ;----------------------------------------------;
  446.  
  447. BLANK:         MOV     BLANK_IT,OFF            ;Turn off blank request.
  448.                PUSH    ES
  449.                PUSH    BX
  450.                PUSH    CX
  451.                PUSH    DX
  452.                MOV     AX,40H
  453.                MOV     ES,AX
  454.  
  455.                MOV     AL,ES:[CRT_MODE]
  456.                CMP     GRAPHIC_APPS,ON         ;Blank graphics modes?
  457.                JNZ     CK_TYPE
  458.                CMP     AL,7                    ;Mono?
  459.                JZ      CK_TYPE
  460.                CMP     AL,3                    ;Text?
  461.                JBE     CK_TYPE
  462.                MOV     AX,TIME_OUT
  463.                MOV     COUNTER,AX
  464.                JMP     BLANK_END
  465.  
  466. CK_TYPE:       MOV     BLANK_SCREEN,ON         ;Note screen will be blanked.
  467.                MOV     COUNTER,0
  468.                STI
  469.  
  470.                CMP     BLANK_FLAG,HARD_BLANK   ;Hardware blank?
  471.                JZ      DO_HARDWARE
  472.                CMP     AL,3                    ;Text mode?
  473.                JA      DO_HARDWARE
  474.                CMP     ES:BYTE PTR [ACTIVE_PAGE],0
  475.                JNZ     DO_HARDWARE
  476.                CMP     ES:WORD PTR CRT_COLS,80
  477.                JA      DO_HARDWARE
  478.                PUSH    BP
  479.                PUSH    ES
  480.                MOV     DL,24                   ;25 rows?
  481.                MOV     AX,1130H
  482.                INT     10H
  483.                POP     ES
  484.                POP     BP
  485.                CMP     DL,24
  486.                JA      DO_HARDWARE
  487.  
  488.                CALL    SAVE_SCREEN             ;Software blank.
  489.                MOV     BLANK_TYPE,SOFTWARE
  490.                JMP     SHORT BLANK_END
  491.  
  492. DO_HARDWARE:   MOV     BL,10H                  ;Ega or Vga?
  493.                MOV     AH,12H
  494.                INT     10H
  495.                CMP     BL,10H
  496.                JZ      CGA_OR_MONO
  497.                TEST    ES:BYTE PTR [EGA_INFO],EGA_ACTIVE
  498.                JNZ     CGA_OR_MONO
  499.  
  500.                CLI
  501.                MOV     DX,3BAH                 ;Status register; read to
  502.                IN      AL,DX                   ; initialize address register.
  503.                ADD     DX,20H
  504.                IN      AL,DX
  505.                SUB     DX,1AH                  ;Attribute address register. 3C0h
  506.                XOR     AL,AL                   ; Turn bit 5 off; palette address
  507.                OUT     DX,AL                   ; source.
  508.                MOV     BLANK_TYPE,EGA_VGA
  509.                JMP     SHORT BLANK_END
  510.  
  511. CGA_OR_MONO:   CLI
  512.                MOV     BLANK_TYPE,CGA_MONO
  513.                MOV     DX,ES:[ADDR_6845]
  514.                ADD     DX,4                    ;Control register.
  515.                MOV     AL,ES:[CRT_MODE_SET]    ;Get current setting.
  516.                AND     AL,NOT VIDEO_SIGNAL     ;Turn off video bit.
  517.                OUT     DX,AL
  518.                MOV     ES:[CRT_MODE_SET],AL    ;Save this setting.
  519.                CMP     BYTE PTR ES:[CRT_MODE],3  ;Text?
  520.                JA      BLANK_END
  521.                MOV     AL,ES:[CRT_PALETTE]
  522.                MOV     SAVE_PALETTE,AL
  523.                INC     DX                      ;Color select register.
  524.                AND     AL,NOT 1111B            ;Turn off border.
  525.                OUT     DX,AL
  526.  
  527. BLANK_END:     STI
  528.                POP     DX
  529.                POP     CX
  530.                POP     BX
  531.                POP     ES
  532.                RET
  533.  
  534. ;----------------------------------------------;
  535.  
  536. UNBLANK:       MOV     UNBLANK_IT,OFF          ;Turn off unblank request.
  537.                MOV     BLANK_SCREEN,OFF
  538.                MOV     AX,TIME_OUT
  539.                MOV     COUNTER,AX
  540.                STI
  541.  
  542.                PUSH    ES
  543.                PUSH    DX
  544.  
  545.                CMP     BLANK_TYPE,SOFTWARE
  546.                JZ      UNBLANK_SOFT
  547.                CMP     BLANK_TYPE,CGA_MONO
  548.                JZ      UNBLANK_CGA
  549.  
  550.                CLI
  551.                MOV     DX,3BAH                 ;Ega, Vga unblank.
  552.                IN      AL,DX                   ;Initialize address register.
  553.                ADD     DX,20H
  554.                IN      AL,DX
  555.                SUB     DX,1AH
  556.                MOV     AL,100000B              ;Enable video signal.
  557.                OUT     DX,AL
  558.                JMP     SHORT UNBLANK_END
  559.  
  560. UNBLANK_CGA:   MOV     AX,40H
  561.                MOV     ES,AX
  562.                MOV     DX,ES:[ADDR_6845]
  563.                ADD     DX,4
  564.                CLI
  565.                MOV     AL,ES:[CRT_MODE_SET]
  566.                OR      AL,VIDEO_SIGNAL         ;Enable video signal.
  567.                OUT     DX,AL
  568.                MOV     ES:[CRT_MODE_SET],AL
  569.                CMP     ES:BYTE PTR ES:[CRT_MODE],3
  570.                JA      UNBLANK_END
  571.                MOV     AL,SAVE_PALETTE
  572.                INC     DX
  573.                OUT     DX,AL                   ;Enable border.
  574.                JMP     SHORT UNBLANK_END
  575.  
  576. UNBLANK_SOFT:  CALL    RESTORE_SCREEN
  577.  
  578. UNBLANK_END:   STI
  579.                POP     DX
  580.                POP     ES
  581.                RET
  582.  
  583. ;----------------------------------------------;
  584.  
  585. BLANK_MODE:    CMP     BLANK_TYPE,SOFTWARE
  586.                JZ      BOUNCE_BALL
  587.                JMP     BLANK
  588.  
  589. ;----------------------------------------------;
  590.  
  591. SOFT_CODE      LABEL   BYTE
  592.  
  593. COUNT          DW      ?
  594. PAUSE_CNT      DW      ?
  595.  
  596. OLD_X          DW      0
  597. X_POS          DW      0
  598. Y_POS          DW      0
  599. DELTA_X        DB      56
  600. DELTA_Y        DB      56
  601. X_DIR          DW      +1
  602. Y_DIR          DW      +1
  603. ERROR_TERM     DB      0
  604. SPIN_DIR       DB      +1
  605.  
  606. X_MAX          EQU     319 - 7
  607. Y_MAX          EQU     199 - 6
  608. SPIN_MIN       EQU     6
  609. SPIN_MAX       EQU     106
  610.  
  611. BALL           DB      00000000B, 00000000B, 00000000B, 00000000B
  612. BALL_START     LABEL   BYTE
  613. BALL_WIDTH     EQU     $ - BALL
  614.                DB      00000001B, 01010100B, 00000000B, 00000000B
  615.                DB      00000101B, 01010101B, 00000000B, 00000000B
  616.                DB      00010101B, 01010101B, 01000000B, 00000000B
  617.                DB      00010101B, 01010101B, 01000000B, 00000000B
  618.                DB      00000101B, 01010101B, 00000000B, 00000000B
  619.                DB      00000001B, 01010100B, 00000000B, 00000000B
  620. BALL_END       LABEL   BYTE
  621. BALL_IMAGE     EQU     $ - BALL_START
  622.                DB      00000000B, 00000000B, 00000000B, 00000000B
  623. BALL_LEN       EQU     $ - BALL
  624.  
  625.  
  626. BOUNCE_BALL:   STI
  627.                PUSH    ES
  628.                PUSH    BX
  629.                PUSH    CX
  630.                PUSH    DX
  631.                PUSH    SI
  632.                PUSH    DI
  633.  
  634.                MOV     AX,CS
  635.                MOV     ES,AX
  636.  
  637. ; Bresenham's line drawing algorithm.
  638.  
  639.                MOV     BX,X_POS
  640.                MOV     DX,Y_POS
  641.                MOV     CL,ERROR_TERM
  642.                MOV     AH,DELTA_X
  643.                MOV     AL,DELTA_Y
  644.                CMP     AH,AL
  645.                JB      STEEP
  646.  
  647.                ADD     BX,X_DIR
  648.                JNS     CK_X_MAX
  649.                INC     BX
  650.                INC     BX
  651.                JMP     SHORT NEG_X_DIR
  652. CK_X_MAX:      CMP     BX,X_MAX
  653.                JB      STORE_X
  654.                DEC     BX
  655.                DEC     BX
  656. NEG_X_DIR:     NEG     X_DIR
  657.                CALL    SPIN
  658. STORE_X:       MOV     X_POS,BX
  659.  
  660.                ADD     CL,AL
  661.                MOV     CH,AH
  662.                SHR     CH,1
  663.                CMP     CL,CH
  664.                JBE     SAVE_ERROR
  665.                SUB     CL,AH
  666.  
  667.                ADD     DX,Y_DIR
  668.                JNS     CK_Y_MAX
  669.                INC     DX
  670.                INC     DX
  671.                JMP     SHORT NEG_Y_DIR
  672. CK_Y_MAX:      CMP     DX,Y_MAX
  673.                JB      STORE_Y
  674.                DEC     DX
  675.                DEC     DX
  676. NEG_Y_DIR:     NEG     Y_DIR
  677.                CALL    SPIN
  678. STORE_Y:       MOV     Y_POS,DX
  679.  
  680. SAVE_ERROR:    MOV     ERROR_TERM,CL
  681.                JMP     SHORT CALC_POS
  682.  
  683. ;----------------;
  684.  
  685. STEEP:         ADD     DX,Y_DIR
  686.                JNS     CK_Y_MAX2
  687.                INC     DX
  688.                INC     DX
  689.                JMP     SHORT NEG_Y_DIR2
  690. CK_Y_MAX2:     CMP     DX,Y_MAX
  691.                JB      STORE_Y2
  692.                DEC     DX
  693.                DEC     DX
  694. NEG_Y_DIR2:    NEG     Y_DIR
  695.                CALL    SPIN
  696.  
  697. STORE_Y2:      MOV     Y_POS,DX
  698.  
  699.                ADD     CL,AH
  700.                MOV     CH,AL
  701.                SHR     CH,1
  702.                CMP     CL,CH
  703.                JBE     SAVE_ERROR2
  704.                SUB     CL,AL
  705.  
  706.                ADD     BX,X_DIR
  707.                JNS     CK_X_MAX2
  708.                INC     BX
  709.                INC     BX
  710.                JMP     SHORT NEG_X_DIR2
  711. CK_X_MAX2:     CMP     BX,X_MAX
  712.                JB      STORE_X2
  713.                DEC     BX
  714.                DEC     BX
  715. NEG_X_DIR2:    NEG     X_DIR
  716.                CALL    SPIN
  717. STORE_X2:      MOV     X_POS,BX
  718.  
  719. SAVE_ERROR2:   MOV     ERROR_TERM,CL
  720.  
  721. ;----------------;
  722.  
  723. CALC_POS:      XOR     DI,DI
  724.                MOV     CX,DX
  725.                SHR     CX,1
  726.                JCXZ    DO_Y
  727. NEXT_X:        ADD     DI,80                   ;Row address.
  728.                LOOP    NEXT_X
  729.  
  730. DO_Y:          MOV     AX,BX
  731.                AND     AX,NOT 3
  732.                SHR     AX,1
  733.                SHR     AX,1
  734.                ADD     AX,DI                   ;Column address.
  735.  
  736.                CMP     BX,OLD_X                ;Did column move?
  737.                MOV     OLD_X,BX
  738.                JZ      MOVE_BALL
  739.                CMP     X_DIR,+1                ;Direction of move.
  740.                JNZ     REVERSE
  741.                MOV     SI,OFFSET BALL_START
  742.                MOV     BX,BALL_IMAGE - BALL_WIDTH
  743.  
  744. NEXT_ROTATE:   SHR     BYTE PTR [SI+BX],1      ;Shift two pixels right.
  745.                RCR     BYTE PTR [SI+BX+1],1
  746.                RCR     BYTE PTR [SI+BX+2],1
  747.                RCR     BYTE PTR [SI+BX+3],1
  748.                SHR     BYTE PTR [SI+BX],1
  749.                RCR     BYTE PTR [SI+BX+1],1
  750.                RCR     BYTE PTR [SI+BX+2],1
  751.                RCR     BYTE PTR [SI+BX+3],1
  752.                SUB     BX,BALL_WIDTH
  753.                JNC     NEXT_ROTATE
  754.  
  755.                TEST    X_POS,3                 ;MOD 4 move pixels back a word.
  756.                JNZ     MOVE_BALL
  757.                MOV     DI,SI
  758.                INC     SI
  759.                MOV     CX,BALL_IMAGE
  760.                REP     MOVSB
  761.                JMP     SHORT MOVE_BALL
  762.  
  763. REVERSE:       AND     BX,3                    ;MOD 4, copy first.
  764.                CMP     BX,3
  765.                JNZ     SHIFT_REVERSE
  766.                MOV     DI,OFFSET BALL_END - 1
  767.                MOV     SI,DI
  768.                DEC     SI
  769.                STD
  770.                MOV     CX,BALL_IMAGE
  771.                REP     MOVSB
  772.                CLD
  773.  
  774. SHIFT_REVERSE: MOV     SI,OFFSET BALL_START
  775.                MOV     BX,BALL_IMAGE - BALL_WIDTH
  776. NEXT_REVERSE:  SHL     BYTE PTR [SI+BX+3],1
  777.                RCL     BYTE PTR [SI+BX+2],1    ;Shift two pixels left.
  778.                RCL     BYTE PTR [SI+BX+1],1
  779.                RCL     BYTE PTR [SI+BX],1
  780.                SHL     BYTE PTR [SI+BX+3],1
  781.                RCL     BYTE PTR [SI+BX+2],1
  782.                RCL     BYTE PTR [SI+BX+1],1
  783.                RCL     BYTE PTR [SI+BX],1
  784.                SUB     BX,BALL_WIDTH
  785.                JNC     NEXT_REVERSE
  786.  
  787. MOVE_BALL:     MOV     BX,AX                   ;Screen offset.
  788.                MOV     SI,OFFSET BALL
  789.                MOV     AX,0B800H               ;Screen segment.
  790.                MOV     ES,AX
  791.                MOV     DI,BX
  792.                TEST    DX,1                    ;Odd?
  793.                JZ      INTERLACE
  794.                ADD     DI,2000H
  795. INTERLACE:     MOV     CX,BALL_LEN / BALL_WIDTH / 2
  796. NEXT_LACE:     MOVSW
  797.                MOVSW
  798.                ADD     SI,BALL_WIDTH
  799.                ADD     DI,80 - BALL_WIDTH
  800.                LOOP    NEXT_LACE
  801.  
  802.                MOV     SI,OFFSET BALL + BALL_WIDTH
  803.                MOV     DI,BX
  804.                ADD     DI,2000H
  805.                TEST    DX,1
  806.                JZ      INTERLACE2
  807.                SUB     DI,2000H - 80
  808. INTERLACE2:    MOV     CX,BALL_LEN / BALL_WIDTH / 2
  809. NEXT_LACE2:    MOVSW
  810.                MOVSW
  811.                ADD     SI,BALL_WIDTH
  812.                ADD     DI,80 - BALL_WIDTH
  813.                LOOP    NEXT_LACE2
  814.  
  815.                POP     DI
  816.                POP     SI
  817.                POP     DX
  818.                POP     CX
  819.                POP     BX
  820.                POP     ES  
  821.  
  822.                MOV     AX,PAUSE_CNT            ;Reset pause.
  823.                MOV     COUNT,AX
  824. NEXT_PAUSE:    CMP     UNBLANK_IT,ON           ;If unblank request, exit.
  825.                JZ      BLANK_MODE_END
  826.                DEC     COUNT
  827.                JNZ     NEXT_PAUSE
  828.                JMP     BOUNCE_BALL
  829. BLANK_MODE_END:RET
  830.  
  831. ;----------------------------------------------;
  832.  
  833. SPIN:          MOV     CH,AH                   ;Delta x - delta y.
  834.                SUB     CH,AL
  835.  
  836.                ADD     AH,SPIN_DIR             ;Change delta x and y.
  837.                SUB     AL,SPIN_DIR
  838.                CMP     AH,SPIN_MIN             ;Check bounds.
  839.                JA      CK_SPIN
  840.                INC     AH
  841.                INC     AH
  842.                DEC     AL
  843.                DEC     AL
  844.                JMP     SHORT NEG_SPIN
  845. CK_SPIN:       CMP     AH,SPIN_MAX
  846.                JB      STORE_SPIN
  847.                DEC     AH
  848.                DEC     AH
  849.                INC     AL
  850.                INC     AL
  851. NEG_SPIN:      NEG     SPIN_DIR                ;Reverse direction.
  852.  
  853. STORE_SPIN:    MOV     DELTA_X,AH
  854.                MOV     DELTA_Y,AL
  855.                PUSH    AX
  856.                SUB     AH,AL                   ;Get difference and adjust
  857.                SUB     CH,AH
  858.                ADD     CL,CH                   ; error term.
  859.                POP     AX
  860.                RET
  861.  
  862. ;----------------------------------------------;
  863.  
  864. SAVE_SCREEN:   PUSH    DS
  865.                PUSH    SI
  866.                PUSH    DI
  867.                XOR     BH,BH
  868.                MOV     AH,3                    ;Get cursor mode and save.
  869.                INT     10H
  870.                MOV     CURSOR_MODE,CX
  871.                CALL    GET_CUR_ADDR
  872.                CALL    VIDEO_SETUP
  873.                MOV     AL,ES:[CRT_MODE]        ;Save video mode.
  874.                MOV     SAVE_MODE,AL
  875.                MOV     AX,ES:[CURSOR_POSN]     ;Cursor position.
  876.                MOV     CURSOR_POS,AX
  877.                MOV     DS,CX                   ;Video segment.
  878.                PUSH    CS
  879.                POP     ES
  880.                XOR     SI,SI
  881.                MOV     DI,OFFSET VIDEO_BUFFER
  882.                CALL    DO_SCREEN               ;Save screen contents.
  883.                MOV     AX,4                    ;CGA graphics video mode.
  884.                INT     10H
  885.                POP     DI
  886.                POP     SI
  887.                POP     DS
  888.                RET
  889.  
  890. ;----------------------------------------------;
  891.  
  892. RESTORE_SCREEN:PUSH    SI
  893.                PUSH    DI
  894.                PUSH    BX
  895.                PUSH    CX
  896.  
  897.                MOV     AL,SAVE_MODE            ;Restore video mode.
  898.                XOR     AH,AH
  899.                INT     10H
  900.                XOR     BH,BH                   ;Cursor position.
  901.                MOV     DX,CURSOR_POS
  902.                MOV     AH,2
  903.                INT     10H
  904.                MOV     CX,CURSOR_MODE          ;Cursor type.
  905.                MOV     AH,1
  906.                INT     10H
  907.  
  908.                MOV     AX,40H
  909.                MOV     ES,AX
  910.                MOV     DX,ES:[ADDR_6845]       ;Recover CRTC base address
  911.                MOV     CX,CURSOR_ADDR          ;Also, program registers
  912.                MOV     AL,14                   ; to cursor address for 1-2-3.
  913.                OUT     DX,AL
  914.                INC     DX
  915.                MOV     AL,CH
  916.                OUT     DX,AL
  917.                DEC     DX
  918.                MOV     AL,15
  919.                OUT     DX,AL
  920.                INC     DX
  921.                MOV     AL,CL
  922.                OUT     DX,AL
  923.  
  924.                CALL    VIDEO_SETUP
  925.                MOV     ES,CX
  926.                MOV     SI,OFFSET VIDEO_BUFFER
  927.                XOR     DI,DI
  928.                CALL    DO_SCREEN               ;Restore screen contents.
  929.  
  930.                POP     CX
  931.                POP     BX
  932.                POP     DI
  933.                POP     SI
  934.                RET
  935.  
  936. ;----------------------------------------------;
  937.  
  938. DO_SCREEN:     MOV     CX,80 * 25
  939.  
  940. HORZ_RET:      IN      AL,DX                   ;Get status.
  941.                RCR     AL,1                    ;Is it low?
  942.                JC      HORZ_RET                ;If not, wait until it is.
  943.                CLI                             ;No more interrupts.
  944.  
  945. HWAIT:         IN      AL,DX                   ;Get status.
  946.                RCR     AL,1                    ;Is it high?
  947.                JNC     HWAIT                   ;If no, wait until it is.
  948.  
  949.                MOVSW
  950.                STI                             ;Interrupts back on.
  951.                LOOP    HORZ_RET
  952.                RET                             ;Return
  953.  
  954. ;----------------------------------------------;
  955.  
  956. GET_CUR_ADDR:  MOV     AX,40H
  957.                MOV     ES,AX
  958.                MOV     DX,ES:[ADDR_6845]
  959.                MOV     AL,14
  960.                CLI
  961.                OUT     DX,AL
  962.                INC     DX
  963.                IN      AL,DX
  964.                MOV     AH,AL
  965.                DEC     DX
  966.                MOV     AL,15
  967.                OUT     DX,AL
  968.                INC     DX
  969.                IN      AL,DX
  970.                STI
  971.                MOV     CURSOR_ADDR,AX          ;Cursor address.
  972.                RET
  973.  
  974. ;----------------------------------------------;
  975. ; OUTPUT: DX = Status register; CX = Video segment.  ES -> BIOS data area.
  976.  
  977. VIDEO_SETUP:   MOV     AX,40H
  978.                MOV     ES,AX
  979.                MOV     DX,ES:[ADDR_6845]
  980.                ADD     DX,6
  981.                MOV     CX,0B000H
  982.                CMP     DL,0BAH                 ;Mono?
  983.                JZ      SETUP_END
  984.                ADD     CH,8
  985. SETUP_END:     RET
  986.  
  987. ;**********************************************;
  988. ;              End of resident code.           ;
  989. ;**********************************************;
  990.  
  991. VIDEO_SIZE     EQU     80 * 2 * 25
  992. VIDEO_BUFFER   LABEL   BYTE
  993. SOFT_STUFF     EQU     $ - SOFT_CODE + VIDEO_SIZE
  994.  
  995. RESIDENT_END   DW      SOFT_CODE
  996.  
  997. SYNTAX DB  "Syntax: Conceal [/P password] [filespec] [options]",CR,LF
  998.        DB  "/S = Conceal filespec attribute [ON | OFF]; default = ON",CR,LF
  999.        DB  "/F = File security toggle [ON | OFF]; default is ON",CR,LF
  1000.        DB  "/A = Attribute [+|-A] [+|-S] [+|-H] [+|-R]",CR,LF
  1001.        DB  "/N = New password",CR,LF
  1002.        DB  "/B = Hardware blank [nn][ON | OFF]",CR,LF
  1003.        DB  "/G = Graphic blank  [nn][ON | OFF]",CR,LF
  1004.        DB  "     nn = 0 - 60 minutes; 0 = OFF; default = 3 minutes, ON",CR,LF
  1005.        DB  "/O = Over-graphics blanking [ON | OFF]; default = ON",CR,LF
  1006.        DB  "/T = Password required to unblank [ON | OFF]; default = ON",CR,LF
  1007.        DB  "/H = Hotkey for immediate blank; Ctrl or Alt plus new hotkey",CR,LF
  1008.        DB  "     eg. /H Ctrl Y or /H Alt 1;  default is Alt Z",CR,LF
  1009.        DB  "/U = Uninstall",CR,LF,LF,"$"
  1010.  
  1011. NOT_INSTALLED  DB      "Conceal not installed",CR,LF,"$"
  1012. UNLOAD_MSG     DB      "Conceal can't be uninstalled",CR,LF
  1013.                DB      "Uninstall resident programs in reverse order",CR,LF
  1014.                DB      "Conceal and blank mode has been turn off.",CR,LF,"$"
  1015. NOT_ENOUGH     DB      "Not enough memory to install Conceal",CR,LF,"$"
  1016. ALLOCATE_MSG   DB      "Memory allocation error",CR,LF,BELL,"$"
  1017. INSTALL_MSG    DB      CR,LF,"Conceal installed",CR,LF,"$"
  1018. UNINSTALL_MSG  DB      CR,LF,"Conceal uninstalled",CR,LF,"$"
  1019.  
  1020. INVALID_MSG    DB      "Invalid syntax",CR,LF,"$"
  1021. PASS_MSG       DB      "Invalid password; Access denied",BELL,CR,LF,"$"
  1022. BUFFER_MSG     DB      "Can't allocate memory for Graphics blank once installed.",CR,LF
  1023.                DB      "/U(ninstall) and then reinstall with /G(raphics).",CR,LF,"$"
  1024. PERM_MSG       DB      "Make new password permanent?  Y/N $"
  1025.  
  1026. HOTKEY_MSG     DB      "Press $"
  1027. HOTKEY_MSG2    DB      " to immediately blank screen."
  1028. CR_LF          DB      CR,LF,"$"
  1029.  
  1030. WRONG_VERSION  DB      "Needs DOS 2.0 or later$"
  1031.  
  1032. CONCEAL_COM    DB      "CONCEAL.COM",0
  1033. CONCEAL_LEN    EQU     $ - CONCEAL_COM
  1034. NOT_FOUND      DB      "Could not find Conceal.com",CR,LF
  1035.                DB      "Conceal.com must be in current directory",CR,LF
  1036.                DB      "or in DOS PATH= directory.",CR,LF,"$"
  1037. PATH           DB      "PATH="
  1038. PATH_LEN       EQU     $ - PATH
  1039. WORKSPACE      DB      65 DUP (?)
  1040. ATTR_DTA       DB      SIZE MATCHING DUP (?)
  1041.  
  1042. PATH_END       DW      ?
  1043.  
  1044. NO_FILE        DB      "File not found",CR,LF,"$"
  1045.  
  1046. SCAN_CODES LABEL BYTE
  1047.  
  1048. DB "1",2,"2",3,"3",4,"4",5,"5",6,"6",7,"7",8,"8",9,"9",0AH,"0",0BH,"-",0CH
  1049. DB "=",0DH,"Q",10H,"W",11H,"E",12H,"R",13H,"T",14H,"Y",15H,"U",16H,"I",17H
  1050. DB "O",18H,"P",19H,"[",1AH,"]",1BH,"A",1EH,"S",1FH,"D",20H,"F",21H,"G",22H
  1051. DB "H",23H,"J",24H,"K",25H,"L",26H,";",27H,39,28H,96,29H,"\",2BH,"Z",2CH
  1052. DB "X",2DH,"C",2EH,"V",2FH,"B",30H,"N",31H,"M",32H,",",33H,".",34H,"/",35H
  1053.  
  1054. SCAN_COUNT     EQU     ($ - SCAN_CODES) / 2
  1055.  
  1056. TSR_SEGMENT    DW      ?
  1057. SYNTAX_FLAG    DB      0                       ; = 1 if syntax to be displayed.
  1058.  
  1059. INSTALL_FLAG   DB      0                       ; = 1 if should install.
  1060. PASS_FLAG      DB      0                       ; = 1 if correct password.
  1061. COM_FILESPEC   DW      0                       ; non-zero if filespec found.
  1062.  
  1063. AND_BITS       DB      ?                       ;Attributes.
  1064. OR_BITS        DB      ?
  1065. CONCEALED      DB      TAB,"Concealed",CR,LF,"$"
  1066. UNCONCEALED    DB      TAB,"Unconcealed",CR,LF,"$"
  1067.  
  1068. ALT            DB      " Alt $"
  1069. CTRL           DB      "Ctrl $"
  1070. ALT_CAPS       DB      "ALT"
  1071. CTRL_CAPS      DB      "CTRL"
  1072.  
  1073. SPACES         DB      9 DUP (SPACE), "$"
  1074. ATTR_NAMES     DB      "Archive  $System   $Hidden   $Read-Only$"
  1075.  
  1076. OPTIONS        DB      "PSFANBGOTHU"
  1077. OPTIONS_LEN    EQU     $ - OPTIONS
  1078. OPTIONS_CALLS  DW      PASS, CONCEAL, FILE_CONCEAL, ATTR, NEW_PASS, HARD, SOFT
  1079.                DW      DONT_BLANK, CONCEAL_BLANK, CHANGE_HOT, UNINSTALL
  1080. OPTIONS_END    EQU     $ - 2
  1081.  
  1082. ;----------------------------------------------;
  1083.  
  1084. INITIALIZE     PROC    NEAR
  1085.                CLD                             ;All string operations forward.
  1086.  
  1087.                MOV     DX,OFFSET ATTR_DTA      ;Set up DTA.
  1088.                MOV     AH,1AH
  1089.                INT     21H
  1090.  
  1091.                MOV     BX,OFFSET SIGNATURE     ;Point to start of code.
  1092.                NOT     BYTE PTR [BX]           ;Change a byte so no false match.
  1093.                MOV     AX,CS                   ;Store our segment in AX.
  1094.                MOV     DX,0A000H - 1
  1095. NEXT_PARAG:    INC     DX                      ;Next paragraph.
  1096.                MOV     ES,DX
  1097.                CMP     DX,AX                   ;Is it our segment?
  1098.                JZ      ANNOUNCE                ;If yes, search is done.
  1099.                MOV     SI,BX                   ;Else, point to our signature.
  1100.                MOV     DI,BX                   ; and offset of possible match.
  1101.                MOV     CX,16                   ;Check 16 bytes for match.
  1102.                REP     CMPSB
  1103.                JNZ     NEXT_PARAG              ;If no match, keep looking.
  1104.  
  1105. ;----------------------------------------------;
  1106.  
  1107. ANNOUNCE:      MOV     TSR_SEGMENT,ES
  1108.                MOV     DX,OFFSET SIGNATURE + 1 ;Display our signature.
  1109.                CALL    PRINT_STRING
  1110.  
  1111.                MOV     SI,81H                  ;Point to command line.
  1112. NEXT_CAP:      LODSB                           ;Capitalize parameters.
  1113.                CMP     AL,CR
  1114.                JZ      PARSE
  1115.                CMP     AL,"a"
  1116.                JB      NEXT_CAP
  1117.                CMP     AL,"z"
  1118.                JA      NEXT_CAP
  1119.                AND     BYTE PTR [SI - 1],5FH
  1120.                JMP     SHORT NEXT_CAP
  1121.  
  1122. ;----------------------------------------------;
  1123.  
  1124. PARSE:         MOV     SI,81H                  ;Point to command line again.
  1125. NEXT_PARSE:    CALL    FIND_START
  1126.                LODSB
  1127.                CMP     AL,CR
  1128.                JZ      CK_INSTALL
  1129.                CMP     AL,"/"
  1130.                JNZ     FOUND_FILESPEC
  1131.                MOV     SYNTAX_FLAG,1           ;Parameter found; no need to
  1132.                LODSB                           ; display syntax, unless error
  1133.                PUSH    CS                      ; found.
  1134.                POP     ES
  1135.                MOV     DI,OFFSET OPTIONS
  1136.                MOV     CX,OPTIONS_LEN          ;Command line options.
  1137.                REPNZ   SCASB
  1138.                MOV     DX,OFFSET INVALID_MSG   ;Exit if invalid.
  1139.                JNZ     MSG_EXIT
  1140.                CALL    FIND_START
  1141.                SHL     CX,1
  1142.                MOV     DI,OFFSET OPTIONS_END
  1143.                SUB     DI,CX
  1144.                CALL    [DI]                    ;Process option.
  1145.                JMP     NEXT_PARSE
  1146.  
  1147. FOUND_FILESPEC:DEC     SI                      ;If not "/", then gotta be
  1148.                MOV     COM_FILESPEC,SI         ; filespec.
  1149.                CALL    FIND_END
  1150.                JMP     NEXT_PARSE
  1151.  
  1152. ;-------------------------------------------------------------------;
  1153. ; Exit.  Return ERRORLEVEL code 0 if successful, 1 if unsuccessful. ;
  1154. ;-------------------------------------------------------------------;
  1155.  
  1156. MSG_EXIT:      PUSH    DX
  1157.                MOV     DX,OFFSET SYNTAX        ;Display syntax if error.
  1158.                CALL    PRINT_STRING
  1159.                POP     DX                      ;Display error.
  1160.                CALL    PRINT_STRING
  1161. ERROR_EXIT:    MOV     AL,1                    ;ERRORLEVEL = 1.
  1162.                JMP     SHORT TERMINATE
  1163.  
  1164. GOOD_EXIT:     CMP     SYNTAX_FLAG,1
  1165.                JZ      DO_HOT
  1166.                MOV     DX,OFFSET SYNTAX        ;And syntax.
  1167.                CALL    PRINT_STRING
  1168. DO_HOT:        CALL    DISP_HOTKEY             ;Display hot key if blank active.
  1169.                XOR     AL,AL                   ;ERRORLEVEL = 0.
  1170. TERMINATE:     MOV     AH,4CH                  ;Terminate.
  1171.                INT     21H
  1172.  
  1173. ;----------------------------------------------;
  1174.  
  1175. CK_INSTALL:    CMP     INSTALL_FLAG,1          ;Function requiring installation
  1176.                JNZ     GOOD_EXIT               ; selected?
  1177.                CALL    CK_INSTALLED            ;Are we already installed?
  1178.                JNZ     GOOD_EXIT
  1179.  
  1180. ;----------------------------------------------;
  1181.  
  1182. CK_AVAILABLE:  PUSH    CS
  1183.                POP     ES
  1184.                MOV     AH,49H
  1185.                INT     21H
  1186.  
  1187.                MOV     BX,0FFFFH
  1188.                MOV     AH,4AH
  1189.                INT     21H
  1190.  
  1191.                MOV     AX,RESIDENT_END
  1192.                ADD     AX,15                   ;Round up.
  1193.                MOV     CL,4
  1194.                SHR     AX,CL                   ;Convert to paragraphs.
  1195.                CMP     BX,AX
  1196.                JAE     GET_VERSION
  1197.  
  1198.                MOV     DX,OFFSET NOT_ENOUGH    ;Exit if not enough
  1199.                JMP     MSG_EXIT                ; with message.
  1200.  
  1201. GET_VERSION:   MOV     AH,30H                  ;Get DOS version
  1202.                INT     21H
  1203.                CMP     AL,2
  1204.                JAE     GET_VECTORS
  1205.                MOV     DX,OFFSET WRONG_VERSION ;If not DOS 2 or above, exit.
  1206.                JMP     MSG_EXIT
  1207.  
  1208. GET_VECTORS:   MOV     AX,3508H                ;INT 8
  1209.                INT     21H
  1210.                MOV     OLD8[0],BX
  1211.                MOV     OLD8[2],ES
  1212.                MOV     DX,OFFSET TIMER         ;Install new interrupt.
  1213.                MOV     AX,2508H
  1214.                INT     21H
  1215.  
  1216.                CALL    SETUP_TIME              ;Pause count for software blank.
  1217.  
  1218.                MOV     AX,3521H                ;Get INT 21 interrupt.
  1219.                INT     21H
  1220.                MOV     OLD21[0],BX             ;Save old interrupt.
  1221.                MOV     OLD21[2],ES
  1222.                MOV     DX,OFFSET DOS           ;Install new interrupt.
  1223.                MOV     AX,2521H
  1224.                INT     21H
  1225.  
  1226.                MOV     AX,3509H                ;Get INT 9 vector.
  1227.                INT     21H
  1228.                MOV     OLD9[0],BX              ;Save old interrupt.
  1229.                MOV     OLD9[2],ES
  1230.                MOV     DX,OFFSET KEYBOARD      ;Install new interrupt.
  1231.                MOV     AX,2509H
  1232.                INT     21H
  1233.  
  1234.                MOV     AX,DS:[2CH]             ;Get environment segment.
  1235.                MOV     ES,AX
  1236.                MOV     AH,49H                  ;Free up environment.
  1237.                INT     21H
  1238.  
  1239.                MOV     DX,OFFSET INSTALL_MSG   ;Display install message.
  1240.                CALL    PRINT_STRING
  1241.                CALL    DISP_HOTKEY
  1242.  
  1243.                MOV     DX,RESIDENT_END
  1244.                ADD     DX,15                   ;Round up.
  1245.                MOV     CL,4
  1246.                SHR     DX,CL                   ;Convert to paragraphs.
  1247.                MOV     AX,3100H                ;Return error code of zero.
  1248.                INT     21H                     ;Terminate but stay resident.
  1249.  
  1250. ;----------------------------------------------;
  1251.  
  1252. SETUP_TIME:    PUSH    WORD PTR BLANK_FLAG
  1253.                MOV     BLANK_FLAG,ON
  1254.                XOR     CX,CX
  1255.                MOV     AX,COUNTER
  1256. GET_START:     MOV     BX,COUNTER              ;Wait till start of a count.
  1257.                CMP     BX,AX
  1258.                JZ      GET_START
  1259. GET_TIME:      INC     CX                      ;Get loops for one tick.
  1260.                MOV     AX,COUNTER
  1261.                CMP     AX,BX
  1262.                JZ      GET_TIME
  1263.                SHR     CX,1                    ;Adjust for delay loop.
  1264.                SHR     CX,1
  1265.                SHR     CX,1
  1266.                SHR     CX,1
  1267.                MOV     COUNT,CX
  1268.                MOV     PAUSE_CNT,CX
  1269.                POP     WORD PTR BLANK_FLAG
  1270.                RET
  1271.  
  1272. ;----------------------------------------------;
  1273.  
  1274. PASS:          MOV     DX,SI
  1275.                MOV     ES,TSR_SEGMENT
  1276.                MOV     AH,PASS_CODE
  1277.                MOV     CX,ES:PASS_CNT
  1278. NEXT_PASS:     LODSB                           ;Get password.
  1279.                CMP     AL,SPACE
  1280.                JBE     DECODE2
  1281.                CMP     AL,"/"
  1282.                JZ      DECODE2
  1283.                XOR     [SI-1],AH
  1284.                INC     AH
  1285.                LOOP    NEXT_PASS
  1286.                JMP     SHORT DECODE3
  1287.  
  1288. DECODE2:       DEC     SI
  1289. DECODE3:       PUSH    SI
  1290.                MOV     SI,DX
  1291.                MOV     DI,OFFSET PASSWORD
  1292.                MOV     CX,ES:PASS_CNT
  1293.                REPZ    CMPSB                   ;Does it match?
  1294.                JNZ     BAD_PASS
  1295.                LODSB
  1296.                CMP     AL,SPACE
  1297.                JBE     PASS_END
  1298.                CMP     AL,"/"
  1299.                JZ      PASS_END
  1300. BAD_PASS:      MOV     DX,OFFSET PASS_MSG
  1301.                JMP     MSG_EXIT
  1302.  
  1303. PASS_END:      MOV     PASS_FLAG,1             ;Password valid.
  1304.                POP     SI
  1305.                RET
  1306.  
  1307. ;----------------------------------------------;
  1308.  
  1309. CONCEAL:       MOV     ES,TSR_SEGMENT
  1310.                CALL    CK_ON_OFF               ;Check for ON or OFF.
  1311.                MOV     BP,ES:CONCEAL_FLAG
  1312.                MOV     ES:CONCEAL_FLAG,OFF     ;OFF so attributes can change.
  1313.  
  1314.                MOV     AND_BITS,4              ;System attribute.
  1315.                MOV     OR_BITS,0
  1316.                CMP     BL,OFF                  ;Turn it off?
  1317.                JZ      CONCEAL_PASS            ;If yes, need password.
  1318.                MOV     AND_BITS,0
  1319.                MOV     OR_BITS,4               ;System attribute ON.
  1320.                MOV     BP,BX
  1321.                MOV     INSTALL_FLAG,1          ;Need to install.
  1322.                JMP     SHORT CK_FILESPEC
  1323.  
  1324. CONCEAL_PASS:  CALL    CK_PASSWORD
  1325.  
  1326. CK_FILESPEC:   MOV     DX,COM_FILESPEC         ;Filespec?
  1327.                OR      DX,DX
  1328.                JZ      SAVE_CONCEAL            ;If no, just set security state.
  1329.  
  1330.                PUSH    SI
  1331.                MOV     CHANGE_FLAG,ON          ;Make a change to attributes.
  1332.                MOV     STATS_FLAG,CONCEAL_STATS ;Display secure message.
  1333.                CALL    ATTRIBUTES
  1334.  
  1335. CONCEAL_END:   MOV     ES,TSR_SEGMENT
  1336.                MOV     ES:CONCEAL_FLAG,BP      ;Restore security state.
  1337.                POP     SI
  1338.                RET
  1339.  
  1340. ;----------------------------------------------;
  1341.  
  1342. FILE_CONCEAL:  MOV     ES,TSR_SEGMENT
  1343.                CALL    CK_ON_OFF
  1344.                CMP     BL,ON
  1345.                JZ      SAVE_CONCEAL
  1346.                CALL    CK_PASSWORD
  1347.  
  1348. SAVE_CONCEAL:  MOV     ES,TSR_SEGMENT
  1349.                MOV     ES:CONCEAL_FLAG,BX      ;New security state; ON or OFF.
  1350.                CMP     BL,ON
  1351.                JNZ     FILE_END
  1352.                MOV     INSTALL_FLAG,1          ;Install if ON.
  1353. FILE_END:      RET
  1354.  
  1355. ;----------------------------------------------;
  1356.  
  1357. ATTRIBUTES:    PUSH    CS
  1358.                POP     ES
  1359.                MOV     DI,OFFSET WORKSPACE     ;Find delimiters in filespec.
  1360.                MOV     PATH_END,DI
  1361.                MOV     DX,COM_FILESPEC
  1362.                MOV     SI,DX
  1363. NEXT_ASCII:    LODSB
  1364.                STOSB
  1365.                CMP     AL,SPACE
  1366.                JBE     ASCII_END
  1367.                CMP     AL,"/"
  1368.                JZ      ASCII_END
  1369.                CMP     AL,":"
  1370.                JZ      FOUND_DELIMIT
  1371.                CMP     AL,"\"
  1372.                JNZ     NEXT_ASCII
  1373. FOUND_DELIMIT: MOV     PATH_END,DI
  1374.                JMP     NEXT_ASCII
  1375. ASCII_END:     MOV     BYTE PTR [SI - 1],0
  1376.  
  1377.                NOT     AND_BITS                ;Flip NOT bits.
  1378.  
  1379.                MOV     CX,7H
  1380.                MOV     AH,4EH                  ;Find first.
  1381.                INT     21H
  1382.                JNC     DISPLAY_NAME
  1383.                MOV     DX,OFFSET NO_FILE       ;Exit if none.
  1384.                JMP     MSG_EXIT
  1385.  
  1386. ;-----------------------;
  1387.  
  1388. DISPLAY_NAME:  MOV     SI,OFFSET ATTR_DTA.FILE_NAME
  1389.                MOV     DI,PATH_END             ;Add filename to path, if any.
  1390.                MOV     CX,14
  1391. NEXT_NAME2:    LODSB
  1392.                STOSB
  1393.                OR      AL,AL
  1394.                JZ      PAD_NAME
  1395.                CALL    PRINT_CHAR              ;Print name.
  1396.                LOOP    NEXT_NAME2
  1397.  
  1398. PAD_NAME:      MOV     AL,SPACE                ;Tab over 14.
  1399.                CALL    PRINT_CHAR
  1400.                LOOP    PAD_NAME
  1401.  
  1402.                MOV     DX,OFFSET WORKSPACE
  1403.                CMP     CHANGE_FLAG,ON          ;Change attributes?
  1404.                JNZ     DO_STATS
  1405.  
  1406. CHANGE_ATTR:   MOV     CL,[ATTR_DTA.ATTRIBUTE]
  1407.                AND     CL,AND_BITS             ;Turn off some bits.
  1408.                OR      CL,OR_BITS              ;Turn on some bits.
  1409.                XOR     CH,CH
  1410.                MOV     AX,4301H                ;Change File Mode.
  1411.                INT     21H
  1412.                JC      ATTRS_END
  1413.  
  1414. DO_STATS:      CALL    DISPLAY_STATS           ;Display status message.
  1415.                MOV     AH,4FH                  ;Find next.
  1416.                INT     21H
  1417.                JNC     DISPLAY_NAME            ;Display it.
  1418. ATTRS_END:     RET
  1419.  
  1420. ;----------------------------------------------;
  1421.  
  1422. DISPLAY_STATS: CMP     STATS_FLAG,CONCEAL_STATS ;Secure stats or attribute stats?
  1423.                JZ      STATS2
  1424.  
  1425. STATS1:        MOV     AX,4300H                ;Get attribute.
  1426.                INT     21H
  1427.                MOV     AL,TAB
  1428.                CALL    PRINT_CHAR
  1429.  
  1430.                MOV     BL,CL
  1431.                SHL     BL,1
  1432.                SHL     BL,1
  1433.                MOV     CX,4                    ;Four attributes.
  1434.                XOR     DI,DI
  1435.  
  1436. NEXT_STAT:     CMP     CX,3                    ;Skip volume and directory bits.
  1437.                JNZ     GET_BIT
  1438.                SHL     BL,1
  1439.                SHL     BL,1
  1440. GET_BIT:       MOV     DX,OFFSET SPACES        ;Assume it's off.
  1441.                SHL     BL,1
  1442.                JNC     DISPLAY_BIT
  1443.                MOV     DX,OFFSET ATTR_NAMES    ;Else, display the one that's on.
  1444.                ADD     DX,DI
  1445. DISPLAY_BIT:   CALL    PRINT_STRING
  1446.                ADD     DI,10
  1447.                LOOP    NEXT_STAT
  1448.                MOV     DX,OFFSET CR_LF         ;New line.
  1449.                CALL    PRINT_STRING
  1450.                JMP     SHORT STATS_END
  1451.  
  1452. STATS2:        MOV     DX,OFFSET CONCEALED      ;Display "Secured" or "Unsecured"
  1453.                CMP     OR_BITS,4
  1454.                JZ      DISP_STATS
  1455.                MOV     DX,OFFSET UNCONCEALED
  1456. DISP_STATS:    CALL    PRINT_STRING
  1457.  
  1458. STATS_END:     RET
  1459.  
  1460. ;----------------------------------------------;
  1461. PLUS           EQU     0
  1462. MINUS          EQU     1
  1463. SIGN_FLAG      DB      ?
  1464. FLAGS          DB      "ASHR"
  1465. FLAGS_LEN      EQU     $ - FLAGS
  1466. FLAGS_BITS     DB      20H, 4, 2, 1
  1467. FLAGS_END      EQU     $ - 1
  1468.  
  1469. ATTR:          MOV     CHANGE_FLAG,OFF         ;Assume no changes.
  1470.                MOV     SIGN_FLAG,PLUS          ;Default is plus.
  1471.                MOV     AND_BITS,0
  1472.                MOV     OR_BITS,0
  1473.  
  1474. NEXT_ATTR:     CALL    FIND_START
  1475.                LODSB
  1476.                CMP     AL,CR
  1477.                JBE     GOT_ATTR
  1478.                CMP     AL,"/"
  1479.                JZ      GOT_ATTR
  1480.                CMP     AL,"+"
  1481.                JNZ     CK_MINUS
  1482.                MOV     SIGN_FLAG,PLUS
  1483.                JMP     NEXT_ATTR
  1484.  
  1485. CK_MINUS:      CMP     AL,"-"
  1486.                JNZ     CK_FLAGS
  1487.                MOV     SIGN_FLAG,MINUS
  1488.                JMP     NEXT_ATTR
  1489.  
  1490. CK_FLAGS:      MOV     DI,OFFSET FLAGS
  1491.                MOV     CX,FLAGS_LEN
  1492.                REPNZ   SCASB
  1493.                JZ      GOT_FLAG
  1494.                MOV     DX,OFFSET INVALID_MSG
  1495.                JMP     MSG_EXIT
  1496.  
  1497. GOT_FLAG:      MOV     CHANGE_FLAG,ON          ;Change attribute.
  1498.                MOV     BX,OFFSET FLAGS_END
  1499.                SUB     BX,CX
  1500.                MOV     AL,[BX]
  1501.  
  1502.                MOV     DI,OFFSET OR_BITS       ;Assume plus.
  1503.                CMP     SIGN_FLAG,PLUS
  1504.                JZ      STORE_BIT
  1505.                MOV     DI,OFFSET AND_BITS
  1506. STORE_BIT:     OR      [DI],AL
  1507.                JMP     NEXT_ATTR
  1508.  
  1509. GOT_ATTR:      DEC     SI
  1510.                PUSH    SI
  1511.                MOV     ES,TSR_SEGMENT
  1512.                PUSH    ES:CONCEAL_FLAG
  1513.  
  1514.                CMP     CHANGE_FLAG,ON          ;If no changes, don't need
  1515.                JNZ     ATTR_READY              ; password.
  1516.                CMP     ES:CONCEAL_FLAG,ON      ;Else, if security ON, then
  1517.                JNZ     ATTR_READY              ; need password to change
  1518.                CALL    CK_PASSWORD             ; attributes.
  1519.                MOV     ES:CONCEAL_FLAG,OFF     ;Turn off security temporarily.
  1520.  
  1521. ATTR_READY:    MOV     STATS_FLAG,ATTR_STATS   ;Display attribute messages.
  1522.                CALL    ATTRIBUTES
  1523.  
  1524.                MOV     ES,TSR_SEGMENT
  1525.                POP     ES:CONCEAL_FLAG         ;Restore security status.
  1526.                POP     SI                      ;Command line pointer.
  1527.                RET
  1528.  
  1529. ;----------------------------------------------;
  1530.  
  1531. NEW_PASS:      CALL    CK_PASSWORD             ;Need password to change password
  1532.                MOV     ES,TSR_SEGMENT
  1533.                PUSH    ES:CONCEAL_FLAG
  1534.                MOV     ES:CONCEAL_FLAG,OFF     ;Security temporarily OFF.
  1535.  
  1536.                CMP     BYTE PTR [SI],SPACE     ;Is there a password?
  1537.                JA      GOT_PASS
  1538.                JMP     NEW_END
  1539. GOT_PASS:      MOV     AH,PASS_CODE
  1540.                MOV     BP,SI                   ;Start of password.
  1541.                XOR     CX,CX
  1542. NEXT_PASS2:    LODSB                           ;Get password.
  1543.                CMP     AL,SPACE
  1544.                JBE     STORE_PASS
  1545.                CMP     AL,"/"
  1546.                JZ      STORE_PASS
  1547.                XOR     BYTE PTR [SI - 1],AH
  1548.                INC     AH
  1549.                INC     CX
  1550.                JMP     NEXT_PASS2
  1551.  
  1552. STORE_PASS:    DEC     SI
  1553.                PUSH    SI
  1554.                MOV     ES:PASS_CNT,CX
  1555.                MOV     SI,BP
  1556.                MOV     DI,OFFSET PASSWORD      ;Store new password.
  1557.                REP     MOVSB
  1558.  
  1559. ;----------------------------------------------;
  1560.  
  1561.                PUSH    CS
  1562.                POP     ES
  1563.                MOV     DX,OFFSET PERM_MSG      ;Make change permanent?
  1564.                CALL    PRINT_STRING
  1565.                MOV     AH,1
  1566.                INT     21H
  1567.                PUSH    AX
  1568.                MOV     DX,OFFSET CR_LF
  1569.                CALL    PRINT_STRING
  1570.                POP     AX
  1571.                AND     AL,5FH
  1572.                CMP     AL,"Y"
  1573.                JZ      GET_VER
  1574.                JMP     NEW_DONE
  1575.  
  1576. GET_VER:       MOV     AH,30H                  ;Get DOS version.
  1577.                INT     21H
  1578.                CMP     AL,3                    ;Filename in environment
  1579.                JB      TRY_CURRENT             ; not support before DOS 3.x.
  1580.  
  1581.                MOV     DS,DS:[2CH]             ;Segment of environment.
  1582.                XOR     SI,SI
  1583. FIND_ENV_END:  LODSB                           ;Find end of environment.
  1584.                OR      AL,AL
  1585.                JNZ     FIND_ENV_END
  1586.                LODSB
  1587.                OR      AL,AL
  1588.                JNZ     FIND_ENV_END
  1589.  
  1590.                INC     SI                      ;Bump pointer past word count.
  1591.                INC     SI
  1592.                MOV     DI,OFFSET WORKSPACE     ;Copy our name.
  1593.                CALL    COPY_NAME
  1594.                PUSH    CS
  1595.                POP     DS
  1596.                MOV     DX,OFFSET WORKSPACE     ;Try to write answer.
  1597.                CALL    WRITE_ANS
  1598.                JNC     NEW_DONE
  1599.  
  1600. TRY_CURRENT:   MOV     DX,OFFSET CONCEAL_COM   ;Try current directory.
  1601.                CALL    WRITE_ANS
  1602.                JNC     NEW_DONE
  1603.  
  1604. ; See if PATH= is in environment.
  1605.                MOV     DS,DS:[2CH]             ;Segment of environment.
  1606. LOOK_AT_PATH:  MOV     BX,-1                   ;Offset zero in environment.
  1607. NEXT_PATH:     INC     BX
  1608.                MOV     SI,BX
  1609.                CMP     BYTE PTR [SI],0         ;Terminating null?
  1610.                JNZ     PATH_SEARCH
  1611.                CMP     BYTE PTR [SI+1],0       ;Double null?
  1612.                JNZ     NEXT_PATH
  1613.                JMP     SHORT CANT_SAVE         ;If so, end of environment.
  1614.  
  1615. PATH_SEARCH:   MOV     DI,OFFSET PATH          ;Search for "PATH=".
  1616.                MOV     CX,PATH_LEN
  1617.                REP     CMPSB
  1618.                JNZ     NEXT_PATH
  1619.  
  1620. ; PATH= found; search for paths.
  1621. NEXT_STRING:   CMP     BYTE PTR [SI],0         ;Terminating null?
  1622.                JZ      CANT_SAVE
  1623.                CMP     BYTE PTR [SI-1],0       ;Double null?
  1624.                JZ      CANT_SAVE
  1625.  
  1626. MOVE_STRING:   MOV     DI,OFFSET WORKSPACE     ;Get path.
  1627. NEXT_BYTE:     LODSB
  1628.                OR      AL,AL
  1629.                JZ      SEARCH_PATH
  1630.                CMP     AL,";"
  1631.                JZ      SEARCH_PATH
  1632.                STOSB
  1633.                JMP     NEXT_BYTE
  1634.  
  1635. SEARCH_PATH:   CALL    COPY_PATH               ;Create filespec.
  1636.                PUSH    DS
  1637.                PUSH    CS
  1638.                POP     DS
  1639.                MOV     DX,OFFSET WORKSPACE
  1640.                CALL    WRITE_ANS               ;Try to write answer.
  1641.                POP     DS
  1642.                JC      NEXT_STRING             ;If failed, try next path.
  1643.                JMP     SHORT NEW_DONE          ;Else, done.
  1644.  
  1645. CANT_SAVE:     PUSH    CS
  1646.                POP     DS
  1647.                MOV     DX,OFFSET NOT_FOUND     ;Answer write error message.
  1648.                CALL    PRINT_STRING
  1649.  
  1650. NEW_DONE:      POP     SI
  1651.  
  1652. NEW_END:       MOV     ES,TSR_SEGMENT
  1653.                POP     ES:CONCEAL_FLAG
  1654.                RET
  1655.  
  1656. ;----------------------------------------------;
  1657.  
  1658. COPY_NAME:     LODSB
  1659.                STOSB
  1660.                OR      AL,AL
  1661.                JNZ     COPY_NAME
  1662.                RET
  1663.  
  1664. ;----------------------------------------------;
  1665.  
  1666. COPY_PATH:     PUSH    SI
  1667.                PUSH    DS
  1668.                CMP     DI,OFFSET WORKSPACE
  1669.                JZ      MOVE_NAME
  1670.                CMP     BYTE PTR ES:[DI-1],"\"  ;Filespec delimiter?
  1671.                JZ      MOVE_NAME
  1672.                CMP     BYTE PTR ES:[DI-1],":"
  1673.                JZ      MOVE_NAME
  1674.                MOV     AL,"\"                  ;If no, add one.
  1675.                STOSB
  1676.  
  1677. MOVE_NAME:     PUSH    CS
  1678.                POP     DS
  1679.                MOV     SI,OFFSET CONCEAL_COM   ;Tack on "CONCEAL.COM".
  1680.                MOV     CX,CONCEAL_LEN
  1681.                REP     MOVSB
  1682.  
  1683. COPY_END:      POP     DS
  1684.                POP     SI
  1685.                RET
  1686.  
  1687. ;----------------------------------------------;
  1688. ; INPUT:  DX -> Compute.com filespec.
  1689. ; OUTPUT: CY=0 if successful; CY=1 if failed.
  1690.  
  1691. WRITE_ANS:     PUSH    SI
  1692.                MOV     AX,3D02H                ;Open for reading and writing.
  1693.                INT     21H
  1694.                JC      WRITE_END
  1695.                MOV     BX,AX
  1696.                MOV     DX,OFFSET WORKSPACE
  1697.                MOV     CX,SIZE WORKSPACE
  1698.                MOV     AH,3FH                  ;Read signature.
  1699.                INT     21H
  1700.                JC      WRITE_END
  1701.  
  1702.                MOV     SI,OFFSET SIGNATURE + 1     ;Make sure we found correct
  1703.                MOV     DI,OFFSET WORKSPACE - 100H  ; Secure.com.
  1704.                ADD     DI,SI
  1705.                SUB     CX,OFFSET SIGNATURE + 1 - 100H
  1706.                REP     CMPSB
  1707.                STC
  1708.                JNZ     WRITE_END
  1709.  
  1710.                XOR     CX,CX
  1711.                MOV     DX,OFFSET PASSWORD - 100H
  1712.                MOV     AX,4200H                ;Seek offset of new password.
  1713.                INT     21H
  1714.                JC      WRITE_END
  1715.  
  1716.                PUSH    DS
  1717.                MOV     DS,TSR_SEGMENT
  1718.                MOV     DX,OFFSET PASSWORD
  1719.                MOV     CX,PASSWORD_LEN + SIZE PASS_CNT
  1720.                MOV     AH,40H                  ;Write answer to disk.
  1721.                INT     21H
  1722.                POP     DS
  1723.                JC      WRITE_END
  1724.  
  1725.                MOV     AH,3EH                  ;Close file.
  1726.                INT     21H
  1727. WRITE_END:     POP     SI
  1728.                RET
  1729.  
  1730. ;----------------------------------------------;
  1731.  
  1732. CK_PASSWORD:   CMP     PASS_FLAG,1             ;Correct password on command
  1733.                JZ      CK_PASS_END             ; line?
  1734.                MOV     DX,OFFSET PASS_MSG
  1735.                JMP     MSG_EXIT
  1736. CK_PASS_END:   RET
  1737.  
  1738. ;----------------------------------------------;
  1739.  
  1740. HARD:          MOV     CH,HARD_BLANK
  1741.                JMP     SHORT GET_BLANK
  1742.  
  1743. ;----------------------------------------------;
  1744.  
  1745. SOFT:          MOV     CH,SOFT_BLANK
  1746.  
  1747. GET_BLANK:     MOV     ES,TSR_SEGMENT
  1748.                CMP     BYTE PTR [SI],"0"       ;Time-out parameter?
  1749.                JB      CK_HARD
  1750.                CMP     BYTE PTR [SI],"9"
  1751.                JA      CK_HARD
  1752.  
  1753.                LODSB
  1754.                SUB     AL,"0"
  1755.                MOV     BL,AL
  1756.                LODSB
  1757.                SUB     AL,"0"
  1758.                JC      CK_TIME
  1759.                CMP     AL,9
  1760.                JA      CK_TIME
  1761.                XCHG    BL,AL
  1762.                MOV     BH,10
  1763.                MUL     BH
  1764.                ADD     BL,AL
  1765.                INC     SI
  1766.  
  1767. CK_TIME:       DEC     SI
  1768.                OR      BL,BL                   ;If no or zero time-out, just
  1769.                JZ      STORE_HARD              ; store status.
  1770.                CMP     BL,60                   ;60 minute max.
  1771.                JBE     MAKE_TIME
  1772.                MOV     DX,OFFSET INVALID_MSG
  1773.                JMP     MSG_EXIT
  1774.  
  1775. MAKE_TIME:     MOV     AX,1092                 ;Convert minutes to timer ticks.
  1776.                XOR     BH,BH
  1777.                MUL     BX
  1778.                MOV     ES:TIME_OUT,AX
  1779.                MOV     ES:COUNTER,AX
  1780.  
  1781.  
  1782. CK_HARD:       CALL    CK_ON_OFF
  1783.                CMP     BL,ON
  1784.                JZ      DO_ON
  1785. STORE_HARD:    MOV     ES:BLANK_FLAG,BL        ;Store blank status.
  1786.                JMP     SHORT HARD_END
  1787.  
  1788. DO_ON:         CMP     CH,SOFT_BLANK
  1789.                JNZ     STORE_ON
  1790.                MOV     BUFFER_FLAG,ON            ;Graphics buffer required.
  1791.                ADD     RESIDENT_END,SOFT_STUFF
  1792.                CALL    CK_INSTALLED
  1793.                JZ      STORE_ON
  1794.                CMP     ES:BUFFER_FLAG,ON       ;Is graphics buffer installed?
  1795.                JZ      STORE_ON
  1796.                MOV     DX,OFFSET BUFFER_MSG    ;If no, complain.
  1797.                JMP     MSG_EXIT
  1798.  
  1799. STORE_ON:      MOV     ES:BLANK_FLAG,CH        ;Store blank status.
  1800.                MOV     INSTALL_FLAG,1
  1801. HARD_END:      RET
  1802.  
  1803. ;----------------------------------------------;
  1804.  
  1805. DONT_BLANK:    MOV     ES,TSR_SEGMENT
  1806.                CALL    CK_ON_OFF
  1807.                MOV     ES:GRAPHIC_APPS,BL      ;Store graphics app blank status.
  1808.                RET
  1809.  
  1810. ;----------------------------------------------;
  1811.  
  1812. CONCEAL_BLANK: MOV     ES,TSR_SEGMENT          ;Password unblanking status.
  1813.                CALL    CK_ON_OFF
  1814.                CMP     BL,ON
  1815.                JZ      STORE_CONCEAL
  1816.                CALL    CK_PASSWORD
  1817. STORE_CONCEAL: MOV     ES:UNBLANK_FLAG,BL
  1818.                RET
  1819.  
  1820. ;----------------------------------------------;
  1821.  
  1822. CHANGE_HOT:    MOV     BP,TSR_SEGMENT          ;Save segment.
  1823.                MOV     DX,CS
  1824.                CALL    FIND_START              ;Find start of parameter.
  1825.                CMP     AL,CR
  1826.                JZ      HOT_END
  1827.                MOV     BX,SI
  1828.                MOV     ES,DX
  1829.                MOV     DI,OFFSET ALT_CAPS      ;Is it "ALT"?
  1830.                MOV     CX,3
  1831.                REP     CMPSB
  1832.                JNZ     CK_CTRL
  1833.  
  1834.                MOV     ES,BP
  1835.                MOV     ES:HOT_SHIFT_KEY,ALT_STATE
  1836.                JMP     SHORT GET_HOT
  1837.  
  1838. CK_CTRL:       MOV     SI,BX
  1839.                MOV     DI,OFFSET CTRL_CAPS     ;Is it "CTRL"?
  1840.                MOV     CX,4
  1841.                REP     CMPSB
  1842.                JZ      GOT_CTRL
  1843.                MOV     SI,BX
  1844.                JMP     SHORT GET_HOT
  1845. GOT_CTRL:      MOV     ES,BP
  1846.                MOV     ES:HOT_SHIFT_KEY,CTRL_STATE
  1847.  
  1848. GET_HOT:       CALL    FIND_START              ;Find parameter start.
  1849.                CMP     AL,CR
  1850.                JZ      HOT_END
  1851.                LODSB
  1852.                MOV     CX,SCAN_COUNT
  1853.                MOV     ES,DX
  1854.                MOV     DI,OFFSET SCAN_CODES
  1855. NEXT_HOT:      SCASB                           ;Look up hotkey.
  1856.                JZ      FOUND_HOT
  1857.                INC     DI
  1858.                LOOP    NEXT_HOT
  1859.                JMP     SHORT HOT_END
  1860.  
  1861. FOUND_HOT:     MOV     AH,[DI]
  1862.                MOV     ES,BP
  1863.                MOV     ES:COMBO,AL             ;Store hotkey ASCII
  1864.                MOV     ES:HOT_KEY_SCAN,AH      ; and scan code.
  1865. HOT_END:       RET
  1866.  
  1867. ;---------------------------------------------------;
  1868. ; This subroutine uninstalls the resident TSR.      ;
  1869. ;---------------------------------------------------;
  1870.  
  1871. UNINSTALL:     CALL    CK_INSTALLED            ;Are we installed?
  1872.                JNZ     DO_VECTORS
  1873.                MOV     DX,OFFSET NOT_INSTALLED
  1874.                JMP     MSG_EXIT
  1875.  
  1876. DO_VECTORS:    MOV     CX,AX                   ;Save segment in CX.
  1877.                MOV     ES,AX
  1878.                CMP     ES:UNBLANK_FLAG,ON      ;Password required to unblank?
  1879.                JZ      UN_PASS
  1880.                CMP     ES:CONCEAL_FLAG,OFF     ;Security ON ?
  1881.                JZ      VARS_OFF
  1882.  
  1883. UN_PASS:       CALL    CK_PASSWORD
  1884.  
  1885. VARS_OFF:      MOV     ES:BLANK_FLAG,OFF       ;Turn OFF in case can't uninstall
  1886.                MOV     ES:CONCEAL_FLAG,OFF
  1887.  
  1888.                MOV     AX,3508H                ;Get interrupt 8h.
  1889.                INT     21H
  1890.                CMP     BX,OFFSET TIMER         ;Has it been hooked by another?
  1891.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  1892.                MOV     BX,ES
  1893.                CMP     BX,CX                   ;Is the segment vector same?
  1894.                JNZ     UNINSTALL_ERR           ;If no, exit with error message.
  1895.  
  1896.                MOV     AX,3521H                ;Get interrupt 21h.
  1897.                INT     21H
  1898.                CMP     BX,OFFSET DOS           ;Has it been hooked by another?
  1899.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  1900.                MOV     BX,ES
  1901.                CMP     BX,CX                   ;Is the segment vector same?
  1902.                JNZ     UNINSTALL_ERR           ;If no, exit with error message.
  1903.  
  1904.                MOV     AX,3509H                ;Get interrupt 9h.
  1905.                INT     21H
  1906.                CMP     BX,OFFSET KEYBOARD      ;Has it been hooked by another?
  1907.                JNZ     UNINSTALL_ERR           ;If yes, exit with error message.
  1908.                MOV     BX,ES
  1909.                CMP     BX,CX                   ;Is the segment vector same?
  1910.                JZ      RESTORE_VECTOR          ;If no, exit with error message.
  1911.  
  1912. UNINSTALL_ERR: MOV     DX,OFFSET UNLOAD_MSG    ;And exit with error message.
  1913. LILLY_ERR:     JMP     MSG_EXIT
  1914.  
  1915. RESTORE_VECTOR:MOV     DX,ES:OLD9[0]           ;Restore old INT 9.
  1916.                MOV     DS,ES:OLD9[2]
  1917.                MOV     AX,2509H
  1918.                INT     21H
  1919.  
  1920.                MOV     DX,ES:OLD8[0]           ;Restore old INT 8.
  1921.                MOV     DS,ES:OLD8[2]
  1922.                MOV     AX,2508H
  1923.                INT     21H
  1924.  
  1925.                MOV     DX,ES:OLD21[0]          ;Restore old INT 21.
  1926.                MOV     DS,ES:OLD21[2]
  1927.                MOV     AX,2521H
  1928.                INT     21H
  1929.  
  1930. DEALLOCATE:    MOV     AH,49H                  ;Return memory to system pool.
  1931.                INT     21H
  1932.                PUSH    CS
  1933.                POP     DS
  1934.                MOV     DX,OFFSET ALLOCATE_MSG
  1935.                JC      LILLY_ERR               ;Display message if problem.
  1936.  
  1937.                MOV     DX,OFFSET UNINSTALL_MSG ;Display uninstall message.
  1938.                CALL    PRINT_STRING
  1939.                JMP     GOOD_EXIT
  1940.  
  1941. ;----------------------------------------------;
  1942. ; OUTPUT: BX = ON or OFF.  If neither found, BL = ON.
  1943.  
  1944. CK_ON_OFF:     CALL    FIND_START
  1945.                PUSH    SI
  1946.                MOV     BX,ON                   ;Assume ON.
  1947.                LODSB
  1948.                CMP     AL,"O"
  1949.                JNZ     ON_OFF_DONE
  1950.                ADD     SP,2
  1951.                LODSB
  1952.                CMP     AL,"N"
  1953.                JZ      ON_OFF_END
  1954.                CMP     AL,"F"
  1955.                JNZ     ON_OFF_ERR
  1956.                LODSB
  1957.                CMP     AL,"F"
  1958.                JNZ     ON_OFF_ERR
  1959.                MOV     BX,OFF
  1960.                JMP     SHORT ON_OFF_END
  1961.  
  1962. ON_OFF_DONE:   POP     SI
  1963. ON_OFF_END:    RET
  1964.  
  1965. ON_OFF_ERR:    MOV     DX,OFFSET INVALID_MSG
  1966.                JMP     MSG_EXIT
  1967.  
  1968. ;-------------------------------------------------------;
  1969. ; OUTPUT: ZR = 1 if not installed; ZR = 0 if installed. ;
  1970.  
  1971. CK_INSTALLED:  MOV     AX,TSR_SEGMENT
  1972.                MOV     BX,CS
  1973.                CMP     AX,BX                   ;Compare segments.
  1974.                RET
  1975.  
  1976. ;----------------------------------------------;
  1977.  
  1978. FIND_START:    LODSB
  1979.                CMP     AL,CR
  1980.                JZ      START_END
  1981.                CMP     AL,SPACE
  1982.                JBE     FIND_START
  1983. START_END:     DEC     SI
  1984.                RET
  1985.  
  1986. ;----------------------------------------------;
  1987.  
  1988. FIND_END:      LODSB
  1989.                CMP     AL,CR
  1990.                JZ      END_END
  1991.                CMP     AL,"/"
  1992.                JZ      END_END
  1993.                CMP     AL,SPACE
  1994.                JA      FIND_END
  1995. END_END:       DEC     SI
  1996.                RET
  1997.  
  1998. ;----------------------------------------------;
  1999.  
  2000. DISP_HOTKEY:   MOV     ES,TSR_SEGMENT
  2001.                CMP     ES:BLANK_FLAG,OFF       ;Blank status active?
  2002.                JZ      HOTKEY_END
  2003.                PUSH    DS
  2004.                MOV     DX,OFFSET HOTKEY_MSG    ;Display hotkey message.
  2005.                CALL    PRINT_STRING
  2006.                MOV     DS,TSR_SEGMENT
  2007.                MOV     BL,COMBO
  2008.                MOV     DX,OFFSET ALT
  2009.                CMP     HOT_SHIFT_KEY,ALT_STATE
  2010.                JZ      DISP_STATE
  2011.                MOV     DX,OFFSET CTRL
  2012. DISP_STATE:    POP     DS
  2013.                CALL    PRINT_STRING            ;And current hotkey.
  2014.                MOV     DL,BL
  2015.                MOV     AH,2
  2016.                INT     21H
  2017.                MOV     DX,OFFSET HOTKEY_MSG2
  2018.                CALL    PRINT_STRING
  2019. HOTKEY_END:    RET
  2020.  
  2021. ;----------------------------------------------;
  2022.  
  2023. PRINT_CHAR:    MOV     DL,AL
  2024.                MOV     AH,2                    ;Print character via DOS.
  2025.                JMP     SHORT DOS_INT
  2026.  
  2027. PRINT_STRING:  MOV     AH,9                    ;Print string via DOS.
  2028. DOS_INT:       INT     21H
  2029.                RET
  2030.  
  2031. INITIALIZE     ENDP
  2032.  
  2033. _TEXT          ENDS
  2034.                END     START
  2035.