home *** CD-ROM | disk | FTP | other *** search
- ;==============================================================================
- ;FMARK.ASM - mark a position in memory,
- ; above which TSRs will later be cleared by RELEASE
- ; this version leaves a minimal size MARK in memory,
- ; storing the rest on disk
- ; requires a single command line parameter naming
- ; the file where the mark will be stored
- ;
- ; Syntax: FMARK [/Q] [d:][path]filename
- ;==============================================================================
- ; written for TASM
- ; by Kim Kokkonen, TurboPower Software
- ; Copyright (c) 1986,1991 Kim Kokkonen, TurboPower Software.
- ; May be freely distributed but not sold except by permission.
- ; telephone: 719-260-6641, Compuserve 76004,2611
- ;==============================================================================
- ; version 2.0 6/17/86
- ; start at a version number compatible with other TSR utilities
- ; :
- ; long intervening history
- ; :
- ; version 3.0 9/24/91
- ; add Quiet option
- ; version 3.1 11/4/91
- ; no change
- ; version 3.2 11/22/91
- ; change method of accessing high memory
- ; store parent len as well as parent segment
- ; version 3.3 1/8/92
- ; detect full disk while writing mark file
- ; erase partial mark file if any error occurs during execution
- ; version 3.4 2/14/92
- ; no change
- ;==============================================================================
- ;
- Cseg segment public para
- assume cs:Cseg, ds:Cseg, es:Cseg
- locals @@
-
- org 016H ;access to parent's PSP
- parpsp label word
-
- org 02CH
- envseg label word ;access to environment segment
-
- org 80H
- cmdlen label byte ;command line length
- org 81H
- cmdlin label byte ;first character of command line
-
- org 100H
-
- fmark proc near
-
- ;deallocate environment block of this mark
- push es
- mov ax,envseg ;environment segment
- mov es,ax ; into es
- mov ah,49H
- int 21H ;deallocate, no reason for an error to occur
- pop es
-
- ;find first mcb in high memory, if any
- mov ax,3000h ;get DOS version
- int 21H
- cmp al,3
- jb @@7 ;no XMS driver possible
- mov ax,4300h
- int 2Fh ;multiplex call for XMS
- cmp al,80h ;proper signature?
- jne @@7 ;no XMS driver
- mov ax,4310h ;get XMS control address
- int 2Fh
- mov xmsxxx,bx ;save it
- mov xmsxxx[2],es
- mov ah,10h
- mov dx,0FFFFh
- call dword ptr xmsadr ;ask to allocate FFFF paras of UMB
- cmp bl,0B0h ;will fail with B0 if UMBs avail
- je @@0
- cmp bl,0B1h ;will fail with B1 if UMBs all allocated
- jne @@7 ;no UMBs exist
- @@0: int 12H
- mov cl,6
- shl ax,cl ;get segment of top of memory
-
- @@1: mov es,ax
- cmp byte ptr es:[0000h],'M' ;potential mcb?
- jnz @@6 ;not an mcb, try next segment
- @@2: mov cx,ax ;save potential start mcb in cx
- @@3: inc ax
- add ax,es:[0003h] ;ax = start of next mcb
- jc @@5 ;can't be an mcb if we wrapped
- mov es,ax ;address of next mcb
- mov dl,es:[0000h]
- cmp dl,'M'
- jz @@3 ;good start mcb
- cmp dl,'Z'
- jz @@9 ;good end mcb
- @@5: mov ax,cx ;restore last start segment
- @@6: cmp ax,0FFFFh ;top of memory?
- je @@7
- inc ax ;try next segment
- jmp @@1
-
- @@7: xor cx,cx ;no matching UMB
- @@9: mov firsthimcb,cx ;store first high mcb
-
- ;parse command line for file name
- push cs
- pop es
- mov si,offset cmdlin ;point to command line
- mov di,offset filnm ;point to filename storage string
- cld
-
- get1: lodsb ;get first non-blank
- cmp al,32 ;skip space
- je get1
- cmp al,9 ;skip tab
- je get1
- cmp al,13 ;check for end of input
- jne geto ;got a non-blank, now get the parameter
- cmp di,offset filnm ;filename already specified?
- jne gotit ;done if so
- jmp error ;no parameter --> error
-
- geto: cmp al,'/' ;check for option
- je getoc
- cmp al,'-'
- jne get2
- getoc: lodsb
- call upcase
- cmp al,'Q'
- jnz operr
- mov quiet,1 ;set quiet option
- jmp get1 ;loop around
-
- operr: mov dx,offset badopt ;bad option
- jmp errmsg
-
- get2: cmp di,offset filnm ;filename already specified?
- jne operr ;error if so
-
- get2a: call upcase ;upcase char in al
- stosb ;store the non-blank character
- lodsb ;get next character
- cmp al,32
- je get1 ;loop back around for blank
- cmp al,9
- je get1 ;loop back around for tab
- cmp al,13
- je gotit ;terminate for <cr>
- jmp short get2a ;keep adding characters to filename
-
- ;create the specified file
- gotit: mov al,0
- stosb ;terminate ASCIIZ pathname
- mov dx,offset filnm
- xor cx,cx ;normal attribute
- mov ah,3CH
- int 21H ;DOS CREAT
- jae store
-
- mov dx,offset badfil ;bad file name
- jmp errmsg
-
- ;store the interrupt vector table
- store: mov bx,ax ;keep file handle in bx
- push ds ;save ds
- mov cx,400H ;1024 bytes to store
- xor ax,ax
- mov ds,ax ;segment 0
- assume ds:nothing
- mov dx,ax ;offset 0
- call blockwrite ;write interrupts to file
- assume ds:cseg
-
- ;store the EGA save pointer
- egasav: push ds ;save ds
- mov cx,0008H ;8 bytes to store
- mov ax,0040H
- mov ds,ax ;BIOS data segment
- assume ds:nothing
- mov dx,00A8H ;EGA save table pointer
- call blockwrite ;write save pointers to file
- assume ds:cseg
-
- ;store the interapplications communications area
- intcom: push ds ;save ds
- mov cx,0010H ;16 bytes to store
- mov ax,0040H
- mov ds,ax ;BIOS data segment
- assume ds:nothing
- mov dx,00F0H ;interapplications communication area
- call blockwrite ;write interapp communications area to file
- assume ds:cseg
-
- ;store the parent's psp
- parent: push ds
- mov cx,2 ;2 bytes to store
- mov dx,offset parpsp ;point to parent's psp
- call blockwrite ;write parent psp to file
- assume ds:cseg
-
- parlen: push ds
- mov ax,ds:[parpsp]
- dec ax
- mov ds,ax
- assume ds:nothing
- mov dx,3 ;ds:dx -> parent's length
- mov cx,2
- call blockwrite ;write parent psp to file
- assume ds:cseg
-
- ;determine whether EMS is present
- ems: push bx ;temporarily store the file handle
- xor bx,bx ;zero the EMS handle count in case EMS not present
- mov dx,offset emsnm
- mov ax,3D00H
- int 21H
- jb sthand ;EMS driver not installed
-
- ;EMS present, close the open "handle" first
- mov bx,ax ;EMS handle into bx
- mov ah,3EH
- int 21H ;close handle
-
- ;get the current EMS page map
- mov ah,4DH
- mov di,offset emsmap ;es=cs already
- xor bx,bx ;required by some versions of EMM (bug workaround)
- cld ;required by some versions of EMM
- int 67H
- or ah,ah
- jz sthand ;result ok
- xor bx,bx ;error, return zero EMS handles
-
- ;store the number of active handles
- sthand: mov emscnt,bx ;count of active handles
-
- ;write the handle table to disk
- shl bx,1
- shl bx,1 ;4 bytes per handle
- inc bx
- inc bx ;2 more bytes for the handle count
- mov cx,bx ;number of bytes to write
- pop bx ;get file handle back
- mov dx,offset emscnt ;what we're writing
- push ds
- call blockwrite ;write EMS table to file
- assume ds:cseg
-
- ;write the allocated mcb chain
- stomcb: push bx ;save file handle
- mov ah,52H ;get first mcb segment
- int 21H
- mov ax,es:[bx-2] ;ax=first mcb
- push cs
- pop es ;es=cs
-
- mov di,emscnt ;get starting address of mcbmap
- shl di,1
- shl di,1
- add di,offset emsmap
- mov si,di ;cs:[si] -> mcbcnt
- add di,2 ;cs:[di] -> mcbmap
- xor cx,cx ;cx will count mcbs
- cld
- push ds
- assume ds:nothing
-
- mcbnext:stosw ;store mcb segment held by ax
- mov ds,ax ;ds:[0] points to mcb
- mov ax,ds:[1] ;get mcb owner
- stosw ;store it
- inc cx ;increment count
- cmp byte ptr ds:[0],'Z' ;end of mcb chain?
- je mcbdone
- mov ax,ds ;restore ax to mcb segment
- inc ax ;skip over mcb itself
- add ax,ds:[3] ;add length of memory block
- jmp mcbnext
-
- mcbdone:mov ax,cs:firsthimcb ;check for high memory
- or ax,ax
- jz mcbend
- mov cs:firsthimcb,0 ;only do it once
- jmp mcbnext
-
- mcbend: pop ds
- assume ds:cseg
- mov [si],cx ;store number of mcbs
- sub di,si ;di=number of bytes in mcb group table
- mov cx,di ;count of bytes in cx
- mov dx,si ;what we're writing (mcbcnt+mcbmap)
- pop bx ;get file handle back
- push ds
- call blockwrite ;write mcb table to file
- assume ds:cseg
-
- ;close up the table file
- closfl: mov ah,3EH
- int 21H ;close handle
- jae idstr ;ok, continue
-
- mov dx,offset badcls ;error while closing file
- jmp delfil
-
- ;put a standard ID string into the PSP for RELEASE to check
- idstr: mov si,offset id
- mov di,60H ;unused area of the PSP
- mov cx,idlen ;characters in ID string
- cld
- rep movsb ;copy string
-
- ;copy the filename into the command tail
- mov si,offset filnm
- mov di,offset cmdlin
- xor cx,cx
- nxtf: lodsb
- or al,al
- jz donf
- inc cx
- stosb
- jmp nxtf
- donf: mov cmdlen,cl
-
- ;print message and TSR
- gores: cmp quiet,0 ;check quiet flag
- jnz gores1
- mov dx,offset didit
- mov ah,9
- int 21H ;write success message including filename
- mov dx,offset crlf ;newline
- mov ah,9
- int 21H
-
- gores1: xor dx,dx ;get number of paragraphs to keep
- mov dl,cmdlen ;length of command line
- add dx,0090H ;rest of PSP plus paragraph margin
- mov cl,4
- shr dx,cl ;convert to paragraphs
- mov ax,3100H
- int 21H ;terminate but stay resident
-
- ;close mark file, delete it, show error message
- errclo: mov ah,3EH
- int 21H ;close handle, ignore error
-
- ;delete mark file and show error message
- assume ds:cseg
- delfil: push dx
- mov dx,offset filnm
- mov ah,41H
- int 21H
- pop dx
-
- ;error output - show syntax line
- ;dx has offset of error message
- errmsg: mov ah,9
- int 21H
- error:
- mov dx,offset syntax
- mov ah,9
- int 21H
- mov ax,4C01H
- int 21H
-
- fmark endp
-
- ;blockwrite assumes that ds was pushed before the call
- blockwrite proc near
- mov ah,40H
- int 21H ;write block to file
- pop dx ;get return address
- pop ds ;get ds back
- assume ds:cseg
- push dx ;return address back on stack
- mov dx,offset nowrit
- jc errclo ;jump if error during write
- cmp ax,cx
- jne errclo ;jump if not all bytes written
- ret
- blockwrite endp
-
- upcase proc near
- cmp al,'a'
- jb noup
- cmp al,'z'
- ja noup
- and al,0DFH ;uppercase
- noup: ret
- upcase endp
-
- emsnm db 'EMMXXXX0',0 ;file name for testing EMS presence
- id db 'FM3.4 TSR' ;id string for RELEASE check
- idlen equ $-id
-
- ;messages
- badfil db 13,10,'Could not open file for writing',36
- nowrit db 13,10,'Error while writing',36
- badcls db 13,10,'Error closing table file',36
- badopt db 13,10,'Bad command line option',36
- syntax db 13,10,'Syntax: FMARK [/Q] [d:][path]filename'
- crlf db 13,10,36
- didit db 'FMARK 3.4, Copyright 1991 TurboPower Software',13,10
- didit2 db 'Marked current memory position in '
-
- ;data storage area
- filnm db 50H dup (36) ;mark file name
- quiet db 0 ;quiet flag
- xmsadr label dword ;XMS control address
- xmsxxx dw 2 dup (0)
- firsthimcb dw 0 ;segment of first mcb in high mem
- emscnt dw 0 ;holds number of active pages in map that follows
- emsmap = $ ;EMS page map (up to 1024 bytes)
- mcbcnt = emsmap+400H ;number of allocated mcbs
- mcbmap = mcbcnt+2 ;MCB map (up to 1024 bytes)
-
- Cseg ends
- end Fmark