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