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

  1.         .MODEL  small, pascal
  2.         INCLUDE tsr.inc
  3.  
  4. ;* INSTALLATION SECTION - The following code and data are used only
  5. ;* during the TSR's installation phase. When the program terminates
  6. ;* through Function 31h, memory occupied by the following code and
  7. ;* data segments is returned to the operating system.
  8.  
  9. DGROUP  GROUP INSTALLCODE, INSTALLDATA
  10.  
  11. INSTALLDATA SEGMENT WORD PUBLIC 'DATA2' ; Data segment for installation phase
  12.  
  13.         PUBLIC  _MsgTbl
  14.  
  15. _MsgTbl WORD    Msg0                    ; Deinstalled okay
  16.         WORD    Msg1                    ; Installed okay
  17.         WORD    Msg2                    ; Already installed
  18.         WORD    Msg3                    ; Can't install
  19.         WORD    Msg4                    ; Can't find flag
  20.         WORD    Msg5                    ; Can't deinstall
  21.         WORD    Msg6                    ; Requires DOS 2+
  22.         WORD    Msg7                    ; MCB damaged
  23.         WORD    Msg8                    ; Invalid ID
  24.         WORD    Msg9                    ; Invalid memory block address
  25.         WORD    Msg10                   ; Successful access
  26.         WORD    Msg11                   ; Can't access
  27.         WORD    Msg12                   ; Unrecognized option
  28.  
  29. Msg0    BYTE    CR, LF, "TSR deinstalled", CR, LF, 0
  30. Msg1    BYTE    CR, LF, "TSR installed", CR, LF, 0
  31. Msg2    BYTE    CR, LF, "TSR already installed", CR, LF, 0
  32. Msg3    BYTE    CR, LF, "Can't install TSR", CR, LF, 0
  33. Msg4    BYTE    CR, LF, "Can't find MS-DOS Critical Error Flag", CR, LF, 0
  34. Msg5    BYTE    CR, LF, "Can't deinstall TSR", CR, LF, 0
  35. Msg6    BYTE    CR, LF, "Requires MS-DOS 2.0 or later", CR, LF, 0
  36. Msg7    BYTE    CR, LF, "Memory Control Block damaged", CR, LF, 0
  37. Msg8    BYTE    CR, LF, "No ID numbers available", CR, LF, 0
  38. Msg9    BYTE    CR, LF, "Can't free memory block:  invalid address", CR, LF,0
  39. Msg10   BYTE    CR, LF, "TSR successfully accessed", CR, LF, 0
  40. Msg11   BYTE    CR, LF, "Can't access:  TSR not installed", CR, LF, 0
  41. Msg12   BYTE    CR, LF, "Unrecognized option", CR, LF, 0
  42.  
  43. INSTALLDATA ENDS
  44.  
  45.  
  46. INSTALLCODE SEGMENT PARA PUBLIC 'CODE2'
  47.  
  48.         ASSUME  ds:@data
  49.  
  50. ;* GetOptions - Scans command line for argument of form /X or -X
  51. ;* where X = specified ASCII character. Presumes that argument is
  52. ;* preceded by either '/' or '-'. Comparisons are case insensitive.
  53. ;* Designed to be callable only from an assembly-language program.
  54. ;*
  55. ;* Params: ES = Segment address of Program Segment Prefix
  56. ;*         AL = Argument character for which to scan
  57. ;*
  58. ;* Return: AX    = One of the following codes:
  59. ;*                 NO_ARGUMENT  if empty command line
  60. ;*                 OK_ARGUMENT  if argument found
  61. ;*                 BAD_ARGUMENT if argument not as specified
  62. ;*         ES:DI = Pointer to found argument
  63.  
  64. GetOptions PROC NEAR
  65.  
  66.         and     al, 11011111y           ; Make character upper case
  67.         mov     ah, NO_ARGUMENT         ; Assume no argument
  68.         mov     di, 80h                 ; Point to command line
  69.         sub     ch, ch
  70.         mov     cl, BYTE PTR es:[di]    ; Command-line count
  71.         jcxz    exit                    ; If none, quit
  72.         sub     bx, bx                  ; Initialize flag
  73.  
  74. ; Find start of argument
  75.  
  76. loop1:
  77.         inc     di                      ; Point to next character
  78.         mov     dl, es:[di]             ; Get character from argument list
  79.         cmp     dl, '/'                 ; Find option prefix '/'
  80.         je      analyze
  81.         cmp     dl, '-'                 ;   or option prefix '-'
  82.         je      analyze
  83.         .IF     (dl != ' ') && (dl != TAB ) ; If not white space,
  84.         inc     bx                      ; Set flag if command line not empty
  85.         .ENDIF
  86.  
  87.         loop    loop1
  88.  
  89.         or      bx, bx                  ; Empty command line?
  90.         jz      exit                    ; Yes?  Normal exit
  91.         jmp     SHORT e_exit            ; Error if no argument is preceded
  92.                                         ;   by '-' or '/' prefixes
  93.  
  94. ; '/' or '-' prefix found. Compare command-line character
  95. ; with character specified in AL.
  96. analyze:
  97.         mov     ah, OK_ARGUMENT         ; Assume argument is okay
  98.         inc     di
  99.         mov     dl, es:[di]
  100.         and     dl, 11011111y           ; Convert to upper-case
  101.         cmp     dl, al                  ; Argument as specified?
  102.         je      exit                    ; If so, normal exit
  103.         mov     ah, BAD_ARGUMENT        ; Else signal bad argument,
  104.         inc     bx                      ;   raise flag, and
  105.         jmp     loop1                   ;   continue scan
  106.  
  107. e_exit:
  108.         mov     ah, BAD_ARGUMENT
  109. exit:
  110.         mov     al, ah
  111.         cbw                             ; AX = return code
  112.         ret
  113.  
  114. GetOptions ENDP
  115.  
  116.  
  117. ;* FatalError - Displays an error message and exits to DOS.
  118. ;* Callable from a high-level language.
  119. ;*
  120. ;* Params: Err = Error number
  121. ;*
  122. ;* Return: AL = Error number returned to DOS (except DOS 1.x)
  123.  
  124. FatalError PROC FAR,
  125.         Err:WORD
  126.  
  127.         mov     ax, Err
  128.         push    ax
  129.         mov     bx, @data
  130.         mov     ds, bx                  ; DS points to DGROUP
  131.         mov     bx, OFFSET _MsgTbl
  132.         shl     ax, 1                   ; Double to get offset into _MsgTbl
  133.         add     bx, ax                  ; BX = table index
  134.         mov     si, [bx]                ; DS:SI points to message
  135.         sub     bx, bx                  ; BH = page 0
  136.  
  137.         .WHILE  1
  138.         lodsb                           ; Get character from ASCIIZ string
  139.         .BREAK .IF al == 0              ; Break if null terminator
  140.         mov     ah, 0Eh                 ; Request video Function 0Eh
  141.         int     10h                     ; Display text, advance cursor
  142.         .ENDW
  143.  
  144.         pop     ax                      ; Recover original error code
  145.  
  146.         .IF     ax == WRONG_DOS         ; If DOS error,
  147.         int     20h                     ;   terminate Program (Version 1.x)
  148.         .ELSE                           ; Else,
  149.         mov     ah, 4Ch                 ;   request DOS Function 4Ch
  150.         int     21h                     ;   terminate Program (2.x and later)
  151.         .ENDIF
  152.  
  153. FatalError ENDP
  154.  
  155.  
  156. ;* GetResidentSize - Returns the number of paragraphs between Program
  157. ;* Segment Prefix (PSP) and beginning of INSTALLDATA. This is the size of
  158. ;* the program less the now-unneeded installation code and data -- in other
  159. ;* words, the size of the resident TSR block. The return value can serve as
  160. ;* the argument for the routine KeepTsr.
  161. ;*
  162. ;* Params: PspSeg - PSP segment address
  163. ;*
  164. ;* Return: AX = Number of paragraphs
  165.  
  166. GetResidentSize PROC FAR,
  167.         PspSeg:WORD
  168.  
  169.         mov     ax, INSTALLDATA         ; Bottom of installation section
  170.         inc     ax                      ;   plus one paragraph
  171.         sub     ax, PspSeg              ; AX = number of paragraphs in
  172.         ret                             ;   block to be made resident
  173.  
  174. GetResidentSize ENDP
  175.  
  176.  
  177. ;* KeepTsr -  Calls Terminate-and-Stay-Resident function to
  178. ;* make TSR resident. Callable from a high-level language.
  179. ;*
  180. ;* Params:  ParaNum - Number of paragraphs in resident block
  181. ;*
  182. ;* Return:  DOS return code = 0
  183.  
  184. KeepTsr PROC    FAR,
  185.         ParaNum:WORD
  186.  
  187.         mov     ax, @data
  188.         mov     ds, ax                  ; DS:SI points to "Program
  189.         mov     si, OFFSET Msg1         ;   installed" message
  190.         sub     bx, bx                  ; BH = page 0
  191.  
  192.         .WHILE  1
  193.         lodsb                           ; Get character from ASCIIZ string
  194.         .BREAK .IF al == 0              ; Break if null terminator
  195.         mov     ah, 0Eh                 ; Request video Function 0Eh
  196.         int     10h                     ; Display text, advance cursor
  197.         .ENDW
  198.  
  199.         mov     dx, ParaNum             ; DX = number of paragraphs
  200.         mov     ax, 3100h               ; Request Function 31h, err code = 0
  201.         int     21h                     ; Terminate-and-Stay-Resident
  202.         ret
  203.  
  204. KeepTsr ENDP
  205.  
  206.  
  207. ;* FreeTsr - Deinstalls TSR by freeing its two memory blocks: program
  208. ;* block (located at PSP) and environment block (located from address
  209. ;* at offset 2Ch of PSP). Callable from a high-level language.
  210. ;*
  211. ;* Params:  PspSeg - Segment address of TSR's Program Segment Prefix
  212. ;*
  213. ;* Return:  AX = 0 if successful, or one of the following error codes:
  214. ;*          MCB_DESTROYED       if Memory Control Block damaged
  215. ;*          INVALID_ADDR        if invalid block address
  216.  
  217. FreeTsr PROC    FAR,
  218.         PspSeg:WORD
  219.  
  220.         mov     es, PspSeg              ; ES = address of resident PSP
  221.         mov     ah, 49h                 ; Request DOS Function 49h
  222.         int     21h                     ; Release memory in program block
  223.  
  224.         .IF     !carry?                 ; If no error:
  225.         mov     es, es:[2Ch]            ; ES = address of environment block
  226.         mov     ah, 49h                 ; Request DOS Function 49h
  227.         int     21h                     ; Release Memory in environment block
  228.         .IF     !carry?                 ; If no error:
  229.         sub     ax, ax                  ; Return AX = 0
  230.         .ENDIF                          ; Else exit with AX = error code
  231.         .ENDIF
  232.  
  233.         ret
  234.  
  235. FreeTsr ENDP
  236.  
  237.  
  238. ;* CallMultiplexC - Interface for CallMultiplex procedure to make it
  239. ;* callable from a high-level language. Separating this ability from
  240. ;* the original CallMultiplex procedure keeps assembly-language calls
  241. ;* to CallMultiplex neater and more concise.
  242. ;*
  243. ;* Params: FuncNum - Function number for multiplex handler
  244. ;*         RecvPtr - Far address to recieve ES:DI pointer
  245. ;*
  246. ;* Return: One of the following return codes:
  247. ;*              NOT_INSTALLED      IS_INSTALLED       NO_IDNUM
  248. ;*         ES:DI pointer written to address in RecvPtr
  249.  
  250. CallMultiplexC PROC FAR USES ds si di,
  251.         FuncNum:WORD, RecvPtr:FPVOID
  252.  
  253.         mov     al, BYTE PTR FuncNum    ; AL = function number
  254.         call    CallMultiplex           ; Multiplex
  255.  
  256.         lds     si, RecvPtr             ; DS:SI = far address of pointer
  257.         mov     [si], di                ; Return ES:DI pointer for the
  258.         mov     [si+2], es              ;   benefit of high-level callers
  259.         ret
  260.  
  261. CallMultiplexC ENDP
  262.  
  263.  
  264. INSTALLCODE ENDS
  265.  
  266.         END
  267.