home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / masm / masm6 / tsr / install.asm < prev    next >
Encoding:
Assembly Source File  |  1990-11-16  |  10.1 KB  |  265 lines

  1.         .MODEL  small, pascal, os_dos
  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.         mov     ah, 0Eh                 ; Request video Function 0Eh
  137.  
  138.         .WHILE  1
  139.         lodsb                           ; Get character from ASCIIZ string
  140.         .BREAK .IF al == 0              ; Break if null terminator
  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. ;* KeepTsr -  Calls Terminate-and-Stay-Resident function to
  157. ;* make TSR resident. Callable from a high-level language.
  158. ;*
  159. ;* Params:  ParaNum - Number of paragraphs in resident block
  160. ;*
  161. ;* Return:  DOS return code = 0
  162.  
  163. KeepTsr PROC    FAR,
  164.         ParaNum:WORD
  165.  
  166.         mov     ax, @data
  167.         mov     ds, ax                  ; DS:SI points to "Program
  168.         mov     si, OFFSET Msg1         ;   installed" message
  169.         sub     bx, bx                  ; BH = page 0
  170.         mov     ah, 0Eh                 ; Request video Function 0Eh
  171.  
  172.         .WHILE  1
  173.         lodsb                           ; Get character from ASCIIZ string
  174.         .BREAK .IF al == 0              ; Break if null terminator
  175.         int     10h                     ; Display text, advance cursor
  176.         .ENDW
  177.  
  178.         mov     dx, ParaNum             ; DX = number of paragraphs
  179.         mov     ax, 3100h               ; Request Function 31h, err code = 0
  180.         int     21h                     ; Terminate-and-Stay-Resident
  181.         ret
  182.  
  183. KeepTsr ENDP
  184.  
  185.  
  186. ;* FreeTsr - Deinstalls TSR by freeing its two memory blocks: program
  187. ;* block (located at PSP) and environment block (located from address
  188. ;* at offset 2Ch of PSP). Callable from a high-level language.
  189. ;*
  190. ;* Params:  PspSeg - Segment address of TSR's Program Segment Prefix
  191. ;*
  192. ;* Return:  AX = 0 if successful, or one of the following error codes:
  193. ;*          MCB_DESTROYED       if Memory Control Block damaged
  194. ;*          INVALID_ADDR        if invalid block address
  195.  
  196. FreeTsr PROC    FAR,
  197.         PspSeg:WORD
  198.  
  199.         mov     es, PspSeg              ; ES = address of resident PSP
  200.         mov     ah, 49h                 ; Request DOS Function 49h
  201.         int     21h                     ; Release Memory in program block
  202.  
  203.         .IF     !carry?                 ; If no error:
  204.         mov     es, es:[2Ch]            ; ES = address of environment block
  205.         mov     ah, 49h                 ; Request DOS Function 49h
  206.         int     21h                     ; Release Memory in environment block
  207.         .IF     !carry?                 ; If no error:
  208.         sub     ax, ax                  ; Return AX = 0
  209.         .ENDIF                          ; Else exit with AX = error code
  210.         .ENDIF
  211.  
  212.         ret
  213.  
  214. FreeTsr ENDP
  215.  
  216.  
  217. ;* CallMultiplexC - Interface for CallMultiplex procedure to make it
  218. ;* callable from a high-level language. Separating this ability from
  219. ;* the original CallMultiplex procedure keeps assembly-language calls
  220. ;* to CallMultiplex neater and more concise.
  221. ;*
  222. ;* Params: FuncNum - Function number for multiplex handler
  223. ;*         RecvPtr - Far address to recieve ES:DI pointer
  224. ;*
  225. ;* Return: One of the following return codes:
  226. ;*              NOT_INSTALLED      IS_INSTALLED       NO_IDNUM
  227. ;*         ES:DI pointer written to address in RecvPtr
  228.  
  229. CallMultiplexC PROC FAR USES ds si di,
  230.         FuncNum:WORD, RecvPtr:FPVOID
  231.  
  232.         mov     al, BYTE PTR FuncNum    ; AL = function number
  233.         call    CallMultiplex           ; Multiplex
  234.  
  235.         lds     si, RecvPtr             ; DS:SI = far address of pointer
  236.         mov     [si], di                ; Return ES:DI pointer for the
  237.         mov     [si+2], es              ;   benefit of high-level callers
  238.         ret
  239.  
  240. CallMultiplexC ENDP
  241.  
  242.  
  243. ;* GetResidentSize - Returns the number of paragraphs between Program
  244. ;* Segment Prefix and beginning of INSTALLCODE. This routine allows
  245. ;* TSRs written in a high-level language to determine the size in
  246. ;* paragraphs required to make the program resident.
  247. ;*
  248. ;* Params: PspSeg - PSP segment address
  249. ;*
  250. ;* Return: AX = Number of paragraphs
  251.  
  252. GetResidentSize PROC FAR,
  253.         PspSeg:WORD
  254.  
  255.         mov     ax, INSTALLCODE         ; Bottom of resident section
  256.         sub     ax, PspSeg              ; AX = number of paragraphs in
  257.         ret                             ;   block to be made resident
  258.  
  259. GetResidentSize ENDP
  260.  
  261.  
  262. INSTALLCODE ENDS
  263.  
  264.         END
  265.