home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / MASM.ZIP / SAMPLES / TSR / SNAP.AS$ / SNAP.bin
Encoding:
Text File  |  1991-03-13  |  20.4 KB  |  517 lines

  1.         .MODEL  small, pascal, os_dos
  2.         .SEQ
  3.         INCLUDE demo.inc
  4.         INCLUDE tsr.inc
  5.  
  6. OpenBox         PROTO
  7. CloseBox        PROTO
  8.  
  9.         .CODE
  10.         .DATA
  11. INSTALLDATA SEGMENT WORD PUBLIC 'I_DATA'
  12. INSTALLDATA ENDS
  13.  
  14. INSTALLCODE SEGMENT PARA PUBLIC 'I_CODE'
  15. INSTALLCODE ENDS
  16.  
  17.         .STACK
  18.         .DATA
  19.  
  20. DEFAULT_COLR    EQU     1Eh             ; Default = white on blue (color)
  21. DEFAULT_MONO    EQU     70h             ; Default = reverse video (mono)
  22.  
  23. ; Set ALT+LEFT SHIFT+S as hot key combination. To set multiple shift
  24. ; keys, OR the appropriate values together for the shift value (HOT_SHIFT).
  25.  
  26. HOT_SCAN        EQU     1Fh             ; Hot key scan code (S)
  27. HOT_SHIFT       EQU     shAlt OR shLeft ; Shift value (ALT+LEFT SHIFT)
  28. HOT_MASK        EQU     (shIns OR shCaps OR shNum OR shScroll) XOR 0FFh
  29.  
  30. ROW1            EQU     9               ; Query box begins on row 9
  31. ROW2            EQU     14              ;   and ends on row 14
  32. HEIGHT          EQU     ROW2 - ROW1 + 1 ; Number of rows in query box
  33.  
  34. Box     BYTE    '┌──────────────────────────────────────┐', 0
  35.         BYTE    '│  Enter file name                     │', 0
  36.         BYTE    '│  (press Esc to cancel):              │', 0
  37.         BYTE    '│                                      │', 0
  38.         BYTE    '│                                      │', 0
  39. boxend  BYTE    '└──────────────────────────────────────┘', 0
  40. LEN     EQU     (LENGTHOF boxend) - 1
  41.  
  42. OldPos  WORD    ?                       ; Original cursor position
  43. Handle  WORD    ?                       ; File handle number
  44. FilSpec BYTE    (LEN - 3) DUP(0)        ; ASCIIZ string for file spec
  45.  
  46. ; Fill attribute for prompt box. This is changed by running SNAP with
  47. ; the /Cx switch, where x = new display attribute in hexadecimal. For
  48. ; example, to change the colors to yellow on brown for a color monitor,
  49. ; enter
  50. ;         SNAP /C6E
  51. ; where the first digit specifies the background color and the second
  52. ; digit the foreground color. Typical values for x on a monochrome
  53. ; system are
  54. ;       07 normal                 70 reverse video
  55. ;       0F high intensity         78 reverse video, high intensity
  56.  
  57. BoxFill BYTE    DEFAULT_MONO            ; Assume monochrome
  58.  
  59. ; Hold contains the screen text and attributes replaced by the query box.
  60. ; Buffer holds text captured from the screen, with room for 50 rows of 82
  61. ; characters, including carriage return/linefeed. To change Buffer's
  62. ; capacity, replace the dimensions with r * (c + 2) DUP(?), where r and
  63. ; c are row and column count respectively.
  64.  
  65. Hold    BYTE    (HEIGHT * LEN) + 3 DUP(?)
  66. Buffer  BYTE    50 * 82 DUP(?)
  67.  
  68.  
  69.         .CODE
  70.  
  71. ;* Snap - Main procedure for resident program. Called from the Activate
  72. ;* procedure when TSR is invoked by the proper key combination.
  73. ;*
  74. ;* Params:  DS, ES = @data
  75. ;*
  76. ;* Return:  None
  77.  
  78. Snap    PROC    FAR
  79.  
  80.         INVOKE  GetVidConfig            ; Get video information
  81.  
  82.         mov     al, vconfig.mode        ; AL = video mode
  83.         .IF     (al <= 3) || (al == 7)  ; If text mode:
  84.  
  85.         INVOKE  GetCurPos               ; Get original cursor coordinates
  86.         mov     OldPos, ax              ;   and store them
  87.  
  88.         INVOKE  OpenBox                 ; Display query box
  89.  
  90.         mov     bl, vconfig.cols        ; Calculate column
  91.         sub     bl, LEN
  92.         shr     bl, 1
  93.         add     bl, 3
  94.  
  95.         INVOKE  StrInput,               ; Request input
  96.                 ROW1 + 4,               ; Row
  97.                 bl,                     ; Column
  98.                 LEN - 4,                ; Maximum string
  99.                 ADDR FilSpec            ; Address of string buffer
  100.  
  101.         push    ax                      ; Save terminating keypress
  102.         call    CloseBox                ; Restore screen to original state
  103.         pop     ax                      ; Recover key
  104.         .IF     al != ESCAPE            ; If ESC key not pressed:
  105.         call    OpenFile                ; Open (or create) file
  106.  
  107.         .IF     !carry?                 ; If okay,
  108.         call    Capture                 ;   write screen to file
  109.         .ELSE
  110.         mov     ax, 0E07h               ; Write bell character
  111.         int     10h                     ;   (ASCII 7) to console
  112.         .ENDIF                          ; End file-okay test
  113.         .ENDIF                          ; End ESC test
  114.  
  115.         mov     ax, OldPos              ; Recover original cursor position
  116.         mov     bl, ah
  117.  
  118.         INVOKE  SetCurPos,              ; Restore cursor
  119.                 bx, ax                  ; Pass cursor row and column
  120.  
  121.         .ENDIF                          ; End text mode test
  122.  
  123.         retf                            ; Far return to Activate procedure
  124.  
  125. Snap    ENDP
  126.  
  127.  
  128. ;* OpenBox - Saves portion of screen to Hold buffer, then opens a box.
  129. ;*
  130. ;* Uses:    vconfig - Video configuration structure
  131. ;*
  132. ;* Params:  None
  133. ;*
  134. ;* Return:  None
  135.  
  136. OpenBox PROC
  137.  
  138.         mov     dh, ROW1                ; DH = top screen row for box
  139.         mov     dl, vconfig.cols
  140.         sub     dl, LEN
  141.         shr     dl, 1                   ; DL = left col for centered box
  142.         push    dx                      ; Save coords
  143.         sub     ch, ch
  144.         mov     cl, dh                  ; CX = row
  145.         sub     dh, dh                  ; DX = column
  146.         GetVidOffset cx, dx
  147.         mov     si, ax                  ; Get video offset in SI
  148.         mov     bx, HEIGHT              ; BX = number of window rows
  149.         mov     cx, LEN                 ; CX = number of columns
  150.  
  151.         push    ds
  152.         pop     es
  153.         mov     di, OFFSET Hold         ; Point ES:DI to hold buffer
  154.         mov     ax, si
  155.         stosw                           ; Copy video offset to buffer
  156.         mov     ax, bx
  157.         stosw                           ; Number of rows to buffer
  158.         mov     ax, cx
  159.         stosw                           ; Number of cols to buffer
  160.         mov     al, vconfig.cols
  161.         shl     ax, 1                   ; AX = number of video cells/row
  162.         mov     ds, vconfig.sgmnt       ; DS = video segment
  163.  
  164.         .REPEAT
  165.         push    si                      ; Save ptr to start of line
  166.         push    cx                      ;   and number of columns
  167.         .IF     vconfig.adapter == CGA  ; If CGA adapter,
  168.         INVOKE  DisableCga              ;   disable video
  169.         .ENDIF
  170.         rep     movsw                   ; Copy one row to buffer
  171.         .IF     vconfig.adapter == CGA  ; If CGA adapter,
  172.         INVOKE  EnableCga               ;   reenable CGA video
  173.         .ENDIF
  174.         pop     cx                      ; Recover number of columns
  175.         pop     si                      ;   and start of line
  176.         add     si, ax                  ; Point to start of next line
  177.         dec     bx                      ; Decrement row counter
  178.         .UNTIL  zero?                   ; Loop while rows remain
  179.  
  180. ; Screen contents (including display attributes) are now copied to buffer.
  181. ; Next open window, overwriting the screen portion just saved.
  182.  
  183.         push    es
  184.         pop     ds                      ; Restore DS
  185.  
  186.         mov     ax, 0600h               ; Scroll service
  187.         mov     bh, BoxFill             ; BH = fill attribute
  188.         pop     cx                      ; CX = row/col for upper left
  189.         mov     dh, ROW2
  190.         mov     dl, cl
  191.         add     dl, LEN
  192.         dec     dl                      ; DX = row/col for lower right
  193.         int     10h                     ; Blank window area on screen
  194.  
  195. ; Write box frame and text to screen
  196.  
  197.         mov     dx, cx                  ; DX = row/col for upper left
  198.         mov     si, OFFSET Box          ; Point to text
  199.         mov     cx, HEIGHT              ; Number of rows in box
  200.  
  201.         .REPEAT
  202.         push    dx                      ; Save coordinates
  203.         sub     bh, bh
  204.         mov     bl, dh                  ; BX = row
  205.         sub     dh, dh                  ; DX = column   
  206.         INVOKE  StrWrite, bx, dx, si    ; Display one line of box
  207.         pop     dx                      ; Recover coordinates
  208.         inc     dh                      ; Next screen row
  209.         add     si, LEN                 ; Point to next line in box
  210.         inc     si
  211.         .UNTILCXZ
  212.  
  213.         ret
  214.  
  215. OpenBox ENDP
  216.  
  217.  
  218. ;* CloseBox - Restores the original screen text to close the window
  219. ;* previously opened by the OpenBox procedure
  220. ;*
  221. ;* Uses:    vconfig - Video configuration structure
  222. ;*
  223. ;* Params:  None
  224. ;*
  225. ;* Return:  None
  226.  
  227. CloseBox PROC
  228.  
  229.         mov     si, OFFSET Hold
  230.         lodsw
  231.         mov     di, ax                  ; DI = video offset of window
  232.         lodsw
  233.         mov     bx, ax                  ; BX = number of window rows
  234.         lodsw
  235.         mov     cx, ax                  ; CX = number of columns
  236.  
  237.         mov     al, vconfig.cols
  238.         shl     ax, 1                   ; AX = number of video cells/row
  239.  
  240.         .REPEAT
  241.         push    di                      ; Save ptr to start of line
  242.         push    cx                      ;   and number of columns
  243.         .IF     vconfig.adapter == CGA  ; If CGA adapter,
  244.         INVOKE  DisableCga              ;   disable video
  245.         .ENDIF
  246.         rep     movsw                   ; Copy one row to buffer
  247.         .IF     vconfig.adapter == CGA  ; If CGA adapter,
  248.         INVOKE  EnableCga               ;   reenable CGA video
  249.         .ENDIF
  250.         pop     cx                      ; Recover number of columns
  251.         pop     di                      ;   and start of line
  252.         add     di, ax                  ; Point to start of next line
  253.         dec     bx                      ; Decrement row counter
  254.         .UNTIL  zero?                   ; Loop while rows remain
  255.  
  256.         ret
  257.  
  258. CloseBox ENDP
  259.  
  260.  
  261. ;* OpenFile - Opens or creates specified file. Resets file pointer to
  262. ;* end of file so that subsequent text is appended to bottom of file.
  263. ;*
  264. ;* Params:  DS:SI = Pointer to file spec
  265. ;*
  266. ;* Return:  None
  267.  
  268. OpenFile PROC
  269.  
  270.         mov     ax, 3D01h               ; Request DOS to open file
  271.         mov     dx, OFFSET FilSpec      ; DS:DX points to file specification
  272.         int     21h                     ; Open File
  273.         .IF     carry?                  ; If it doesn't exist,
  274.         mov     ah, 3Ch                 ;   request create file
  275.         sub     cx, cx                  ;   with normal attributes
  276.         int     21h                     ; Create File
  277.         .ENDIF
  278.  
  279.         .IF     !carry?                 ; If no error,
  280.         mov     Handle, ax              ;   store file handle
  281.         mov     bx, ax
  282.         mov     ax, 4202h               ; Request DOS to reset file pointer
  283.         sub     cx, cx                  ;   to end of file
  284.         sub     dx, dx
  285.         int     21h                     ; Set file pointer
  286.         .ENDIF
  287.         ret
  288.  
  289. OpenFile ENDP
  290.  
  291.  
  292. ;* Capture - Copies screen text to Buffer, then writes Buffer to file.
  293. ;*
  294. ;* Uses:    vconfig - Video configuration structure
  295. ;*
  296. ;* Params:  None
  297. ;*
  298. ;* Return:  None
  299.  
  300. Capture PROC
  301.  
  302.         mov     es, vconfig.sgmnt       ; ES points to video segment address
  303.         sub     si, si                  ; ES:SI points to 1st video byte
  304.         sub     bx, bx                  ; BX = index to capture buffer
  305.         mov     dx, 3DAh                ; DX = address of CGA status register
  306.  
  307.         .REPEAT
  308.         sub     ch, ch
  309.         mov     cl, vconfig.cols        ; CX = number of columns in line
  310.         mov     di, cx
  311.         dec     di
  312.         shl     di, 1                   ; ES:DI points to video byte for
  313.         add     di, si                  ;   last column in line
  314.  
  315.         .REPEAT
  316.         .IF     vconfig.adapter == CGA  ; If CGA,
  317.         cli                             ;   disallow interruptions
  318.         .REPEAT
  319.         in      al, dx                  ; Read current video status
  320.         .UNTIL  !(al & 1)               ;   until horizontal retrace done
  321.         .REPEAT
  322.         in      al, dx                  ; Read video status
  323.         .UNTIL  al & 1                  ;   until horizontal retrace starts
  324.         .ENDIF                          ; End CGA retrace check
  325.  
  326.         mov     al, es:[di]             ; Get screen char, working backward
  327.         sti                             ; Reenable interrupts in case CGA
  328.         sub     di, 2                   ; DI points to next character
  329.         .UNTILCXZ (al != ' ')           ; Scan for last nonblank character
  330.  
  331.         .IF     !zero?                  ; If nonblank char found,
  332.         inc     cx                      ;   adjust column counter
  333.         mov     di, si                  ; ES:DI points to start of line
  334.  
  335.         .REPEAT
  336.         .IF     vconfig.adapter == CGA  ; If CGA,
  337.         cli                             ;   disallow interruptions
  338.         .REPEAT
  339.         in      al, dx                  ; Read current video status
  340.         .UNTIL  !(al & 1)               ;   until horizontal retrace done
  341.         .REPEAT
  342.         in      al, dx                  ; Read video status
  343.         .UNTIL  al & 1                  ;   until horizontal retrace starts
  344.         .ENDIF                          ; End CGA retrace check
  345.  
  346.         mov     al, es:[di]             ; Get character, working forward
  347.         sti
  348.         add     di, 2                   ; DI points to next character
  349.         mov     Buffer[bx], al          ; Copy to buffer
  350.         inc     bx
  351.         .UNTILCXZ
  352.         .ENDIF                          ; End check for nonblank char
  353.  
  354.         mov     WORD PTR Buffer[bx], CRLF; Finish line with return/line feed
  355.         add     bx, 2
  356.         mov     al, vconfig.cols
  357.         sub     ah, ah
  358.         shl     ax, 1
  359.         add     si, ax                  ; SI points to start of next line
  360.         dec     vconfig.rows            ; Decrement row count
  361.         .UNTIL  sign?                   ; Repeat for next screen row
  362.  
  363.         mov     ah, 40h                 ; Request DOS Function 40h
  364.         mov     cx, bx                  ; CX = number of bytes to write
  365.         mov     bx, Handle              ; BX = file handle
  366.         mov     dx, OFFSET Buffer       ; DS:DX points to buffer
  367.         int     21h                     ; Write to file
  368.         .IF     (ax != cx)              ; If number of bytes written !=
  369.         stc                             ;   number requested, set carry
  370.         .ENDIF                          ;   flag to indicate failure
  371.  
  372.         pushf                           ; Save carry flag
  373.         mov     ah, 3Eh                 ; Request DOS Function 3Eh
  374.         int     21h                     ; Close file
  375.         popf                            ; Recover carry
  376.         ret
  377.  
  378. Capture ENDP
  379.  
  380.  
  381. @CurSeg ENDS
  382.  
  383. ;* INSTALLATION SECTION - The following code and data are used only
  384. ;* during SNAP's installation phase. When the program terminates
  385. ;* through Function 31h, the above code and data remain resident;
  386. ;* memory occupied by the following code and data segments is returned
  387. ;* to the operating system.
  388.         
  389. DGROUP  GROUP INSTALLCODE, INSTALLDATA
  390.  
  391. INSTALLDATA SEGMENT WORD PUBLIC 'I_DATA'
  392.  
  393. IDstr   BYTE    'SNAP DEMO TSR', 0      ; Multiplex identifier string
  394.  
  395. INSTALLDATA ENDS
  396.  
  397. INSTALLCODE SEGMENT PARA PUBLIC 'I_CODE'
  398.         ASSUME  ds:@data
  399.  
  400. Begin   PROC    NEAR
  401.  
  402.         mov     ax, DGROUP
  403.         mov     ds, ax                  ; Initialize DS
  404.         mov     ah, 15
  405.         int     10h                     ; Get Video Mode
  406.         .IF     al != 7                 ; If not default monochrome,
  407.         mov     BoxFill, DEFAULT_COLR   ;   reset to default color value
  408.         .ENDIF
  409.  
  410. ; Before calling any of the TSR procedures, initialize global data
  411.  
  412.         INVOKE  InitTsr,                ; Initialize data
  413.                 es,                     ; Segment of PSP
  414.                 ADDR IDstr,             ; Far address of multiplex ID string
  415.                 ADDR BoxFill            ; Far address of memory shared
  416.                                         ;   with multiplex handler
  417.         .IF     ax == WRONG_DOS         ; If DOS version less than 2.0,
  418.         jmp     exit                    ;   exit with message
  419.         .ENDIF
  420.  
  421. ; This section gets the command-line argument to determine task:
  422. ;    No argument   = install
  423. ;    /D or -D      = deinstall
  424. ;    /Cx or -Cx    = change box-fill attribute to value x
  425.  
  426.         mov     al, 'd'                 ; Search command line for
  427.         call    GetOptions              ;   /D or -D argument
  428.         cmp     ax, NO_ARGUMENT         ; No argument?
  429.         je      installtsr              ; If so, try to install
  430.         cmp     ax, OK_ARGUMENT         ; /D argument found?
  431.         je      deinstalltsr            ; If so, try to deinstall
  432.         mov     al, 'c'                 ; Else search command line for
  433.         call    GetOptions              ;   /C or -C argument
  434.         cmp     ax, BAD_ARGUMENT        ; If neither /D or /C arguments,
  435.         je      exit                    ;   quit with error message
  436.  
  437. ; This section changes the fill attribute of SNAP's prompt box. It converts
  438. ; to binary the two-digit hex number following the /C argument, calls the
  439. ; multiplex handler to find the address of the attribute variable stored in
  440. ; shared memory, then resets the attribute to the new value. It does not
  441. ; verify that the value specified in the command line is a valid two-digit
  442. ; hex number.
  443.  
  444.         mov     ax, es:[di+1]           ; AH = low digit, AL = high digit
  445.         mov     cx, 2                   ; Process two digits
  446.  
  447.         .REPEAT
  448.         sub     al, '0'                 ; Convert digit to binary
  449.         .IF     (al > 9)                ; If not digit 0-9,
  450.         and     al, 00011111y           ;   mask out lower-case bit
  451.         sub     al, 7                   ; Convert A to 10, B to 11, etc.
  452.         .ENDIF
  453.         xchg    ah, al                  ; Get next digit in AL
  454.         .UNTILCXZ
  455.  
  456.         mov     cl, 4
  457.         shl     al, cl                  ; Multiply high digit by 16
  458.         or      al, ah                  ; AL = binary value of attribute
  459.         push    ax                      ; Save new attribute
  460.  
  461.         mov     al, 2                   ; Request function 2
  462.         call    CallMultiplex           ; Get shared memory addr in ES:DI
  463.         .IF     ax != IS_INSTALLED      ; If TSR is not installed,
  464.         pop     ax                      ;   clean stack and
  465.         mov     ax, CANT_ACCESS         ;   quit with error message
  466.         jmp     exit
  467.         .ELSE                           ; If TSR is installed,
  468.         pop     ax                      ;   recover new fill attribute in AL
  469.         mov     es:[di], al             ; Write it to resident shared memory
  470.         mov     ax, OK_ACCESS           ; Signal successful completion
  471.         jmp     exit
  472.         .ENDIF
  473.  
  474. ; This section sets up the TSR's interrupt handlers and
  475. ; makes the program memory-resident
  476.  
  477. installtsr:
  478.         push    es                      ; Preserve PSP address
  479.  
  480.         mov     ax, @code
  481.         mov     es, ax
  482.         mov     bx, OFFSET Snap         ; ES:BX points to Snap
  483.         INVOKE  Install,                ; Install handlers
  484.                 HOT_SCAN,               ; Scan code of hot key
  485.                 HOT_SHIFT,              ; Bit value of hot key
  486.                 HOT_MASK,               ; Bit mask for shift hot key
  487.                 es::bx                  ; Far address of Snap procedure
  488.  
  489.         pop     bx                      ; Recover PSP address
  490.         or      ax, ax                  ; If nonzero return code,
  491.         jnz     exit                    ;   exit with appropriate message
  492.         mov     ax, INSTALLCODE         ; Bottom of resident section
  493.         sub     ax, bx                  ; AX = number of paragraphs in
  494.                                         ;   block to be made resident
  495.         INVOKE  KeepTsr,                ; Make TSR memory-resident
  496.                 ax                      ; Resident paragraphs
  497.  
  498. ; This section deinstalls the resident TSR from memory
  499.  
  500. deinstalltsr:
  501.  
  502.         INVOKE  Deinstall               ; Unchain interrupt handlers
  503.  
  504.         .IF     ax > OK_ARGUMENT        ; If successful,
  505.         INVOKE  FreeTsr,                ;   deinstall TSR by freeing memory
  506.                 ax                      ; Address of resident seg
  507.         .ENDIF                          ; Else exit with message
  508. exit:
  509.         INVOKE  FatalError,             ; Exit to DOS with message
  510.                 ax                      ; Error number
  511.  
  512. Begin   ENDP
  513.  
  514. INSTALLCODE ENDS
  515.  
  516.         END     Begin
  517.