home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mass61.zip / mass.zip / masm61 / DISK3 / SAMPLES / TSR / SNAP.AS$ / SNAP
Text File  |  1992-11-12  |  21KB  |  511 lines

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