Google
 

Trailing-Edge - PDP-10 Archives - BB-J713A-BM - language-sources/ovrlay.mac
There are 38 other files named ovrlay.mac in the archive. Click here to see a list.
TITLE	OVRLAY - OVERLAY HANDLER FOR LINK
SUBTTL	D.M.NIXON/DMN/JLd/JNG/MCHC/DZN	27-Aug-79


;COPYRIGHT (C) 1974, 1979 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;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 WHICH IS NOT SUPPLIED BY DIGITAL.



CUSTVR==0		;CUSTOMER VERSION
DECVER==4		;DEC VERSION
DECMVR==1		;DEC MINOR VERSION
DECEVR==50		;DEC EDIT VERSION



ENTRY	.OVRLA,.OVRLU
INTERN	%OVRLA
EXTERN	FUNCT.

%OVRLA==<BYTE(3)CUSTVR(9)DECVER(6)DECMVR(18)DECEVR>

COMMENT	\
THIS ROUTINE PRESERVES ALL ACCS EXCEPT 0 AND 1 WHICH IT DESTROYS FREELY.
\


SALL
SUBTTL	FEATURE TEST SWITCHES


COMMENT \	STANDARD DEC SETTING

TOPS20==0			;-1 = TOPS-20 VERSION
FT2SEG==-1			;-1 = TWO SEGMENT VERSION
FTWRITE==0			;-1 = WRITEABLE OVERLAYS
FTREGION==0			;-1 = MULTIPLE REGIONS
FTRELOC==-1			;-1 = RELOCATABLE OVERLAYS
FTMANUAL==-1			;-1 = MANUAL OVERLAY CALLS
FTLOG==-1			;-1 = LOG FILE CAPABILITY
FTKI10==0			;-1 = KI10 DOUBLE MOVE INST.
FTSFD==5			;   = LENGTH OF SFDS ALLOWED
\

IFNDEF	TOPS20,<TOPS20==0>
IFNDEF	FT2SEG,<FT2SEG==-1>
IFNDEF	FTWRITE,<FTWRITE==0>
IFNDEF	FTREGION,<FTREGION==0>
IFNDEF	FTRELOC,<FTRELOC==-1>
IFNDEF	FTLOG,<FTLOG==-1>
IFNDEF	FTMANUAL,<FTMANUAL==-1>
IFNDEF	FTKI10,<FTKI10==0>
IFNDEF	FTSFD,<FTSFD==5>

IFE TOPS20,<SEARCH	MACTEN, UUOSYM	;GET STANDARD DEFINITIONS
>
IFN TOPS20,<SEARCH	MACSYM, MONSYM	;GET STANDARD DEFINITIONS
	FTKI10==-1
>
SUBTTL	REVISION HISTORY


;START OF VERSION 1
;1	INITIAL VERSION
;2	ADD FUNCTION CALLS TO RNT, IFS & CBC
;3	FIX VARIOUS BUGS IN MANUAL CALLS
;4	MAKE IT REENTRANT (TWO SEGMENT VERSION)
;5	REDUCE SIZE OF OVERHEAD TABLES
;6	SUPPORT DDT SYMBOLS

;START OF VERSION 1A
;7	JLd	17-Jan-75	SPR 10-14994
;	Fix explicit calls to initialize the overlay list
;	when necessary.

;10	CHANGE GETCUR TO USER PC OF PUSHJ RATHER THAN ADDRESS OF ARGBLOCK
;	THIS IS FOR COBOL WHICH CONSTRUCTS ARG BLOCK IN LIBOL

;11	JLd	26-Mar-75	SPR 10-15706
;	Make relocatable overlays work with all multiple calls:
;	Unrelocate EXTTAB when the overlay is removed.

;12	JLd	27-Mar-75	SPR 10-15706
;	Cause the symbol table to be kept even if core must
;	be expanded.

;13	JNG	26-Jun-75	SPR 10-16380
;	Move symbol table before getting core for an absolute link
;	to avoid problems when trying to move up the symbols.

;14	JNG	27-Jun-75
;	Fix bug introduced by edit 10.  Clean up some code.

;15	JNG	29-Jun-75
;	Edit 11 inserted an instruction into the range of a
;	JUMPN T2,.-3  ... oops!!!

;16	JNG	2-Jul-75	SPR 10-15993
;	Try harder to shrink when we have more core than we need.

;17	JNG	5-Aug-75	SPR 10-15734
;	Reset ADDCOR and SIZCOR after calling MOVSYM,
;	which destroys them.

;START OF VERSION 1B
;20	JNG	8-Oct-75
;	If a manual call comes from the high segment, pretend it is
;	from the ROOT so COBDDT will work properly.

;START OF VERSION 2 (TOPS-20 ONLY)
;21	DMN	13-Nov-75
;	Make overlays work on TENEX
;START OF VERSION 2C -- FROM NOW ON, MAJOR & MINOR VERSIONS SAME AS LINK
;22	JNG	10-Feb-76
;	Make OVRLAY's version correspond to LINK. Clean
;	up the listing. Fix a minor bug in edit 21.

;23	JNG	10-Feb-76	SPR 18030
;	Make sure we have CORE before reading in a relocatable overlay
;	into other than its intended address and symbols are in core.

;24	JNG	10-Feb-76	SPR 18030
;	Try harder to keep symbols in core when debugging, even if
;	this means expanding core.

;25	JNG	22-Feb-76	SPR 18572
;	Fix some minor bugs in non-TTY log file handling, and in the
;	INIOVL manual call subroutine.

;		Edits 26 and 27 were not used

;START OF VERSION 3A
;30	JNG	20-Jun-76
;	Release on both TOPS-10 and TOPS-20 as OVRLAY version 3A(30)

;START OF VERSION 4
;31	JNG	27-Feb-77	SPR 10-21893
;	Allow a call to INIOVL with no args to just read in the
;	symbol table & do other initialization that is not normally
;	done until the first overlay is read in.

;32	JNG	10-Apr-77
;	Keep the symbol table up to date always if symbols are
;	available due to load-time switches.  Never look at the
;	initial .JBSYM or .JBDDT to decide what to do.

;33	JNG	10-Apr-77	SPR 10-22407
;	Make OVRLAY assemble with FTLOG=0.

;34	JNG	10-Apr-77	SPR 10-22436
;	Make OVRLAY work with FTRELOC=0.

;35	JNG	10-Apr-77
;	Set up reference lists correctly when link comes into core.

;36	JNG	10-Apr-77
;	Save the PPN around the LOOKUP in OVRLAY.

;37	MCHC	20-SEP-77
;	Don't output version change message if the change is from zero.
;START OF VERSION 4A
;40	DZN	15-Sep-78
;	On TOPS-20, if DDT exists, set its internal symbol table pointer
;	whenever we change .JBSYM.

;41	DZN	5-Oct-78
;	Use new NAME% form of JSYS names to avoid conflicts with user-defined
;	globals.

;42	DZN	5-Oct-78
;	Change FTENEX conditional to TOPS20 to be consistent with the rest
;	of LINK. Use proper mnemonics for JSYS arguments. Some code cleanup.

;43	DZN	13-Oct-78
;	Fix link deletion problems. Make REMOV. take only a single argument,
;	and delete that link and all of its inferiors (otherwise lost links
;	result). Allow RUNOV. to delete the calling link as documented. Also
;	remove OVLAOC message (use OVLARC instead).

;44	DZN	15-Oct-78
;	Fix argument checking for calls to manual subroutines. This involves
;	allowing all double and single precision argument types to work,
;	making the OVLIAT message fatal and not type junk, and getting
;	the correct user PC (see edit 10).

;45	DZN	15-Oct-78
;	Fix PDL overflow if many calls to RUNOV. RUNOV. now unbinds back
;	through the return PC on the stack, allowing replacement of links
;	at the same level to succeed without the PDL overflow.

;46	JNG	15-Jun-79
;	Use 7.01 GETTABs if available to find overlay file.

;47	DZN	25-Jul-79
;	Clean up the listing for release.

;50	DZN	27-Aug-79
;	Release on both TOPS-10 and TOPS-20 as version 4A(50).
SUBTTL	DEFINITIONS


;ACCUMULATORS
T0=0				;[42] T0-T5 MUST BE 0-5 FOR JSYS ARGS
T1=1
T2=2
T3=3
T4=4
T5=5

P1=10
P2=11
L=16
P=17

;FLAGS IN ET.FLG
F.LIC==400000		;LINK IN CORE
F.MDL==200000		;ROUTINE IN MULTIPLE LINKS
F.RLC==100000		;LINK IS RELOCATED

;FLAGS IN CS.FLG (LHS)
CF.RLO==1		;OTHER RELOCATION STILL TO DO

;FUNCT. ARGS
F.ILL==0		;ALWAYS ILLEGAL
F.GAD==1		;GET SPECIFIC ADDRESS
F.COR==2		;GET ANY ADDRESS
F.RAD==3		;RETURN SPECIFIC ADDRESS
F.GCH==4		;GET ANY CHAN #
F.RCH==5		;RETURN SPECIFIC CHAN #
F.GOT==6		;GET CORE FROM OTS
F.ROT==7		;RETURN CORE TO OTS
F.RNT==10		;GET INITIAL RUNTIME FROM OTS
F.IFS==11		;GET DEV:FILE[PPN] FROM OTS
F.CBC==12		;CUT BACK CORE

;SUBROUTINE ARG TYPES
A.UND==0
A.LOG==1
A.SPI==2
A.SPR==4
A.OCT==6
A.LBL==7
A.DPR==10
A.DPI==11
A.DO==12
A.CMP==14
A.AS==17
SUBTTL	MACROS


DEFINE	SEGMENT (N)<
 IFN FT2SEG,<
  IFNDEF %SEG%,<
   TWOSEG
   RELOC	400000
   RELOC	0
   %SEG%==0
  >
  IFIDN <N><LOW>,<
   IFN %SEG%,<
    RELOC
    %SEG%==0
  >>
  IFIDN <N><HIGH>,<
   IFE %SEG%,<
    RELOC
    %SEG%==-1
>>>>

DEFINE SPUSH (AC) <
 IRP AC,<
	PUSH	P,AC
>>

DEFINE SPOP (AC) <
 IRP AC,<
	POP	P,AC
>>

IFE FTKI10,<
 DEFINE DMOVE (AC,M)<
	MOVE	AC,M
	MOVE	AC+1,1+M
  >

 DEFINE DMOVEM (AC,M)<
	MOVEM	AC,M
	MOVEM	AC+1,1+M
 >
>;END IFE FTKI10
DEFINE	TYPE (MESSAGE)<
 IFE TOPS20,<
	OUTSTR	[ASCIZ \MESSAGE\]
 >
 IFN TOPS20,<
	HRROI	T1,[ASCIZ \MESSAGE\]
	PSOUT%			;;[41]
>>

DEFINE	TYPEC (CHAR)<
 IFE TOPS20,<
	MOVEI	T1,CHAR
	OUTCHR	CHAR
 >
 IFN TOPS20,<
	MOVEI	T1,CHAR		;;[42]
	PBOUT%			;;[41]
>>

IFN FTLOG,<
 DEFINE	OUTLOG (TEXT)<
	PUSHJ	P,LOGTST
	CAI	[ASCIZ \TEXT\]
>>
IFE FTLOG,<
 SYN	TYPE,OUTLOG
>

IFE TOPS20,<
  OPDEF	STOP	[EXIT]
>
IFN TOPS20,<
  DEFINE	STOP<
	HALTF%			;;[41]
	JRST	.-1;;		;;[41] HALTF% IS CONTINUABLE
  >
>

OPDEF	PJRST	[JRST]
OPDEF	HALT	[HALT]
SUBTTL	CONTROL SECTION OFFSETS


;CONTROL SECTION STUFF
LOC	0
	CS.HDR:!		;HEADER (LH)
CS.LEN:!	BLOCK	1	;LENGTH (RH)
CS.RGN:!	BLOCK	1	;REGION #
CS.NUM:!	BLOCK	1	;LINK NUMBER
CS.LNM:!	BLOCK	1	;LOGICAL NAME
	CS.BPT:!		;BACK POINTER
	CS.FPT:!		;FORWARD POINTER
CS.PTR:!	BLOCK	1	;..
CS.SYM:!	BLOCK	1	;SYMBOL TABLE PTR.
	CS.FLG:!		;FLAGS
CS.STA:!	BLOCK	1	;START ADDRESS (RH)
	CS.SIZ:!		;LENGTH (LH)
	CS.ADR:!		;ADDRESS (RH)
CS.COR:!	BLOCK	1	;..
CS.EXT:!	BLOCK	1	;AOBJN PTR TO EXTERNAL TRANSFER TABLES
CS.INT:!	BLOCK	1	;AOBJN PTR TO INTERNAL TRANSFER TABLES
CS.DDT:!	BLOCK	1	;POINTER TO DDT SYMBOLS ON DSK
CS.RLC:!	BLOCK	1	;HOLD OFFSET IF RELOCATED
RELOC	0

;EXTTAB ENTRY OFFSETS
LOC	0
ET.OVL:!	BLOCK	1	;JSP T1,.OVRLA
	ET.FLG:!		;FLAGS (BITS 0-8)
	ET.RGN:!		;REGION # (BITS 9-17)
ET.ADR:!	BLOCK	1	;ADDRESS IF IN CORE (RH)
	ET.NUM:!		;NUMBER (LH)
	ET.MDL:!		;ONLY IF MULTIPLY-DEFINED (POINTS TO TABLE)
ET.CST:!	BLOCK	1	;THIS CONTROL SECTION (RH)
	ET.BRF:!		;BACK REFERENCE (LH)
	ET.FRF:!		;FORWARD REFERENCE (RH)
	ET.NAM:!		;EXTERNAL REQUEST NAME (IF UNDEFINED)
ET.REF:!	BLOCK	1	;LINKED REFERENCES
ET.LEN:!	RELOC	0
;EXTTAB OFFSETS WHEN CALLED BY JSP
JT.FLG==ET.FLG-1
JT.ADR==ET.ADR-1
JT.CST==ET.CST-1
JT.MDL==ET.MDL-1
JT.NUM==ET.NUM-1
JT.REF==ET.REF-1
JT.NAM==ET.NAM-1
JT.LEN==ET.LEN-1

;INTTAB ENTRY OFFSETS
LOC	0
	IT.FLG:!		;FLAGS (BITS 0-12)
IT.ADD:!	BLOCK	1	;ADDRESS IN CORE (RH)
IT.REF:!	BLOCK	1	;FORWARD REFERENCE (RH)
IT.LEN:!	RELOC	0

;MULTIPLY-DEFINED ENTRY OFFSETS
LOC	0
MT.ADR:!	BLOCK	1	;EQUIV TO ET.ADR
	MT.NUM:!		;LINK # (EQUIV TO ET.NUM)
MT.CST:!	BLOCK	1	;EQUIV TO ET.CST
MT.LEN:!	RELOC	0
SUBTTL	PRINCIPLE ENTRY POINT


COMMENT	\
CALLING  SEQUENCE
ET.OVL:	JSP	T1,.OVRLA
ET.FLG:	FLAGS & REGION # ,, ADDRESS OF INTTAB IN CORE
ET.CST:	LINK#	,, ADDRESS OF CONTROL SECTION
ET.REF:	BACK PTR ,, FORWARD PTR
\

	SEGMENT	LOW
	'.OVRLA'
.OVRLA:
;************* REPLACE
	JRST	SETINI		;INITIALIZE FIRST TIME
;*************	BY
;	MOVE	T0,JT.FLG(T1)	;GET 1ST WORD OF ARG BLOCK
;*************	AFTER FIRST TIME

	JUMPGE	T0,OVRL1	;NOT KNOWN TO BE IN CORE
	HRRZ	T1,JT.ADR(T1)	;GET ADDRESS
	JRST	@(T1)		;GO TO IT

.OVRWARN::	Z		;-1 IF WARNINGS NOT TO BE TYPED
.OVRLOG::	Z		;-1 IF LOG FILE ON TTY

	SEGMENT	HIGH
;HERE IF LINK IS NOT KNOWN TO BE IN CORE

OVRL1:	PUSH	P,T2		;GET A SPARE ACC
	TLNE	T0,F.MDL	;MULTIPLY DEFINED?
	JRST	MDL0		;YES, SEE WHICH WE WANT

IFN FTREGION,<
	TLZ	T0,777000	;CLEAR FLAGS
	MOVEM	T0,CURRGN	;SAVE REGION #
>

;SEE IF IT REALLY IS IN CORE
INC0:	HLRZ	T0,JT.NUM(T1)	;GET NUMBER WE WANT
INC1:	MOVE	T2,FSTLNK	;GET START OF TREE
	CAMN	T0,CS.NUM(T2)	;MATCH?
	JRST	INC2		;YES
	HRRZ	T2,CS.FPT(T2)	;GET FORWARD POINTER
	JUMPN	T2,.-3		;TRY AGAIN
	JRST	NINC		;NOT IN CORE

;HERE WHEN LINK IS IN CORE
;SET INCORE BIT, GET ADDRESS, AND LINK REFERENCE POINTERS
;ENTER WITH
;T1 = EXTTAB+1 (USE JT.XXX SYMBOLS)
INC2:
IFN FTRELOC,<
	MOVE	T0,CS.RLC(T2)	;GET OFFSET
	ADDM	T0,JT.ADR(T1)	;FIXUP INCORE ADDRESS
>
	MOVSI	T2,F.LIC	;INCORE BIT
IFN FTRELOC,<
	SKIPE	T0		;NEED TO RELOCATE IT?
	TLO	T2,F.RLC	;YES
>
	IORB	T2,JT.FLG(T1)	;SET FOR NEXT TIME
	HRRZ	T0,IT.REF(T2)	;GET POSSIBLE FORWARD REF
	HRLI	T0,IT.REF(T2)	;POINT TO INTTAB+1
	ADDI	T1,JT.REF	;POINT TO REFERENCE WORD IN EXTTAB
	MOVEM	T0,(T1)		;STORE IN EXTTAB
	HRRM	T1,IT.REF(T2)	;MAKE INTTAB POINT TO THIS EXTTAB
	EXCH	T2,T0		;SO WE CAN INDEX
	TRNE	T2,-1		;IF THERE WAS A FORWARD REF
	HRLM	T1,(T2)		;[35] CHANGE STORED BACK REF

;RESTORE AND EXIT
INC3:	POP	P,T2		;RESTORE ACC
	HRRZ	T1,T0		;GET ADDRESS
	JRST	@(T1)		;GO TO IT
;HERE IF NOT IN CORE, READ IN PREAMBLE
NINC:	PUSH	P,T1		;SAVE PC
	MOVE	T1,JT.NUM(T1)	;LINK # WE WANT
NINC1:	HRRZM	T1,CURLNK	;SAVE LINK CONTROL SECTION ADDRESS
	HLRZ	T0,T1		;LINK #
	PUSHJ	P,RP0		;READ PREAMBLE
	PUSHJ	P,CP0		;CHECK PATH
	POP	P,T1		;RESTORE PC
	MOVE	T0,JT.FLG(T1)	;GET FLAGS
	TLNN	T0,F.MDL	;SPECIAL IF MULTIPLY DEFINED
	JRST	INC0		;NO, TRY AGAIN
MINC:	MOVE	T1,T0		;POINTER TO ACTUAL ENTRY IN MDL TABLE
IFN FTRELOC,<
	HRRZ	T2,MT.ADR(T1)	;GET UNRELOCATED ADDRESS
	HLRZ	T0,MT.NUM(T1)	;GET NUMBER
	MOVE	T1,FSTLNK	;START AT FRONT
	CAME	T0,CS.NUM(T1)	;THIS ONE?
	JRST	[HRRZ	T1,CS.FPT(T1)	;GET NEXT (MUST BE THERE)
		JRST	.-1]		;TRY TEST AGAIN
	MOVE	T0,CS.RLC(T1)	;GET RELOCATION OFFSET
	ADD	T0,T2		;PLUS ORIGINAL ADDRESS
>
IFE FTRELOC,<
	MOVE	T0,MT.ADR(T1)	;GET TRUE ADDRESS
>
	JRST	INC3		;GO TO IT (BUT DON'T MARK INCORE)
;RP0 - READ IN PREAMBLE
;ENTER WITH
;T0 = LINK #

RP0:	MOVE	T1,INCIDX	;GET INCORE LOWEST
	CAIL	T0,(T1)		;SEE IF IN CORE
	CAILE	T0,377(T1)
	SKIPA	T1,T0		;NO
	JUMPN	T0,RP1		;YES, BUT DON'T ALLOW 0
	SKIPLE	T0
	CAMLE	T0,HILINK	;CHECK UPPER RANGE
	JRST	.ERII		;ILLEGAL INDEX
	ANDCMI	T1,377		;WILL BE LOWEST BLOCK IN CORE
	MOVEM	T1,INCIDX	;EVENTUALLY
	LSH	T1,-8		;INTO BLOCK NUMBER
	ADD	T1,DI.LPT	;PLUS BASE
	PUSHJ	P,%USETI	;SET ON IT
	MOVE	T0,[IOWD 200,IDXBFR]
	PUSHJ	P,%INZ		;READ IT IN

;HERE WHEN INDEX BUFFER CONTAINS POINTER TO LINK WE NEED
RP1:	MOVE	T1,T0		;GET INDEX # AGAIN
	ANDI	T1,377		;THIS BLOCK ONLY
	ROT	T1,-1		;HALF
	SKIPGE	T1		;EVEN HALF?
	SKIPA	T1,IDXBFR(T1)	;NO
	HLRZ	T1,IDXBFR(T1)	;YES
	PUSHJ	P,%USETU	;SET ON IT
	PUSHJ	P,%INB		;READ PREAMBLE BLOCK
	MOVE	T1,[INBFR,,PS.ZZ]
	BLT	T1,PS.END	;STORE NEW DATA
	POPJ	P,
SUBTTL	CHECK PATH


CP0:	SPUSH	<P1,P2>		;GET MORE ACS
	PUSH	P,L		;AND ARG LIST PTR
	MOVE	P1,FSTLNK	;GET BASE OF INCORE LINKS
	HLRZ	P2,PS.FPT	;POINTER TO LIST OF WHAT WE NEED
	HRRZ	T1,PS.FPT	;BLOCK # WE NEED
	CAME	T1,UBLOCK	;SAME AS CURRENT?
	PUSHJ	P,[PUSHJ P ,%USETU	;NO, SET ON IT
		PJRST	%INB]		;READ IT
CP1:	HRRZ	T0,CS.FPT(P1)	;GET NEXT LINK CONTROL SEC IN CORE (BYPASS 0)
	JUMPE	T0,CP3		;FIRST TIME ONLY ROOT THERE
	HRLZ	P1,P1		;SAVE LAST GOOD PTR
	HRR	P1,T0		;RESET LINK PTR
	MOVE	T1,INBFR(P2)	;GET LINK # WE WANT
	HRRZ	T0,CS.NUM(P1)	;LINK# WE HAVE
	JRST	CP1B		;BYPASS TEST FOR ROOT

CP1A:	HRRZ	T0,CS.FPT(P1)	;GET NEXT CONTROL SEC.
	JUMPE	T0,CP3		;RAN OUT
	HRLZ	P1,P1		;SAVE LAST GOOD PTR
	HRR	P1,T0		;RESET LINK PTR
	HRRZ	T0,CS.NUM(P1)	;LINK#
	MOVS	T1,INBFR(P2)	;GET NEXT PAIR
	CAIE	T0,(T1)		;MATCH?
	JRST	CP2		;NO, FIRST DIFFERENCE
	MOVS	T1,T1		;TEST FOR SECOND LINK#
	HRRZ	T0,CS.FPT(P1)	;GET NEXT CONTROL SEC.
	JUMPE	T0,CP3		;ALL DONE
	HRLZ	P1,P1		;SAVE LAST GOOD PTR
	HRR	P1,T0		;RESET LINK PTR
	HRRZ	T0,CS.NUM(P1)	;LINK#
CP1B:	CAIE	T0,(T1)		;MATCH?
	JRST	CP2		;NO
	CAIGE	P2,177		;WILL REQUIRED PTR FIT IN 128 WORDS?
	AOJA	P2,CP1A		;YES, LOOP
	AOS	T1,UBLOCK	;GET NEXT BLOCK
	PUSHJ	P,%USETI	;SET ON IT
	PUSHJ	P,%INB		;READ IT IN
	SETZ	P2,		;START AT FRONT
	JRST	CP1A		;AND KEEP TRYING
CP2:	PUSH	P,P1		;SAVE FIRST DIFF
	HRRZ	P1,P1		;CLEAR PREV
	PUSHJ	P,DELPTH	;[43] DELETE ALL OLD LINKS
	POP	P,P1
	HLRZ	P1,P1		;GET LAST GOOD ONE

;NOW TO GET THE LINK# WE NEED, MUST BE DONE IN REVERSE ORDER
;SINCE WE HAVE ONLY ONE BUFFER
;BUT WE CANNOT DO "OTHER" RELOCATION HERE
;MUST WAIT TIL ALL LINKS ARE IN CORE
CP3:	PUSHJ	P,GTLNK		;GET IT
	MOVE	P1,THSLNK	;GET POINTER TO NEW LINK
	HRRZ	T1,PS.BPT	;GET ADDRESS OF BACK POINTER LIST
	CAME	T1,UBLOCK	;CURRENTLY IN CORE?
	PUSHJ	P,[PUSHJ P ,%USETU	;NO, SET ON IT
		PJRST	%INB]		;READ IT
	HLRZ	P2,PS.BPT
	ANDI	T1,177		;OFFSET IN THIS BUFFER
	MOVE	T0,INBFR(P2)	;WHOM IT SHOULD BE LINKED TO
	TRNE	T0,-1		;IF LAST HALF WORD IS NULL
	TLZA	T0,-1		;NO, SO CLEAR LEFT
	HLRZ	T0,T0		;YES, USE LEFT HALF
	HLRZ	T1,CS.BPT(P1)	;GET BACK LINK
	HRRZ	T1,CS.NUM(T1)	;WHOM IT IS LINKED TO
	CAMN	T1,T0		;SAME?
	JRST	CP4		;YES, RETURN
	PUSHJ	P,RP0		;GET THIS PREAMBLE
	HLRZ	P1,CS.BPT(P1)	;RESET P1 TO POINT TO FATHER
	JRST	CP3		;AND READ IN LINK

;ROUTINE TO DELETE A LINK. THIS IMPLIES DELETING ALL OF ITS INFERIORS (THE
;PATH) TOO. IF WE TRY TO DELETE THE CURRENT LINK (THE ONE THAT CALLED US),
;GIVE ?OVLARC.
;
;CALL:
;	P1/	CONTROL BLOCK ADDR OF LINK TO START AT
;DESTROYS P1.

DELPTH:	MOVEM	P1,THSLNK	;[43] SET UP LINK FOR GBLNK
	SKIPN	OKOVLC		;[43] OK TO DELETE THE CALLER'S LINK
	CAME	P1,CURLNK	;[43]   OR NOT THE CALLER'S LINK?
	SKIPA			;[43] YES--DELETE THIS LINK
	JRST	.ERARC		;[43] NO--ATTEMPT TO REMOVE CALLER
	HRRZ	P1,CS.FPT(P1)	;[43] ADVANCE TO NEXT WHILE WE CAN
	PUSHJ	P,GBLNK		;[43] GIVE BACK THE LINK
	JUMPN	P1,DELPTH	;[43] FREE MORE IF ANY
	POPJ	P,		;[43] ALL DONE
;HERE TO CHECK FOR OTHER RELOCATION
CP4:
IFN FTRELOC,<
	MOVE	P1,FSTLNK	;START AT FRONT
CP4A:	MOVE	T1,CS.FLG(P1)	;GET FLAGS
	TLZN	T1,CF.RLO	;OTHER RELOCATION STILL TO DO?
	JRST	CP4C		;NOT FOR THIS ONE
	MOVEM	T1,CS.FLG(P1)	;CLEAR FLAG
	MOVE	T1,FSTLNK	;HOWEVER SEE IF WORTH DOING
CP4B:	HRRZ	T1,CS.FPT(T1)	;GET NEXT
	JUMPE	T1,CP4C		;NOTHING ON PATH WAS RELOCATED
	SKIPN	CS.RLC(T1)	;IS THIS LINK RELOCATED?
	JRST	CP4B		;NO, TRY NEXT
	PUSHJ	P,RLO		;DO RELOCATION
CP4C:	HRRZ	P1,CS.FPT(P1)	;GET NEXT
	JUMPN	P1,CP4A		;AND CHECK IT
>;END IFN FTRELOC

;HERE TO GET SYMBOLS RIGHT (FOR NOW, WILL FIX LATER)
CP5:
	SKIPN	.JBSYM##		;[32] SYMBOLS SET UP AT OVINI4?
	JRST	CP6			;NO
	MOVE	P1,FSTLNK		;GET START OF LIST
CP5A:	SKIPN	CS.SYM(P1)		;ALREADY SETUP?
	PUSHJ	P,GTSYM			;NO
	MOVEI	P2,(P1)			;REMEMBER LAST
	HRRZ	P1,CS.FPT(P1)		;GET NEXT
	JUMPN	P1,CP5A
IFE TOPS20,<
;HERE WITH ALL LINKS AND SYMBOLS IN CORE.
;MOVE SYMBOLS DOWN IF POSSIBLE SO CORE REDUCTION WILL WIN.

	HLRZ	P1,CS.SIZ(P2)		;GET SIZE OF HIGHEST LINK
	ADD	P1,CS.ADR(P2)		;FIND WHAT SHOULD BE FIRST
					;FREE WORD IN CORE.
	MOVEI	P1,200(P1)		;LEAVE SOME ROOM FOR LATER
CP7:	HRRZ	P2,.JBSYM##		;GET CURRENT SYMBOL LOC
	CAMG	P2,P1			;ARE THEY UP TOO HIGH?
	JRST	CP6			;NO, FORGET IT (SNH)
	MOVEM	P1,ADDCOR		;ADDRESS THAT WE WANT
	SUB	P2,P1			;MAX SIZE OF BLOCK WE WANT
	HLRO	P1,.JBSYM##		;GET - S.T. SIZE
	ADD	P2,P1			;FIND SPACE BETWEEN BLOCKS
	SKIPL	P2			;DO THE BLOCKS OVERLAP?
	SETZ	P2,			;NO, NO ADJUSTMENT NEEDED
	MOVN	P1,P1			;LENGTH THAT WE WANT
	ADD	P1,P2			;ADJUST FOR ANY OVERLAP
	MOVEM	P1,SIZCOR		;STORE FOR FUNCT.
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.GAD]		;TO GET CORE WHERE WE WANT
		A.AS,[ASCIZ /OVL/]	;THAT'S US
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;WHERE WE WANT THE CORE
		A.SPI,SIZCOR]		;HOW MUCH WE WANT
	PUSHJ	P,FUNCT.		;CALL OTS
	SKIPN	STATUS			;MAKE IT?
	JRST	CP8			;YES, GO MOVE SYMBOLS
	MOVE	P1,ADDCOR		;ADDR OF CORE WE CAN'T GET
	ADD	P1,PAGSIZ		;POINT TO SOME WE CAN
	JRST	CP7			;AND GO TRY AGAIN
;HERE TO COPY THE SYMBOL TABLE DOWN AND DELETE THE OLD COPY.

CP8:	HLRO	P2,.JBSYM##		;GET SYMBOL TABLE SIZE
	MOVN	P2,P2			;...
	ADD	P2,ADDCOR		;POINT TO END OF NEW S.T.
	HRLZ	P1,.JBSYM##		;SOURCE IS OLD S.T.
	HRR	P1,ADDCOR		;DEST IS NEW S.T.
	BLT	P1,-1(P2)		;COPY DOWN S.T.
	HRRZ	T0,.JBSYM##		;ADDR OF OLD S.T.
	SUB	T0,ADDCOR		;FIND HOW FAR THEY MOVED
	MOVN	T0,T0			;FIX SIGN FOR ADJSYM
	HRRZ	P1,.JBSYM##		;GET ADDR OF S.T. TO FREE
	CAMGE	P1,P2			;UNLESS THEY OVERLAP
	MOVE	P1,P2			;THEY DO ... ADJUST POINTER
	MOVEM	P1,ADDCOR		;POINT TO CORE TO FREE
	PUSHJ	P,ADJSYM		;ADJUST ALL S.T. PNTRS
	SKIPN	STATUS			;MAKE SURE ALL IS OK
	JRST	CP6			;MADE IT
.ERCSC:	PUSHJ	P,FATAL			;THIS SHOULDN'T HAPPEN
	TYPE	(<CSC	Cannot shrink core>)
	STOP				;SO DIE QUIETLY

CP6:	MOVEI	L,1+[-3,,0		;ARG LIST
		A.SPI,[F.CBC]		;TO REDUCE CORE IF POSSIBLE
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS]		;ERROR STATUS
	PUSHJ	P,FUNCT.	;CALL OTS

>;END IFE TOPS20
IFN TOPS20,<
CP6:>
	POP	P,L		;RESTORE ARG LIST PTR
	SPOP	<P2,P1>		;AND ACCS USED
	POPJ	P,
SUBTTL	READ IN DDT SYMBOLS


GTSYM:	SKIPN	T1,CS.DDT(P1)	;GET DSK SYMBOL PTR
	POPJ	P,		;NONE, GIVE UP
	PUSHJ	P,%USETI	;SET ON IT
	HLRE	T1,T1		;LENGTH
	HRRZ	T0,.JBSYM##	;TOP OF WHAT WE HAVE
	ADD	T0,T1		;BOTTOM
	MOVEM	T0,ADDCOR
	MOVMM	T1,SIZCOR	;SETUP ARGS
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.GAD]		;FOR GET CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPE	STATUS		;DID WE WIN
	JRST	GTSYM1		;NO
	MOVE	T0,ADDCOR	;WHERE TO READ INTO
	HLL	T0,CS.DDT(P1)	;DDT SYMBOL PTR
	MOVEM	T0,CS.SYM(P1)	;INDIVIDUAL LINK SYMBOL PTR
	SUBI	T0,1		;ONE LESS FOR IOWD
	PUSHJ	P,%INZ		;READ IT IN
	MOVN	T1,SIZCOR	;GET LENGTH
	HRLI	T1,-1(T1)	;IN BOTH HALVES, COMPENSATE FOR CARRY
	ADDM	T1,.JBSYM##	;ADJUST SYM PTR
IFN TOPS20,<
	PUSHJ	P,CHKDDT	;[40] STORE S.T. PTR IN DDT IF IT'S THERE
>
IFN FTRELOC,<
	SKIPN	CS.RLC(P1)	;WAS LINK RELOCATED
>
	POPJ	P,		;NO, RETURN
				;FALL INTO RLS0
IFN FTRELOC,<
COMMENT \
USES AC T0 - T5 AS FOLLOWS
T0	TO HOLD TEMP HALF WORD
T1	BYTE WORD (18 BYTES)
T2	TO HOLD BYTE COUNT IN LSH WORD (T1)
T3	OFFSET
T4	AOBJN WORD FOR BYTE WORDS (IN INBFR)
T5	- NO. OF WORDS FOR WHOLE LINK
\

RLS1:	SPUSH	<T3,T4,T5>	;MORE ACCS
	MOVE	T0,CS.NUM(P1)	;GET LINK#
	PUSHJ	P,RP0		;READ PREAMBLE AGAIN
	MOVE	T3,CS.RLC(P1)	;GET OFFSET
	SKIPN	T1,PS.RDR	;BLOCK WE NEED
	JRST	ERNRTS		;NOT RELOCATABLE
	HLRE	T5,T1		;-NO. OF WORDS IN LINK
	HRRZ	T2,CS.SYM(P1)	;FIRST WORD
	HRLI	T2,-^D18	;AOBJN WORD
	PUSHJ	P,RLCRD1	;FIRST TIME
	PUSHJ	P,RLCRW		;GET FIRST WORD

RLS2:	JUMPGE	T1,RLS4		;NO RELOCATION FOR LHS
	HLRZ	T0,(T2)		;GET 1/2 WORD
	ADD	T0,T3		;RELOCATE
	HRLM	T0,(T2)		;PUT BACK
RLS4:	LSH	T1,1		;RIGHT HALF BIT
	JUMPGE	T1,RLS5		;NO RELOCATION
	HRRZ	T0,(T2)		;GET 1/2 WORD
	ADD	T0,T3		;RELOCATE
	HRRM	T0,(T2)		;PUT BACK
RLS5:	LSH	T1,1
	JUMPN	T1,RLS6		;MORE TO DO FOR THIS BYTE WORD?
	AOBJN	T2,.		;USE UP ALL WORDS
	CAIA			; IN THIS 18
RLS6:	AOBJN	T2,RLS2		;LOOP FOR ALL OF LINK
RLS3:	AOJGE	T5,RLCZ		;RAN OUT OF WORDS
	PUSHJ	P,RLCRW		;GET NEXT RELOC WORD
	JUMPE	T1,[ADDI T2,^D18	;NONE FOR THIS WORD
		JRST	RLS3]		;IGNORE 0 WORDS
	HRLI	T2,-^D18	;RESET COUNT
	JRST	RLS2		;GET NEXT DATUM
>;END OF IFN FTRELOC
GTSYM1:	PUSHJ	P,MOVSYM	;TRY TO MOVE SYMBOL TABLE UP
	SKIPN	STATUS		;DID WE WIN?
	JRST	GTSYM		;YES, TRY AGAIN
.ERNCS:	PUSHJ	P,WARNIN
	  POPJ	P,
	TYPE	(<NCS	Not enough core to load symbols>)
	PJRST	CRLF
	SUBTTL	MOVE SYMBOL TABLE UP


MOVSYM:	HRRZ	T0,.JBSYM##	;GET BASE OF SYMBOL TABLE
	HLRE	T1,.JBSYM##	;LENGTH
	SUB	T0,T1		;NEXT FREE (WE HOPE)?
	HRRZ	T1,PAGSIZ	;MINIMUM TO EXPAND BY
	DMOVEM	T0,ADDCOR	;STORE ARGS
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.GAD]		;FOR GET CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;SEE IF WE CAN GET IT
	SKIPN	T1,STATUS	;WELL?
	JRST	MOVSY3		;GOT IT, NOW MOVE UP SYMBOLS
	CAIE	T1,2		;OTHER ALLOCATED BLOCKS IN THE WAY?
	  POPJ	P,		;NO, GIVE UP
	HLRE	T1,.JBSYM##	;NOW MUST FIND PIECE AS LONG AS ST
	MOVNM	T1,SIZCOR	;SO SET UP FOR NEXT FUNCT. CALL
MOVSY1:	HRRZ	T1,PAGSIZ	;SEE IF CORE A PAGE HIGHER IS FREE
	ADDM	T1,ADDCOR	;SO CAN PUT THE SYMBOL TABLE THERE
	MOVEI	L,1+[-5,,0		;USUAL ARG LIST FOR FUNCT.
		A.SPI,[F.GAD]		;GET CORE AT ADDRESS
		A.AS,[ASCIZ /OVL/]	;CODE FOR ERRORS
		A.SPI,STATUS		;RETURN STATUS
		A.SPI,ADDCOR		;ADDRESS OF PIECE OF CORE
		A.SPI,SIZCOR]		;SIZE OF IT
	PUSHJ	P,FUNCT.	;TRY FOR IT
	SKIPN	T1,STATUS	;MAKE IT?
	  JRST	MOVSY2		;YES, NOW BLT SYMBOLS
	CAIN	T1,2		;OTHER BLOCKS STILL IN THE WAY?
	JRST	MOVSY1		;YES, TRY HIGHER YET
	POPJ	P,		;NO, GIVE UP ON SYMBOLS

MOVSY2:	HRLZ	T0,.JBSYM##	;OLD LOC OF SYMBOLS
	HRR	T0,ADDCOR	;AND NEW LOC
	HRRZ	T1,T0		;CALC WHERE THEY WILL END
	ADD	T1,SIZCOR	;..
	BLT	T0,-1(T1)	;AND MOVE THE SYMBOLS
	HRRZ	T0,.JBSYM##	;GET ADDRESS TO RETURN
	EXCH	T0,ADDCOR	;STORE IT; GET NEW ADDRESS
	SUB	T0,ADDCOR	;FIND THEIR DIFFERENCE FOR ADJSYM
	JRST	ADJSYM		;GO FIXUP ALL OTHER SYM POINTERS
;MOVE SYMBOL TABLE UP BY REVERSE BLT LOOP
MOVSY3:	HRRZ	T0,.JBSYM##	;BOTTOM OF SYMBOLS
	HLRE	T1,.JBSYM##	;-LENGTH
	MOVM	T1,T1
	HRL	T1,T1		;+LENGTH ,, +LENGTH
	ADD	T1,T0		;+LENGTH ,, TOP + 1
	SUBI	T1,1		;,,TOP
	TLO	T1,(1B0)	;SIGN BIT ON
	MOVEM	T0,ADDCOR	;ADDRESS WE WILL GIVE BACK
IFN FT2SEG,<
	PUSHJ	P,PAGSIZ	;MUST BE IN LOW SEG
>
	SEGMENT	LOW
PAGSIZ:	POP	T1,.-.(T1)	;*** MODIFIED ***
	JUMPL	T1,.-1		;LOOP FOR ALL SYMBOLS
IFN FT2SEG,<
	POPJ	P,		;RETURN
>
	SEGMENT	HIGH
	HRRZ	T0,PAGSIZ	;ADJUST SYMBOL PTR BY HOW MUCH THEY MOVED
ADJSYM:	ADDM	T0,.JBSYM##
IFN TOPS20,<
	PUSHJ	P,CHKDDT	;[40] STORE S.T. PTR IN DDT IF IT'S THERE
>
	MOVE	T1,FSTLNK	;MUST DO SAME FOR ALL LINKS IN CORE
	SKIPE	CS.SYM(T1)	;MY NOT BE ANY
	ADDM	T0,CS.SYM(T1)	;ADJUST
	HRRZ	T1,CS.FPT(T1)	;GET NEXT
	JUMPN	T1,.-3		;FOR ALL
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.RAD]		;FOR RETURN CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;GIVE SPACE BACK
	POPJ	P,		;RETURN
SUBTTL	GIVE BACK LINK


GBLNK:	SKIPE	.JBSYM##	;[32] KEEPING SYMBOLS UP TO DATE?
	PUSHJ	P,GBSYM		;YES, RETURN SYMBOL SPACE
	MOVE	T1,THSLNK	;GET START OF CONTROL SECTION
;CLEAR BI-DIRECTIONAL REFERENCE IN EXTTAB
	MOVSI	T0,F.LIC	;TO CLEAR INCORE FLAG
	MOVE	T1,CS.EXT(T1)	;GET AOBJN POINTER TO TRANS TABLES
	JUMPGE	T1,GBLNK1	;IGNORE IF NONE
GBLNK0:	HLRZ	T2,ET.NUM(T1)	;GET LINK #
	JUMPE	T2,GBLNKU	;MUST BE UNDEFINED IF IN ROOT
	MOVE	T2,ET.REF(T1)	;GET OTHER REF POINTER
	TRNE	T2,-1
	HLLM	T2,(T2)		;BACK LINK IN FORWARD OVERLAY
	MOVS	T2,T2
	TRNE	T2,-1		;SKIP IF NO FORWARD LINK
	HLRM	T2,(T2)		;FORWARD LINK IN BACK OVERLAY
	ANDCAM	T0,ET.FLG(T1)	;CLEAR FLAG FOR COMPLETNESS
GBLNKU:	ADDI	T1,ET.LEN-1	;5 WORD BLOCKS
	AOBJN	T1,GBLNK0	;LOOP FOR ALL OF TABLES

;NOW TO CLEAR ALL DIRECT REFERENCES
GBLNK1:	MOVE	T1,THSLNK	;GET CONTROL SECTION AGAIN
	PUSH	P,T3		;SAVE UNTIL END OF LOOP
	MOVN	T3,CS.RLC(T1)	;GET RELOC OFFSET
	MOVE	T1,CS.INT(T1)	;AOBJN PTR TO INT TRANS TABLE
	JUMPGE	T1,GBLNK5	;NONE
GBLNK2:	HRRZ	T2,IT.REF(T1)	;GET FORWARD REF
	JUMPE	T2,GBLNK4	;END OF CHAIN
GBLNK3:	HRL	T2,(T2)		;GET ITS REF
GBLNK6:	SETZM	(T2)		;CLEAR THIS
	ANDCAM	T0,ET.ADR-ET.REF(T2)	;AND ITS INCORE FLAG
	ADDM	T3,ET.ADR-ET.REF(T2)	;REMOVE RELOCATION
	HLRZ	T2,T2		;GET NEXT
	JUMPN	T2,GBLNK6	;LOOP IF EXISTS
GBLNK4:	ADDI	T1,IT.LEN-1	;TWO WORD TABLES
	AOBJN	T1,GBLNK2	;LOOP
;NOW TO CLEAR FORWARD & BACKWARD LINKS
GBLNK5:	MOVE	T1,THSLNK	;POINT TO CONTROL SECTION
	POP	P,T3		;RESTORE AFTER LOOP
	MOVE	T1,CS.PTR(T1)	;GET POINTERS
	TRNE	T1,-1		;SKIP IF NO FORWARD ONE
	HLLM	T1,CS.BPT(T1)	;STORE BACK PTR IN FORWARD LINK
	MOVS	T1,T1
	TRNE	T1,-1		;SKIP IF NO BACK PTR
	HLRM	T1,CS.FPT(T1)	;STORE FORWARD PTR IN BACK LINK
;NOW TO DELETE LINK
IFN FTLOG,<
	SKIPE	.OVRLOG		;NEED TO PUT IN LOG FILE
	PUSHJ	P,LNKOUT	;YES, PUT IN LOG FILE
>;END OF IFN FTLOG
	MOVE	T1,THSLNK	;GET CONTROL SECTION OF THIS LINK
	MOVE	T1,CS.COR(T1)	;GET CORE SIZE AND ORIGIN
	HRRZM	T1,ADDCOR	;ORIGIN
	HLRZM	T1,SIZCOR	;LENGTH
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.RAD]		;FOR RETURN CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPN	STATUS		;MAKE SURE OK
	POPJ	P,		;&RETURN
.ERCDL:	PUSHJ	P,FATAL
	TYPE	(<CDL	Cannot delete>)
	PUSHJ	P,PRNLNK	;PRINT LINK#
	PUSHJ	P,PRNFRS	;INDIC WHY
	STOP			;AND GIVE UP
SUBTTL	GIVE BACK SYMBOLS


GBSYM:	MOVE	T1,THSLNK	;GET START OF CONTROL SECTION
	MOVE	T0,CS.SYM(T1)	;GET SYMBOL TABLE PTR
	JUMPE	T0,CPOPJ	;NONE
	HRRZM	T0,ADDCOR	;GIVE BACK AT THIS ADDRESS
	HLRE	T0,T0
	MOVM	T0,T0
	MOVEM	T0,SIZCOR	;THIS MUCH
	HRL	T0,T0
	ADDM	T0,.JBSYM##	;REDUCE SYMBOL TABLE
IFN TOPS20,<
	PUSHJ	P,CHKDDT	;[40] STORE S.T. PTR IN DDT IF IT'S THERE
>
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.RAD]		;FOR RETURN CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPE	STATUS		;MAKE SURE OK
	JRST	.ERCDL		;NO
	POPJ	P,		;YES, RETURN
SUBTTL	GET NEW LINK


GTLNK:	SKIPN	T1,.JBSYM##	;SYMBOLS MAY BE IN THE WAY
	JRST	GTLNK4		;NO SUCH LUCK
	MOVE	T0,PS.ADD	;SEE IF THEY ARE IN THE WAY
	ADD	T0,PS.LEN
	CAIGE	T0,(T1)		;ARE THEY?
	JRST	GTLNK4		;NO, GO LOAD THE LINK
	PUSHJ	P,MOVSYM	;YES, TRY TO MOVE THEM
	SKIPN	STATUS		;DID WE
	JRST	GTLNK		;YES, TRY AGAIN
	JRST	GTLNK0		;NO - MUST RELOCATE LINK
GTLNK4:	DMOVE	T0,PS.ADD	;GET WHERE WE WANT LINK TO GO & LENGTH OF IT
	DMOVEM	T0,ADDCOR	;STORE FOR FUNCT. CALL
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.GAD]		;FOR GET CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPN	STATUS		;CHECK FOR FAILURE
	JRST	GTLNK2		;GOT WHAT WE NEED
GTLNK0:
IFN FTRELOC,<
	DMOVE	T0,PS.ADD	;GET ADDR AND SIZE OF LINK
	DMOVEM	T0,ADDCOR	;STORE FOR FUNCT. CALL
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.COR]		;FOR GET CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPE	STATUS		;CHECK FOR FAILURE
	JRST	.ERCGC		;FAILED
	HRRZ	T1,.JBSYM##	;IF LOADING SYMBOLS
	JUMPE	T1,GTLNK1	;NO
	CAMLE	T1,ADDCOR	;SEE IF ABOVE SYMBOLS
	JRST	GTLNK1		;NO, ALL IS WELL
				;GIVE BACK SPACE, MOVE SYMBOLS AND TRY AGAIN
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.RAD]		;FOR GIVE BACK CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SPUSH	<ADDCOR,SIZCOR>	;PRESERVE THESE ACROSS MOVSYM
	PUSHJ	P,MOVSYM	;MOVE SYMBOLS
	SPOP	<SIZCOR,ADDCOR>	;RESTORE FROM MOVSYM
	SKIPN	STATUS		;DID THAT WIN?
	JRST	GTLNK		;YES, TRY WHOLE CYCLE AGAIN
	MOVEI	L,1+[-5,,0		;MUST DO WITH WHAT WE CAN
		A.SPI,[F.COR]		; GET, EVEN IF SYMBOLS ARE
		A.AS,[ASCIZ /OVL/]	; IN THE WAY
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.		;GET THAT CORE BACK
	SKIPE	STATUS			;STILL THERE?
	JRST	.ERCGC			;NO???????????? BUG IN OTS
>
GTLNK1:	MOVEI	T1,PS.NUM-CS.NUM	;FAKE PTR IN THSLNK
	MOVEM	T1,THSLNK	;FOR ERROR MESSAGES

IFE FTRELOC,<
	PUSHJ	P,FATAL
.ERACF:	TYPE	(<ACF	Absolute core request failed for>)
	PUSHJ	P,PRNLNK	;PRINT LINK NUMBER
	STOP
>
IFN FTRELOC,<
	PUSHJ	P,WARNIN
	  JRST	GTLNK2
.ERACF:	TYPE	(<ACF	Absolute core request failed for>)
	PUSHJ	P,PRNLNK	;PRINT LINK NUMBER
	PUSHJ	P,CRLF		;END LINE
				;FALL INTO GTLNK2
>
GTLNK2:	MOVE	T1,PS.OVL	;BLOCK# LINK STARTS AT
	PUSHJ	P,%USETI	;SET ON IT
	MOVN	T1,PS.LEN	;-LENGTH
	HRLZ	T0,T1		;LEFT HALF OF IOWD
	HRR	T1,ADDCOR	;START OF BLOCK
	HRRI	T0,-1(T1)	;-LENGTH,,ADDRESS-1
	PUSHJ	P,%INZ		;READ IT
;*** NOW CHECK RELOCATION ***
IFN FTRELOC,<
	MOVE	T0,ADDCOR	;ADDRESS WE GOT
	SUB	T0,PS.ADD	;ADDRESS WE WANTED
	MOVE	T1,PS.CST	;WHERE CONTROL SECT SHOULD BE
	ADD	T1,T0		;WHERE IT IS
	MOVEM	T1,THSLNK	;POINT TO IT
	PUSHJ	P,RLC0		;SEE IF RELOCATION REQUIRED
>
IFE FTRELOC,<
	MOVE	T1,PS.CST	;[34] LINK IS ALWAYS WHERE EXPECTED
	MOVEM	T1,THSLNK	;[34] POINT THSLNK TO IT
>
IFN FTLOG,<
	SKIPN	.OVRLOG		;NEED TO PUT IN LOG FILE?
	JRST	GTLNK3		;NO
	PUSHJ	P,LNKIN		;YES, PRINT IT
	MOVE	T1,THSLNK
	SKIPE	CS.RLC(T1)	;DID IT NEED RELOCATION?
	PUSHJ	P,LNKRLL	;YES
GTLNK3:>;END OF IFN FTLOG
	MOVE	T1,THSLNK	;ADDRESS OF LINK WE JUST READ IN
	MOVE	T0,CS.FPT(P1)	;GET FORWARD POINTER
	HRLZM	P1,CS.BPT(T1)	;LINK TOWARDS ROOT
	HRRM	T0,CS.FPT(T1)	;POSSIBLE FORWARD LINK
	HRRM	T1,CS.FPT(P1)	;PUTIN NEW FORWARD LINK
	EXCH	T1,T0		;SO WE CAN INDEX TO FORWARD PTR
	TRNE	T1,-1		;BUT NOT IF 0
	HRLM	T0,CS.BPT(T1)	;LINK FORWARD LINK TO THIS ONE
	POPJ	P,

IFN FTRELOC!FTLOG<
.ERCGC:	PUSHJ	P,FATAL
	TYPE	(<CGC	Cannot get core from OTS>)
	PUSHJ	P,PRNFRS	;INDICATE WHY
	STOP
>
SUBTTL	MULTIPLY-DEFINED ENTRY POINTS


MDL0:	PUSH	P,T3		;ACC FOR AOBJN WORD
	MOVE	T3,JT.MDL(T1)	;GET AOBJN PTR TO MDL TABLE
	ADDI	T3,1		;BYPASS NAME
MDL1:	HLRZ	T0,MT.NUM(T3)	;GET LINK# WE WANT
	MOVE	T2,FSTLNK	;START OF INCORE LIST
	CAMN	T0,CS.NUM(T2)	;MATCH?
	JRST	MDLIC		;YES
	HRRZ	T2,CS.FPT(T2)	;GET NEXT
	JUMPN	T2,.-3		;TRY AGAIN
	ADDI	T3,1		;WORDS ARE PAIRS
	AOBJN	T3,MDL1		;TRY NEXT POSSIBLE ENTRY
	PUSH	P,T1		;SAVE PTR
				;WE HAVE SEVERAL POSSIBLE CHOICES
				;READ ALL THE PREAMBLES AND PICK THE
				;ONE WITH THE LARGEST PATH IN CORE
				;IF POSSIBLE ONE THAT DOES NOT OVERLAY
				;EXISTING LINKS
	MOVE	T3,JT.MDL(T1)	;GET AOBJN PTR BACK
	ADDI	T3,1		;BYPASS NAME
	SPUSH	<T4,T5>		;USED AS COUNTERS
	SETZB	T4,T5		;INITIALIZE
MDL3:	HLRZ	T0,MT.NUM(T3)	;GET POSSIBLE LINK
	PUSHJ	P,RP0		;READ PREAMBLE IN
	HRRZ	T1,PS.FPT	;BLOCK# WE NEED
	CAME	T1,UBLOCK	;SAME AS CURRENT?
	PUSHJ	P,[PUSHJ P,%USETU	;NO SET ON IT
		PJRST	P,%INB]		;AND READ IT IN
	HLRZ	T1,PS.FPT	;REL WORD IN BLOCK
	ADDI	T1,INBFR	;FIX IN CORE
	HRLI	T1,(POINT 18,0,17)	;BYPASS FIRST BYTE SINCE ITS 0
	MOVE	T2,FSTLNK	;GET START
	JFFO	T3,MDL5		;BYPASS ROOT AND CLEAR T4 ON THE FLY
MDL4:	ILDB	T0,T1		;GET NEXT ONE WE WANT
	CAME	T0,CS.NUM(T2)	;MATCH?
	JRST	MDL6		;NO, END OF THIS TRY
	ADDI	T4,1		;ONE MORE MATCH
MDL5:	HRRZ	T2,CS.FPT(T2)	;GET NEXT
	JUMPN	T2,MDL4		;AS LONG AS THERE IS ONE
MDL6:	CAIG	T4,(T5)		;LONGEST PATH YET?
	JRST	.+3		;NO
	HRRZ	T5,T4		;LENGTH
	HRL	T5,T3		;PTR TO IT
	ADDI	T3,1		;WORDS ARE IN PAIRS
	AOBJN	T3,MDL3		;MORE TO TRY?
	HLRZ	T3,T5		;NO PICK LONGEST
	SPOP	<T5,T4>
	JUMPN	T3,.ERARL	;HOWEVER IF NONE WERE ANY GOOD
	MOVE	T1,0(P)		; RESTORE ORIGINAL PTR
	MOVE	T3,JT.MDL(T1)	; AND USE FIRST!
	ADDI	T3,1		;BYPASS NAME
.ERARL:	PUSHJ	P,WARNIN	;WARN USER ABOUT CONFLICT
	  JRST	MDL2		;NOT WANTED, RESTORE T1
	TYPE	(<ARL	Ambiguous request in>)
	HRRZ	T1,MT.CST(T3)	;GET CONTROL SEC ADDRESS
	MOVEM	T1,THSLNK	;FOR ERROR MESSAGE
	PUSHJ	P,PRNLNK	;LINK #
	TYPE	(< for >)
	MOVE	T1,0(P)		;GET EXTTAB PTR
	MOVE	T1,JT.MDL(T1)	;GET MULTIPLE-DEFINED PTR
	MOVE	T1,0(T1)	;GET NAME
	PUSHJ	P,PRNSBX
	TYPE	(<, using link number >)
	HLRZ	T0,MT.NUM(T3)	;GET ONE WE PICKED OUT
	PUSHJ	P,PRNDEC
	PUSHJ	P,CRLF
MDL2:	POP	P,T1
	HRRM	T3,JT.ADR(T1)	;STORE POINTER INCASE RELOCATED
	EXCH	T1,0(P)		;GET OLD T3, PUT T1 ON STACK
	MOVE	T3,MT.CST(T3)	;GET LINK #
	EXCH	T1,T3		;PUT IN T1, RESTORE T3
	JRST	NINC1		;NOT INCORE

MDLIC:	HRRZ	T0,T3		;POINTER TO INTTAB
	POP	P,T3		;RESTORE ACC
	JRST	MINC		;AND SEE IF RELOCATED
SUBTTL	RELOCATE LINK


IFN FTRELOC,<
COMMENT \
USES AC T0 - T5 AS FOLLOWS
T0	TO HOLD TEMP HALF WORD
T1	BYTE WORD (18 BYTES)
T2	TO HOLD BYTE COUNT IN LSH WORD (T1)
T3	OFFSET
T4	AOBJN WORD FOR BYTE WORDS (IN INBFR)
T5	- NO. OF WORDS FOR WHOLE LINK
\

RLC0:	SKIPE	T0		;NONE FOR THIS LINK
	PUSHJ	P,RLC1		;RELOCATE THIS LINK
	MOVSI	T0,CF.RLO	; GET FLAG
	MOVE	T1,THSLNK	;GET POINTER
	SKIPE	PS.ORL		;ANY OTHER RELOCATION?
	IORM	T0,CS.FLG(T1)	;YES, DO IT LATER
	POPJ	P,

RLC1:	SPUSH	<T3,T4,T5>	;MORE ACCS
	MOVE	T3,T0		;SAFER PLACE
	MOVE	T1,PS.CST	;WHERE CS SHOULD HAVE BEEN
	ADD	T1,T3		;WHERE IT IS
	MOVEM	T3,CS.RLC(T1)	;STORE DIFF
	SKIPN	T1,PS.REL	;BLOCK WE NEED
	JRST	.ERNRT		;NOT RELOCATABLE
	HLRE	T5,T1		;-NO. OF WORDS IN LINK
	HRRZ	T2,ADDCOR	;FIRST WORD
	HRLI	T2,-^D18	;AOBJN WORD
	PUSHJ	P,RLCRD1	;FIRST TIME
	PUSHJ	P,RLCRW		;GET FIRST WORD
RLC2:	JUMPGE	T1,RLC4		;NO RELOCATION FOR LHS
	HLRZ	T0,(T2)		;GET 1/2 WORD
	ADD	T0,T3		;RELOCATE
	HRLM	T0,(T2)		;PUT BACK
RLC4:	LSH	T1,1		;RIGHT HALF BIT
	JUMPGE	T1,RLC5		;NO RELOCATION
	HRRZ	T0,(T2)		;GET 1/2 WORD
	ADD	T0,T3		;RELOCATE
	HRRM	T0,(T2)		;PUT BACK
RLC5:	LSH	T1,1
	JUMPN	T1,RLC6		;MORE TO DO FOR THIS BYTE WORD?
	AOBJN	T2,.		;USE UP ALL WORDS
	CAIA			; IN THIS 18
RLC6:	AOBJN	T2,RLC2		;LOOP FOR ALL OF LINK
RLC3:	AOJGE	T5,RLCZ		;RAN OUT OF WORDS
	PUSHJ	P,RLCRW		;GET NEXT RELOC WORD
	JUMPE	T1,[ADDI T2,^D18	;NONE FOR THIS WORD
		JRST	RLC3]		;IGNORE 0 WORDS
	HRLI	T2,-^D18	;RESET COUNT
	JRST	RLC2		;GET NEXT DATUM

RLCZ:	SPOP	<T5,T4,T3>	;RESTORE ACCS
	POPJ	P,		;RETURN

RLCRW0:	JUMPE	T5,RLCZ		;SEE IF ALL DONE
	PUSHJ	P,RLCRD		;NO, FILL BUFFER
RLCRW:	AOBJP	T4,RLCRW0	;JUMP IF BUFFER IS EMPTY
	MOVE	T1,(T4)		;GET NEXT WORD
	POPJ	P,

RLCRD:	AOS	T1,UBLOCK	;READ NEXT BLOCK
RLCRD1:	PUSHJ	P,%USETU	;SET ON IT
	PUSHJ	P,%INB		;READ IT IN
	MOVE	T4,[-201,,INBFR-1]	;ACCOUNT FOR INITIAL AOBJX
	POPJ	P,
SUBTTL	OTHER RELOCATION


COMMENT	\
USES AC T0 - T5 AS FOLLOWS
T0	TEMP 1/2 WORD
T1	WORD TO RELOC
T2	RELOC BYTES
T3	OFFSET
T4	AOBJN COUNTER FOR NO. OF WORDS IN BUFFER
T5	-NO. OF WORDS IN THIS LINK,, -NO. OF WORDS IN PS.ORL
\

RLO:	MOVE	T0,CS.NUM(P1)	;GET LINK#
	PUSHJ	P,RP0		;READ IN PREAMBLE AGAIN
	SPUSH	<T3,T4,T5>	;NEED ACCS AGAIN
	MOVE	T1,PS.ORL	;GET POINTER
	HLRZ	T5,T1		;-NO. OF WORDS IN PS.ORL
	PUSHJ	P,RLCRD1	;SETUP FIRST TIME
RLO1:	JUMPE	T5,RLCZ		;ALL DONE
	PUSHJ	P,RLCRW		;READ A WORD
	JUMPE	T1,RLCZ		;ALL DONE
	MOVN	T1,T1		;NO. OF WORDS
	HRL	T5,T1		;FORM AOBJN COUNTER
	PUSHJ	P,RLCRW		;GET LINK#,,ADDRESS
	HLRZ	T2,T1		;LINK#
	HRRZ	T3,T1		;ADDRESS WE WOULD LIKE IT AT
	MOVE	T1,FSTLNK	;START OF CHAIN
RLO2:	CAMN	T2,CS.NUM(T1)	;ONE WE WANT?
	JRST	RLO3		;YES
	HRRZ	T1,CS.FPT(T1)	;GET NEXT
	JUMPN	T1,RLO2		;TRY IT
.ERLNC:	PUSHJ	P,FATAL		;NOT IN CORE!
	TYPE	(<LNC	link number >)
	MOVE	T0,T2		;NUMBER WE WANTED
	PUSHJ	P,PRNDEC	;BUT FAILED TO FIND
	TYPE	(< not in core>)
	STOP
RLO3:	HRRZ	T1,CS.ADR(T1)	;WHERE IT REALLY IS
	SUBM	T1,T3		;DIFFERENCE
	JUMPE	T3,RLO8		;OK, ITS THERE
RLO4:	AOBJP	T5,RLO1		;GET NEXT LINK 
	PUSHJ	P,RLCRW		;GET A RELOC WORD
	HLLZ	T2,T1		;RELOC BITS
	HRRZ	T1,T1		;ADDRESS
	ADD	T1,CS.RLC(P1)	;PUT IN RIGHT PLACE
RLO5:	JUMPGE	T2,RLO6		;NO RELOC FOR LHS
	HLRZ	T0,(T1)		;GET 1/2 WORD
	ADD	T0,T3		;ADDRESS IT SHOULD BE AT
	HRLM	T0,(T1)
RLO6:	LSH	T2,1		;GET RHS RELOC
	JUMPGE	T2,RLO7		;NONE
	HRRZ	T0,(T1)
	ADD	T0,T3
	HRRM	T0,(T1)
RLO7:	LSH	T2,1
	JUMPE	T2,RLO4		;GET NEXT
	AOJA	T1,RLO5


RLO8:	HLRE	T1,T5		;NO. OF WORDS LEFT IN THIS AREA
	MOVM	T1,T1
	HRL	T1,T1
	ADD	T5,T1		;BYPASS THEM
RLO9:	ADD	T4,T1		;AND IN BUFFER
	JUMPL	T4,RLO1		;TRY NEXT AREA
	HLRZ	T2,T4		;STORE EXCESS
	PUSHJ	P,RLCRD		;GET NEXT BLOCK
	MOVE	T1,T2
	HRL	T1,T1		;AOBJN TO ADD TO BUFFER PTR
	JRST	RLO9

>;END OF IFN FTRELOC
SUBTTL	INITIALIZE FILE


SETINI:	PUSH	P,T1		;SAVE CALLER PC
	PUSHJ	P,OVINI		;ZERO CORE AND GET CHAN# AND OPEN OVERLAY FILE
	POP	P,T1		;RESTORE PC
	JRST	.OVRLA		;TRY AGAIN
SUBTTL	OVINI - ZEROES CORE AND GETS CHAN# FOR OVERLAY FILE


OVINI:	MOVE	T0,[I.ZZ,,I.ZZ+1]
	SETZB	T1,I.ZZ
	BLT	T0,I.END	;ZERO DATA
IFE TOPS20,<
	MOVX	T0,%CNPGS	;[42] GET PAGE SIZE
	GETTAB	T0,		;FROM MONITOR
	  MOVEI	T0,2000		;ASSUME K
>
IFN TOPS20,<
	DMOVEM	T2,TEMP2	;[42] SAVE THE ACCS
	MOVEI	T0,1000		;WE KNOW ITS PAGES
>
	HRRM	T0,PAGSIZ	;ONLY USED IF SYMBOLS LOADED
	PUSH	P,L		;SAVE CURRENT ARG POINTER
IFN FTLOG,<
	MOVEI	L,1+[-4,,0		;ARG LIST FOR GET RUNTIME FNCT
		A.SPI,[F.RNT]		;FUNCTION #4
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;RETURN STATUS
		A.SPI,ITIME]		;RETURN RUNTIME
	PUSHJ	P,FUNCT.	;GET IT
>
IFE TOPS20,<
	MOVEI	L,1+[-4,,0		;ARG LIST FOR GET CHAN FNCT
		A.SPI,[F.GCH]		;FUNCTION #4
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;RETURN STATUS
		A.SPI,IOCHN]		;RETURN CHAN #
	PUSHJ	P,FUNCT.	;GET IT
	SKIPE	STATUS		;DID WE WIN
	JRST	.ERCNA		;NOT AVAILABLE
	HRLZ	T1,IOCHN	;GET CHAN #
	LSH	T1,5		;SHIFT INTO AC FIELD
	IORM	T1,%INIT	;MODIFY INIT
	IORM	T1,%LUKUP+1	;[36]
	IORM	T1,%USETI
	IORM	T1,%IN
	IORM	T1,%STS
IFN FTWRITE,<
	IORM	T1,%USETO
	IORM	T1,%OUT
>
	SKIPE	IDEV		;ALREADY SETUP?
	JRST	OVINI1		;YES
	MOVSI	T1,'OVL'	;SET DEFAULT EXT
	MOVEM	T1,LEXT


;NOW TRY TO GET WHERE WE CAME FROM (INCLUDING SFD'S) VIA GETTAB.
;IF UNAVAILABLE (OLD MONITOR), USE INFO FROM FUNCT.

	MOVSI	T1,-<.PTMAX-.PTSFD-1>	;[46] NUMBER OF SFD'S
	HRROI	T0,.GTRS0	;[46] GETTAB FOR RUN FROM SFD, THIS JOB
SFDLUP:	PUSH	P,T0		;[46] SAVE OVER GETTAB
	GETTAB	T0,		;[46] GET IT
	  JRST	NOSFD		;[46] GETTAB FAILED, SEE WHY
	MOVEM	T0,LPATH+.PTSFD(T1)	;[46] STORE THIS SFD
	POP	P,T0		;[46] RESTORE
	ADDI	T0,1		;[46] INCREMENT GETTAB ARG
	AOBJN	T1,SFDLUP	;[46] LOOP FOR ALL SFD'S
	JRST	GETUFD		;[46] GOT ALL SFDS, NOW FOR UFD


;HERE WHEN A GETTAB TO GET AN SFD FAILED.  SEE IF THE MONITOR IS TOO OLD.

NOSFD:	POP	P,T0		;[46] KEEP STACK IN PHASE
	TRNE	T1,-1		;[46] FAIL FIRST TIME?
	JRST	GETUFD		;[46] NO, GOT SOME SFDS, USE NEW DATA
	JRST	NOT701		;[46] GO USE FUNCT.
;HERE IF THE 7.01 GETTABS WORK.  FILL IN THE REST OF THE DATA.

GETUFD:	SETZM	LPATH+.PTSFD(T1)	;[46] FORCE A ZERO AFTER THE LAST SFD
	HRROI	T1,.GTRDI	;[46] UFD OF PATH WE WERE RUN FROM
	GETTAB	T1,		;[46] GET IT
	  JRST	NOT701		;[46] CAN'T
	SKIPN	T1		;[46] THERE?
	JRST	NOT701		;[46] NO, GIVE UP
	MOVEM	T1,LPATH+.PTPPN	;[46] STORE UFD TO FINISH PATH BLOCK
	HRROI	T1,.GTRDV	;[46] GET DEVICE WE WERE RUN FROM
	GETTAB	T1,		;[46]  . . .
	  JRST	NOT701		;[46] NOT THERE FORGET IT
	SKIPN	T1		;[46] AVAILABLE?
	JRST	NOT701		;[46] NOPE, DON'T USE THIS INFO
	MOVEM	T1,IDEV		;[46] YES, STORE DEVICE
	HRROI	T1,.GTRFN	;[46] THE FILE NAME WE CAME FROM
	GETTAB	T1,		;[46] GET IT
	  JRST	NOT701		;[46] CAN'T, LEAVE WELL ENOUGH ALONE
	SKIPN	T1		;[46] RETURN ANYTHING?
	  JRST	NOT701		;[46] NO, IGNORE IT
	MOVEM	T1,LNAME	;[46] OK, STORE IT
	MOVEI	T1,LPATH	;[46] NOW POINT LOOKUP BLOCK TO PATH BLOCK
	MOVEM	T1,LPPN		;[46] STORE IN .RBPPN
	JRST	OVINI1		;[46] DONE, PROCEED


;HERE IF THE GETTABS DON'T WORK.  USE FUNCT. TO ASK THE OTS THE
;CONTENTS OF THE ACS AT STARTUP.

NOT701:	MOVEI	L,1+[-6,,0		;[46] ARG LIST FOR GET FILE SPEC FNCT
		A.SPI,[F.IFS]		;FUNCTION #11
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;RETURN STATUS
		A.SPI,IDEV		;RETURN DEVICE
		A.SPI,LNAME		;RETURN FILE NAME
		A.SPI,LPPN]		;RETURN PPN
	PUSHJ	P,FUNCT.	;GET IT
>;END IFE TOPS20
IFN TOPS20,<
	SKIPE	STRPTR		;STRING SETUP?
	JRST	OVINI1		;YES
	MOVEI	T1,OVRL1+1000	;[42] SEE IF A PURE PAGE IN THE
	LSH	T1,-9		;[42]   MIDDLE OF OVRLAY IS
	HRLI	T1,.FHSLF	;[42]   SHARABLE
	RPACS%			;[41] READ ACCESSABILITY
	  ERJMP	.ERRPA
	TXNE	T2,PA%PRV	;[42] PRIVATE?
	JRST	.EROPP		;TOO BAD
	RMAP%			;[41] JFN FROM WHENCE WE CAME
	  ERJMP	.ERRMP
	HLRZ	T2,T1		;[42] JFN
	HRROI	T1,INBFR	;[42] WHERE TO STORE IT
	MOVEM	T1,STRPTR	;[42] FOR GTJFN%
	MOVX	T3,<<FLD .JSAOF,JS%DEV>!<FLD .JSAOF,JS%DIR>!
		    <FLD .JSAOF,JS%NAM>!JS%PAF> ;[42] DEV:<DIR>NAME
	JFNS%			;[41]
>;END IFN TOPS20
OVINI1:	MOVX	T1,<MOVE T0,JT.FLG(T1)> ;[42]
	MOVEM	T1,.OVRLA	;REPLACE INST
	MOVE	T1,.JBSA##	;GET START ADDRESS
	MOVE	T0,.JBREL##	;AND INITIAL CORE SIZE
	DMOVEM	T0,%JBREL	;STORE
	MOVEI	T1,RESTART	;SO WE CAN RE-INIT THE OVERLAY FILE
	HRRM	T1,.JBSA##	;AFTER ^C START
IFE TOPS20,<
	PUSHJ	P,%INIT		;DO INIT & LOOKUP
>
IFN TOPS20,<
	MOVEI	T1,[ASCIZ /OVL/]
	HRRM	T1,DEFTBL+5	;SET DEFAULTS
	MOVSI	T1,(1B2)		;OLD FILE
	MOVEM	T1,DEFTBL
	MOVEI	T1,DEFTBL	;[42]
	MOVE	T2,STRPTR	;[42]
	GTJFN%			;[41]
	  JRST	.ERGJF
	HRRZM	T1,JFN		;[42] SAVE THE JFN
	MOVX	T2,<<FLD ^D36,OF%BSZ>!OF%RD> ;[42] 36 BITS, FOR INPUT
	OPENF%			;[41]
	  JRST	.EROPF
	SETZM	STRPTR		;FOR STARTUP PROCEDURE
>
	MOVEI	T1,1		;READ BLOCK 1
	PUSHJ	P,%USETU	;SET ON BLOCK
	PUSHJ	P,%INB		;READ IT IN
	MOVE	T1,[INBFR,,DI.HDR]
	BLT	T1,DI.END	;STORE USEFUL STUFF IN FIRST BLOCK
	HLRE	T1,DI.LPT	;GET NUMBER OF LINKS
	MOVMM	T1,HILINK	;STORE FOR RANGE CHECK
	MOVE	T1,.JBVER##	;GET VERSION NUMBER
	CAME	T1,DI.VER	;SEE IF SAME
	PUSHJ	P,.ERIVN	;WARN USER
	MOVE	T1,DI.LPT	;GET BLOCK # OF NUMBERS
	PUSHJ	P,%USETI
	MOVE	T0,[IOWD 200,IDXBFR]
	PUSHJ	P,%INZ
	SETZ	T0,
	PUSHJ	P,RP1		;READ IN PREAMBLE FOR LINK 0
	MOVE	T1,PS.CST	;CONTROL SECTION FOR LINK 0
	MOVEM	T1,FSTLNK
;*** THIS IS A TEMP CROCK TO MAKE SURE OTS AND OVRLAY
;*** AGREE ABOUT WHO OWNS THE CORE
	MOVE	T0,PS.NFL	;NEXT FREE LOC
	MOVEM	T0,ADDCOR	;STORE FOR FUNCT. CALL
OVINI2:	SETOM	SIZCOR		;-1 MEANS GET WHATS FREE
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.GAD]		;FOR GET CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPN	STATUS		;DID WE WIN?
	JRST	OVINI3		;YES
	PUSHJ	P,WARNIN	;NO
	  JRST	OVINI5
	TYPE	(<STS	OTS reserved space too small>)
OVINI5:	MOVEI	T0,1000		;NO, WILL HAVE TO GO RELOCATABLE
	ADDM	T0,ADDCOR	;LEAVE SOME SPACE
	JRST	OVINI2		;AND TRY AGAIN

OVINI3:	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.RAD]		;FOR RETURN CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
IFN TOPS20,<
	DMOVE	T2,TEMP2	;[42] RESTORE THE ACCS
>
;NOW FOR DDT SYMBOLS FOR ROOT
	SETZM	.JBSYM##	;[32] ASSUME NOT KEEPING SYMBOLS IN CORE
IFN TOPS20,<
	PUSHJ	P,CHKDDT	;[40] STORE S.T. PTR IN DDT IF IT'S THERE
>
	SKIPN	T1,PS.RDX	;GET POINTER
	JRST	POPL		;NOT WANTED, OR AVAILABLE
	PUSHJ	P,%USETI	;SET ON BLOCK
	HLRE	T1,T1		;-LENGTH
	MOVMM	T1,SIZCOR	;WHAT WE NEED
	ADD	T1,.JBREL##	;FROM TOP OF CORE
	ADDI	T1,1		;SYMBOL TABLE POINTS BEYOND TOP
	CAML	T1,ADDCOR	;LESS THAN END OF ROOT?
	JRST	OVINI4		;NO, USE THE ADDRESS
	MOVE	T0,T1		;YES, SAVE ADDR WANTED
	SUB	T1,ADDCOR	;GET THE OVERLAP
	MOVN	T1,T1		;  OF SYMBOLS OVER ROOT
	ADDI	T1,1777		;ROUND UP, TO THE NEAREST
	ANDI	T1,776000	;  1K BOUNDRY.
	ADD	T1,T0		;ADD TO FIRST TRY
OVINI4:	MOVEM	T1,ADDCOR	;SET START OF SYMBOLS ADDR
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.GAD]		;FOR GET CORE FUNCTION
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;LENGTH
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPE	STATUS		;DID WE GET IT?
	JRST	[POP	P,L		;NO
		PJRST	.ERNCS]		;GIVE WARNING
	MOVE	T0,ADDCOR	;GET ADDRESS
	HLL	T0,PS.RDX	;-LENGTH
	MOVE	T1,PS.CST	;ADDRESS OF HEADER
	MOVEM	T0,CS.SYM(T1)	;SET SYMBOL PTR
	MOVEM	T0,.JBSYM##	;AND FOR DDT
IFN TOPS20,<
	PUSHJ	P,CHKDDT	;[40] STORE S.T. PTR IN DDT IF IT'S THERE
>
	SUBI	T0,1		;IOWD IS 1 LESS
	PUSHJ	P,%INZ		;READ IT IN
POPL:	POP	P,L
	POPJ	P,
;ROUTINE TO STUFF C(.JBSYM) INTO DDT IF DDT IS IN MEMORY (TOPS-20 ONLY).
;THIS IS BECAUSE DDT DOESN'T LOOK FOR SYMBOL TABLES IN JOBDAT, BUT MUST
;BE FORCE-FED. SAVES ALL ACS.

IFN TOPS20,<
CHKDDT:	PUSH	P,T1		;[40] SAVE SOME TEMPS
	PUSH	P,T2		;[40]   ..
	MOVX	T1,<.FHSLF,,770>;[40] SEE IF PAGE 770 EXISTS
	RPACS%			;[41]   ..
	TXNN	T2,PA%EX	;[40]   ..
	JRST	CHKEND		;[40] NO--CAN'T BE STANDARD DDT
	MOVE	T1,770000	;[40] SEE IF IT'S DDT THAT'S THERE
	CAME	T1,[JRST 770002];[40] CROCK, BUT THIS IS WHAT EXEC DOES
	JRST	CHKEND		;[40] NOT DDT
	MOVE	T1,.JBSYM##	;[40] IT'S DDT--STORE S.T. POINTER
	MOVEM	T1,@770001	;[40]   IN STANDARD PLACE
CHKEND:	POP	P,T2		;[40] RESTORE TEMPS
	POP	P,T1		;[40]   ..
	POPJ	P,		;[40] DONE
>
SUBTTL	INIT & LOOKUP


IFE TOPS20,<
	SEGMENT	LOW
%INIT:	OPEN	.-.,IBLOCK
	  JRST	.ERDOE
%LUKUP:	PUSH	P,LPPN		;[36] SAVE PPN OVER LOOKUP
	LOOKUP	.-.,LBLOCK
	  JRST	[POP	P,LPPN	;[36] RESTORE PPN
		JRST	.ERFLE]	;[36] REPORT LOOKUP ERROR
	POP	P,LPPN		;[36] RESTORE PPN
	POPJ	P,

IBLOCK:	EXP	16		;MODE
IDEV:	0
	0			;NO BUFFERS

LBLOCK:	EXP	4		;NO. OF EXTENDED ARGS
LPPN:	0
LNAME:	0
LEXT:	0
	0

IFN FTSFD,<
LPATH:	EXP	0,0,0		;TWO IGNORED & PPN
	BLOCK	FTSFD
	EXP	0
>

%USETU:	HRRZM	T1,UBLOCK	;STORE INCORE BLOCK TO BE
%USETI:	USETI	.-.,(T1)	;SET ON BLOCK FOR INPUT
	POPJ	P,

%INB:	MOVE	T0,[IOWD 200,INBFR]
%INZ:	SETZ	T1,
%IN:	IN	.-.,T0		;INPUT
	  POPJ	P,		;OK
	JRST	.ERIST		;INPUT ERROR
SUBTTL	WRITEABLE OVERLAYS


IFN FTWRITE,<
%USETO:	USETO	.-.,(T1)	;SET ON BLOCK FOR OUTPUT
	POPJ	P,

%OUTPT:	OUT	.-.,T1		;OUTPUT
	  POPJ	P,
	JRST	.EROST
>

	SEGMENT	HIGH

>;END IFE TOPS20
SUBTTL	JSYS CODE


IFN TOPS20,<
%USETU:	HRRZM	T1,UBLOCK	;STORE INCORE BLOCK TO BE
%USETI:	DMOVEM	T1,TEMP2	;[42] SAVE JSYS ACS
	MOVEI	T2,-1(T1)	;[42] GET BLOCK -1
	LSH	T2,7		;[42] WORDS
	MOVE	T1,JFN		;[42] 
	SFPTR%			;[41] SET INPUT PTR
	  JRST	.ERSFP
	DMOVE	T1,TEMP2	;[42] RESTORE JSYS ACS
	POPJ	P,

%INB:	MOVE	T0,[IOWD 200,INBFR]
%INZ:	DMOVEM	T2,TEMP2	;[42] SAVE JSYS ACS
	MOVE	T1,JFN		;[42]
	AOS	T2,T0		;[42] ADDRESS
	HRLI	T2,(POINT 36,)	;[42] BYTE PTR
	HLRO	T3,T0		;[42] - WORD COUNT
	SIN%			;[41]
	  ERJMP	.ERIST
	DMOVE	T2,TEMP2	;[42] RESTORE JSYS ACS
	POPJ	P,

	SEGMENT	LOW
DEFTBL:	GJ%OLD			;[42] FILE MUST EXIST
	.NULIO,,.NULIO		;[42] DON'T READ FROM ANYWHERE
	POINT 7,[ASCIZ /DSK/]
	0
	0
	POINT 7,[ASCIZ /OVL/]
	0
	0
	0

STRPTR:	0			;POINTER TO OVERLAY FILE

	SEGMENT	HIGH
>
SUBTTL	MANUAL CALL SUBROUTINES


IFN FTMANUAL,<

	ENTRY	INIOV.
;CALLED BY
;	MOVEI	16,1+[-1,,0
;		[ASCIZ /DEV:FILE.EXT[PRJ,PRG,SFD,LIST]/]]
;	PUSHJ	17,INIOVL

	'INIOVL'
INIOV.:	HRRZ	T1,(P)		;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC	;[44]   ..
IFE TOPS20,<
	SKIPN	-1(L)		;[31] ANY ARGUMENTS?
	PJRST	OVINI		;[31] NO, JUST NORMAL INITIALIZATION
	MOVSI	T1,'DSK'	;SET THE DEFAULTS
	MOVEM	T1,IDEV
	SETZM	LNAME		;WILL CAUSE ERROR IF NOT RESET
	SETZM	LPPN		;USERS PATH
	MOVSI	T1,'OVL'
	MOVEM	T1,LEXT
	PUSHJ	P,GETSPC	;GET THE FILE SPEC
>
IFN TOPS20,<
	SKIPN	-1(L)		;[31] ANY ARGUMENTS?
	PJRST	OVINI		;[31] NO, JUST INITIALIZE
	HRROI	T1,@(L)		;[42] GET POINTER TO ARG STRING
	MOVEM	T1,STRPTR	;SETUP PTR
>
	PUSHJ	P,OVINI		;OPEN OVERLAY FILE
	POPJ	P,		;RETURN
	ENTRY	GETOV.
;CALLED BY
;	MOVEI	16,1+[-N,,0
;		[LINK NAME]
;		...
;		[LINK NAME]]
;	PUSHJ	P,GETOVL

	'GETOVL'
GETOV.:	HRRZ	T1,(P)		;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC	;[44]   ..
	SKIPN	-1(L)		;[44] CHECK FOR NO ARGS
	POPJ	P,		;JUST IGNORE
	PUSH	P,L		;SAVE L
	HLL	L,-1(L)		;FORM AOBJN WORD
	PUSHJ	P,GETCUR	;SEE WHO CALLED
GTOVL1:	PUSHJ	P,GETNUM	;CONVERT ARG IT TO A LINK NUMBER
	JFCL	GETOV.-1	;INCASE OF ILL ARG TYPE
	PUSHJ	P,INCORE	;SEE IF ALREADY INCORE
	  JRST	GTOVL3		;NO
GTOVL2:	AOBJN	L,GTOVL1	;LOOP FOR ALL ARGS
	PJRST	POPL		;RESTORE AND RETURN

GTOVL3:	PUSHJ	P,RP0		;READ PREAMBLE
	PUSHJ	P,CP0		;CHECK PATH
	JRST	GTOVL2		;TRY NEXT
SUBTTL	MANUAL CALL SUBROUTINES -- REMOV.


;REMOV. DELETES THE REQUESTED LINK AND ALL OF ITS INFERIORS, THEN ATTEMPTS
;TO SHRINK MEMORY.
;
;CALL:
;	MOVEI	16,1+[1,,0
;		      Z TYPE,[LINK]
;	PUSHJ	17,REMOV.
;
;DEPENDING ON TYPE (SEE GETNUM) LINK CAN BE A LINK NUMBER OR ASCII NAME.

	ENTRY	REMOV.

	'REMOVL'
REMOV.:	HRRZ	T1,(P)		;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC	;[44]   ..
	PUSH	P,L		;[44] SAVE L
	PUSHJ	P,GETCUR	;[43] GET CURRENT LINK SETUP
	PUSHJ	P,GETNUM	;GET LINK # TO REMOVE
	JFCL	REMOV.-1	;IN CASE OF ILL ARG TYPE
	PUSHJ	P,INCORE	;GET ADDRESS
	  JRST	REMOV1		;[43] NOT IN CORE--NOTHING TO DO
	MOVEI	P1,(T1)		;[43] GO DO THE WORK
	PUSHJ	P,DELPTH	;[43]   ..
	MOVEI	L,1+[-3,,0		;ARG LIST
		A.SPI,[F.CBC]		;TO REDUCE CORE IF POSSIBLE
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS]		;ERROR STATUS
	PUSHJ	P,FUNCT.	;CALL OTS
REMOV1:	PJRST	POPL		;[43] RESTORE AND RETURN
SUBTTL	RUNOV. - GETS LINK INTO CORE AND JUMPS TO ITS START ADDRESS


	ENTRY	RUNOV.
;CALLED BY
;	MOVEI	16,1+[-1,,0
;		[LINK NAME OR NUMBER]]
;	PUSHJ	P,RUNOVL

	'RUNOVL'
RUNOV.:	HRRZ	T1,(P)		;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC	;[44]   ..
	PUSHJ	P,GETCUR	;POINT TO CALLER
	PUSHJ	P,GETNUM	;CONVERT ARG TO A LINK NUMBER
	JFCL	RUNOV.-1	;INCASE OF ILL ARG TYPE
	PUSHJ	P,INCORE	;SEE IF ALREADY INCORE
	  JRST	[PUSH	P,T0		;SAVE LINK# INCASE WAS A NAME
		PUSHJ	P,RP0		;READ PREAMBLE
		SETOM	OKOVLC		;[43] ALLOW OVERLAY OF CALLER
		PUSHJ	P,CP0		;CHECK PATH
		SETZM	OKOVLC		;[43] DISALLOW OVERLAY OF CALLER
		POP	P,T0		;RESTORE LINK #
		JRST	.-1]		;TRY AGAIN
	HRRZ	T0,CS.STA(T1)	;GET START ADDRESS
	JUMPE	T0,RUNOV1	;[45] SEE IF THERE'S A START ADDRESS
	POP	P,(P)		;[45] LOSE USER'S RETURN PC
	JRST	@T0		;[45]   SINCE LINK WILL NEVER RETURN

RUNOV1:	MOVEM	T1,THSLNK	;[45] SO WE CAN ADDRESS LINK
.ERNSA:	PUSHJ	P,FATAL
	TYPE	(<NSA	No start address for>)
	PUSHJ	P,PRNLNK	;PRINT NUMBER
	STOP
IFN FTWRITE,<

	ENTRY	SAVOV.
;CALLED BY
;	MOVEI	16,1+[-N,,0
;		[LINK NAME]
;		...
;		[LINK NAME]]
;	PUSHJ	P,SAVOVL

	'SAVOVL'
SAVOV.:	HRRZ	T1,(P)		;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC	;[44]   ..
	PUSHJ	P,.ERNYA	;[44]

	ENTRY	CLROV.
;CALLED BY
;	MOVEI	16,1+[-N,,0
;		[LINK NAME]
;		...
;		[LINK NAME]]
;	PUSHJ	P,CLROVL

	'CLROVL'
CLROV.:	HRRZ	T1,(P)		;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC	;[44]   ..
	PUSHJ	P,.ERNYA	;[44]

.ERNYA:	PUSHJ	P,WARNIN
	  JRST	RETZB
	TYPE	(<NYA	Subroutine >)
	POP	P,T1		;GET PC+1
	MOVE	T1,-2(T1)	;GET SIXBIT NAME
	PUSHJ	P,PRNSBX
	TYPE	(< not yet available>)
	PJRST	RETZB		;RETURN 0
	ENTRY	TMPOV.
;	CALLED BY
;	MOVEI	16,1+[-1,,0
;		[ASCIZ /DEV:FILE.EXT[PRJ,PRG,SFD,LIST]/]]
;	PUSHJ	17,TMPOVL

	'TMPOVL'
TMPOV.:	HRRZ	T1,(P)		;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC	;[44]   ..
	PUSHJ	P,.ERNYA	;[44]
	PUSH	P,L		;SAVE L
	PUSH	P,IDEV		;SAVE
	PUSHJ	P,GETSPC	;GET FILE SPEC
	POP	P,T1		;RESTORE
	EXCH	T1,IDEV
	MOVEM	T1,WDEV		;NEW DEVICE
	MOVEI	L,1+[-4,,0		;ARG LIST FOR GET CHAN FNCT
		A.SPI,[F.GCH]		;FUNCTION #4
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;RETURN STATUS
		A.SPI,WCHAN]		;RETURN CHAN #
	PUSHJ	P,FUNCT.	;GET IT
	SKIPE	STATUS		;DID WE WIN
	JRST	.ERCNA		;NOT AVAILABLE
	HRLZ	T1,WCHN		;GET CHAN #
	LSH	T1,5		;SHIFT INTO AC FIELD
	IORM	T1,WINIT	;STORE CHAN #

	SEGMENT	LOW
WINIT:	OPEN	.-.,WMODE	;OPEN DEVICE
	  JRST	.ERDOE		;ERROR

WMODE:	EXP	16
WDEV:	0
	0


	SEGMENT	HIGH
>;END OF IFN FTWRITE
>;END OF IFN FTMANUAL
SUBTTL	USEFUL SUBROUTINES


;GETNUM - ROUTINE TO CONVERT ARG INTO LINK #
;ENTER WITH
;L CONTAINS POINTER TO ARGUMENT WHICH IS EITHER
;LINK NUMBER OR LINK NAME

GETNUM:	LDB	T1,[POINT 4,0(L),12]	;GET TYPE
	JRST	@TYPTBL(T1)	;DO CONVERSION

TYPTBL:	A.UND,TY.SP
	A.LOG,TY.SP
	A.SPI,TY.SP
	    3,TY.ILL
	A.SPR,TY.SP		;[44]
	    5,TY.ILL
	A.OCT,TY.SP		;[44]
	A.LBL,TY.ILL
	A.DPR,TY.DP
	A.DPI,TY.DP
	A.DO ,TY.DP		;[44]
	   13,TY.ILL
	A.CMP,TY.DP
	   15,TY.ILL
	   16,TY.ILL
	A.AS ,TY.STR

TY.ILL:	PUSHJ	P,FATAL	;[44]
.ERIAT:	TYPE	(<IAT	Illegal argument type on call to >)
	MOVE	T1,(P)		;[44] GET ROUTINE NAME POINTED TO
	MOVE	T1,@(T1)	;[44]   BY THE JFCL
	PUSHJ	P,PRNSBX	;PRINT IT
	TYPE	(< from >)
	MOVE	T0,USERPC	;[44] GET USER'S PC FOR MESSAGE
	SUBI	T0,1		;[44] MAKE IT PC OF CALL
	PUSHJ	P,PRNOCT
	PUSHJ	P,CRLF		;[44] END THE LINE
	STOP			;[44] DIE
TY.DP0:	MOVE	T0,T1		;PUT LOW ORDER WORD INTO HIGH
	CAIA			;CANNOT SKIPA OVER 0

TY.SP:	MOVE	T0,@(L)		;GET ARG
	TLNN	T0,-1		;18 BITS?
	POPJ	P,		;YES, MUST BE NUMBER
	PUSHJ	P,TY.PTR	;SAVE ACC AND SETUP PTRS
TY.SP1:	ILDB	T1,T2		;GET CHAR
	SKIPE	T1		;LEAVE NULL ALONE
	SUBI	T1," "		;SIXBITIZE
	IDPB	T1,T3		;STORE 
	TLNE	T2,(77B5)	;MORE TO READ?
	JRST	TY.SP1		;YES
	ANDCMI	T0,77		;CLEAR 6TH CHAR

;NOW TO CONVERT NAME TO A LINK NUMBER
TY.NO:	MOVE	T3,T0		;PUT IN SAFE PLACE
	MOVE	T1,DI.NPT	;GET BLOCK
	HLRE	T2,T1		;TOTAL WORD LENGTH
	PUSHJ	P,%USETU	;SET ON BLOCK
TY.NO1:	PUSHJ	P,%INB		;READ A BLOCK
	MOVE	T1,[-100,,INBFR]	;FORM AOBJN WORD
TY.NO2:	CAMN	T3,1(T1)	;MATCH?
	JRST	TY.NO3		;YES
	ADDI	T1,1
	AOBJN	T1,TY.NO2	;LOOP IN THIS BLOCK
	ADDI	T2,200		;SEE IF MORE BLOCKS
	JUMPL	T2,TY.NO1	;YES
.ERULN:	PUSHJ	P,FATAL
	TYPE	(<ULN	Unknown link name >)
	MOVE	T1,T3		;GET NAME
	PUSHJ	P,PRNSBX
	STOP

TY.NO3:	HRRZ	T0,0(T1)	;GET NUMBER
	JRST	T3POPJ		;RESTORE
TY.DP:
IFN FTKI10,<
	DMOVE	T0,@(L)		;GET ARG
>
IFE FTKI10,<
	MOVEI	T1,@(L)		;GET ADDRESS
	DMOVE	T0,(T1)		;GET ARG
>
	JUMPE	T0,TY.DP0	;LOW ORDER ONLY?
	JUMPE	T1,TY.SP	;HIGH ORDER ONLY?
	PUSHJ	P,TY.PTR	;SAVE ACCS AND SETUP PTRS
	PUSH	P,T4		;NEED ANOTHER ACC
TY.DP1:	ILDB	T4,T2		;GET CHAR
	SKIPE	T4		;LEAVE NULL ALONE
	SUBI	T4," "		;SIXBITIZE
	IDPB	T4,T3		;STORE 
	TLNE	T3,(77B5)	;MORE TO STORE?
	JRST	TY.DP1		;YES
	POP	P,T4		;RESTORE LAST ACC
	JRST	TY.NO		;AND CONVERT TO NUMBER

TY.STR:	PUSHJ	P,TY.PTR	;SAVE ACCS AND SETUP PTRS
	HRRI	T2,@(L)		;FILL IN INPUT ADDRESS
	SETZ	T0,		;START WITH 0
TYSTR1:	ILDB	T1,T2		;GET CHAR
	JUMPE	T1,TY.NO	;DONE, NOW CONVERT TO LINK #
	SUBI	T1," "		;SIXBITIZE
	TLNE	T3,(77B5)	;RAN OUT OF SPACE?
	IDPB	T1,T3		;NO
	JRST	TYSTR1		;LOOP

TY.PTR:	EXCH	T2,(P)		;PUT T2 ON STACK
	SPUSH	<T3,T2>		;SAVE TWO ACCS
	MOVSI	T2,(POINT 7,T0)	;READ PTR
	MOVSI	T3,(POINT 6,T0)	;WRITE PTR
	POPJ	P,
;GETSPC - ROUTINE TO CONVERT STRING IN FILE SPEC
IFE TOPS20,<
;ENTER WITH
;L CONTAINING ARG POINTER
;RETURNS
;IDEV	 	DEVICE
;LNAME		FILE NAME
;LEXT		EXTENSION
;LPPN		PPN
;LPATH		FULL PATH

GETSPC:	PUSH	P,L		;SAVE L
	PUSH	P,T2		;NEED AC FOR 2ND BYTE POINTER
	MOVE	L,@L		;ADDRESS OF LIST
	HRLI	L,(POINT 7,)	;FORM INPUT BYTE PTR
	PUSHJ	P,GETSBX	;GET DEVICE
	CAIE	T1,":"		;WAS IT?
	JRST	GETNAM		;NO, TRY FILE NAME
	MOVEM	T0,IDEV
	PUSHJ	P,GETSBX	;GET FILE NAME
GETNAM:	MOVEM	T0,LNAME	;STORE IT
	CAIE	T1,"."		;EXT TO FOLLOW?
	JRST	GETPRJ		;NO, TRY PPN
	PUSHJ	P,GETSBX	;GET EXT
	HLLZM	T0,LEXT		;SAVE IT
GETPRJ:	SETZM	LPPN		;INCASE NONE
	CAIE	T1,"["		;PPN TO FOLLOW?
	PJRST	POP2L		;NO, GIVE UP
	GETPPN	T1,		;GET DEFAULT IN CASE [,XXX]
	  JFCL			;OVRLAY WITH JACCT?
	PUSH	P,T1		;SAVE FOR REFERENCE
	PUSHJ	P,GETOCT	;GET PRJ
	TRNN	T0,-1		;IS IT [,XXX]?
	HLRZ	T0,0(P)		;YES, DEFAULT TO LOGGED-IN PRJ
	HRLZM	T0,LPPN
	PUSHJ	P,GETOCT	;GET PRG
	TRNN	T0,-1		;IS IT [XXX,] ?
	HRRZ	T0,0(P)		;YES, DEFAULT TO LOGGED-IN PRG
	HRRM	T0,LPPN
	POP	P,0(P)		;REMOVE LOGGED IN PPN FROM STACK
IFN FTSFD,<
	CAIN	T1,"]"		;CLOSED CORRECTLY?
	PJRST	POP2L		;YES
	MOVE	T1,LPPN		;PUT PPN
	MOVEM	T1,LPATH+2	;IN DIRECTORY BLOCK
	MOVEI	T1,LPATH
	MOVEM	T1,LPPN		;PATH POINTER
	PUSH	P,T3		;NEED AC
	MOVSI	T3,-FTSFD	;NO. ALLOWED
	PUSHJ	P,GETSBX	;GET NAME
	MOVEM	T0,LPATH+3(T3)	;STORE
	CAIN	T1,","		;MORE?
	AOBJN	T3,.-3		;ENOUGH ROOM?
	POP	P,T3		;END
>;END OF IFN FTSFD
POP2L:	POP	P,T2		;RESTORE T2
	PJRST	POPL
>;END IFE TOPS20
;GETSBX - ROUTINE TO CONVERT ARG INTO SIXBIT
;ENTER WITH
;L CONTAINS BYTE POINTER TO ARGUMENT
;RETURNS
;T0 = SIXBIT WORD
;T1 = BREAK CHARACTER
;USES
;T2 = BYTE POINTER FOR STORE

GETSBX:	MOVSI	T2,(POINT 6,T0)
	SETZ	T0,
GTSBX1:	ILDB	T1,L		;GET NEXT CHAR
	CAIL	T1,"a"		;TEST FOR LOWER CASE
	CAILE	T1,"z"		;...
	CAIA			;NO
	SUBI	T1,"a"-"A"	;MAKE UPPER CASE
	CAIL	T1,"0"		;TEST FOR VALID ALPHANUMERICS
	CAILE	T1,"Z"		;...
	POPJ	P,		;END TEST FAILED
	CAILE	T1,"9"		;SEE IF 0-9
	CAIL	T1,"A"		;OR A-Z
	CAIA			;YES
	POPJ	P,		;NO
	SUBI	T1," "		;SIXBITIZE
	IDPB	T1,T2		;STORE
	JRST	GTSBX1		;LOOP


GETOCT:	SETZ	T0,		;CLEAR STORE AC
GTOCT1:	ILDB	T1,L		;GET NEXT CHAR
	CAIL	T1,"0"		;TEST FOR VALID OCTAL
	CAILE	T1,"7"		;ONLY
	POPJ	P,		;BREAK
	LSH	T0,3		;MAKE SPACE
	ADDI	T0,-"0"(T1)	;STORE NEW OIT
	JRST	GTOCT1		;LOOP
GETCUR:	SPUSH	<T2,T3,T4>	;NEED SOME ACCS
	MOVE	T4,USERPC	;[44] GET USER'S RETURN PC
	SKIPN	T1,FSTLNK	;GET START OF OVERLAY LIST
	PUSHJ	P,OVINI		;NOT YET SETUP
	MOVE	T1,FSTLNK	;IT IS NOW
GTCUR1:	HLRZ	T3,CS.SIZ(T1)	;GET LENGTH OF LINK
	HRRZ	T2,CS.ADR(T1)	;AND LOWER BOUND
	ADD	T3,T2		;UPPER BOUND
	CAML	T4,T2		;SEE IF ENCLOSED
	CAML	T4,T3		;BETWEEN T2<L<T3
	JRST	GTCUR2		;NO
GTCUR4:	MOVEM	T1,CURLNK	;SAVE PTR TO LINK
	MOVE	T2,CS.NUM(T1)	;GET LINK NUMBER
	MOVEM	T2,CURNUM	;SAVE IT
	POP	P,T4		;LEAVE THIS POP OUT OF T3POPJ!!
T3POPJ:	SPOP	<T3,T2>
	POPJ	P,

GTCUR2:	HRRZ	T1,CS.FPT(T1)	;GET NEXT
	JUMPN	T1,GTCUR1	;VALID?
	HRRZ	T3,.JBHRL##	;GET END OF HIGH SEG, IF ANY
	JUMPE	T3,GTCUR3	;NO HIGH SEG, NOT POSSIBLE!
	HRRZ	T3,.JBREL##	;HIGHEST ADDRESS IN LOW SEG
	CAIGE	T3,400000	;LOW SEG OVER 128K?
	MOVEI	T3,377777	;NO, ASSUME HI SEG STARTS AT 128K
IFE TOPS20,<
	MOVE	T2,[-2,,.GTUPM]	;NEED TO FIND HI-SEG ORIGIN
	GETTAB	T2,		;CURRENTLY AVAIL ONLY BY GETTAB
	  SKIPA			;NOT THERE, ASSUME 400000
	SKIPN	T2		;GETTAB IMPLIMENTED?
>
	MOVSI	T2,1(T3)	;NO, ASSUME DEFAULT
	HLRZ	T2,T2		;PUT IN CORRECT PLACE
	ANDCMI	T2,777		;ZAP BITS RESERVED FOR FUTURE
	HRRZ	T3,.JBHRL##	;GET HIGHEST LEGAL ADDR IN HI SEG
	CAML	T4,T2		;IS THIS FROM THE HIGH SEG?
	CAMLE	T4,T3		;MAYBE. IS IT?
GTCUR3:	PUSHJ	P,.ERIMP	;NO, NOT POSSIBLE!
	MOVE	T1,FSTLNK	;YES, PRETEND FROM THE ROOT
	JRST	GTCUR4		;AND GO FILL THINGS IN
;INCORE - ROUTINE TO SEE IF LINK # IS IN CORE
;ENTER WITH
;T0 = LINK #
;RETURNS
;+1	NOT IN CORE
;+2	IN CORE (T1 = ADDRESS)
;USES T1

INCORE:	MOVE	T1,FSTLNK	;GET START
	CAMN	T0,CS.NUM(T1)	;ONE WE WANT?
	JRST	CPOPJ1		;YES
	HRRZ	T1,CS.FPT(T1)	;NO, GET NEXT
	JUMPN	T1,.-3
	POPJ	P,
SUBTTL	ERROR HANDLING


	'.OVRLU'
.OVRLU:	EXP	.+1		;FOR @ IN JRST @(T1)
	PUSHJ	P,WARNIN
	  JRST	RETZB
.ERUSC:	TYPE	(<USC	Undefined subroutine >)
	MOVE	T1,(P)		;GET PC+1 OF CALLER
	MOVEI	T1,@-1(T1)	;ADDRESS OF EXTTAB
	MOVE	T1,ET.NAM(T1)	;GET SIXBIT NAME OF CALLED ROUTINE
	PUSHJ	P,PRNSBX
	TYPE	(< called from PC = >)
	MOVE	T1,(P)		;GET PC+1 BACK
	MOVEI	T0,-1(T1)	;BACKUP
	PUSHJ	P,PRNOCT
RETZB:	SETZB	0,1		;RETURN 0
CRLF:	TYPE	(<
>)
	POPJ	P,		;END LINE AND RETURN TO USER

.ERII:	PUSHJ	P,FATAL
	TYPE	(<ILN	Illegal link number >)
	PUSHJ	P,PRNDEC
	STOP

.ERIVN:	SKIPE	DI.VER		;[37] IGNORE IF VERSION NUMBER WAS 0
	PUSHJ	P,WARNIN
	  POPJ	P,
	TYPE	(<IVN	Inconsistent version numbers>)
	PJRST	CRLF
IFE TOPS20,<
.ERDOE:	PUSHJ	P,FATAL
	TYPE	(<DOE	Device open error for >)
	MOVE	T1,IBLOCK+1	;GET DEVICE
	PUSHJ	P,PRNSBX
	STOP

.ERFLE:	PUSHJ	P,FATAL
	TYPE	(<FLE	File lookup error >)
	HRRZ	T0,LEXT		;GET ERROR CODE
	PUSHJ	P,PRNOCT	;OUTPUT IT
	TYPE	(< for >)
	MOVE	T1,IDEV
ERFLEE:	PUSHJ	P,PRNSBX
	MOVEI	T1,":"
	OUTCHR	T1
	MOVE	T1,LNAME
	PUSHJ	P,PRNSBX
	MOVEI	T1,"."
	OUTCHR	T1
	HLLZ	T1,LEXT
	SKIPE	T1
	PUSHJ	P,PRNSBX
	SKIPE	LPPN
	PUSHJ	P,PRNPPN	;PRINT PPN
	STOP

IFN FTLOG,<
.ERFEE:	PUSHJ	P,FATAL
	TYPE	(<FLE	File enter error >)
	HRRZ	T0,LEXT		;GET ERROR CODE
	PUSHJ	P,PRNOCT	;OUTPUT IT
	TYPE	(< for >)
	MOVE	T1,$DEV
	JRST	ERFLEE
>

.ERCNA:	PUSHJ	P,FATAL
	TYPE	(<CNA	I/O channel not available>)
	STOP
>;END IFE TOPS20
.ERARC:	PUSHJ	P,FATAL
	TYPE	(<ARC	Attempt to remove caller from>)
	PUSHJ	P,PRNLNK
	STOP

.ERIST:	PUSHJ	P,FATAL
	TYPE	(<IEO	Input error for overlay file>)
IFE TOPS20,<
	PUSHJ	P,%STS
>
IFN TOPS20,<
	PUSHJ	P,JSYSER
>
	STOP

IFN FTWRITE,<
.EROST:	PUSHJ	P,FATAL
	TYPE	(<OEO	output error for overlay file>)
	PUSHJ	P,PSTS
	STOP
>

.ERIMP:	PUSHJ	P,FATAL
	TYPE	(<IMP	Impossible error condition at PC = >)
	MOVE	T1,(P)		;GET PC
	MOVEI	T0,-1(T1)	;BACKUP
	PUSHJ	P,PRNOCT
	STOP

IFN FTRELOC,<
ERNRTS:	MOVEM	P1,THSLNK	;ENTRY FROM SYMBOLS
.ERNRT:	PUSHJ	P,FATAL
	TYPE	(<NRT	No relocation tables for>)
	PUSHJ	P,PRNLNK
	STOP
>
IFN TOPS20,<
.EROPP:	PUSHJ	P,FATAL
	TYPE	(<OPP	Overlay handler in private page>)
	STOP


.ERSFP:	PUSHJ	P,FATAL
	TYPE	(<SFP	SFPTR% JSYS failed>)
	PUSHJ	P,JSYSER
	STOP

.ERRPA:	PUSHJ	P,FATAL
	TYPE	(<RPA	RPACS% JSYS failed>)
	PUSHJ	P,JSYSER
	STOP

.ERRMP:	PUSHJ	P,FATAL
	TYPE	(<RMP	RMAP% JSYS failed>)
	PUSHJ	P,JSYSER
	STOP

.ERGJF:	PUSHJ	P,FATAL
	TYPE	(<GJF	GTJFN% JSYS failed>)
	PUSHJ	P,JSYSER
	STOP

.EROPF:	PUSHJ	P,FATAL
	TYPE	(<OPF	OPENF% JSYS failed>)
	PUSHJ	P,JSYSER
	STOP

>
IFE TOPS20,<
	SEGMENT	LOW
%STS:	GETSTS	.-.,T1		;GET ERROR STATUS
IFN FT2SEG,<
	JRST	PSTS
>
	SEGMENT	HIGH
PSTS:	TYPE	(<, status (>)
	HRLO	T1,T1		;PUT -1 MARKER IN RHS
	PUSHJ	P,PRNO18	;PRINT 18 BITS OF OCTAL
	MOVEI	T0,")"
	PJRST	PRNT0
>

PRNO18:	SETZ	T0,
	LSHC	T0,3		;GET NEXT DIGIT
	TRNN	T1,-1		;LAST DIGIT?
	PJRST	PRNT00		;YES, PRINT AND RETURN
	PUSHJ	P,PRNT00
	JRST	PRNO18		;LOOP

PRNLNK:	OUTLOG	(< link >)
	MOVE	T1,THSLNK	;GET CONTROL SECTION ADDRESS
	SKIPE	CS.LNM(T1)	;DOES IT HAVE A NAME?
	JRST	PRNLNM		;YES
	OUTLOG	(<number >)
	MOVE	T1,THSLNK	;GET CONTROL SECTION ADDRESS AGAIN
	MOVE	T0,CS.NUM(T1)	;LINK#
PRNDEC:	IDIVI	T0,^D10
	HRLM	T1,(P)		;STORE ON STACK
	SKIPE	T0		;DONE?
	PUSHJ	P,PRNDEC	;NOT YET
PRNTO0:	HLRZ	T0,(P)		;RECOVER
PRNT00:	ADDI	T0,"0"
PRNT0:
IFN FTLOG,<
	SKIPE	INLOG		;REAL LOG FILE
	PJRST	LOGCHR		;YES
>
IFE TOPS20,<
	OUTCHR	T0
>
IFN TOPS20,<
	PUSH	P,T1
	MOVE	T1,T0		;[42]
	PBOUT%			;[41]
	POP	P,T1
>
	POPJ	P,
PRNLNM:	OUTLOG	(<name >)
	MOVE	T1,THSLNK	;GET CONTROL SECTION ADDRESS AGAIN
	MOVE	T1,CS.LNM(T1)	;GET IT
PRNSBX:	SETZ	T0,
	LSHC	T0,6		;SHIFT CHAR UP
	ADDI	T0," "
	PUSHJ	P,PRNT0		;AND OUTPUT IT
	JUMPN	T1,PRNSBX	;IF MORE TO DO
	POPJ	P,

PRNOCT:	IDIVI	T0,8
	HRLM	T1,(P)		;STORE ON STACK
	SKIPE	T0		;DONE?
	PUSHJ	P,PRNOCT	;NOT YET
	PJRST	PRNTO0

PRNFRS:	TYPE	(<, FUNCT. return status >)
	MOVE	T0,STATUS
	PJRST	PRNT00

IFN TOPS20,<
JSYSER:	HRROI	T1,[ASCIZ	/
	/]			;[42]
	PSOUT%			;[41]
	HRROI	T1,INBFR	;[42] WHERE TO STORE STRING
	HRLOI	T2,.FHSLF	;[42] THIS FORK, LAST ERROR
	SETZ	T3,		;[42] ANY LENGTH
	ERSTR%			;[41]
	  POPJ	P,		;TOO BAD
	  POPJ	P,		;...
	HRROI	T1,INBFR	;[42]
	PSOUT%			;[41] GIVE IT TO THE USER
	POPJ	P,
>
IFE TOPS20,<
PRNPPN:	MOVEI	T1,"["
	OUTCHR	T1
IFN FTSFD,<
	MOVE	T0,LPPN		;GET PPN TO PRINT
	TLNN	T0,-1		;PPN OR POINTER TO PATH?
	JRST	PRNPTH		;POINTER TO PATH
> ;END IFN FTSFD
	HLRZ	T0,LPPN
	PUSHJ	P,PRNOCT
	MOVEI	T0,","
	OUTCHR	T0
	HRRZ	T0,LPPN
	PUSHJ	P,PRNOCT
	MOVEI	T0,"]"
	PJRST	PRNT0

;HERE TO PRINT A POINTER TO A PATH BLOCK
IFN FTSFD,<
PRNPTH:	HLRZ	T0,LPATH+2	;PROJECT
	PUSHJ	P,PRNOCT	;PRINT IT
	MOVEI	T0,","		;COMMA TO SEPERATE
	OUTCHR	T0		;PRINT IT
	HRRZ	T0,LPATH+2	;PROGRAMMER
	PUSHJ	P,PRNOCT	;PRINT IT
	PUSH	P,T3		;NEED AN AOBJN AC
	MOVSI	T3,-FTSFD	;SETUP TO LOOP OVER SFD'S
PRNPT1:	SKIPN	T1,LPATH+3(T3)	;GET NEXT SFD, IF ANY
	  JRST	PRNPT2		;DONE
	MOVEI	T0,","		;LEADING COMMA
	OUTCHR	T0		;TYPE IT
	PUSHJ	P,PRNSBX	;TYPE SFD NAME IN SIXBIT
	AOBJN	T3,PRNPT1	;LOOP OVER ENTIRE PATH
PRNPT2:	POP	P,T3		;RESTORE T3
	MOVEI	T0,"]"		;CLOSING BRACKET
	PJRST	PRNT0		;TYPE IT
> ;END IFN FTSFD
> ;END IFE TOPS20

FATAL:	TYPE	(<
?OVL>)
	POPJ	P,

WARNIN:	SKIPGE	.OVRWARN
	JRST	CPOPJ		;NOT WANTED
	TYPE	(<
%OVL>)
CPOPJ1:	AOS	(P)
CPOPJ:	POPJ	P,

INFO:	TYPE	(<
[OVL>)
	POPJ	P,
SUBTTL	LOG FILE 


IFN FTLOG,<
	ENTRY	LOGOV.
;	CALLED BY
;	MOVEI	16,1+[-1,,0
;		[ASCIZ /DEV:FILE.EXT[PRJ,PRG,SFD,LIST]/]]
;	PUSHJ	17,LOGOVL

	'LOGOVL'
LOGOV.:	PUSH	P,L		;SAVE L
	SKIPN	-1(L)		;CHECK FOR NO ARGS
	JRST	CLSLOG		;MEANS CLOSE LOG FILE
IFE TOPS20,<
	MOVSI	T1,'LOG'	;SET DEFAULT EXT
	MOVEM	T1,LEXT
	PUSH	P,IDEV		;SAVE DEVICE
	PUSHJ	P,GETSPC	;GET FILE SPEC
	POP	P,T1		;GET BACK IDEV
	EXCH	T1,IDEV		;SWAP WITH NEW
	MOVEM	T1,$DEV		;AND STORE
	CAMN	T1,[SIXBIT /TTY/]
	JRST	LOGTTY		;TTY IS SPECIAL
	PUSH	P,IOCHN		;SO WE CAN USE COMMON ARG LIST
	MOVEI	L,1+[-4,,0		;ARG LIST FOR GET CHAN FNCT
		A.SPI,[F.GCH]		;FUNCTION #4
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;RETURN STATUS
		A.SPI,IOCHN]		;RETURN CHAN #
	PUSHJ	P,FUNCT.	;GET IT
	HLRZ	T1,IOCHN	;GET CHAN#
	HLRZM	T1,LCHAN	;SAVE IT
	POP	P,IOCHN		;RESTORE PRIMARY I/O CHAN
	SKIPE	STATUS		;DID WE WIN
	JRST	.ERCNA		;NO
	LSH	T1,5		;INTO AC FIELD
	IORM	T1,$INIT	;SET INST
	IORM	T1,$ENTER
	IORM	T1,$CLOSE
	IORM	T1,$OUT
	IORM	T1,$STS
	IORM	T1,$OBUF
	SEGMENT	LOW
$INIT:	OPEN	.-.,OBLOCK	;OPEN DEVICE
	SEGMENT	HIGH
IFN FT2SEG,<
	XCT	$INIT		;IN LOW SEG
>
	  JRST	.ERDOE		;FAILED
	MOVEI	T1,OBLOCK	;BLOCK AGAIN
	DEVSIZ	T1,		;GET BUFFER SIZE
	  PUSHJ	P,.ERIMP	;SHOULD NOT HAPPEN
	HLRZ	T2,T1		;NO. OF BUFFERS
	HRRZ	T1,T1		;SIZE OF EACH BUFFER
	IMULI	T1,(T2)		;TOTAL SIZE WE NEED
	MOVEM	T1,SIZCOR	;SAFE PLACE
	MOVEI	L,1+[-5,,0		;ARG LIST
		A.SPI,[F.GOT]		;GET CORE FROM OTS
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;ERROR STATUS
		A.SPI,ADDCOR		;RETURNED ADDRESS
		A.SPI,SIZCOR]		;WHAT WE NEED
	PUSHJ	P,FUNCT.	;CALL OTS
	SKIPE	STATUS		;DID WE WIN
	JRST	.ERCGC		;NO
	MOVE	T1,ADDCOR
	HRL	T1,SIZCOR	;SAVE ARGS
	MOVEM	T1,.OVRLOG	;SO WE CAN RESTORE
	PUSH	P,.JBFF##	;NOW TO ALLOCATE BUFFERS
	HRRZM	T1,.JBFF
IFN FT2SEG,<
	JRST	$OBUF		;IN LOW SEG
>
	SEGMENT	LOW
$OBUF:	OUTBUF	.-.,0		;DEFAULT NO.
	POP	P,.JBFF		;RESTORE
$ENTER:	ENTER	.-.,LBLOCK	;ENTER FILE NAME
	  JRST	.ERFEE		;ERROR
	PJRST	POPL
	SEGMENT	HIGH
>;END IFE TOPS20
IFN TOPS20,<
	DMOVEM	T2,TEMP2	;[42] SAVE JSYS ACS
	HRROI	T1,[ASCIZ /LOG/];[42]
	MOVEM	T1,DEFTBL+5	;[42] SET DEFAULT
	MOVX	T1,OF%WR	;[42] OUTPUT USE
	MOVEM	T1,DEFTBL
	HRROI	T2,@(L)		;[42] GET ADDRESS
	MOVE	T1,(T2)		;[42] GET FIRST WORD
	ANDCMI	T1,377		;CLEAR JUNK
	CAMN	T1,[ASCII /TTY:/]
	JRST	LOGTTY		;TTY IS SPECIAL
	MOVEI	T1,DEFTBL	;[42] 
	GTJFN%			;[41]
	  JRST	.ERGJF
	HRRZM	T1,LOGJFN	;[42] SAVE JFN
	MOVX	T2,<<FLD 7,OF%BSZ>!OF%WR> ;[42] 7-BIT BYTES FOR WRITE
	OPENF%			;[41]
	  JRST	.EROPF
	DMOVE	T2,TEMP2	;[42] 
	PJRST	POPL		;RESTORE L AND RETURN
>;END IFN TOPS20

LOGTTY:	SETOM	.OVRLOG		;INDICATE WE WANT LOG FILE ON TTY
	PJRST	POPL		;RESTORE L AND RETURN
CLSLOG:	MOVE	T1,.OVRLOG	;SEE IF
	AOJE	T1,ENDLOG	; ONLY TTY
IFE TOPS20,<
	SEGMENT	LOW
$CLOSE:	RELEASE	.-.,		;GIVE UP CHAN
	SEGMENT	HIGH
IFN FT2SEG,<
	XCT	$CLOSE		;IN LOW SEG
>
	MOVEI	L,1+[-4,,0
		A.SPI,[F.RCH]		;FUNCTION TO RETURN CHAN
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;STATUS
		A.SPI,LCHAN]		;CHAN #
	PUSHJ	P,FUNCT.	;CALL OTS
	MOVE	T1,.OVRLOG	;GET CORE ARGS
	HRRZM	T1,ADDCOR	;ADDRESS
	HLRZM	T1,SIZCOR	;SIZE
	MOVEI	T1,1+[-5,,0
		A.SPI,[ROT]		;FUNCTION TO RETURN CORE TO OS
		A.AS,[ASCIZ /OVL/]	;CODE
		A.SPI,STATUS		;STATUS
		A.SPI,ADDCOR		;ADDRESS
		A.SPI,SIZCOR]		;SIZE
	PUSHJ	P,FUNCT.	;CALL OTS
>;END IFE TOPS20
IFN TOPS20,<
	MOVE	T1,LOGJFN	;[42]
	CLOSF%			;[41]
	  JFCL
>
ENDLOG:	SETZM	.OVRLOG		;NO MORE LOG FILE
	PJRST	POPL		;RESTORE F AND RETURN

	SEGMENT	LOW
IFE TOPS20,<
OBLOCK:	EXP	1		;MODE
$DEV:	0			;DEVICE
	OBUF,,0			;OUTPUT ONLY

OBUF:	BLOCK	3
>
IFN TOPS20,<
LOGJFN:	0			;HOLD JFN OF LOG FILE
>
	SEGMENT	HIGH
LNKIN:	PUSHJ	P,LINFO
	OUTLOG	(<RLN	Reading in>)
LNKNO:	PUSHJ	P,PRNLNK	;PRINT NAME OR NUMBER
	OUTLOG	(< after >)
	PUSHJ	P,TIME		;RUNTIME
PRNSQB:	OUTLOG	(<]
>)
	SETZM	INLOG		;NO MORE
	POPJ	P,

LNKOUT:	PUSHJ	P,LINFO
	OUTLOG	(<DLN	Deleting>)
	JRST	LNKNO

LNKRLL:	PUSHJ	P,LINFO
	OUTLOG	(<RLL	Relocating>)
	PUSHJ	P,PRNLNK
	OUTLOG	(< at >)
	MOVE	T1,THSLNK
	HRLO	T1,CS.ADR(T1)	;FIND WHERE
	PUSHJ	P,PRNO18
	PJRST	PRNSQB		;AND RETURN

LINFO:	SKIPG	.OVRLOG		;REAL LOG FILE?
	JRST	INFO		;NO
	SETOM	INLOG		;YES, FLAG IT
	OUTLOG	(<[OVL>)
	POPJ	P,
LOGTST:	SKIPGE	INLOG		;REAL LOG FILE?
	JRST	LOGIT		;YES
IFE TOPS20,<
	HRRZ	T1,@(P)		;GET ADDRESS OF MESSAGE
	OUTSTR	(T1)		;OUTPUT IT
>
IFN TOPS20,<
	HRRO	T1,@(P)		;[42] GET ADDRESS OF MESSAGE
	PSOUT%			;[41] OUTPUT IT
>
	JRST	CPOPJ1		;SKIP RETURN

IFE TOPS20,<
LOGIT:	MOVE	T1,@0(P)	;ADDRESS OF MESSAGE
	HRLI	T1,(POINT 7,)	;BYTE PTR
LOGIT1:	ILDB	T0,T1		;GET BYTE
	JUMPE	T0,CPOPJ1	;DONE
	SOSG	OBUF+2		;ROOM?
	PUSHJ	P,$OUT		;NO
	IDPB	T0,OBUF+1	;STORE CHAR
	JRST	LOGIT1		;LOOP

LOGCHR:	SOSG	OBUF+2		;ROOM?
	PUSHJ	P,$OUT		;NO
	IDPB	T0,OBUF+1	;STORE CHAR
	POPJ	P,

	SEGMENT	LOW
$OUT:	OUT	.-.,
	  POPJ	P,		;OK
.EROEL:	PUSHJ	P,FATAL
	TYPE	(<OEL	output error for overlay log file>)
$STS:	GETSTS	.-.,T1
	PUSHJ	P,PSTS
	PJRST	CRLF
	SEGMENT	HIGH
>;END IFE TOPS20
IFN TOPS20,<
LOGIT:	DMOVEM	T2,TEMP2	;[42] SAVE JSYS ACS
	MOVE	T1,LOGJFN	;[42]
	HRRO	T2,@0(P)	;[42] ADDRESS OF MESSAGE
	SETZ	T3,		;[42] TERMINATE ON ZERO BYTE
	SOUT%			;[41]
	  ERJMP	.EROEL
	DMOVE	T2,TEMP2	;[42] RESTORE JSYS ACS
	POPJ	P,

LOGCHR:	DMOVEM	T2,TEMP2	;[42] SAVE JSYS ACS
	MOVE	T1,LOGJFN	;[42]
	MOVE	T2,T0		;[42] GET CHAR
	BOUT%			;[41]
	  ERJMP	.EROEL
	DMOVE	T2,TEMP2	;[42] RESTORE JSYS ACS
	POPJ	P,

.EROEL:	PUSHJ	P,FATAL
	TYPE	(<OEL	output error for overlay log file>)
	PUSHJ	P,JSYSER
	PJRST	CRLF
>
TIME:	SPUSH	<T2,T3>
IFE TOPS20,<
	SETZ	T0,		;THIS JOB
	RUNTIM	T0,		;RUNNING TIME IN MILLISECS
>
IFN TOPS20,<
	MOVX	T1,.FHJOB	;[42] WHOLE JOB
	RUNTM%			;[41]
	MOVE	T0,T1		;[42]
	IMULI	T0,^D1000	;* MILISECS
	IDIVI	T0,(T2)		;[42] AFTER SECONDS DIVIDER IS APPLIED
>
	SUB	T0,ITIME
	IDIV	T0,[^D3600000]	;GET HOURS
	MOVE	T3,T1		;SAVE REST
	MOVEI	T2," "		;FILL WITH SPACE
	JUMPE	T0,.+3		;NO HOURS
	PUSHJ	P,PRNDC2	;TYPE TWO DIGITS
	PUSHJ	P,PRNCLN	;TYPE COLON
	MOVE	T0,T3		;RESTORE REST
	IDIVI	T0,^D60000	;GET MINS
	MOVE	T3,T1		;SAVE REST
	JUMPE	T0,.+3		;NO MINS
	PUSHJ	P,PRNDC2	;TYPE TWO DIGITS
	PUSHJ	P,PRNCLN	;TYPE COLON
	MOVE	T0,T3		;RESTORE THE REST
	IDIVI	T0,^D1000	;GET SECONDS
	MOVE	T3,T1		;SAVE REM
	PUSHJ	P,PRNDC2	;PRINT TWO DIGITS
	MOVEI	T0,"."
	PUSHJ	P,PRNCL0	;SET NEW FILLER
	MOVE	T0,T3		;GET MILLISECS
	IDIVI	T0,^D10
	PUSHJ	P,PRNDC2	;TWO DIGITS IS ENOUGH
	PJRST	T3POPJ

PRNDC2:	CAILE	T0,^D9		;SEE IF ONE DIGIT
	PJRST	PRNDEC		;NO--JUST OUTPUT
	SKIPE	INLOG		;REAL LOG FILE?
	JRST	[EXCH	T0,T2		;YES
		PUSHJ	P,LOGCHR	;OUTPUT FILLER
		EXCH	T0,T2
		PJRST	PRNT00]		;OUTPUT DIGIT
	TYPEC	T2		;OUTPUT FILLER
	PJRST	PRNT00		;AND DIGIT

PRNCLN:	MOVEI	T0,":"
PRNCL0:	MOVEI	T2,"0"		;NEW FILLER
	PJRST	PRNT0
>;END OF IFN FTLOG
SUBTTL	RESTART PROCEDURE


RESTART:
	MOVE	T1,FSTLNK	;GET CONTROL SECTION OF LINK 0
	SETZM	CS.PTR(T1)	;CLEAR FORWARD PTR
	MOVE	T1,CS.EXT(T1)	;POINTER TO EXTTABS
	MOVSI	T0,F.LIC	;MUST REMOVE FLAG
	ANDCAM	T0,ET.FLG(T1)	;SO DO IT
	ADDI	T1,ET.LEN-1
	AOBJN	T1,.-2		;FOR ALL
	MOVE	T1,[I.ZZ,,I.ZZ+1]
	SETZM	I.ZZ
	BLT	T1,I.END	;ZERO ALL DATA
	MOVE	T1,[JRST SETINI]	;REPLACE INITIALIZING INST
	MOVEM	T1,.OVRLA	;SO WE RE-INIT FILE
	DMOVE	T0,%JBREL	;ORIGINAL .JBREL & .JBSA
	MOVEM	T0,.JBREL##	;[42] RESET .JBREL FOR TOPS20
	MOVEM	T1,.JBSA##	;BACK AS IT WAS
IFN TOPS20,<
	MOVX	T1,.FHSLF	;[42] ONLY DO CORE UUO IF PAT IS AROUND
	GCVEC%			;[41] SO WON'T DRAG IT IN IF NOT
	MOVE	T1,.JBSA##	;RESTORE AC 1 FOR DISPATCH
	SKIPE	T2		;[42] GCVEC% RETURNS T2=0 IF PAT NOT AROUND
>;END IFN TOPS20
	CORE	T0,		;RESET OTHERWISE FREE CORE NOT AVAILABLE
	  JFCL
	JRST	(T1)		;GO TO START

	SEGMENT	LOW
%JBREL:	Z			;HOLD .JBREL
%JBSA:	Z			;HOLD .JBSA
	SEGMENT	HIGH
SUBTTL	ERROR MESSAGES (TEXT)


COMMENT	\
ACF	Absolute core request failed for link number [number]
ARC	Attempt to remove caller from link number [number]
ARL	Ambigous request in link number [number] for [symbol], using link number [number]
CDL	Cannot delete link number [number], FUNCT. return status [number] 
CGC	Cannot get core from OTS, FUNCT. return status [number] 
CNA	I/O channel not available
CSC	Cannot shrink core
DLN	Deleting link number [number] after [time]
DOE	Device open error for [file spec.]
FEE	File enter error [code] for [file spec]
FLE	File lookup error [code] for [file spec]
GJF	GTJFN% JSYS failed
IAT	Illegal argument type on call to [subroutine]
IEO	Input error for overlay file, status ([number])
ILN	Illegal link number [number]
IMP	Impossible error condition at PC = [number]
IVN	Inconsistent version numbers
NRT	No relocation tables for link number [number]
NSA	No start address for link number [number]
NYA	Subroutine [subroutine] not yet available
OEL	output error for overlay log file, status ([number])
OEO	output error for overlay file, status ([number])
OPF	OPENF% JSYS failed
OPP	Overlay handler in private page
RLL	Relocating link number [number] at [address]
RLN	Reading in link number [number] after [time]
RMP	RMAP% JSYS failed
RPA	RPACS% JSYS failed
SFP	SFPTR% JSYS failed
STS	OTS reserved space too small
ULN	Unknown link name [name]
USC	Undefined subroutine [subroutine] called from [number]
\
SUBTTL	DATA FROM OVERLAY FILE


	SEGMENT	LOW
I.ZZ:!				;FIRST WORD TO ZERO
;FIRST BLOCK OF OVL FILE (DIRECTORY)
DI.HDR:	BLOCK	1		;CODE ,, LENGTH
DI.RGN:	BLOCK	1		;NO OF REGIONS
DI.VER:	BLOCK	1		;VERSION #
DI.LPT:	BLOCK	1		;LINK NUMBER POINTER (USETI)
DI.NPT:	BLOCK	1		;LINK LOGICAL NAME POINTER
DI.EPT:	BLOCK	1		;ENTRY POINTER
DI.END==.-1

;PREAMBLE OF EACH LINK SECTION
PS.ZZ:!
PS.HDR:	BLOCK	1		;0,,LENGTH
PS.RGN:	BLOCK	1		;REGION NUMBER
PS.NUM:	BLOCK	1		;LINK NUMBER
PS.NAM:	BLOCK	1		;LOGICAL NAME
PS.BPT:	BLOCK	1		;BACK POINTER
PS.FPT:	BLOCK	1		;FORWARD POINTER
PS.EPT:	BLOCK	1		;EQUIVALENCE POINTER
PS.CST:	BLOCK	1		;ADDRESS OF CONTROL SECTION
PS.FLG:	BLOCK	1		;FLAGS
PS.ADD:	BLOCK	1		;ADDRESS LOADED AT
PS.LEN:	BLOCK	1		;LENGTH OF LINK
PS.OVL:	BLOCK	1		;BLOCK # FOR CODE
PS.SYM:	BLOCK	1		;BLOCK # FOR SYMBOLS (FUTURE)
PS.REL:	BLOCK	1		;BLOCK # FOR RELOC FIXUP
PS.ORL:	BLOCK	1		;BLOCK # FOR OTHER RELOC TABLES
PS.GLB:	BLOCK	1		;NOT USED
PS.RDX:	BLOCK	1		;BLOCK # FOR DDT SYMBOL TABLE
PS.RDR:	BLOCK	1		;BLOCK # FOR RELOC FOR DDT SYMBOLS
PS.NFL:	BLOCK	1		;NEXT FREE LOCATION
PS.END==.-1
SUBTTL	IMPURE DATA


INCIDX:	BLOCK	1		;LOWEST INDEX IN CORE
STATUS:	BLOCK	1		;STATUS ON RETURN FROM OTS
IOCHN:	BLOCK	1		;CHAN # FOR I/O
ADDCOR:	BLOCK	1		;ADDRESS OF CORE FOR OTS CALL
SIZCOR:	BLOCK	1		;LENGTH OF CALL FOR OTS CALL
IOPTR:	BLOCK	1		;I/O POINTER FOR DUMP MODE
UBLOCK:	BLOCK	1		;NEXT BLOCK FOR I/O
IFN FTREGION,<
CURRGN:	BLOCK	1		;REGION # OF CALLER
THSRGN:	BLOCK	1		;REGION # OF TEMP LINK
>
FSTLNK:	BLOCK	1		;POINTER TO CONTROL BLOCK OF FIRST LINK
CURLNK:	BLOCK	1		;POINTER TO CONTROL BLOCK OF LINK MAKING REQUEST
CURNUM:	BLOCK	1		;LINK # OF CURLNK
THSLNK:	BLOCK	1		;POINTER TO TEMP LINK
HILINK:	BLOCK	1		;HIGHEST LINK NUMBER
IFN FTLOG,<
INLOG:	BLOCK	1		;-1 WHILE OUTPUTTING STUFF TO REAL LOG FILE
LCHAN:	BLOCK	1		;CHAN # FOR LOG FILE
ITIME:	BLOCK	1		;RUN TIME AT START
>
IFN FTWRITE,<
WCHAN:	BLOCK	1		;CHAN # FOR OUTPUT FILE
WPTR:	BLOCK	1		;PTR TO BIT TABLE
>
IFN TOPS20,<
JFN:	BLOCK	1		;JFN OF THE OVERLAY FILE
TEMP2:	BLOCK	2		;SAVE ACCS 2 & 3
>
USERPC:	BLOCK	1		;[44] USER RETURN PC FOR MANUAL CALLS
OKOVLC:	BLOCK	1		;[43] -1 = OK TO OVERLAY CALLER (RUNOV.)

IDXBFR:	BLOCK	200		;200 WORD WINDOW OF LINK POINTERS
INBFR:	BLOCK	200		;200 WORD WINDOW OF FILE

	I.END==.-1			;LAST WORD TO ZERO
	SEGMENT	HIGH
	PURGE	%SEG%
SUBTTL	THE END


	END