home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-08 | 21.8 KB | 1,114 lines |
- page ,132
- title crt0dat - DOS and Windows shared startup and termination
- ;***
- ;crt0dat.asm - DOS and Windows shared startup and termination
- ;
- ; Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
- ;
- ;Purpose:
- ; Shared startup and termination.
- ;
- ; NOTE: This source is included in crt0.asm for assembly purposes
- ; when building .COM startup. This is so the .COM startup resides
- ; in a single special object that can be supplied to the user.
- ;
- ;*******************************************************************************
-
- _NFILE_ = 20 ; Maximum number of file handles
-
- ifdef _QWIN
- _WFILE_ = 20 ; Maximum number of QWIN file handles
- endif
-
- ?DF = 1 ;; tell cmacros.inc we want to define our own segments
-
- .xlist
- include version.inc
- include cmacros.inc
- include msdos.inc
- include defsegs.inc
- include stdlib.inc
- .list
-
- ifndef _WINDOWS
- _DEBUGSCREEN equ 1 ; debug screen swapping
- endif
-
- ifdef FARSTACK
- ife sizeD
- error <You cannot have a far stack in Small or Medium memory models.>
- endif
- endif
-
- ifdef _COM_
- if sizeC or sizeD
- error <Must use Small memory model for .COM files.>
- endif
- endif ;_COM_
-
-
- CrtDefSegs <code,cdata,data>
-
- ifdef _DEBUGSCREEN
- CrtDefSegs <dbdata>
- endif ; _DEBUGSCREEN
-
- ifndef _WINDOWS
- CrtDefSegs <xiqcseg>
- endif
-
- CrtDefSegs <xifseg,xiseg,xoseg,xofseg,xpseg,xcseg,xcfseg>
-
- CrtDefSegs <xifcseg>
-
-
- ifdef _COM_
- CrtDefSegs <emdata, emcode>
- endif ;_COM_
-
- defGrp DGROUP ; define DGROUP
-
- codeOFFSET equ offset _TEXT:
- dataOFFSET equ offset DGROUP:
-
- page
-
-
- sBegin xifbseg
- xifbegin label byte ; Far initializers begin/end
- sEnd xifbseg
-
- sBegin xifeseg
- xifend label byte
- sEnd xifeseg
-
-
- sBegin xibseg
- xibegin label byte ; Initializers begin/end
- sEnd xibseg
-
- sBegin xieseg
- xiend label byte
- sEnd xieseg
-
-
- sBegin xifcbseg
- xifcbegin label byte ; far C++ constructors begin/end
- sEnd xifcbseg
-
- sBegin xifceseg
- xifcend label byte
- sEnd xifceseg
-
-
- sBegin xobseg
- xontab label byte ; atexit/onexit begin/end
- sEnd xobseg
-
- sBegin xoeseg
- xonend label byte
- sEnd xoeseg
-
-
- ife sizeC
- ; in large model _fatexit = atexit so table not needed
- sBegin xofbseg
- xfontab label byte ; far atexit/onexit begin/end
- sEnd xofbseg
-
- sBegin xofeseg
- xfonend label byte
- sEnd xofeseg
- endif
-
-
- sBegin xpbseg
- xpbegin label byte ; Pre-terminators begin/end
- sEnd xpbseg
-
- sBegin xpeseg
- xpend label byte
- sEnd xpeseg
-
-
- sBegin xcbseg
- xcbegin label byte ; C terminators begin/end
- sEnd xcbseg
-
- sBegin xceseg
- xcend label byte
- sEnd xceseg
-
-
- sBegin xcfbseg
- xcfbegin label byte ; C far terminators begin/end
- sEnd xifbseg
-
- sBegin xcfeseg
- xcfend label byte
- sEnd xcfeseg
-
-
- sBegin cdata ; floating point setup segment
- assumes ds,data
-
- dw 0 ; force segment to be at least 0's
- labelD <PUBLIC,_fpinit> ; public for signal
- fpmath dd 1 dup (?) ; linking trick for fp
- fpdata dd 1 dup (?)
- fpsignal dd 1 dup (?) ; fp signal message
-
- sEnd
-
- ifdef _BAT16
- extrn LibvapExit:NEAR
- endif ;_BAT16
-
- ifdef _DEBUGSCREEN
- sBegin dbdata ;
- assumes ds,data ; Used to do the running under
- externW __aDBswpflg ; a debugger screen swapping
- externW __aDBexit ;
- sEnd dbdata ;
- extrn __aDBdoswp:ABS ;
- endif ; _DEBUGSCREEN
-
- ifndef _WINDOWS
- sBegin xiqcseg
- labelW <PUBLIC,__qczrinit> ;* QC -Zr initializer call address
- dw 1 dup(?)
- sEnd xiqcseg
- endif
-
-
- ifdef _COM_
- sBegin EmData
- labelB _EmDataLabel
- sEnd EmData
-
- sBegin EmCode
- globalW _EmDataSeg,0
- sEnd EmCode
-
- else ;not _COM
- ifndef _WINDOWS
- EMULATOR_DATA segment para public 'FAR_DATA'
- EMULATOR_DATA ends
-
- EMULATOR_TEXT segment para public 'CODE'
-
- public __EmDataSeg
- __EmDataSeg dw EMULATOR_DATA
-
- EMULATOR_TEXT ends
- endif ;not _WINDOWS
- endif ;not _COM_
-
- sBegin data
- assumes ds,data
-
- ifndef _WINDLL
- ; special C environment string
- labelB <PUBLIC,_acfinfo>
- cfile db '_C_FILE_INFO='
- cfilex db 0
- cfileln = cfilex-cfile
- endif ;!_WINDLL
-
- globalD _aintdiv,0 ; divide error interrupt vector save
-
- globalT _fac,0 ; floating accumulator
- globalW errno,0 ; initial error code
- globalW _umaskval,0 ; initial umask value
-
- ifndef _WINDLL
- ;=============== following must be in this order
-
- globalW _pspadr,0 ; psp:0 (far * to PSP segment)
- globalW _psp,0 ; psp:0 (paragraph #)
-
- ;=============== above must be in this order
- endif
-
- ;=============== following must be in this order
- ifdef _WINDOWS
-
- labelW <PUBLIC,_winver> ; WIN version
- globalB _winminor,0
- globalB _winmajor,0
-
- endif ;_WINDOWS
-
- labelW <PUBLIC,_osver> ; OS version
- globalB _osminor,0
- globalB _osmajor,0
-
- globalW _osversion,0
-
- ;=============== above must be in this order
-
-
- ifdef _WINDOWS
- globalB _osmode,_WIN_MODE ; Windows
- globalB _cpumode,_PROT_MODE ; protected mode (default)
- else
- globalB _osmode,_DOS_MODE ; DOS
- globalB _cpumode,_REAL_MODE ; real mode
- endif
-
- labelW <PUBLIC,_oserr>
- globalW _doserrno,0 ; initial DOS error code
-
- ;
- ; --- I/O Data ---
- ;
-
- globalW _nfile,_NFILE_ ; maximum number of file handles
-
- ifdef _QWIN
- globalW _wfile,_WFILE_ ; maximum number of QWIN file handles
- globalW _wnfile,(_NFILE_+_WFILE_) ; maximum number of total file handles
- endif
-
- ifdef _WINDOWS
- ifdef _BAT16
- labelB <PUBLIC,_osfile>
- db 3 dup (FOPEN+FTEXT+FDEV); stdin/out/err
- db _NFILE_-3 dup (0) ; the other handles
- else ;_BAT16
- labelB <PUBLIC,_osfile>
- db _NFILE_ dup (0) ; (no std files in windows)
- endif ;_BAT16
- else
- labelB <PUBLIC,_osfile>
- db 3 dup (FOPEN+FTEXT) ; stdin, stdout, stderr
- db 2 dup (FOPEN) ; stdaux, stdprn
- db _NFILE_-5 dup (0) ; the other 15 handles
- endif ;_WINDOWS
-
- ifdef _QWIN
- labelB <PUBLIC,_wsfile>
- db (FOPEN+FTEXT+FDEV) ; stdin/out/err
- db _WFILE_-1 dup (0) ; the other QWIN handles
-
- ; Make sure _osfile and _wsfile are contiguous
- .ERRE offset _osfile+_NFILE_ EQ offset _wsfile
- endif ;_QWIN
-
- ifdef _QWIN
- ;Force in QWIN system
- extrn __qwinused:word ; QWIN used/notused flag
- endif
-
- ; --- End I/O Data ---
-
- globalW __argc,0
- globalDP __argv,0
- globalDP _environ,0 ; environment pointer
-
- labelD <PUBLIC,_pgmptr> ; pointer to program name
- dw dataOFFSET dos2nam
- ifdef _COM_
- dw 0 ; No relocations in tiny model
- elseifdef _QC2
- dw 0 ; No DGROUP references allowed
- elseifdef _WINDOWS
- dw 0 ; No DGROUP references allowed
- else ;DEFAULT
- dw DGROUP
- endif
-
- dos2nam db 0 ; dummy argv[0] for DOS 2.X
-
-
- ; signal related common data
-
- globalW _child,0 ; flag used to handle signals from child process
-
- ifndef _WINDOWS
- ;Overlay related data
- globalB _ovlflag,0 ;Overlay flag (0 = no overlays)
- globalB _intno,0 ;Overlay interrupt value (e.g., 3F)
- globalD _ovlvec,0 ;Address of original overlay handler
- endif ;!_WINDOWS
-
-
- globalB _exitflag,0 ; callable exit
-
- sEnd data
-
- page
-
- externNP _fptrap
-
- ifndef _WINDLL
- externP _cintDIV
- endif
-
- ifndef _WINDOWS
- externP _nullcheck
- endif
-
- ifdef FARSTACK
- ifdef _WINDOWS
- externP _GetDGROUP
- endif
- endif
-
- ifdef _QWIN
- externNP _wcexit ; exit the QWIN system
- endif
-
- ifdef _WINDLL
- extern __nearstub:near ; weak extern substitute
- extern __freefarheap(__nearstub):near ; free up all far heap mem
- extern __freebasedheap(__nearstub):near; free up all based heap mem
- endif
-
- if (_NFILE_ NE 20)
- ifdef _WINDOWS
- extern SETHANDLECOUNT:far ; set file count
- endif
- endif
-
- sBegin code
- assumes cs,code
-
- if sizeC
- global proc far
- endif
-
- page
- ;***
- ;_cinit - C initialization
- ;
- ;Purpose:
- ; This routine performs the shared DOS and Windows initialization.
- ; The following order of initialization must be preserved -
- ;
- ; 1. Integer divide interrupt vector setup
- ; 2. Floating point initialization
- ; 3. Copy ;C_FILE_INFO into _osfile
- ; 4. Check for devices for file handles 0 - 4
- ; 5. General C initializer routines
- ;
- ;Entry:
- ;
- ;Exit:
- ;
- ;Uses:
- ;
- ;Exceptions:
- ;
- ;*******************************************************************************
-
- cProc _cinit,<PUBLIC>,<>
-
- ifdef _WINDOWS ; add windows prolog/epilog code to far frames
- if sizeC
- cBegin
- else
- cBegin <nogen>
- endif ;sizeC
- else
- cBegin <nogen> ; no local frame to set up in standard libs
- endif ; _WINDOWS
-
- assumes ds,data
- ifndef FARSTACK
- assumes ss,data
- endif
-
- ifdef _COM_
- ;
- ; Initialize the DGROUP portion of _pgmptr. We must do this at
- ; runtime since there are no load-time fixups in .COM files.
- ;
- mov word ptr [_pgmptr+2],ds ; init seg portion of _pgmptr
- endif ;_COM_
-
-
- if (_NFILE_ NE 20)
- ;
- ; *** Increase File Handle Count ***
- ;
- ifdef _WINDOWS
- mov bx,_NFILE_ ; number of file handle to allow
- push bx
- call SETHANDLECOUNT ; issue the system call
- ;check for error here, if desired (AX equals number of files supported)
- else
- ; This code only works on DOS Version 3.3 and later.
- mov ah,67h ; system call number
- mov bx,_NFILE_ ; number of file handles to allow
- callos ; issue the system call
- ;check for error here, if desired (if carry set, AX equals error code)
- endif
- ;
- ; *** End Increase File Handle Count ***
- ;
- endif ; (_NFILE_ NE 20)
-
- ifndef _BAT16
- ifndef _WINDLL
-
- ; 1. Integer divide interrupt vector setup
-
- mov ax,DOS_getvector shl 8 + 0
- callos ; save divide error interrupt
- mov word ptr [_aintdiv],bx
- mov word ptr [_aintdiv+2],es
-
- push cs
- pop ds
- assumes ds,nothing
- mov ax,DOS_setvector shl 8 + 0
- mov dx,codeOFFSET _cintDIV
- callos ; set divide error interrupt
-
- ifdef FARSTACK
- ifdef _WINDOWS
- callcrt _GetDGROUP
- mov ds, ax
- else
- mov ax, DGROUP
- mov ds, ax
- endif
- else
- push ss
- pop ds ; restore DS=DGROUP
- endif
- assumes ds,data
-
- endif ;!_WINDLL
- endif ;!_BAT16
-
-
- ; 2. Floating point initialization
-
-
- if memS
-
- ifdef _WINDOWS
- mov cx,word ptr [fpmath+2]
- jcxz nofloat_i
-
- else ;not _WINDOWS
- cmp word ptr [fpmath], 0 ; Note: make sure offset __fpmath != 0
- je nofloat_i
-
- mov word ptr [fpmath+2], cs ; fix up these far addresses
- mov word ptr [fpsignal+2], cs ; in the small model math libs
-
- ifdef _COM_
- mov [_EmDataSeg], cs
- mov ax, offset DGROUP:_EmDataLabel
- sub ax, offset EMULATOR_DATA:_EmDataLabel
- mov cl, 4
- shr ax, cl
- add [_EmDataSeg], ax
- endif ;_COM_
-
- endif ;not _WINDOWS
-
- else ;not memS
-
- mov cx,word ptr [fpmath+2]
- jcxz nofloat_i
-
- endif ;not memS
-
- ifdef _WINDLL
- xor si,si ; no environment in Win DLL
- else ;!_WINDLL
- mov es,[_psp] ; psp segment
- mov si,es:[DOS_ENVP] ; environment segment
- endif ;_WINDLL
-
- mov ax, word ptr [fpdata]
- mov dx, word ptr [fpdata+2]
- xor bx,bx ; (si) = environment segment
- call [fpmath] ; fpmath(0) - init
- jnc fpok
- jmp _fptrap ; issue "Floating point not loaded"
- ; error and abort
- fpok:
-
- ifndef _WINDLL
-
- mov ax, word ptr [fpsignal]
- mov dx, word ptr [fpsignal+2]
- mov bx,3
- call [fpmath] ; fpmath(3) - set signal address
-
- endif ;!_WINDLL
-
- nofloat_i:
-
-
-
- ifndef _WINDLL
-
- ; 3. Copy _C_FILE_INFO= into _osfile
-
- ; fix up files inherited from parent using _C_FILE_INFO=
-
- mov es,[_psp] ; es = PSP
- mov cx,word ptr es:[DOS_envp] ; es = user's environment
- jcxz nocfi ; no environment !!!
- mov es,cx
- xor di,di ; start at 0
-
- cfilp:
- cmp byte ptr es:[di],0 ; check for end of environment
- je nocfi ; yes - not found
- mov cx,cfileln
- mov si,dataOFFSET cfile
- repe cmpsb ; compare for '_C_FILE_INFO='
- je gotcfi ; yes - now do something with it
- mov cx,07FFFh ; environment max = 32K
- xor ax,ax
- repne scasb ; search for end of current string
- jne nocfi ; no 00 !!! - assume end of env.
- jmp cfilp ; keep searching
-
- ; found _C_FILE_INFO= and transfer info into _osfile
-
- gotcfi:
- push es
- push ds
- pop es ; es = DGROUP
- pop ds ; ds = env. segment
- assumes ds,nothing
- assumes es,data
- mov si,di ; si = startup of _osfile info
- mov di,dataOFFSET _osfile ; di = _osfile block
-
- mov cl, 4
-
- osfile_lp:
- lodsb
- sub al, 'A'
- jb donecfi
- shl al, cl
- xchg dx, ax
-
- lodsb
- sub al, 'A'
- jb donecfi
- or al, dl
- stosb
- jmp short osfile_lp
-
- donecfi:
- ifdef FARSTACK
- push es
- else
- push ss
- endif
- pop ds ; ds = DGROUP
- assumes ds,data
-
- nocfi:
-
- endif ;!_WINDLL
-
-
- ifndef _WINDOWS
-
- ; 4. Check for devices for file handles 0 - 4
- ;
- ; Clear the FDEV bit (which might be inherited from C_FILE_INFO)
- ; and then call DOS to see if it really is a device or not
- ;
- mov bx,4
-
- devloop:
- and _osfile[bx],not FDEV ; clear FDEV bit on principal
-
- mov ax,DOS_ioctl shl 8 + 0 ; issue ioctl(0) to get dev info
- callos
- jc notdev
-
- test dl,80h ; is it a device ?
- jz notdev ; no
- or _osfile[bx],FDEV ; yes - set FDEV bit
-
- notdev:
- dec bx
- jns devloop
-
- endif ;!_WINDOWS
-
-
- ; 5. General C initializer routines
-
- mov si,dataOFFSET xifbegin
- mov di,dataOFFSET xifend
- call farinitterm ; call the far initializers
-
- mov si,dataOFFSET xibegin
- mov di,dataOFFSET xiend
- call initterm ; call the initializers
-
- mov si,dataOFFSET xifcbegin
- mov di,dataOFFSET xifcend
- call farinitterm ; call far C++ constructors.
-
- ifdef _WINDOWS ; add epilog code to windows far frame
- if sizeC
- cEnd
- else
- ret
- cEnd <nogen>
- endif ;sizeC
- else
- ret
- cEnd <nogen> ; standard C libs
- endif ; _WINDOWS
-
-
- page
- ;***
- ;exit(status), _exit(status), _cexit(void), _c_exit(void) - C termination
- ;
- ;Purpose:
- ;
- ; Entry points:
- ;
- ; exit(code): Performs all the C termination functions
- ; and terminates the process with the return code
- ; supplied by the user.
- ;
- ; _exit(code): Performs a quick exit routine that does not
- ; do certain 'high-level' exit processing. The _exit
- ; routine terminates the process with the return code
- ; supplied by the user.
- ;
- ; _cexit(): Performs the same C lib termination processing
- ; as exit(code) but returns control to the caller
- ; when done (i.e., does NOT terminate the process).
- ;
- ; _c_exit(): Performs the same C lib termination processing
- ; as _exit(code) but returns control to the caller
- ; when done (i.e., does NOT terminate the process).
- ;
- ; Termination actions:
- ;
- ; exit(), _cexit ():
- ;
- ; 1. call user's terminator routines
- ; 2. call C runtime preterminators
- ;
- ; _exit(), _c_exit():
- ;
- ; 3. call C runtime terminators
- ; 4. perform _nullcheck() for null pointer assignment
- ; 5. terminate floating point
- ; 6. reset divide by zero interrupt vector
- ; 7. return to DOS or caller
- ;
- ; Notes:
- ;
- ; The termination sequence is complicated due to the multiple entry
- ; points sharing the common code body while having different entry/exit
- ; sequences.
- ;
- ;Entry:
- ; exit(), _exit()
- ; int status - exit status (0-255)
- ;
- ; _cexit(), _c_exit()
- ; <no input>
- ;
- ;Exit:
- ; exit(), _exit()
- ; <EXIT to DOS>
- ;
- ; _cexit(), _c_exit()
- ; Return to caller
- ;
- ;Uses:
- ;
- ;Exceptions:
- ;
- ;*******************************************************************************
-
- ifndef _WINDLL
-
- ;
- ;--- exit(): Full exit and term process ---
- ;
-
-
- public _exit
- _exit:
- cProc dummy1,<>,<>
-
- parmw status ; termination code
-
- cBegin
-
- xor cx,cx ; exit(): cl = 0, ch = 0
- jmp short common1 ; join common code
-
- cEnd <nogen>
-
- ;
- ;--- _exit(): Quickie exit and term process ---
- ;
-
-
- public __exit
- __exit:
- cProc dummy2,<>,<>
-
- parmw status ; termination code
-
- cBegin
-
- mov cx,1 ; _exit(): cl = 1, ch = 0
- jmp short common1 ; join common code
-
- cEnd <nogen>
-
- endif ;!_WINDLL
-
- if sizeC
- global endp
- endif
-
- ;
- ;--- _cexit(): Full exit and return to caller ---
- ;
-
- cProc _cexit,<PUBLIC>,<SI,DI>
-
- cBegin
-
- mov cx,(1 SHL 8) ; _cexit(): ch = 1, cl = 0
- jmp short common1 ; join common code
-
- cEnd <nogen>
-
- ;
- ;--- _c_exit(): Quickie exit and return to caller ---
- ;
-
- cProc _c_exit,<PUBLIC>,<SI,DI>
-
- cBegin
-
- mov cx,(1 SHL 8)+1 ; _c_exit(): ch = 1, cl = 1
- ;fall through
-
- ;
- ;--- Common entry point ---
- ; cx = entry value:
- ; cl = full vs quick exit path
- ; 0 = exit() code
- ; 1 = _exit() code
- ; ch = term process vs return to caller
- ; 0 = term process
- ; 1 = return to caller
- ;
-
- common1: ; all code paths join here
-
- assumes ds,data
- ifndef FARSTACK
- assumes ss,data
- endif
-
- ;
- ; save exit flag (used by terminators)
- ;
- mov [_exitflag],ch
-
- ;
- ; If _exit()/_c_exit(), jump over the initial termination processing
- ; cx = entry code
- ;
-
- push cx ; save entry code on top of stack
- or cl,cl ; cl != 0 means _exit()/_c_exit()
- jnz short common2 ; if _exit()/_c_exit(), jump down
- ;fall thru ; continue (exit, _cexit)
-
-
- ; 1. call user terminators
- ; (atexit/onexit processing)
-
- mov si,dataOFFSET xontab
- mov di,dataOFFSET xonend
- call initterm ; atexit/onexit table
-
- ife sizeC
- ; in large code, _fatexit = atexit so no need to walk far table
- mov si,dataOFFSET xfontab
- mov di,dataOFFSET xfonend
- call farinitterm ; far atexit/onexit table
- endif
-
- ; 2. call C runtime preterminators
- ; - flushall
- ; - rmtmp
-
- mov si,dataOFFSET xpbegin ; beginning of pre-terminators
- mov di,dataOFFSET xpend ; end of pre-terminators
- call initterm
-
- ifdef _QWIN
- ;
- ; Exit the QWIN system. We can't do this in the pre-terminators because
- ; we want to make sure flushall() gets called before _QWINExit.
- ;
- mov si,[status]
- push si
- call _wcexit
- add sp,2
-
- endif ;_QWIN
-
- ifdef _DEBUGSCREEN
- ;
- ; Tell the debugger we are going to exit
- ;
- cmp __aDBswpflg,__aDBdoswp ; Are we under a debugger?
- jne @F ; No -- skip forward
- cCall __aDBexit ; Yes -- tell it we are exiting
- @@:
- endif ; _DEBUGSCREEN
-
- ;
- ;--- Common entry point ---
- ;
-
- common2: ; __exit() enters here
-
-
- ; 3. perform C terminators
-
- mov si,dataOFFSET xcbegin
- mov di,dataOFFSET xcend
- call initterm ; call the terminators
-
- mov si,dataOFFSET xcfbegin
- mov di,dataOFFSET xcfend
- call farinitterm ; call the far terminators
-
- ; 4. perform _nullcheck() for null pointer assignment
-
- ifndef _COM_ ; DS:0 is the PSP in .COM files!
- ifndef _WINDOWS ; Don't validate the copyright message in windows
-
- call _nullcheck ; check data in NULL data segment at DS:0
- ; this must be far call in large code models
- ; since user can stub it out
- or ax,ax ; zero if no null ptr assignment detected
- jz afternullchk
-
- pop ax ; get entry code
- or ah,ah ; ah != 0 means _cexit()/_c_exit()
- push ax ; put it back for later
- jnz short afternullchk ; jump if no status value (_cexit/_c_exit)
-
- cmp status,0 ; zero if no other error has occurred
- jnz short afternullchk
- mov status,255 ; nonzero status to indicate an
- ; null-pointer-assignment error
- afternullchk:
-
- endif ;_WINDOWS
- endif ;_COM_
-
- ; 5. terminate floating point
- ; 6. reset divide by zero interrupt vector
-
- call _ctermsub ; fast cleanup
-
- ifdef _WINDLL
- ; 6a. free up all global memory to the OS
- ; [NOTE 1: This is necessary because WINDLL memory is
- ; shared and windows won't reclaim it.]
- ; [NOTE 2: This routine must be called last because a
- ; terminator may reference the heap.]
-
- call __freefarheap ; free up far memory
- call __freebasedheap ; free up based memory
- endif
-
- ; 7. return to the DOS or caller
-
- ifdef _WINDLL
- ; Always return to caller (exit/_exit is illegal)
- pop ax ; clean off stack
- else
- pop ax ; get entry code off top of stack
- or ah,ah ; ah = 0 means term process
- jnz returning ; skip down if not term'ing
-
- ; 7a. return to the DOS
-
- exiting:
- mov ax,status ; get return value
-
- ifdef _BAT16
- jmp LibvapExit ;* BAT16 uses different exit code
- else ; _BAT16
- callos terminate ; exit with al = return code
- endif ; _BAT16
-
- ;*** PROCESS IS TERMINATED ***
-
- endif ;_WINDLL
-
- ; 7b. Return to caller.
-
- returning:
-
- cEnd <nolocals>
-
-
- page
- ;***
- ;_ctermsub - more C termination code
- ;
- ;Purpose:
- ; This routine
- ; (1) performs floating-point termination
- ; (2) resets the divide by zero interrupt vector
- ; (3) restore int 3F handler
- ;
- ;Entry:
- ;
- ;Exit:
- ;
- ;Uses:
- ; AX,BX,CX,DX.
- ;
- ;Exceptions:
- ;
- ;*******************************************************************************
-
- labelNP <PUBLIC,_ctermsub>
-
- ; 4. terminate floating point
-
-
- mov cx,word ptr [fpmath+2] ; test for floating point
- jcxz nofloat_t ; no
-
- mov bx,2 ; yes - cleanup
- call [fpmath]
-
- nofloat_t:
-
-
- ifndef _BAT16
- ifndef _WINDLL
-
- ; 5. reset divide by zero interrupt vector
-
- push ds
- lds dx,[_aintdiv] ; ds:dx = restore vector
- mov ax,DOS_setvector shl 8 + 0
- callos ; set divide error interrupt
- pop ds
-
- endif ;!_WINDLL
- endif ;!_BAT16
-
-
- ret
-
-
- page
- ;***
- ;initterm - do a set of initializers or terminators
- ;
- ;Purpose:
- ; The initializors and terminators may be written in C
- ; so we are assuming C conventions (DS=SS, CLD, SI and DI preserved)
- ; We go through them in reverse order for onexit.
- ;
- ;Entry:
- ; SI = start of procedure list
- ; DI = end of procedure list
- ;
- ;Exit:
- ;
- ;Uses:
- ;
- ;Exceptions:
- ;
- ;*******************************************************************************
-
- if sizeC
- farinitterm: ; large code farinitterm = initterm
- endif
-
- initterm:
- cmp si,di ; are we done?
- jae itdone ; yes - no more
-
- if sizeC
- sub di,4
- mov ax,[di]
- or ax,[di+2]
- jz initterm ; skip null procedures
- call dword ptr [di]
- else
- dec di
- dec di
- mov cx,[di]
- jcxz initterm ; skip null procedures
- call cx
- endif
- jmp initterm ; keep looping
-
- itdone:
- ret
-
- page
-
- ife sizeC ; S/C models only
- ;***
- ;farinitterm - do a set of far initializers or terminators
- ;
- ;Purpose:
- ; The initializors and terminators may be written in C
- ; so we are assuming C conventions (DS=SS, CLD, SI and DI preserved)
- ; We go through them in reverse order for onexit.
- ;
- ;Entry:
- ; SI = start of procedure list
- ; DI = end of procedure list
- ;
- ;Exit:
- ;
- ;Uses:
- ;
- ;Exceptions:
- ;
- ;*******************************************************************************
-
- farinitterm:
- cmp si,di ; are we done?
- jae faritdone ; yes - no more
-
- sub di,4
- mov ax,[di]
- or ax,[di+2]
- jz farinitterm ; skip null procedures
- call dword ptr [di]
- jmp farinitterm ; keep looping
-
- faritdone:
- ret
- endif ;sizeC
-
- sEnd
-
- end
-