home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / tsr / tsrsrc33.zip / FMARK.ASM < prev    next >
Assembly Source File  |  1992-01-08  |  16KB  |  420 lines

  1. ;==============================================================================
  2. ;FMARK.ASM - mark a position in memory,
  3. ;            above which TSRs will later be cleared by RELEASE
  4. ;            this version leaves a minimal size MARK in memory,
  5. ;              storing the rest on disk
  6. ;            requires a single command line parameter naming
  7. ;              the file where the mark will be stored
  8. ;
  9. ; Syntax:  FMARK [/Q] [d:][path]filename
  10. ;==============================================================================
  11. ; written for TASM
  12. ; by Kim Kokkonen, TurboPower Software
  13. ; Copyright (c) 1986,1991 Kim Kokkonen, TurboPower Software.
  14. ; May be freely distributed but not sold except by permission.
  15. ; telephone: 719-260-6641, Compuserve 76004,2611
  16. ;==============================================================================
  17. ; version 2.0  6/17/86
  18. ;   start at a version number compatible with other TSR utilities
  19. ; :
  20. ; long intervening history
  21. ; :
  22. ; version 3.0  9/24/91
  23. ;   add Quiet option
  24. ; version 3.1  11/4/91
  25. ;   no change
  26. ; version 3.2  11/22/91
  27. ;   change method of accessing high memory
  28. ;   store parent len as well as parent segment
  29. ; version 3.3 1/8/92
  30. ;   detect full disk while writing mark file
  31. ;   erase partial mark file if any error occurs during execution
  32. ;==============================================================================
  33. ;
  34. Cseg    segment public para
  35.         assume  cs:Cseg, ds:Cseg, es:Cseg
  36.         locals  @@
  37.  
  38.         org     016H               ;access to parent's PSP
  39. parpsp  label   word
  40.  
  41.         org     02CH
  42. envseg  label   word               ;access to environment segment
  43.  
  44.         org     80H
  45. cmdlen  label   byte               ;command line length
  46.         org     81H
  47. cmdlin  label   byte               ;first character of command line
  48.  
  49.         org     100H
  50.  
  51. fmark   proc    near
  52.  
  53. ;deallocate environment block of this mark
  54.         push    es
  55.         mov     ax,envseg       ;environment segment
  56.         mov     es,ax           ;  into es
  57.         mov     ah,49H
  58.         int     21H             ;deallocate, no reason for an error to occur
  59.         pop     es
  60.  
  61. ;find first mcb in high memory, if any
  62.         mov     ax,3000h                ;get DOS version
  63.         int     21H
  64.         cmp     al,3
  65.         jb      @@7                     ;no XMS driver possible
  66.         mov     ax,4300h
  67.         int     2Fh                     ;multiplex call for XMS
  68.         cmp     al,80h                  ;proper signature?
  69.         jne     @@7                     ;no XMS driver
  70.         mov     ax,4310h                ;get XMS control address
  71.         int     2Fh
  72.         mov     xmsxxx,bx               ;save it
  73.         mov     xmsxxx[2],es
  74.         mov     ah,10h
  75.         mov     dx,0FFFFh
  76.         call    dword ptr xmsadr        ;ask to allocate FFFF paras of UMB
  77.         cmp     bl,0B0h                 ;will fail with B0 if UMBs avail
  78.         je      @@0
  79.         cmp     bl,0B1h                 ;will fail with B1 if UMBs all allocated
  80.         jne     @@7                     ;no UMBs exist
  81. @@0:    int     12H
  82.         mov     cl,6
  83.         shl     ax,cl                   ;get segment of top of memory
  84.  
  85. @@1:    mov     es,ax
  86.         cmp     byte ptr es:[0000h],'M' ;potential mcb?
  87.         jnz     @@6                     ;not an mcb, try next segment
  88. @@2:    mov     cx,ax                   ;save potential start mcb in cx
  89. @@3:    inc     ax
  90.         add     ax,es:[0003h]           ;ax = start of next mcb
  91.         jc      @@5                     ;can't be an mcb if we wrapped
  92.         mov     es,ax                   ;address of next mcb
  93.         mov     dl,es:[0000h]
  94.         cmp     dl,'M'
  95.         jz      @@3                     ;good start mcb
  96.         cmp     dl,'Z'
  97.         jz      @@9                     ;good end mcb
  98. @@5:    mov     ax,cx                   ;restore last start segment
  99. @@6:    cmp     ax,0FFFFh               ;top of memory?
  100.         je      @@7
  101.         inc     ax                      ;try next segment
  102.         jmp     @@1
  103.  
  104. @@7:    xor     cx,cx                   ;no matching UMB
  105. @@9:    mov     firsthimcb,cx           ;store first high mcb
  106.  
  107. ;parse command line for file name
  108.         push    cs
  109.         pop     es
  110.         mov     si,offset cmdlin ;point to command line
  111.         mov     di,offset filnm  ;point to filename storage string
  112.         cld
  113.  
  114. get1:   lodsb                    ;get first non-blank
  115.         cmp     al,32            ;skip space
  116.         je      get1
  117.         cmp     al,9             ;skip tab
  118.         je      get1
  119.         cmp     al,13            ;check for end of input
  120.         jne     geto             ;got a non-blank, now get the parameter
  121.         cmp     di,offset filnm  ;filename already specified?
  122.         jne     gotit            ;done if so
  123.         jmp     error            ;no parameter --> error
  124.  
  125. geto:   cmp     al,'/'           ;check for option
  126.         je      getoc
  127.         cmp     al,'-'
  128.         jne     get2
  129. getoc:  lodsb
  130.         call    upcase
  131.         cmp     al,'Q'
  132.         jnz     operr
  133.         mov     quiet,1          ;set quiet option
  134.         jmp     get1             ;loop around
  135.  
  136. operr:  mov     dx,offset badopt ;bad option
  137.         jmp     errmsg
  138.  
  139. get2:   cmp     di,offset filnm  ;filename already specified?
  140.         jne     operr            ;error if so
  141.  
  142. get2a:  call    upcase           ;upcase char in al
  143.         stosb                    ;store the non-blank character
  144.         lodsb                    ;get next character
  145.         cmp     al,32
  146.         je      get1             ;loop back around for blank
  147.         cmp     al,9
  148.         je      get1             ;loop back around for tab
  149.         cmp     al,13
  150.         je      gotit            ;terminate for <cr>
  151.         jmp     short get2a      ;keep adding characters to filename
  152.  
  153. ;create the specified file
  154. gotit:  mov     al,0
  155.         stosb                    ;terminate ASCIIZ pathname
  156.         mov     dx,offset filnm
  157.         xor     cx,cx            ;normal attribute
  158.         mov     ah,3CH
  159.         int     21H              ;DOS CREAT
  160.         jae     store
  161.  
  162.         mov     dx,offset badfil ;bad file name
  163.         jmp     errmsg
  164.  
  165. ;store the interrupt vector table
  166. store:  mov     bx,ax           ;keep file handle in bx
  167.         push    ds              ;save ds
  168.         mov     cx,400H         ;1024 bytes to store
  169.         xor     ax,ax
  170.         mov     ds,ax           ;segment 0
  171.         assume  ds:nothing
  172.         mov     dx,ax           ;offset 0
  173.         call    blockwrite      ;write interrupts to file
  174.         assume  ds:cseg
  175.  
  176. ;store the EGA save pointer
  177. egasav: push    ds              ;save ds
  178.         mov     cx,0008H        ;8 bytes to store
  179.         mov     ax,0040H
  180.         mov     ds,ax           ;BIOS data segment
  181.         assume  ds:nothing
  182.         mov     dx,00A8H        ;EGA save table pointer
  183.         call    blockwrite      ;write save pointers to file
  184.         assume  ds:cseg
  185.  
  186. ;store the interapplications communications area
  187. intcom: push    ds              ;save ds
  188.         mov     cx,0010H        ;16 bytes to store
  189.         mov     ax,0040H
  190.         mov     ds,ax           ;BIOS data segment
  191.         assume  ds:nothing
  192.         mov     dx,00F0H        ;interapplications communication area
  193.         call    blockwrite      ;write interapp communications area to file
  194.         assume  ds:cseg
  195.  
  196. ;store the parent's psp
  197. parent: push    ds
  198.         mov     cx,2                    ;2 bytes to store
  199.         mov     dx,offset parpsp        ;point to parent's psp
  200.         call    blockwrite              ;write parent psp to file
  201.         assume  ds:cseg
  202.  
  203. parlen: push    ds
  204.         mov     ax,ds:[parpsp]
  205.         dec     ax
  206.         mov     ds,ax
  207.         assume  ds:nothing
  208.         mov     dx,3                    ;ds:dx -> parent's length
  209.         mov     cx,2
  210.         call    blockwrite              ;write parent psp to file
  211.         assume  ds:cseg
  212.  
  213. ;determine whether EMS is present
  214. ems:    push    bx              ;temporarily store the file handle
  215.         xor     bx,bx           ;zero the EMS handle count in case EMS not present
  216.         mov     dx,offset emsnm
  217.         mov     ax,3D00H
  218.         int     21H
  219.         jb      sthand          ;EMS driver not installed
  220.  
  221. ;EMS present, close the open "handle" first
  222.         mov     bx,ax           ;EMS handle into bx
  223.         mov     ah,3EH
  224.         int     21H             ;close handle
  225.  
  226. ;get the current EMS page map
  227.         mov     ah,4DH
  228.         mov     di,offset emsmap ;es=cs already
  229.         xor     bx,bx           ;required by some versions of EMM (bug workaround)
  230.         cld                     ;required by some versions of EMM
  231.         int     67H
  232.         or      ah,ah
  233.         jz      sthand          ;result ok
  234.         xor     bx,bx           ;error, return zero EMS handles
  235.  
  236. ;store the number of active handles
  237. sthand: mov     emscnt,bx               ;count of active handles
  238.  
  239. ;write the handle table to disk
  240.         shl     bx,1
  241.         shl     bx,1                    ;4 bytes per handle
  242.         inc     bx
  243.         inc     bx                      ;2 more bytes for the handle count
  244.         mov     cx,bx                   ;number of bytes to write
  245.         pop     bx                      ;get file handle back
  246.         mov     dx,offset emscnt        ;what we're writing
  247.         push    ds
  248.         call    blockwrite              ;write EMS table to file
  249.         assume  ds:cseg
  250.  
  251. ;write the allocated mcb chain
  252. stomcb: push    bx                      ;save file handle
  253.         mov     ah,52H                  ;get first mcb segment
  254.         int     21H
  255.         mov     ax,es:[bx-2]            ;ax=first mcb
  256.         push    cs
  257.         pop     es                      ;es=cs
  258.  
  259.         mov     di,emscnt               ;get starting address of mcbmap
  260.         shl     di,1
  261.         shl     di,1
  262.         add     di,offset emsmap
  263.         mov     si,di                   ;cs:[si] -> mcbcnt
  264.         add     di,2                    ;cs:[di] -> mcbmap
  265.         xor     cx,cx                   ;cx will count mcbs
  266.         cld
  267.         push    ds
  268.         assume  ds:nothing
  269.  
  270. mcbnext:stosw                           ;store mcb segment held by ax
  271.         mov     ds,ax                   ;ds:[0] points to mcb
  272.         mov     ax,ds:[1]               ;get mcb owner
  273.         stosw                           ;store it
  274.         inc     cx                      ;increment count
  275.         cmp     byte ptr ds:[0],'Z'     ;end of mcb chain?
  276.         je      mcbdone
  277.         mov     ax,ds                   ;restore ax to mcb segment
  278.         inc     ax                      ;skip over mcb itself
  279.         add     ax,ds:[3]               ;add length of memory block
  280.         jmp     mcbnext
  281.  
  282. mcbdone:mov     ax,cs:firsthimcb        ;check for high memory
  283.         or      ax,ax
  284.         jz      mcbend
  285.         mov     cs:firsthimcb,0         ;only do it once
  286.         jmp     mcbnext
  287.  
  288. mcbend: pop     ds
  289.         assume  ds:cseg
  290.         mov     [si],cx                 ;store number of mcbs
  291.         sub     di,si                   ;di=number of bytes in mcb group table
  292.         mov     cx,di                   ;count of bytes in cx
  293.         mov     dx,si                   ;what we're writing (mcbcnt+mcbmap)
  294.         pop     bx                      ;get file handle back
  295.         push    ds
  296.         call    blockwrite              ;write mcb table to file
  297.         assume  ds:cseg
  298.  
  299. ;close up the table file
  300. closfl: mov     ah,3EH
  301.         int     21H                     ;close handle
  302.         jae     idstr                   ;ok, continue
  303.  
  304.         mov     dx,offset badcls        ;error while closing file
  305.         jmp     delfil
  306.  
  307. ;put a standard ID string into the PSP for RELEASE to check
  308. idstr:  mov     si,offset id
  309.         mov     di,60H                  ;unused area of the PSP
  310.         mov     cx,idlen                ;characters in ID string
  311.         cld
  312.         rep     movsb                   ;copy string
  313.  
  314. ;copy the filename into the command tail
  315.         mov     si,offset filnm
  316.         mov     di,offset cmdlin
  317.         xor     cx,cx
  318. nxtf:   lodsb
  319.         or      al,al
  320.         jz      donf
  321.         inc     cx
  322.         stosb
  323.         jmp     nxtf
  324. donf:   mov     cmdlen,cl
  325.  
  326. ;print message and TSR
  327. gores:  cmp     quiet,0         ;check quiet flag
  328.         jnz     gores1
  329.         mov     dx,offset didit
  330.         mov     ah,9
  331.         int     21H             ;write success message including filename
  332.         mov     dx,offset crlf  ;newline
  333.         mov     ah,9
  334.         int     21H
  335.  
  336. gores1: xor     dx,dx           ;get number of paragraphs to keep
  337.         mov     dl,cmdlen       ;length of command line
  338.         add     dx,0090H        ;rest of PSP plus paragraph margin
  339.         mov     cl,4
  340.         shr     dx,cl           ;convert to paragraphs
  341.         mov     ax,3100H
  342.         int     21H             ;terminate but stay resident
  343.  
  344. ;close mark file, delete it, show error message
  345. errclo: mov     ah,3EH
  346.         int     21H                     ;close handle, ignore error
  347.  
  348. ;delete mark file and show error message
  349.         assume  ds:cseg
  350. delfil: push    dx
  351.         mov     dx,offset filnm
  352.         mov     ah,41H
  353.         int     21H
  354.         pop     dx
  355.  
  356. ;error output - show syntax line
  357. ;dx has offset of error message
  358. errmsg: mov     ah,9
  359.         int     21H
  360. error:
  361.         mov     dx,offset syntax
  362.         mov     ah,9
  363.         int     21H
  364.         mov     ax,4C01H
  365.         int     21H
  366.  
  367. fmark   endp
  368.  
  369. ;blockwrite assumes that ds was pushed before the call
  370. blockwrite proc near
  371.         mov     ah,40H
  372.         int     21H             ;write block to file
  373.         pop     dx              ;get return address
  374.         pop     ds              ;get ds back
  375.         assume  ds:cseg
  376.         push    dx              ;return address back on stack
  377.         mov     dx,offset nowrit
  378.         jc      errclo          ;jump if error during write
  379.         cmp     ax,cx
  380.         jne     errclo          ;jump if not all bytes written
  381.         ret
  382. blockwrite endp
  383.  
  384. upcase  proc    near
  385.         cmp     al,'a'
  386.         jb      noup
  387.         cmp     al,'z'
  388.         ja      noup
  389.         and     al,0DFH          ;uppercase
  390. noup:   ret
  391. upcase  endp
  392.  
  393. emsnm   db      'EMMXXXX0',0    ;file name for testing EMS presence
  394. id      db      'FM3.3 TSR'     ;id string for RELEASE check
  395. idlen   equ     $-id
  396.  
  397. ;messages
  398. badfil  db      13,10,'Could not open file for writing',36
  399. nowrit  db      13,10,'Error while writing',36
  400. badcls  db      13,10,'Error closing table file',36
  401. badopt  db      13,10,'Bad command line option',36
  402. syntax  db      13,10,'Syntax:  FMARK [/Q] [d:][path]filename'
  403. crlf    db      13,10,36
  404. didit   db      'FMARK 3.3, Copyright 1991 TurboPower Software',13,10
  405. didit2  db      'Marked current memory position in '
  406.  
  407. ;data storage area
  408. filnm   db      50H dup (36)    ;mark file name
  409. quiet   db      0               ;quiet flag
  410. xmsadr  label   dword           ;XMS control address
  411. xmsxxx  dw      2 dup (0)
  412. firsthimcb dw   0               ;segment of first mcb in high mem
  413. emscnt  dw      0               ;holds number of active pages in map that follows
  414. emsmap  =       $               ;EMS page map (up to 1024 bytes)
  415. mcbcnt  =       emsmap+400H     ;number of allocated mcbs
  416. mcbmap  =       mcbcnt+2        ;MCB map (up to 1024 bytes)
  417.  
  418. Cseg    ends
  419.         end    Fmark
  420.