;FMARK.ASM - mark a position in memory,
;            above which TSRs will later be cleared by RELEASE.COM
;            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 [d:][path]filename
;
; VERSION 2.0  6/17/86
;   start at a version number compatible with other TSR utilities
; VERSION 2.1  7/18/86
;   keep consistent with RELEASE
;
; written for CHASM (CHeap ASseMbler)
; by Kim Kokkonen, TurboPower Software
; telephone: 408-378-3672, Compuserve 72457,2131
;
;
;
fmark  proc    near

;parse command line for file name
       mov     si,81H           ;point to command line
       mov     di,offset(filnm) ;point to filename storage string
       cld

get1   lodsb                    ;get first non-blank
       cmpb    al,32            ;skip space
       je      get1
       cmpb    al,9             ;skip tab
       je      get1
       cmpb    al,13            ;check for end of input
       jne     get2             ;got a non-blank, now get the parameter
       jmp     error            ;no parameter --> error

get2   cmp     al,'a'
       jl      sto1
       cmp     al,'z'
       jg      sto1
       and     al,0DFH          ;uppercase
sto1   stosb                    ;store the non-blank character
       lodsb                    ;get next character
       cmpb    al,32            ;terminate with blank, tab, or <cr>
       je      gotit
       cmpb    al,9
       je      gotit
       cmpb    al,13
       je      gotit
       jmps    get2

;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
       mov     ah,9
       int     21H
       jmp     error

;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
       mov     dx,ax           ;offset 0
       mov     ah,40H
       int     21H             ;write block to file
       pop     ds              ;get ds back
       jae     ems             ;ok, continue

       mov     dx,offset(nowrit) ;write error
       mov     ah,9
       int     21H
       jmp     error

;determine whether EMS is present
ems    push    bx              ;temporarily store the real 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
       shl     bx              ;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
       mov     ah,40H
       int     21H             ;write out the table
       jae     closfl          ;ok,continue

       mov     dx,offset(nowrit) ;error while writing
       mov     ah,9
       int     21H
       jmps    error

;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
       mov     ah,9
       int     21H
       jmps    error

;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,9            ;characters in ID string
       cld
       rep
       movsb                   ;copy string

;deallocate environment block of this mark
deall  mov     ax,[2CH]        ;environment segment
       mov     es,ax           ;  into es
       mov     ah,49H
       int     21H             ;deallocate, no reason for an error to occur

;print message and TSR
gores  mov     dx,offset(didit)
       mov     ah,9
       int     21H             ;write success message including filename
       mov     dx,offset(crlf) ;newline
       mov     ah,9
       int     21H

       xor     dx,dx           ;get number of paragraphs to keep
       mov     dl,[80H]        ;length of command line
       add     dx,80H          ;rest of PSP
       mov     cl,4
       shr     dx,cl           ;convert to paragraphs
       inc     dx              ;round up
       mov     ax,3100H
       int     21H             ;terminate and stay resident

;error output - show syntax line
error  mov     dx,offset(syntax)
       mov     ah,9
       int     21H

;exit with error
errex  mov     ax,4C01H
       int     21H
       endp

;messages
emsnm  db      'EMMXXXX0',0    ;file name for testing EMS presence
id     db      'FMARK TSR'     ;id string for RELEASE check
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
syntax db      13,10,'Syntax:  FMARK [d:][path]filename'
crlf   db      13,10,36
didit  db      13,10,'FMARK 2.1 - Marked current memory position in '

;data storage area
filnm  ds      50H,36          ;file name where tables are written
emscnt db      0,0             ;holds number of active pages in map that follows
emsmap db      0,0             ;holds EMS page map if installed
                               ;(note may extend 1K bytes past end of file in mem)
