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