dos_compilers/Microsoft Pascal v4/WORK/ENTX6L.ASM
2024-07-01 21:27:27 -07:00

515 lines
11 KiB
NASM

PAGE 56,132
title entx - Common Pascal/FORTRAN Initialization module
;---------------------------------------------------------------------------
;
; Microsoft MS-DOS/Windows/XENIX Pascal/FORTRAN Initialization
; Version 3.30 (C) Copyright 1984 Microsoft Corporation
;
; BEGXQQ is called (indirectly) from the C runtime startup routine.
; It performs initialization of the Pascal and FORTRAN runtime
; systems. Note that if it is called again, BEGXQQ simply returns.
;
; ENDXQQ is called (again, indirectly) from the C startup routine,
; just before it terminates the user's program. ENDXQQ also ignores
; all but its first invocation.
;
; Revision History
;
; 06/14/84 Allen Akin
; First version, cribbed from previous
; versions of ENTX and MS-C startup routines
; 07/12/84 Allen Akin
; Modified initializer scheme to allow
; arbitrary numbers of initializers
; 11/07/84 Gordon Whitten
; Moved DOSXQQ to RTIM6.ASM
; 11/21/84 Greg Whitten
; 11/28/84 set up new stack checking
; 11/29/84 set up newer stack checking
; 12/04/84 Allen Akin
; Added calls to old-style escape
; initializers (BEGOQQ and ENDOQQ)
; for compatibility with earlier
; releases.
; 12/04/84 Added floating-point exception handler
; for XENIX.
;---------------------------------------------------------------------------
?DF = 1
include pasrun.inc
page
include sysi.inc
page
; Special segments used in this module
; CreateSeg name, logname,align, combine,class, group
CreateSeg _TEXT, code, byte, public, CODE
CreateSeg _DATA, data, word, public, DATA, DGROUP
ifndef WINDOWS
CreateSeg STACK, STACK, word, stack, STACK, DGROUP
endif
CreateSeg XIB, xibeg, word, public, DATA, DGROUP
CreateSeg XI, xiseg, word, public, DATA, DGROUP
CreateSeg XIE, xiend, word, public, DATA, DGROUP
CreateSeg XCB, xcbeg, word, public, DATA, DGROUP
CreateSeg XC, xcseg, word, public, DATA, DGROUP
CreateSeg XCE, xcend, word, public, DATA, DGROUP
CreateSeg P1IB, pf1ibeg,word, public, DATA, DGROUP
CreateSeg P1I, pf1iseg,word, public, DATA, DGROUP
CreateSeg P1IE, pf1iend,word, public, DATA, DGROUP
CreateSeg P2IB, pf2ibeg,word, public, DATA, DGROUP
CreateSeg P2I, pf2iseg,word, public, DATA, DGROUP
CreateSeg P2IE, pf2iend,word, public, DATA, DGROUP
CreateSeg P3IB, pf3ibeg,word, public, DATA, DGROUP
CreateSeg P3I, pf3iseg,word, public, DATA, DGROUP
CreateSeg P3IE, pf3iend,word, public, DATA, DGROUP
CreateSeg P1CB, pf1cbeg,word, public, DATA, DGROUP
CreateSeg P1C, pf1cseg,word, public, DATA, DGROUP
CreateSeg P1CE, pf1cend,word, public, DATA, DGROUP
CreateSeg P2CB, pf2cbeg,word, public, DATA, DGROUP
CreateSeg P2C, pf2cseg,word, public, DATA, DGROUP
CreateSeg P2CE, pf2cend,word, public, DATA, DGROUP
CreateSeg P3CB, pf3cbeg,word, public, DATA, DGROUP
CreateSeg P3C, pf3cseg,word, public, DATA, DGROUP
CreateSeg P3CE, pf3cend,word, public, DATA, DGROUP
DefGrp DGROUP
page
; System resident public data
; these could be communal variables and off in some other segment
externDP ___argv ; arg pointer set by C startup
externW ___argc ; arg count set by C startup
sBegin data
assumes ds,data
ifdef MSD
externW __psp ; program segment prefix paragraph #
endif
externCP __aaltstkovr ; alternate stack overflow handler
globalW STKBQQ,0 ; stack top - set by main program
globalW CSXEQQ,0 ; pointer to source context list
globalW CLNEQQ,0 ; last line number encountered
globalW PNUXQQ,0 ; pointer to unit initialization list
globalW HDRFQQ,0 ; Unit F open file list header
globalW HDRVQQ,0 ; Unit V open file list header
globalW RESEQQ,0 ; machine error context, stack pointer
globalW REFEQQ,0 ; machine error context, frame pointer
globalW REPEQQ,0 ; machine error context, program offset
globalW RECEQQ,0 ; machine error context, program segment
globalW UPCX87,0 ; offset address of 8087 error context
globalW DGRMQQ,0 ; segment of DGROUP
globalW DOSEQQ,0 ; DOS return code
globalDP AGVXQQ,0 ; pointer to argument vector
globalW AGCXQQ,0 ; count of argument
globalW CURXQQ,1 ; index of argument currently in use
globalW RETLQQ,0 ; return address storage, used by pocket code
ifdef MSD
globalW CESXQQ,0 ; segment for arg string under DOS
endif
sEnd
page
; Local data:
sBegin data
staticW BEGX_CALLED,0 ; non-zero iff BEGXQQ has been called
staticW ENDX_CALLED,0 ; non-zero iff ENDXQQ has been called
sEnd
page
; C Runtime initialization segment:
sBegin xiseg
StaticCP begx,BEGXQQ ; General Pascal/FORTRAN initialization
sEnd
; C Runtime termination segment:
sBegin xcseg
StaticCP endx,PFTERM ; General Pascal/FORTRAN termination
sEnd
page
; Pascal/Fortran initialization segments:
sBegin pf1ibeg ; Unit U initialization level
uuibeg label dword
sEnd
; initializer addresses appear in pf1iseg, here in the middle...
sBegin pf1iend
uuiend label dword
sEnd
sBegin pf2ibeg ; User initialization level
uoibeg label dword
sEnd
; user initializer addresses appear in pf2iseg, here in the middle...
sBegin pf2iend
uoiend label dword
sEnd
sBegin pf3ibeg ; Unit F/V initialization level
ufibeg label dword
sEnd
; unit F/V initializer addresses appear in pf3iseg, here in the middle...
sBegin pf3iend
ufiend label dword
sEnd
page
; Pascal/FORTRAN termination segments:
sBegin pf1cbeg ; Unit U termination level
uucbeg label dword
sEnd
; unit U cleanup addresses appear in pf1cseg, here in the middle...
sBegin pf1cend
uucend label dword
sEnd
sBegin pf2cbeg ; User termination level
uocbeg label dword
sEnd
; user cleanup addresses appear in pf2cseg, here in the middle...
sBegin pf2cend
uocend label dword
sEnd
sBegin pf3cbeg ; Unit F/V termination level
ufcbeg label dword
sEnd
; unit F/V cleanup addresses appear in pf3cseg, here in the middle...
sBegin pf3cend
ufcend label dword
sEnd
page
; BEGXQQ - Common FORTRAN/Pascal Initialization Code
externP SOWGQQ
externP BEGOQQ ; escape initializer, old-style
externP ENDOQQ ; escape terminator, old-style
if XENIXRUNTIME
externP _signal ; XENIX exception-handling routine
externP XFPEQQ ; Pascal/FORTRAN exception vectoring routine
endif
sBegin code
assumes cs,code
assumes ds,dgroup
cProc BEGXQQ,<PUBLIC,FAR>
cBegin
cmp BEGX_CALLED,0 ; have we been called before?
jne breturn ; if so, just return
inc BEGX_CALLED ; prevent further calls
mov ax,seg SOWGQQ ; __chkstk escape for
mov word ptr [__aaltstkovr+2],ax ; P/F stack overflow
mov ax,offset SOWGQQ
mov word ptr [__aaltstkovr],ax
mov ax,seg ___argv ; prepare to address ___argv, which may be far
mov es,ax
mov ax,word ptr es:___argv ; copy C's argv pointer into Pascal's
mov word ptr AGVXQQ,ax
if SizeD
mov ax,word ptr es:___argv+2
mov word ptr AGVXQQ+2,ax
endif
mov ax,seg ___argc
mov es,ax
mov ax,es:___argc ; copy C's arg count into Pascal's
mov AGCXQQ,ax
ifdef MSD
mov ax,__psp ; get program segment prefix pp. address
mov CESXQQ,ax ; save it away for use by Pascal
endif
init1: ; perform first-level initializations,
; including unit U
mov bx,offset DGROUP:uuibeg
init1_1:
cmp bx,offset DGROUP:uuiend
jae init2
push bx
push si
push di
if SizeC
call dword ptr [bx]
else
call word ptr [bx]
endif
pop di
pop si
pop bx
if SizeC
add bx,4
else
add bx,2
endif
jmp init1_1
init2: ; perform second-level initializations
; including unit O and old-style escape
; initializers
if XENIXRUNTIME
mov ax,SEG fpe_handler
push ax
mov ax,OFFSET fpe_handler
push ax
mov ax,08H ; SIGFPE
push ax
call _signal ; set up to catch floating-point exceptions
add sp,6
endif
call BEGOQQ
mov bx,offset DGROUP:uoibeg
init2_1:
cmp bx,offset DGROUP:uoiend
jae init3
push bx
push si
push di
if SizeC
call dword ptr [bx]
else
call word ptr [bx]
endif
pop di
pop si
pop bx
if SizeC
add bx,4
else
add bx,2
endif
jmp init2_1
init3: ; perform third-level initializations
; including units F and V
mov bx,offset DGROUP:ufibeg
init3_1:
cmp bx,offset DGROUP:ufiend
jae initlast
push bx
push si
push di
if SizeC
call dword ptr [bx]
else
call word ptr [bx]
endif
pop di
pop si
pop bx
if SizeC
add bx,4
else
add bx,2
endif
jmp init3_1
initlast:
breturn: ; return -- all done.
cEnd
if XENIXRUNTIME
page
; fpe_handler - Floating-point exception handler for XENIX
; For the present, this routine just calls XFPEQQ (the FORTRAN/Pascal
; floating-point exception handler for XENIX). We go through this
; intermediate routine to keep the stack consistent; if we were to vector
; directly to XFPEQQ, this would not necessarily be done for us.
;
; In the future, this routine may disappear or at least fudge the stack
; to provide a little better context information for debugging.
cProc fpe_handler,<FAR>
cBegin
call XFPEQQ
cEnd
endif
sEnd
page
; ENDXQQ - Explicitly terminate Pascal or FORTRAN program
ExternP _exit ; C exit
sBegin code
assumes cs,code
assumes ds,dgroup
cProc ENDXQQ,<PUBLIC,FAR>
cBegin
ccall _exit,DOSEQQ ; exit, returning code in DOSEQQ
cEnd
sEnd
page
; PFTERM - common Pascal/FORTRAN termination
sBegin code
assumes cs,code
assumes ds,dgroup
cProc PFTERM,<FAR>
cBegin
cmp ENDX_CALLED,0 ; have we been called before?
jne ereturn ; if so, just return
inc ENDX_CALLED ; prevent further calls
term3: ; perform third-level terminations,
; including units F and V
mov bx,offset DGROUP:ufcbeg
term3_1:
cmp bx,offset DGROUP:ufcend
jae term2
push bx
push si
push di
if SizeC
call dword ptr [bx]
else
call word ptr [bx]
endif
pop di
pop si
pop bx
if SizeC
add bx,4
else
add bx,2
endif
jmp term3_1
term2: ; perform second-level terminations,
; including unit O and old-style
; escape terminator
mov bx,offset DGROUP:uocbeg
term2_1:
cmp bx,offset DGROUP:uocend
jae term1
push bx
push si
push di
if SizeC
call dword ptr [bx]
else
call word ptr [bx]
endif
pop di
pop si
pop bx
if SizeC
add bx,4
else
add bx,2
endif
jmp term2_1
term1:
call ENDOQQ
; perform first-level terminations,
; including unit U
mov bx,offset DGROUP:uucbeg
term1_1:
cmp bx,offset DGROUP:uucend
jae termlast
push bx
push si
push di
if SizeC
call dword ptr [bx]
else
call word ptr [bx]
endif
pop di
pop si
pop bx
if SizeC
add bx,4
else
add bx,2
endif
jmp term1_1
termlast:
ereturn: ; return -- all done.
cEnd
sEnd
end