Google
 

Trailing-Edge - PDP-10 Archives - BB-H138F-BM_1988 - 7-sources/dynsym.mac
There are 4 other files named dynsym.mac in the archive. Click here to see a list.
UNIVERSAL DYNSYM -- Symbols associated with dynamic libraries

;
;	COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1984, 1986.
;	ALL RIGHTS RESERVED.
;
;	THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY  BE  USED  AND
;	COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH
;	THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.   THIS  SOFTWARE  OR
;	ANY  OTHER  COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE
;	AVAILABLE TO ANY OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE
;	SOFTWARE IS HEREBY TRANSFERRED.
;
;	THE INFORMATION IN THIS SOFTWARE IS  SUBJECT  TO  CHANGE  WITHOUT
;	NOTICE  AND  SHOULD  NOT  BE CONSTRUED AS A COMMITMENT BY DIGITAL
;	EQUIPMENT CORPORATION.
;
;	DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR  RELIABILITY  OF
;	ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
;

SEARCH DDBSYM,MACSYM

SALL
SUBTTL Edit History

; Version 1.0

;.EDIT 1	Put in section-zero call support
;		DDB,4-APR-84,SPR:NONE

;.EDIT 2	Put in recursive call from section zero
;		DDB,9-APR-84,SPR:NONE

;.EDIT 10	Fix code to handle new PDV format
;		DDB,12-JUN-84,SPR:NONE

; Version 1.1	Start at edit 50

;.EDIT 51	Add GLOBbing in build procedure, make DY$CBK work from JCK.
;		DDB,30-Apr-85,SPR:NONE
SUBTTL Feature Tests

FTPSCT==0			;Generate TWOSEG code

SUBTTL SEGMENT macro -- to support FTPSCT feature test

;SEGMENT MACRO
; DEFINES SEGMENTS IN TERMS OF PSECTS (FTPSCT==-1)
; OR LOW/HIGH RELOCS (FTPSCT==0)
; CURRENT SEGMENTS ARE "DATA" (impure) and some other name (for pure)
; Psect names will be .name., if psecting is selected

IFN FTPSCT,<

    DEFINE SEGMENT (SNAME) <	;;PSECTed version

	IFDEF $SEG$,<
	    IF1,<IFE <$SEG$-1>,<.ENDPS>>
	    IF2,<IFE <$SEG$-2>,<.ENDPS>
		IFN <$SEG$-2>,<$SEG$==2>
	    > ;END IF2
	> ;END IFDEF $SEG$

	IFNDEF $SEG$,<
	    IF1,< $SEG$==1>
	    IF2,< $SEG$==2>
	> ;END IFNDEF

	.PSECT .'SNAME'.
	$NAME$==''SNAME''
    > ;END SEGMENT
> ;END IFN FTPSCT

IFE FTPSCT,<
    DEFINE SEGMENT (SNAME) <	;;TWOSEG version

	IFDEF $SEG$,<
	    IF2,<
		IFE <$SEG$-1>,<$SEG$==2
		    TWOSEG 400000
		> ;END IFE $SEG$-1
		IFE <$SEG$+1>,<$SEG$==2
		    TWOSEG 400000
		> ;END IFE $SEG$+1
	    > ;END IF2
	> ;END IFDEF $SEG$

	IFNDEF $SEG$,<
	    TWOSEG 400000
	    IF1,< $SEG$==1>
	    IF2,< $SEG$==2>
	> ;END IFNDEF $SEG$

	$NAME$==''SNAME''

	IFIDN <SNAME><DATA>,<
	    IFG $SEG$,<
		RELOC
		IF1,<$SEG$==-1>
		IF2,<$SEG$==-2>>>

	IFDIF <SNAME><DATA>,<
	    IFL $SEG$,<
		RELOC
		IF1,< $SEG$==1>
		IF2,< $SEG$==2>>>
    > ;END SEGMENT
> ;END IFE FTPSCT
SUBTTL Dynamic library data structures

; Dynamic library block format version
$DYFVN==VERS.(1,0)

; Version match rule bits:
;   Compare "his" version to "our" version and accept if "his" ...
VM%MAG==1B35			;Accept if MAjor Greater
VM%MAL==1B34			;Accept if MAjor Less
VM%MIG==1B33			;Accept if major equal and MInor Greater
VM%MIL==1B32			;Accept if major equal and MInor Less

; Definition of Dynamic Library BLocK (DLBLK) data structure

.DYCNT==0			;Block length including this word
.DYFVN==1			;Format version number
.DYFLG==2			;Library flag word (digital use only)
    DY%BSY==1B35		;Set if library cannot accept another stream
	; MAGIC WARNING: DY%VER must be the same bits in word as LD%VER
    DY%VER==17B34		;Version matching rules (as defined below)
    DY%MAG==FLD(VM%MAG,DY%VER)	;Accept if MAjor Greater
    DY%MAL==FLD(VM%MAL,DY%VER)	;Accept if MAjor Less
    DY%MIG==FLD(VM%MIG,DY%VER)	;Accept if major equal and MInor Greater
    DY%MIL==FLD(VM%MIL,DY%VER)	;Accept if major equal and MInor Less
.DYUSR==3			;Word for use by library
.DYVER==4			;Library version number in TOPS-20 version format
.DYDTV==5			;IFIW DIGITAL-specified transfer vector
.DYCTV==6			;IFIW library-specific transfer vector
.DYDGV==7			;IFIW DIGITAL-specified galactic variable vector
.DYCGV==10			;IFIW library-specific galactic variable vector
; [The possibility of additional entries is reserved to DIGITAL]

; Definition of Local Dynamic Library BLocK (LDLBLK) data structure

.LDFAK==-1			;For user mode: PUSHJ P, @RL.CTV+.RLDYN 
.LDCNT==0			;Block length including this word
.LDFVN==1			;Format version number
.LDFLG==2			;Flag word (DIGITAL use only)
    LD%VMA==1B35		;Use version match rule from here rather than master
	;MAGIC WARNING: LD%VER must be the same bits of word as DY%VER
    LD%VER==17B34		;Version matching rules (as defined below)
    LD%MAG==FLD(VM%MAG,LD%VER)	;Accept if MAjor Greater
    LD%MAL==FLD(VM%MAL,LD%VER)	;Accept if MAjor Less
    LD%MIG==FLD(VM%MIG,LD%VER)	;Accept if major equal and MInor Greater
    LD%MIL==FLD(VM%MIL,LD%VER)	;Accept if major equal and MInor Less
    LD%INI==1B30		;Library has been loaded and vectors updated
.LDUSR==3			;User word
.LDCLS==4			;OWL/GBP to service class string (ASCIZ)
.LDSPC==5			;OWL/GBP to file spec string (ASCIZ)
.LDVER==6			;Library version number
.LDDTV==7			;IFIW local DIGITAL-specified transfer vector
.LDCTV==10			;IFIW local library-specific transfer vector
.LDDGV==11			;IFIW local DIGITAL-specified galactic variable vector
.LDCGV==12			;IFIW library-specific galactic variable vector
; [The possibility of additional entries is reserved to DIGITAL]

IFN LD%VER-DY%VER, <
    PRINTX ? LD%VER and DY%VER may not refer to different bits
>

; Special definition -- 
.RLBOO==1			;Entry point RTLBOO must reside at offset
				; .RLBOO in the CTVEC of the run-time library
.RLDYN==2			;Entry point DYNDYN must reside at offset
				; .RLDYN in the CTVEC of the run-time library
.RLNUL==241			;[51] Entry point RL$NUL must reside at offset
				; .rlnul in the CTVEC of the run-time library

; Definition of DIGITAL-specified entry points (by offset)
.DEMIN==1			;Master init

; A name for 1b0 (IFIW flag)
IFIW==1B0

; Definition of section zero attribute block (ZY) data structure.
; This goes on a stack, so indexes are relative to LAST location.
.ZYRTZ==0			; Set if we should return into 
				; section 0 after call
.ZYSP==-1			; Saved stack pointer (SP0+4)
.ZYURA==-2			; User return address
.ZYLEN==3			; Length of ZY block

; Definition of section zero support vector (ZV) data structure.
; This is a counted vector defined in ZERBOO to allow a dynamic
; library called through libZER to find the support routines in the
; appropriate ZERBOO.
.ZVCNT==0			;Count word
.ZVBKR==1			;IFIW DY$BKR
.ZVZBL==2			;IFIW DY.ZBL
.ZVSEC==3			;IFIW DY.SEC
.ZVCS0==4			;IFIW DY$CS0
.ZVLEN==5			;Length (goes in .ZVCNT)
SUBTTL Signalling data structures

; The handler block.  
; A handler block exists for each handler currently established.
; The handler block must exist from the time of establishing to the
; time of removing, but its contents may be changed by the user
; program.

.HNHND==0			;xFIW address of handler
.HNCLS==1			;Enable mask
				;(see bit definitions below)
.HNCIM==2			;Character interrupt mask
.HNUDA==3			;xFIW address of user data

.HNLEN==4			;Size of block in words

; Handler action codes.
; These are returned by a handler to tell SIGNAL what to do.
.HNRES==0			;Resignal
.HNCON==1			;Continue
.HNUNW==2			;Unwind

; The establish block
; A stack of these blocks is kept on a pseudo-stack at SG.ENS in SIG, one for
; each established handler.  Each frame keeps the registers at time of
; establishing, and the address of the corresponding handler block.
; Offsets are relative to the END of the block (so that they can be used
; relative to the stack pointer).

.ESAC0==-20			;AC0 of register save block
.ESAC1==-17			;AC1
.ESAC2==-16			;AC2
.ESAC3==-15			;AC3
.ESSP==-1			;Stack pointer at time of entry to establishing
				;routine
.ESHND==0			;Address of handler block

.ESLEN==21

; The signal block
; This block represents one level of a signal in progress.

.SGCC==0			;Condition code (see definitions below)
.SGNXT==1			;xFIW Address of next (lower) level of signal
.SGFAC==2			;OWL/GBP to facility code string (ASCIZ)
.SGCND==3			;OWL/GBP to condition name string (ASCIZ)
.SGMSG==4			;OWL/GBP to message string (ASCIZ)
.SGPC==5			;PC of source of signal
.SGCLS==6			;Class of condition (bit mask)
				;(See bit definitions below)
.SGFLG==7			;Flags
    SG%INT==1B0			;We are at interrupt level
    SG%NPR==1B1			;Do not print this block (computer use only)
    SG%DYN==1B2			;This block is dynamic and may be thrown away
				;when done
.SGDAT==10			;Address of signal-specific data block
				;User data for software signal

.SGLEN==11

; Classes of signalled conditions (bit masks):
SG%UNW==1B0			;Unwind
SG%APR==1B1			;APR trap
SG%DER==1B2			;Data error interrupt
SG%QUO==1B3			;Disk quota interrupt
SG%EOF==1B4			;End of File interrupt
SG%ILI==1B5			;Illegal instruction interrupt
				;(or monitor call error)
SG%ILR==1B6			;Illegal memory read interrupt
SG%ILW==1B7			;Illegal memory write interrupt
SG%INS==1B8			;Inferior stop interrupt
SG%NXM==1B9			;Non-existent page interrupt
SG%PDL==1B10			;PDL overflow interrupt (not useful?)
SG%SOF==1B11			;Software-originated signal
SG%RES==1B12			;System resources interrupt
SG%CHR==1B13			;Character interrupt
SG%TRM==1B14			;Terminal interrupt

; A condition code field (this definition is compatible with the BLISS
; condition code, but the usage of the SIG facility is not compatible with
; BLISS signalling).
SG%ID==MASKB(4,32)		;Condition ID
SG%SEV==MASKB(33,35)		;Severity
SG%SUC==1B35			;Success
SG%FAC==MASKB(4,17)		;Facility code (including SG%FCD)
SG%FCD==1B4			;Set if facility is customer-defined
SG%MSG==MASKB(18,32)		;Message ID (including SG%MCD)
SG%MCD==1B18			;Customer-defined message flag

; Severity code values
.SGWRN==0			;Warning
.SGSUC==1			;Success
.SGERR==2			;Error
.SGINF==3			;Information
.SGSEV==4			;Severe error
SUBTTL Macros in aid of condition handling

; Static definition of an SG block (signal block)
; Note: the strings passed are made literals in the current section and
; IFIWs put into the block
DEFINE $SGBLK (cc,nxt,fac,cnd,msg,pc,cls,flg<0>,dat<0>) <
    EXP cc
    EXP nxt
    POINT 7, [ASCIZ fac]
    POINT 7, [ASCIZ cnd]
    POINT 7, [ASCIZ msg]
    EXP pc, cls, flg, dat
>

; Static definition of an HN block (handler block)
DEFINE $HNBLK (hnd,cls,cim<0>,uda<0>) <
    EXP hnd,cls,cim,uda
>

; Definition of a condition word
DEFINE $SGCC (fac,msg,sev) <FLD(fac,SG%FAC)!FLD(msg,SG%MSG)!FLD(sev,SG%SEV)>

; Run-time comparison of condition codes

; Compare code in memory to immediate value
DEFINE $CMCCI (mem, immed, temp<T0>) <
    MOVE temp, mem
    TXZ temp, ^-SG%ID
    CAME temp, [immed&SG%ID]
>

; Compare code in memory to code in accumulator
; NOTE: reg IS TRASHED
DEFINE $CMCC (reg, mem, temp<T0>) <
    MOVE temp, mem
    TXZ temp, ^-SG%ID
    TXZ reg, ^-SG%ID
    CAME temp, reg
>

; Definitions of ERJMP and ERCAL included here because a DYNLIB-user might
; not want to have JSYS definitions (from MONSYM) lying around.
OPDEF ERJMP [JUMP 16, 0]
OPDEF ERCAL [JUMP 17, 0]
SUBTTL RTL condition codes and related information

; All RTL condition codes and associated FAO patterns are defined here, so
; that the condition names can be made available to user programs.

; RTL-defined facilities.  Each entry specifies code, facility number,
; and facility name.

DEFINE $FACS <
    FACDEF (DY, 1, "DYNLIB")
    FACDEF (SG, 2, "SIGNAL")
    FACDEF (ME, 3, "MEMORY")
    FACDEF (MT, 4, "MTHLIB")
    FACDEF (RL, 5, "RTL")
>

; Symbols for facility numbers

DEFINE FACDEF (code, number, ignore) <
    $'code'$==number
>

$FACS

PURGE FACDEF

; Message/condition definitions

; For each facility, there will be a separate master definition macro
; named $fcMSG.  It will call MSGDEF for each message.

DEFINE $DYMSG <
    MSGDEF DY, FLL, .SGERR, 100, "Failed to load library of class !AZ!/    from file !AZ"
    MSGDEF DY, UPC, .SGINF, 7, "Requested from user PC !OH"
    MSGDEF DY, DYV, .SGERR, 14, "Caller built for outdated DYNLIB version !VER"
    MSGDEF DY, SEC, .SGERR, 0, "No section available to load library into"
    MSGDEF DY, CLS, .SGERR, 0, "Library service class specified not provided in library file specified"
    MSGDEF DY, LBV, .SGERR, 14, "Library found build for outdated DYNLIB version !VER"
    MSGDEF DY, VER, .SGERR, 30, "Version of library found (!VER) not good enough for caller (!VER)"
    MSGDEF DY, EPC, .SGINF, 11, "JSYS error occurred at PC !OH"
    MSGDEF DY, CTV, .SGERR, 0, "Error processing customer transfer vector"
    MSGDEF DY, DTV, .SGERR, 0, "Error processing DIGITAL transfer vector"
    MSGDEF DY, DGV, .SGERR, 0, "Error processing DIGITAL galactic vector"
    MSGDEF DY, CGV, .SGERR, 0, "Error processing customer galactic vector"
    MSGDEF DY, BOF, .SGERR, 0, "Invalid offset into LTVEC called"
    JERWRD==^D28			;Number of words for JSYS message plus 2 user words
    MSGDEF DY, JER, .SGERR, JERWRD*4, "JSYS error:!/    !JER"
    MSGDEF DY, MIE, .SGERR, 11, "Master INIT of library failed, returning error code !SW"
    MSGDEF DY, MIA, .SGERR, 100, "DYNMIN failed to initialize !AA"
    MSGDEF DY, NYI, .SGSEV, 12, "Feature called from !OH not yet implemented"
>

DEFINE $MEMSG <
    MSGDEF ME, IMC, .SGERR, 0, "Insufficient memory in chunk !SW to allocate !SW word!%s"
    MSGDEF ME, NAL, .SGSEV, 0, "Attempt to free unallocated block at !OH"
    MSGDEF ME, NCA, .SGSEV, 16, "No chunk available to manage addresses !OH to !OH"
>

DEFINE $SGMSG <
    MSGDEF SG, UNW, .SGINF, 0, "Unwind -- computer use only"
    MSGDEF SG, FRM, .SGINF, 7, "Signal originated at PC !OH"
    MSGDEF SG, ROS, .SGERR, 7, "Attempt to remove handler other than most recently established: !OH"
    MSGDEF SG, TRP, .SGSEV, 10, "Trap occurred within trap handler at PC !OH"
    MSGDEF SG, IOV, .SGWRN, 10, "Integer overflow at PC !OH"
    MSGDEF SG, IDC, .SGWRN, 10, "Integer divide check at PC !OH"
    MSGDEF SG, FOV, .SGWRN, 10, "Floating point overflow at PC !OH"
    MSGDEF SG, FDC, .SGWRN, 10, "Floating point divide check at PC !OH"
    MSGDEF SG, FUN, .SGWRN, 10, "Floating point underflow at PC !OH"
>

DEFINE $MTMSG <
    MSGDEF MT, ERR, .SGWRN, 4, "Math library error --  NUM1 = !SW, NUM2 = !SW"
    MSGDEF MT, OEM, .SGINF, 0, "Original error message: "
>

DEFINE $RLMSG <
    MSGDEF RL, IBF, .SGERR, 21, "Illegal byte pointer format: !BP"
    MSGDEF RL, IBS, .SGERR, 21, "Illegal byte size in !BP"
    MSGDEF RL, IBP, .SGERR, 21, "Illegal byte position in !BP"
>

; Define condition value symbols

DEFINE MSGDEF (facnam, cnam, sev, extra, msg) <
    .'facnam'MAX==.'facnam'MAX+1
    facnam'$'cnam==$SGCC($'facnam'$,.'facnam'MAX,sev)
>

DEFINE FACMSG (facnam) <
    .'facnam'MAX==0
    $'facnam'MSG
>

FACMSG (DY)
FACMSG (ME)
FACMSG (SG)
FACMSG (MT)
FACMSG (RL)

PURGE MSGDEF, FACMSG
SUBTTL Memory management definitions

; The header looks like this:
.MBDES==-1
    MB%LEN==MASKB(12,35)	;We support very large blocks (this doesn't
				;include the header and trailer)
				;Must be at LO end of word, as it is masked out
    MB%ALO==1B0			;Set if block is allocated
    MB%BEG==1B1			;Set if block is first in chunk
    MB%END==1B2			;Set if block is last in chunk

.MBHLN==1			;Header length

; The trailer looks like this (offsets are relative to block address plus
; block length):
.MBADR==0			;Address of the block this is a trailer for
.MBTLN==1			;Trailer length

.MBOVH==.MBHLN+.MBTLN		;Total memory block overhead

; Some pre-defined chunks:
.MEERR==0			;Error chunk
.MERTL==1			;General RTL chunk
.MEMAX==1			;Max pre-allocated chunk
SUBTTL Dynamic library data structure building macros

; These macros make building the default master and local dynamic library
; blocks trivially easy, and may simplify building non-default blocks as
; well (depending on the departures from normality involved).

; Naming conventions:
;   There are a lot of related names involved in a library.  The following
;   names are basic:  The library name, the library abbreviation, the name
;   of each exported address (routine entry or galactic variable).  The rest
;   of the names used are derived systematically from these (the default names
;   can be overridden).

; Object			Master	Master		Local	Local
; Description			Name	Name		Name	Name
;					Macro			Macro
;-----------------------------------------------------------------------
; Dynamic Library		*LIBNAM			N/A
; Abbreviation for library	*LA			N/A
; Dynamic Library Block		LIBNAM	MLBNAM		LIBNAM	LLBNAM
; Digital Transfer Vector	LA.DTV	MDVNAM		LA.DTV	LDVNAM
; Customer Transfer Vector	LA.CTV	MCVNAM		LA.CTV	LCVNAM
; Digital Global Vector		LA.DGV	MDGNAM		LC.DGV	LDGNAM
; Customer Global Vector	LA.CGV	MCGNAM		LA.CGV	LCGNAM
; Vector entry for address	N/A			*RTN	
; Normal call name		N/A			RTN	NCNAM
; Address (entry or global)	RTN			N/A	RANAM

; Entries marked "*" are master names used to form the others.
; LIBDEF -- Define all exported address information for a dynamic library

; Define a dynamic library.  All information that must go into the data
; structures is specified here.  It is extracted at need by macros you
; can call explicitly to build various data structures.

; Arguments are:
;   LIBNAM	Name of the library (for use by name macros)
;   LIBABR	Abreviation for library (2 characters) (no default)
;   LIBMAC	Name of macro to associate with library (no default)
;   LIBVER	Library version number
;   VERMAT	Version matching rule to use
;   CLSNAM	Class name string for service provided
;		(quoted string)
;   FILSPC	File spec to load to get server for this class
;		(quoted string)
;   DTVEC	List of DIGITAL-specified entry points.
;		Each entry in this list is either the ordered
;		quadruple <vector-name, real-name, call-name,
; 		sect-zer-call-process>, or just the vector name (in which case
;		the angle brackets are optional).  Default call and
;		routine name is vector-name (for local).  The
; 		call-name and the sect-zer-call-process must be blank for
;		galactic variable entries.
;   CTVEC	List of library-specific entry points separated by commas
;		and enclosed in angle brackets.  Same format as DTVEC.
;   DGVEC	List of DIGITAL-specified galactic variables, in same format
;		as for DTVEC above.
;   CGVEC	List of DIGITAL-specified galactic variables, in same format
;		as for DTVEC above.
;   MUWINI	Value to statically initialize user word in master dynamic
;		library table to
;   LUWINI	Value to statically initialize user word in local dynamic
;		library table to
;   MFWINI	Value to statically initialize flag word in master dynamic
;		library table to
;   LFWINI	Value to statically initialize flag word in local dynamic
;		library table to

DEFINE $LIBDEF (LIBNAM,LIBABR,LIBMAC,LIBVER,VERMAT,CLSNAM,FILSPC,DTVEC,CTVEC,DGVEC,CGVEC,MUWINI<0>,LUWINI<0>,MFWINI<0>,LFWINI<0>) <
    DEFINE LIBMAC (MACNAM,PRE) 
    <MACNAM (PRE,LIBNAM,LIBABR,LIBVER,VERMAT,MUWINI,LUWINI,MFWINI,LFWINI,CLSNAM,FILSPC,<DTVEC>,<CTVEC>,<DGVEC>,<CGVEC>)>
    >

; Define the master dynamic library block for a library.

DEFINE $DLBLK (LIBMAC,BLKNAM,DVN,CVN,DGVN,CGVN) <
    LIBMAC MDB1,<BLKNAM,DVN,CVN,DGVN,CGVN>>

; Define the local dynamic library block for a library.

DEFINE $LDLBLK (LIBMAC,BLKNAM,VERMAT,DVN,CVN,DGVN,CGVN,M1INST) <
    LIBMAC LDB1,<BLKNAM,VERMAT,DVN,CVN,DGVN,CGVN,M1INST>>

; Define vector entry names as externals (used in program to call a library)
DEFINE $LDLEXT (LIBMAC) <
    LIBMAC LEXT1>

; For libraries converted to dynamic libraries, this defines a set of jacket
; routines that accept calls in normal fashion and issue dynamic library
; calls.  They don't handle skip returns.
DEFINE $LDLJCK (LIBMAC,BLKNAM,LOCMAT,DVN,CVN,DGVN,CGVN,M1INST) <
    LIBMAC LJCK,<BLKNAM,LOCMAT,DVN,CVN,DGVN,CGVN,M1INST>>

; For calling dynamic libraries from section zero, this macro produces
; a jacket which accepts a normal (not indirect) call in section zero
; (or elsewhere), with global or local stack, and if necessary maps
; into section DY.ZMS.  Skip returns are not handled.
DEFINE $LDLZER (LIBMAC,BLKNAM,LOCMAT,DVN,CVN,DGVN,CGVN,M1INST) <
    LIBMAC LZER,<BLKNAM,LOCMAT,DVN,CVN,DGVN,CGVN,M1INST>>
; Naming macros -- these macros produce the systematic names

DEFINE RTNNAM (PRE,POST,VNAM,SPCNAM,LIBABR)
    <IFB <SPCNAM>,<PRE'VNAM'POST>
    IFNB <SPCNAM>,<PRE'SPCNAM'POST>>
DEFINE NCNAM (PRE,POST,VNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<PRE'VNAM'POST>
    IFNB <SPCNAM>,<PRE'SPCNAM'POST>>
DEFINE LLBNAM (PRE,POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<PRE'LIBNAM'POST>
    IFNB <SPCNAM>,<PRE'SPCNAM'POST>>
DEFINE MLBNAM (POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<LIBNAM'POST> IFNB <SPCNAM>,<SPCNAM'POST>>
DEFINE LCVNAM (PRE,POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<PRE'LIBABR'.CTV'POST> 
    IFNB <SPCNAM>,<PRE'SPCNAM'POST>>
DEFINE MCVNAM (POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<LIBABR'.CTV'POST> IFNB <SPCNAM>,<SPCNAM'POST>>
DEFINE LDVNAM (PRE,POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<PRE'LIBABR'.DTV'POST> 
    IFNB <SPCNAM>,<PRE'SPCNAM'POST>>
DEFINE MDVNAM (POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<LIBABR'.DTV'POST> IFNB <SPCNAM>,<SPCNAM'POST>>
DEFINE LCGNAM (PRE,POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<PRE'LIBABR'.CGV'POST> 
    IFNB <SPCNAM>,<PRE'SPCNAM'POST>>
DEFINE MCGNAM (POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<LIBABR'.CGV'POST> IFNB <SPCNAM>,<SPCNAM'POST>>
DEFINE LDGNAM (PRE,POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<PRE'LIBABR'.DGV'POST> 
    IFNB <SPCNAM>,<PRE'SPCNAM'POST>>
DEFINE MDGNAM (POST,LIBNAM,LIBABR,SPCNAM) 
    <IFB <SPCNAM>,<LIBABR'.DGV'POST> IFNB <SPCNAM>,<SPCNAM'POST>>
; Worker macros for structure building

DEFINE MDB1 (BLKNAM,DVN,CVN,DGVN,CGVN,LIBNAM,LIBABR,LIBVER,VERMAT,MUWINI,LUWINI,MFWINI,LFWINI,CLSNAM,FILSPC,DTVEC,CTVEC,DGVEC,CGVEC) <
    MLBNAM (:,LIBNAM,LIBABR,BLKNAM)
    EXP ^D9,$DYFVN
    IFNB <VERMAT>, <EXP MFWINI!FLD(VERMAT,DY%VER)>
    IFB <VERMAT>, <EXP MFWINI!DY%MIG>
    EXP MUWINI,LIBVER
    IFIW!MDVNAM (,LIBNAM,LIBABR,DVN)
    IFIW!MCVNAM (,LIBNAM,LIBABR,CVN)
    IFIW!MDGNAM (,LIBNAM,LIBABR,DGVN)
    IFIW!MCGNAM (,LIBNAM,LIBABR,CGVN)

    MTVEC DV,BLKNAM,LIBNAM,LIBABR,DVN,<DTVEC>
    MTVEC CV,BLKNAM,LIBNAM,LIBABR,CVN,<CTVEC>
    MTVEC DG,BLKNAM,LIBNAM,LIBABR,DGVN,<DGVEC>
    MTVEC CG,BLKNAM,LIBNAM,LIBABR,CGVN,<CGVEC>
    >

DEFINE LDB1 (BLKNAM,LOCMAT,DVN,CVN,DGVN,CGVN,M1INST,LIBNAM,LIBABR,LIBVER,VERMAT,MUWINI,LUWINI,MFWINI,LFWINI,CLSNAM,FILSPC,DTVEC,CTVEC,DGVEC,CGVEC) <
    IFNB <M1INST>,<M1INST>
    IFB <M1INST>,<    EXTERN RL.CTV
	PUSHJ 17,@RL.CTV+.RLDYN>
    LLBNAM (,::,LIBNAM,LIBABR,BLKNAM)
    EXP ^D11,$DYFVN
    IFNB <LOCMAT>,<EXP FLD(LOCMAT,LD%VER)!LD%VMA!LFWINI>
    IFB <LOCMAT>,<EXP LFWINI>
    EXP LUWINI
    POINT 7, [ASCIZ CLSNAM]
    POINT 7, [ASCIZ FILSPC]
    EXP LIBVER
    LDVNAM (IFIW!,,LIBNAM,LIBABR,DVN)
    LCVNAM (IFIW!,,LIBNAM,LIBABR,CVN)
    LDGNAM (IFIW!,,LIBNAM,LIBABR,DGVN)
    LCGNAM (IFIW!,,LIBNAM,LIBABR,CGVN)

    LTVEC DV,BLKNAM,LIBNAM,LIBABR,DVN,<DTVEC>
    LTVEC CV,BLKNAM,LIBNAM,LIBABR,CVN,<CTVEC>
    LTVEC DG,BLKNAM,LIBNAM,LIBABR,DGVN,<DGVEC>
    LTVEC CG,BLKNAM,LIBNAM,LIBABR,CGVN,<CGVEC>
    >

DEFINE LTVEC (DCFLG,BLKNAM,LIBNAM,LIBABR,DVN,TVEC) <
    L'DCFLG'NAM (,::,LIBNAM,LIBABR,DVN)
    COUNT (<TVEC>)+1
    XXOFF==0
    IRP TVEC,
	<XXOFF==XXOFF+1
	LTV1 LLBNAM(IFIW!,-1,LIBNAM,LIBABR,BLKNAM),LIBABR,XXOFF,TVEC
	>
    PURGE XXOFF
    >

DEFINE MTVEC (DCFLG,BLKNAM,LIBNAM,LIBABR,TVN,TVEC) <
    M'DCFLG'NAM(:,LIBNAM,LIBABR,TVN)
    COUNT (<TVEC>)+1
    XXOFF==0
    IRP TVEC,
	<XXOFF==XXOFF+1
	MTV1 MLBNAM(,LIBNAM,LIBABR,BLKNAM),LIBABR,XXOFF,TVEC
	>
    PURGE XXOFF
    >

DEFINE MTV1 (LIBBLK,LIBABR,XXOFF,TVEC)
    <MTV LIBBLK,LIBABR,XXOFF,TVEC>

DEFINE LTV1 (FAKLOC,LIBABR,XXOFF,TVEC)
    <LTV FAKLOC,LIBABR,XXOFF,TVEC>

DEFINE LTV (FAKLOC,LIBABR,OFFSET,VNAM,RNAM,CNAM,S0CP) <
    TVENT 1,VNAM,RNAM,CNAM,S0CP,LIBABR,OFFSET,FAKLOC>

DEFINE MTV (LIBBLK,LIBABR,OFFSET,VNAM,RNAM,CNAM,S0CP) <  
    TVENT 0,VNAM,RNAM,CNAM,S0CP,LIBABR,OFFSET,RTNNAM(IFIW ,,VNAM,RNAM,LIBABR)>

DEFINE TVENT (LABFLG,VNAM,RNAM,CNAM,S0CP,LIBABR,OFFSET,CONT) <
    IFN LABFLG, <VNAM::>
    CONT
    >

DEFINE COUNT (VEC,%XXCNT)
    <%XXCNT==0
    IRP VEC, <%XXCNT==%XXCNT+1
	>
    %XXCNT>

DEFINE LEXT1 (IGNORE,LIBNAM,LIBABR,LIBVER,VERMAT,MUWINI,LUWINI,MFWINI,LFWINI,CLSNAM,FILSPC,DTVEC,CTVEC,DGVEC,CGVEC) <
    ; Digital entries
    IRP DTVEC, <
	VXT1 LIBABR,DTVEC
	>
    ; Customer entries
    IRP CTVEC, <
	VXT1 LIBABR,CTVEC
	>
    ; Digital galactic variable entries
    IRP DGVEC, <
	VXT1 LIBABR,DGVEC
	>
    ; Customer galactic variable entries
    IRP CGVEC, <
	VXT1 LIBABR,CGVEC
	>
    >

DEFINE VXT1 (LIBABR,TVEC) <
    VXT2 LIBABR,TVEC
>

DEFINE VXT2 (LIBABR,VNAM,RNAM,CNAM,S0CP) <
    EXTERN VNAM
>

DEFINE LJCK (BLKNAM,LOCMAT,DVN,CVN,DGVN,CGVN,M1INST,LIBNAM,LIBABR,LIBVER,VERMAT,MUWINI,LUWINI,MFWINI,LFWINI,CLSNAM,FILSPC,DTVEC,CTVEC,DGVEC,CGVEC) <
    ..OFF==0
    IRP DTVEC, <
	..OFF==..OFF+1
	LJCK1 LIBNAM,LIBABR,CVN,..OFF,DTVEC
	>
    PURGE ..OFF
    ..OFF==0
    IRP CTVEC, <
	..OFF==..OFF+1
	LJCK1 LIBNAM,LIBABR,CVN,..OFF,CTVEC
	>
    PURGE ..OFF
    IFNB <M1INST>,<M1INST>
    IFB <M1INST>,<    EXTERN RL.CTV
	PUSHJ 17,@RL.CTV+.RLDYN>
    LLBNAM (,::,LIBNAM,LIBABR,BLKNAM)
    EXP ^D11,$DYFVN
    IFNB <LOCMAT>,<EXP FLD(LOCMAT,LD%VER)!LD%VMA!LFWINI>
    IFB <LOCMAT>,<EXP LFWINI>
    EXP LUWINI
    POINT 7,[ASCIZ CLSNAM]
    POINT 7,[ASCIZ FILSPC]
    EXP LIBVER
    LDVNAM (IFIW!,,LIBNAM,LIBABR,DVN)
    LCVNAM (IFIW!,,LIBNAM,LIBABR,CVN)
    LDGNAM (IFIW!,,LIBNAM,LIBABR,DGVN)
    LCGNAM (IFIW!,,LIBNAM,LIBABR,CGVN)

    PURGE TVENT
    DEFINE TVENT (LABFLG,VNAM,RNAM,CNAM,S0CP,LIBABR,OFFSET,CONT) <
	CONT
	>

    LTVEC DV,BLKNAM,LIBNAM,LIBABR,DVN,<DTVEC>
    LTVEC CV,BLKNAM,LIBNAM,LIBABR,CVN,<CTVEC>

    PURGE TVENT
    DEFINE TVENT (LABFLG,VNAM,RNAM,CNAM,S0CP,LIBABR,OFFSET,CONT) <
	IFNB <VNAM>,<VNAM::>
	CONT
	>

    LTVEC DG,BLKNAM,LIBNAM,LIBABR,DGVN,<DGVEC>
    LTVEC CG,BLKNAM,LIBNAM,LIBABR,CGVN,<CGVEC>
    >
    
DEFINE LJCK1 (LIBNAM,LIBABR,CVN,OFF,TVEC) <
    LJCK2 LIBNAM,LIBABR,CVN,OFF,TVEC
    >

DEFINE LJCK2 (LIBNAM,LIBABR,CVN,OFF,VNAM,RNAM,CNAM,S0CP) <
    NCNAM ,::,VNAM,LIBABR,CNAM
    LCVNAM (<JRST @>,<+OFF>,LIBNAM,LIBABR,CVN)
    >

DEFINE LZER (BLKNAM,LOCMAT,DVN,CVN,DGVN,CGVN,M1INST,LIBNAM,LIBABR,LIBVER,VERMAT,MUWINI,LUWINI,MFWINI,LFWINI,CLSNAM,FILSPC,DTVEC,CTVEC,DGVEC,CGVEC) <
    ..OFF==0
    IRP DTVEC, <
	..OFF==..OFF+1
	LZER1 LIBNAM,LIBABR,CVN,..OFF,DTVEC
	>
    PURGE ..OFF
    ..OFF==0
    IRP CTVEC, <
	..OFF==..OFF+1
	LZER1 LIBNAM,LIBABR,CVN,..OFF,CTVEC
	>
    PURGE ..OFF
    IFNB <M1INST>,<M1INST>
    IFB <M1INST>,<    EXTERN RL.CTV
	PUSHJ 17,@RL.CTV+.RLDYN>
    LLBNAM (,::,LIBNAM,LIBABR,BLKNAM)
    EXP ^D11,$DYFVN
    IFNB <LOCMAT>,<EXP FLD(LOCMAT,LD%VER)!LD%VMA!LFWINI>
    IFB <LOCMAT>,<EXP LFWINI>
    EXP LUWINI
    POINT 7,[ASCIZ CLSNAM]
    POINT 7,[ASCIZ FILSPC]
    EXP LIBVER
    LDVNAM (IFIW!,,LIBNAM,LIBABR,DVN)
    LCVNAM (IFIW!,,LIBNAM,LIBABR,CVN)
    LDGNAM (IFIW!,,LIBNAM,LIBABR,DGVN)
    LCGNAM (IFIW!,,LIBNAM,LIBABR,CGVN)

    PURGE TVENT
    DEFINE TVENT (LABFLG,VNAM,RNAM,CNAM,S0CP,LIBABR,OFFSET,CONT) <
	CONT
	>

    LTVEC DV,BLKNAM,LIBNAM,LIBABR,DVN,<DTVEC>
    LTVEC CV,BLKNAM,LIBNAM,LIBABR,CVN,<CTVEC>

    PURGE TVENT
    DEFINE TVENT (LABFLG,VNAM,RNAM,CNAM,S0CP,LIBABR,OFFSET,CONT) <
	IFNB <VNAM>,<VNAM::>
	CONT
	>

    LTVEC DG,BLKNAM,LIBNAM,LIBABR,DGVN,<DGVEC>
    LTVEC CG,BLKNAM,LIBNAM,LIBABR,CGVN,<CGVEC>
    >
    
DEFINE LZER1 (LIBNAM,LIBABR,CVN,OFF,TVEC) <
    LZER2 LIBNAM,LIBABR,CVN,OFF,TVEC
    >

.DYZVO==1			;Distance from the CALL to the RET in code
				;generated by LZER2, below

DEFINE LZER2 (LIBNAM,LIBABR,CVN,OFF,VNAM,RNAM,CNAM,S0CP) <
    NCNAM ,::,VNAM,LIBABR,CNAM
    PUSHJ 17, DY$ZMU##
    IFNB <S0CP>, <S0CP>
    LCVNAM (<PUSHJ 17, @>,<+OFF>,LIBNAM,LIBABR,CVN)
    PUSHJ 17, DY$ZMD##
    POPJ 17, DY.ZMV##		;;Ret makes address of ZV available to DYNLIB
    >

; Macro to massage fortran/cobol arg list for call from section 0
; This should be used only when the arglist was in section zero
; and we were running in section zero.  The two registers specified
; (0 and 1 by default) are trashed.  This macro handles arglists with
; a specified length of 0.
DEFINE $FC (XT0<0>, XT1<1>) <
    $AR 16			;;Make arg-list pointer a global index
    MOVX XT0, IFIW
    MOVE XT1, -1(16)		;;Get -count,,0
    SUB XT1, [1,,0]		;;Make it -count-1,,0
    HRRI XT1, -1(16)		;;Make it -count-1,,argadr-1
    AOBJP XT1, .+3		;;Exit if done
    IORM XT0, 0(XT1)		;;Set IFIW flag on arglist entry
    JRST .-2			;;Loop
>

; Macro to massage registers that contain addresses
DEFINE $AR (regs) <
    IRP regs <
	XHLLI regs, 1000	;;Put current section onto register
    >
>
SUBTTL LIBPDV -- Create code to make the PDV in the library EXE file

; This is necessary because of restrictions in LINK 5.1's ability to
; make PDV's for me.  This should be removed and all library build procedures
; changed when an improved LINK ships.

DEFINE $LIBPDV (LIBMAC,MBNAM,ERRTN,%PDV1,%PDAT,%PARG,%OUT) <
	MOVEI 1, .POADD
	XMOVEI 2, %PDAT
	MOVEM 2, %PARG+.PODAT
	XMOVEI 2, %PDV1
	MOVEM 2, %PDAT
	XMOVEI 2, %PARG
	SETZ 3,
	PDVOP%
	    IFB <ERRTN>,<ERCAL [
		TMSG <
??Fatal error making PDV for dynamic library
>
		HALTF% ]>
	    IFNB <ERRTN>,<ERCAL ERRTN>

	JRST %OUT

    %PDV1: 5
    LIBMAC LPD2
    LIBMAC LPD1,<MBNAM,+IFIW>
    EXP 0
    LIBMAC LPD3

    %PDAT: IFIW %PDV1

    %PARG: EXP 6, .FHSLF, 1
    IFIW %PDAT
    EXP 0, 0

    %OUT:
    >

DEFINE LPD1 (MBNAM,POST,LIBNAM,LIBABR)
    <LLBNAM ,POST,LIBNAM,LIBABR,MBNAM>

DEFINE LPD2 (IGNORE,LIBNAM,LIBABR,LIBVER,VERMAT,MUWINI,LUWINI,MFWINI,LFWINI,CLSNAM,FILSPC) <
    IFIW![ASCIZ CLSNAM]
    >

DEFINE LPD3 (IGNORE,LIBNAM,LIBABR,LIBVER) <
    EXP LIBVER
    >
SUBTTL Utility routines

; GETBP -- Get a OWGBP given address of OWL/GBP

; Make a global byte pointer given a memory reference to a local byte
; pointer.  Works for 6, 7, 8, and 9 bits (only those that might
; conceivably work with ASCII text).  No error checks!!

; Trashes the register specified as r1, and the next register.

DEFINE GETBP (reg, mem, r1<T1>, %OUT) <
    r2==r1+1			;;Must be next register for IDIV
    MOVE reg, mem		;;Get copy of byte pointer into register
    LDB r1, [POINTR reg, BP%POS]	;;Get P (or P,S) field
    CAIL r1, 45
	JRST %OUT		;;Already global
    LDB reg, [POINTR reg, BP%SIZ] ;;Get size field
    IDIV r1, reg		;;P/S (remainder trashes r2)
    SUBI reg, 6			;;S-6
    IMULI reg, 7		;;(S-6)*7 (No more than 7 byte positions for a 
				;;given size in one-word global pointers)
    ADD r1, reg			;;(S-6)*7 + P/S
    MOVE r1, [EXP 53,52,51,50,47,46,45,66,65,64,63,62,61,0,60,57,56,55,54,0,0,73,72,71,70,67](r1)
				;;Get PS field for global into register
;;This is the full explanation of the table in the literal above
;;BPTBL:53			;S=6 P=0
;;	52			;S=6 P=6
;;	51			;S=6 P=14
;;	50			;S=6 P=22
;;	47			;S=6 P=30
;;	46			;S=6 P=36
;;	45			;S=6 P=44
;;	66			;S=7 P=1
;;	65			;S=7 P=10
;;	64			;S=7 P=17
;;	63			;S=7 P=26
;;	62			;S=7 P=35
;;	61			;S=7 P=44
;;	0			;No entry
;;	60			;S=8 P=4
;;	57			;S=8 P=14
;;	56			;S=8 P=24
;;	55			;S=8 P=34
;;	54			;S=8 P=44
;;	0			;No entry
;;	0			;No entry
;;	73			;S=9 P=0
;;	72			;S=9 P=11
;;	71			;S=9 P=22
;;	70			;S=9 P=33
;;	67			;S=9 P=44
    XMOVEI reg, mem		;;Get EFIW to first word of destination
    HRR reg, mem
    DPB r1, [POINTR reg, BP%POS]	;;Set PS field of global
%OUT:
>

.SVAC0==-16
.SVAC1==-15
.SVAC2==-14
.SVAC3==-13
.SVAC4==-12
.SVAC5==-11
.SVAC6==-10
.SVAC7==-7
.SVA10==-6
.SVA11==-5
.SVA12==-4
.SVA13==-3
.SVA14==-2
.SVA15==-1
.SVA16==0

DEFINE SAVACS <
	;Save registers 0-16 on stack in increasing order
	ADJSP P, 17		;;Allocate save block on stack
	MOVEM 2, .SVAC2(P)	;;Put AC2 in save block
	XMOVEI 2, 1(P)		;;Adr of block end + 1
	DMOVEM 0, .SVAC0(P)	;;Put AC0 and AC1 in save block
	DMOVE 0, [EXP -14, 17]	;;Set up 0,1 for reverxe XBLT (2 already set)
	EXTEND 0, [XBLT]	;;Save 3-16 in save block
>

DEFINE RSTACS <
;Restore registers saved by SAVACS
	MOVX 0, 14		;;Count for XBLT
	XMOVEI 1, .SVAC3(P)	;;Source address: AC3 in save block
	MOVX 2, 3		;;Destination address: AC3
	EXTEND 0, [XBLT]	;;Restore 3-16
	DMOVE 0, .SVAC0(P)	;;Restore 0,1
	MOVE 2, .SVAC2(P)	;;Restore 2
	ADJSP P, -17		;;Remove save block from stack (17)
>

	END