;==============================================================================
; MARK.ASM - mark a position in memory,
;            above which TSRs will later be cleared by RELEASE.COM
;            MARK can be called multiple times, each RELEASE will clear
;            above the last MARK called.
; If MARK is called with something on the command line, that text will
; be stored in the program segment prefix at offset 80H, where it is
; later accessible to RELEASE for a "named" release.
;==============================================================================
; written for MASM (version 4 or later) or TASM
; by Kim Kokkonen, TurboPower Software
; telephone: 408-438-8608, Compuserve 72457,2131
;==============================================================================
; VERSION 1.4  2/23/86
;   This version also stores the EMS page map so that RELEASE can release
;   READY! and any future resident programs using expanded memory
; VERSION 1.5  2/28/86
;   to keep consistent with MAPMEM and RELEASE
; VERSION 1.6  3/8/86
;   store all 256 interrupts, but only 32 EMS blocks
; VERSION 1.7  4/1/86
;   close the EMS handle opened to avoid using up a DOS handle
; VERSION 1.8  4/20/86
;   to keep consistent with MAPMEM and RELEASE
; VERSION 1.9  5/22/86
;   to keep consistent with MAPMEM and RELEASE
; VERSION 2.0  5/26/86
;   to keep consistent with MAPMEM and RELEASE
; VERSION 2.1  7/18/86
;   to keep consistent with RELEASE
; VERSION 2.2  3/4/87
;   add save area for BIOS data areas
;     40:A8 (8 bytes for EGA)
;     40:F0 (16 bytes for interapplications communications)
; VERSION 2.3  5/1/87
;   convert to use MASM
;   chop off unused portion of EMS page map when going resident
;   modify so that the data areas are not part of the COM file
; VERSION 2.4  5/17/87
;   for consistency with RELEASE
; VERSION 2.5  6/2/87
;   add version checking between MARK and RELEASE
; VERSION 2.6  1/15/89
;   fix problem occurring when command processor is an EXE file,
;     by storing parent's PSP segment as part of MARK save area
;     (thanks to Tom Rawson for this code)
; VERSION 2.7
;   skipped
; VERSION 2.8
;   for consistency with MARKNET/RELNET
; VERSION 2.9
;   for consistency with MARKNET/RELNET
;==============================================================================

Cseg      segment public para
          assume  cs:Cseg, ds:Cseg, es:nothing

          org     100H
comentry: jmp     doit

;put the following in the MAP file
public idstr,vector,egasav,intcom,emscnt,emsmap

idstr  db      'M2.9 PARAMETER BLOCK FOLLOWS' ;used to find this TSR

;**** the following will be overwritten by the vector table image *************
;success message and version number
didit  db      'MARK 2.9 - Marked current memory position',13,10,36
;file name for testing EMS presence
emsnm  db      'EMMXXXX0',0
;******************************************************************************

vector equ     0120H           ;offset in code seg where vector table is copied
veclen equ     0400H           ;1024 bytes for vectors
egasav equ     vector+veclen
egalen equ     8               ;8 bytes for EGA save area
intcom equ     egasav+egalen
intlen equ     10H             ;16 bytes for interapps communication area
parent equ     intcom+intlen
parlen equ     2               ;2 bytes for parent's PSP
emscnt equ     parent+parlen
emsmap equ     emscnt+2

newloc equ     emsmap+100H     ;location of relocated code

;*****************************************************************************

doit   proc    near

;relocate ourselves out of the way
       mov     di,newloc
       push    di                    ;will act as a return address
       mov     si,offset pmess
       mov     cx,lastcode-pmess
       cld
       rep     movsb
       ret                          ;"return" to the relocated code

;print message
pmess:
       mov     dx,offset didit
       mov     ah,9
       int     21H             ;write success message

;determine whether EMS is present
       mov     dx,offset emsnm
       mov     ax,3D00H
       int     21H
       jnc     emspres           ;ems driver installed
       xor     bx,bx
       jmp     short stocnt

;EMS present, close the open handle first
emspres:
       mov     bx,ax
       mov     ah,3EH
       int     21H

;store the EMS page map
       mov     ah,4DH
       mov     di,emsmap
       xor     bx,bx           ;required by some versions of EMM
       cld                     ;required by some versions of EMM
       int     67H

;store the number of active handles
stocnt:
       mov     di,emscnt
       mov     [di],bx          ;count of active handles

;store the interrupt vector table (overwrites initial messages)
       xor     ax,ax
       mov     ds,ax            ;source address segment 0
       assume  ds:nothing
       xor     si,si            ;offset 0
       mov     di,vector        ;destination offset, es=cs already
       mov     cx,veclen shr 1  ;count of words to store
       rep     movsw            ;copy vectors to our table

;store the EGA save area
       mov     ax,40H
       mov     ds,ax            ;point to BIOS data area
       mov     si,00A8H         ;EGA save area pointer
       mov     di,egasav
       mov     cx,egalen shr 1
       rep     movsw            ;copy information to our save area

;store the interapplications communication area
       mov     si,00F0H         ;interapps communication area address
       mov     di,intcom
       mov     cx,intlen shr 1
       rep     movsw            ;copy information to our save area

;store the parent's PSP segment
       mov     ax,cs           ;CS = PSP
       mov     ds,ax           ;now DS = PSP
       mov     ax,ds:[16h]     ;get parent's PSP from our PSP
       mov     ds:[parent],ax  ;store in data save area

;terminate and stay resident
gores:
       mov     dx,emsmap       ;start at base of ems map
       mov     di,emscnt
       mov     bx,cs:[di]      ;count of active handles
       shl     bx,1
       shl     bx,1            ;multiply EMS handle count by 4
       add     dx,bx
       add     dx,000FH        ;round up for paragraphs
       mov     cl,4
       shr     dx,cl           ;convert to paragraphs
       mov     ax,3100H
       int     21H             ;terminate but stay resident

lastcode:
doit    endp

Cseg    ends
        end     ComEntry
