Google
 

Trailing-Edge - PDP-10 Archives - BB-D868C-BM - language-sources/lnkov2.mac
There are 39 other files named lnkov2.mac in the archive. Click here to see a list.
TITLE LNKOV2 - PHASE 2 OVERLAY MODULE FOR LINK
SUBTTL	D.M.NIXON/DMN/JLd/RKH/JNG/MCHC/DZN	24-Aug-79


;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973, 1979 BY DIGITAL EQUIPMENT CORPORATION


SEARCH	LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
SALL

ENTRY	LNKOV2
EXTERN	LNKMAP,LNKXIT


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

VERSION


SEGMENT
SUBTTL	REVISION HISTORY


;START OF VERSION 2
;135	ADD OVERLAY FACILITY
;136	FIX VARIOUS BUGS
;174	FIX BUGS IN RELOCATABLE OVERLAYS
;203	GET DDT SYMBOLS INTO ALL LINKS
;207	REDUCE SIZE OF OVERHEAD TABLES

;START OF VERSION 2B
;261	Allow loading of null structures (root only)
;322	Set up LSYM correctly to prevent confusing LNKCOR
;332	Restore base of GS area before processing
;362	Always set up the preamble area at OVR8, since edit
;	322 made LNKXIT not set it up. [15706] (JNG).
;410	Avoid ?LNKISN on a node with no internal symbols.
;415	Set up LSYM and NAMPTR to avoid ?ILL MEM REF in LNKCOR
;423	Return RT area when done with it to avoid LNKXIT problems.

;START OF VERSION 2C
;460	Fix bug if multiple multiply-defined references in 1 link.
;461	Prevent loop in LNKCOR by requesting 0 words in rdcst
;467	Prevent ?ADDRESS CHECK by keeping RT.PT at relative
;	 (not absolute) zero when the RT area is empty.
;530	Get triplet flag definitions right.
;536	Get IT.??? flag definitions right.
;557	Clean up listing for release.

;START OF VERSION 3A
;560	Release on both TOPS-10 and TOPS-20 as LINK version 3A(560)

;START OF VERSION 4
;573	Prevent random USETO when root of relocatable overlay
;	structure has no INTTAB or EXTTAB
;576	Correct usage of PT.SGN and PT.OTH in INTTAB hash table.
;621	Generate an EXE file.
;627	Fix LNKARL message when list of links is long.
;635	Use /ARSIZE area for ARL tables, and give intelligent
;	error messages if /ARSIZE area is too small.
;650	Use VM on TOPS-10 if available.
;677	Don't default to /SYMSEG:LOW when loading overlays.
;731	SEARCH MACTEN,UUOSYM
;743	Fix bug with offset calculation of link intab pointer.
;765	Release on both TOPS-10 and TOPS-20 as LINK version 4(765)

;START OF VERSION 4A
;1172	Call LSLOOP correctly.
;1174	Label and clean up all error messages.
;1201	Change references to $SEGxxx to $SSGxxx.
;1217	Clean up the listings for release.
;1220	Release on both TOPS-10 and TOPS-20 as version 4A(1220).
SUBTTL	DEFINITIONS


EI.ZZ==4		;NO. OF WORDS IN EXT/INT HASH BLOCKS

;INDEX TO ITEMS IN EXT/INT TABLE
EI.FLG==0		;FLAGS,,LINK#
EI.SYM==1		;SYMBOL
EI.VAL==2		;VALUE
EI.INT==3		;INTTAB ENTRY
EI.LEN==4		;LENGTH OF SYMBOL BLOCK

;TEMP "SYMBOL" FLAGS
IT.DEF==PS.GLB		;SYMBOL IS DEFINED IN OTHER LINK
IT.MDF==PS.MDF		;SYMBOL IS DEFINED IN MORE THAN 1 LINK
IT.UDF==PS.UDF		;SYMBOL IS NOT YET DEFINED
IT.LST==PS.DDT		;LAST SYMBOL IF EXTENDED

;FLAGS IN OVERLAY BLOCK (JSP CALL)
F.LIC==1B0		;LINK IN CORE (ONLY USED FOR UNDEFS)
F.MDL==1B1		;LINK IS MULTIPLY-DEFINED
F.RLC==1B2		;LINK IS RELOCATED (NOT USED)

;IOWD FOR PREAMBLE SECTION

IFE FTKIONLY,<
PHIOWD:	IOWD	PH.ZZ,PH.HDR
	0
>
IFN FTKIONLY,<EXTERN	PHIOWD>		;BUG IN DMOVE MACRO

DEFINE SETBIT (BIT,%ADD)<
	SKIPE	T1,RT.PT	;;NEED TO SET RELOC TABLE?
	CAMN	T1,RT.LB	;;MAYBE, DO WE?
	JRST	%ADD		;;NO
 %BIT==0
 IRP BIT,<
  IFE BIT,<
	IBP	RT.PT		;;LEAVE 0 THERE
  >
  IFN BIT,<
   IFN BIT-%BIT,<
	MOVEI	T1,BIT		;;BIT PATTERN WE WANT
    %BIT==BIT
   >
	IDPB	T1,RT.PT	;;STORE BIT PATTERN
 >>
 %ADD:	PURGE %BIT
>
SUBTTL	ENTRY POINT


LNKOV2:	JFCL	.+1		;NORMAL ENTRY
E$$OS2::.ERR.	(MS,,V%L,L%I,S%I,OS2,<Overlay segment phase 2>) ;[1174]
	MOVE	T1,SYMSEG	;GET /SYMSEG VALUE
	CAIE	T1,$SSGNONE	;[1201] USER SAY NO?
	SKIPE	NOSYMS		; . . . ?
	SETZM	SYMSEG		;YES, DON'T LOAD SYMBOLS
	RELEASE	DC,		;CLOSE INPUT I/O
	MOVEI	T1,DC		;FINISHED WITH INPUT BUFFERS NOW
	MOVEM	T1,IO.CHN
	PUSHJ	P,DVRET.##	;RETURN TO FREE POOL
	SETZM	IO.PTR+DC
	MOVE	T1,IO.PTR+%OC	;PSEUDO CHAN#
	MOVE	T2,LODNAM	;GET DEFAULT NAME
	SKIPN	I.NAM(T1)	;DID USER SUPPLY?
	MOVEM	T2,I.NAM(T1)	;NO, USE DEFAULT
	MOVE	T2,VERNUM	;GET VERSION#
	SKIPN	I.VER(T1)	;SKIP IF SET BY SWITCH
	MOVEM	T2,I.VER(T1)
OVR2:	MOVEI	T1,BG.IX	;DONE WITH BOUND GLOBALS
	PUSHJ	P,XX.ZAP##	;SO REMOVE THEM
	SETZM	BG.SCH		;CERTAINLY CAN NOT SEARCH THEM NOW
	HRRZ	T2,BRNLEN	;HIGHEST USED
	HLRE	T1,BRNLEN	;-COUNT OF WHATS LEFT
	SUB	T2,T1		;INITIAL SIZE
	ADDI	T2,1
	HRRZ	T1,BRNTBL	;START ADDRESS
	PUSHJ	P,DY.RET##	;GIVE IT BACK
	HRRZ	T1,BRNDSK
	PUSHJ	P,DY.RET##	;PARALLEL TABLE
	MOVN	T1,LNKMAX	;HIGHEST LINK# ASSIGNED
	HRLI	T1,2		;BLOCK NUMBER OF LINK TABLE
	MOVSM	T1,DI.LPT	;PUT IOWD/USETI PTR IN DIRECTORY
	HRRZ	T2,LNMPTR	;NO. OF LINK NAMES
	MOVN	T1,T2		;- FOR IOWD PART
	LSH	T1,1+^D18	;WORD PAIRS IN LEFT HALF
	LSH	T2,1
	ADD	T2,L.MAX	;NO. USED BY LINK #'S
	CAIL	T2,LN.OVL/2	;ENOUGH SPACE LEFT?
	JRST	[HALT]		;NO
	MOVE	T2,L.MAX	;NO. OF WORDS USED
	LSH	T2,-.DBS2W	;[650] BLOCKS
	HRRI	T1,2(T2)	;START BLOCK FOR NAMES
	MOVEM	T1,DI.NPT	;STORE IN DIRECTORY
	MOVSI	T1,(POINT 18)
	MOVEM	T1,PRMPTR	;MAKE SURE ITS SET TO INITIAL VALUE
	MOVE	T1,EXTCNT	;THIS MANY EXTERN REQUESTS
	ADDI	T1,^D50		;A FEW SPARE
	IMULI	T1,^D100	;MAKE SURE HASH TABLE NEVER FILLS
	IDIVI	T1,.HS%		;SO WE WOULD HAVE TO REHASH
	MOVEM	T1,HT.PRM
	PUSHJ	P,NPRIME##	;GET NEAREST PRIME#
	MOVE	T1,GS.LB	;GET BASE
	SETZM	(T1)		;PROBABLY JUNK THERE
	HRRM	T1,HT.PTR	;PUT HASH TABLE THERE
	ADD	T1,HT.PRM	;ACCOUNT FOR IT
	MOVEM	T1,GS.PT
	IORI	T1,.IPM		;ROUND UP
	CAMG	T1,GS.AB	;FIT IN WHAT WE HAVE?
	JRST	OVR2A		;YES
	SUB	T1,GS.AB	;NO, GET DIFF
	MOVM	P2,T1		;WHAT WE NEED
	MOVEI	P1,GS.IX	;FROM WHERE
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,E$$MEF##	;[1174]
	SKIPA	T1,GS.AB	;GS.AB IS NOW SETUP CORRECTLY
OVR2A:	MOVEM	T1,GS.AB
	SUB	T1,GS.PT	;SEE WHATS LEFT
	MOVEM	T1,GS.FR
	AOS	LS.FR		;RESET LS AREA TO USE WORD 0'
	SOS	LS.PT
	SETZM	LSYM		;LS AREA IS NOW EMPTY
	SETZM	NAMPTR		;SO NO TITLES IN IT
OVR3:	SETOM	LNKNO.		;SO WE WILL START BACK AT 0
	MOVE	P2,LC.AB	;MAKE SURE ENOUGH CORE FOR 2 BLOCKS
	SUB	P2,LC.LB
	CAIL	P2,2*.DBS-1
	JRST	OVR3A		;OK
	MOVEI	P1,LC.IX
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,E$$MEF##	;[1174]
OVR3A:	AOS	P1,LNKNO.	;PICKUP LINK #
	CAMLE	P1,LNKMAX	;SEE IF FINISHED
	JRST	OVR4		;YES, NOW RATIONALIZE TABLES
	PUSH	P,LSYM		;SAVE LSYM, SINCE RDCST READS IN
				;AN OLD COPY FROM THE OVL FILE
	PUSHJ	P,RDCST		;READ IN BLOCK CONTAINING CONTROL SEC.
	  JRST	[POP	P,LSYM	;RESTORE LSYM
		JRST	OVR3A]	;GIVE UP -- NO EXTTAB OR INTTAB
	POP	P,LSYM		;BRING BACK LSYM
OVR3C:	SETZB	W1,W3		;NO FLAGS YET
	HLL	R2,CS.EXT	;FORM AOBJN PTR.
	JUMPGE	R2,OVR3I	;DONE IF NONE THERE
OVR3D:	HRRZ	T1,R2		;GET REL ADDRESS
	ADD	T1,LC.LB	;LOCATE
	MOVE	W2,ET.NAM(T1)	;GET NAME
	PUSHJ	P,TRYSYM##	;SEE IF IN TABLE
	  JRST	OVR3F		;NO
	  JFCL			;YES
OVR3E:	ADDI	R2,ET.ZZ-1	;ACCOUNT FOR MULTIPLE WORDS
	AOBJN	R2,OVR3D	;LOOP FOR ALL TABLE
	JRST	OVR3I		;NOW FOR INTTAB

OVR3F:	MOVEI	T2,EI.ZZ	;4 WORD TABLES
	PUSHJ	P,GS.GET##
	MOVX	W1,PT.SGN!PT.OTH!IT.UDF	;[576] NOT YET DEFINED FLAG
	DMOVEM	W1,EI.FLG(T1)	;STORE FLAG & NAME (REST IS ZERO)
	SUB	T1,GS.LB	;REMOVE BASE
	HRL	T1,P3		;HASH TOTAL IN LEFT
	MOVEM	T1,@HT.PTR	;HASH TOTAL ,, REL ADDRESS
	JRST	OVR3E
OVR3I:	HLRE	T2,CS.INT	;GET NO OF WORDS
	JUMPE	T2,OVR3A	;NONE
	IMUL	T2,[-2]		;ACTUALLY 2 WORDS PER ENTRY
	ADDI	T2,1		;PLUS ONE FOR LINK#
	MOVE	T1,LS.FR	;NUMBER OF WORDS FREE
	SUBI	T1,(T2)		;MINUS WHAT WE NEED
	JUMPL	T1,OVR3X	;MUST EXPAND
	MOVEM	T1,LS.FR	;STORE NEW COUNT
	ADDM	T2,LSYM		;COUNT EXTRA WORDS
	MOVE	T3,LS.PT	;GET NEXT FREE
	ADDB	T2,LS.PT
	MOVE	T1,CS.INT
	HRR	T1,CS.NUM	;-COUNT ,, LINK #
	MOVEM	T1,(T3)		;STORE FIRST WORD
	HRRZI	T1,1(T3)	;ACCOUNT FOR IT
	ADD	R2,LC.LB	;FIX SOURCE
	HRL	T1,R2		;FORM BLT PTR
	BLT	T1,-1(T2)	;MOVE ALL WORDS
	JRST	OVR3A		;GET NEXT

OVR3X:	MOVEI	P1,LS.IX
	MOVE	P2,T2
	SUB	P2,LS.FR	;WHAT WE REALLY NEED
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,E$$MEF##	;[1174]
	JRST	OVR3I		;TRY AGAIN
;FIRST MAKE SURE THE POINTERS IN THE LS AREA TERMINATE
;WITH A ZERO, THEN GO PROCESS THEM.

OVR4:	SKIPN	LS.FR		;ANY FREE SPACE AT ALL?
	JRST	[MOVEI	P1,LS.IX	;NO (SIGH), NEED 1 WORD
		MOVEI	P2,1		;ONLY ONE LONELY WORD
		PUSHJ	P,LNKCOR##	;GET IT
		  PUSHJ	P,E$$MEF##	;[1174] NOT 1 WORD ????!!!!!!
		JRST	.+1]		;REJOIN MAIN STREAM
	SOS	LS.FR		;WE NEED ONE WORD
	AOS	LSYM		;FOR OUR ZERO POINTER
	AOS	T1,LS.PT	;SO UPDATE ALL THE RIGHT POINTERS
	SETZM	-1(T1)		;AND CLEAR OUR LONELY LITTLE WORD
	SETZ	R2,		;START ON FIRST WORD
OVR4A:	HRRZ	T1,R2		;GET REL ADDRESS
	ADD	T1,LS.LB
	SKIPN	T1,(T1)		;GET NEXT -LEN,,LINK #
	JRST	OVR5		;TABLE EXHAUSTED, STOP
	HLL	R2,T1		;AOBJN LH
	HRRZM	T1,LNKNO.	;STORE WHO WE ARE
	HRRI	R2,1(R2)	;ACCOUNT FOR WORD
	SETOM	INTCNT		;START AT -1 SO AOS WORKS
OVR4B:	HRRZ	T1,R2
	ADD	T1,LS.LB
	DMOVE	W2,(T1)		;GET NAME AND VALUE
	PUSHJ	P,TRYSYM##	;SEE IF REQUIRED
	  JRST	OVR4C		;NO
	  JFCL
	MOVE	T1,0(P1)	;GET FLAGS
	TXOE	T1,IT.DEF	;SEE IF ALREADY DEFINED
	JRST	OVR4D		;YES, STORE ALL DEFINITIONS
	TXZ	T1,IT.UDF	;NOW DEFINED
	HRR	T1,LNKNO.	;WHICH LINK
	MOVEM	T1,EI.FLG(P1)	;PUT BACK
	HRRZM	W3,EI.VAL(P1)	;VALUE
	AOS	T1,INTCNT	;COUNT NO. IN INTTAB
	HLL	T1,W3		;START OF TABLE
	MOVSM	T1,EI.INT(P1)
OVR4C:	ADDI	R2,1		;WORDS COME IN 2S
	AOBJN	R2,OVR4B	;LOOP FOR ALL THIS LINK
	MOVE	T1,LNKNO.	;GET THIS LINK #
	CAMGE	T1,LNKMAX	;ALL DONE?
	JRST	OVR4A		;NO, GET NEXT LINK
	JRST	OVR5		;YES
;HERE TO HANDLE GLOBAL DEFINED IN MORE THAN 1 LINK
OVR4D:	TXON	T1,IT.MDF	;SIGNAL SO
	MOVEM	T1,0(P1)	;AND STORE BACK
				;NOW MOVE SYMBOL TO NEW LOCATION
	PUSHJ	P,EI.CNT	;SEE HOW LONG IT IS
	ADDI	T2,4		;EXTRA WE NEED
	PUSHJ	P,GS.GET##	;GET NEW BLOCK
	HRRZ	P1,@HT.PTR	;INCASE WE MOVED
	ADD	P1,GS.LB
	EXCH	P1,T1		;PUT NEW BLOCK IN P1 OLD IN T1
	SUBI	T2,EI.LEN	;LENGTH BACK AS IT WAS
	HRLZ	T3,T1
	HRR	T3,P1		;BLT PTR
	HRRZ	T4,P1
	ADDI	T4,(T2)		;END OF BLT +1
	BLT	T3,-1(T4)	;MOVE SYMBOL TO NEW HOME
	MOVE	T3,P1
	SUB	T3,GS.LB	;OFFSET ONLY
	HRRM	T3,@HT.PTR	;MAKE HASH TABLE POINT TO NEW BLOCK
	MOVX	T3,PT.EXT
	IORB	T3,EI.FLG-EI.LEN(T4)	;SET LAST BLOCK EXTENDED
	TXZ	T3,PT.EXT	;NEW LAST NOT EXTENDED
	HRR	T3,LNKNO.	;WHICH LINK
	MOVEM	T3,EI.FLG(T4)	;SET FLAGS FOR NEW LAST BLOCK
	MOVEM	W2,EI.SYM(T4)	;STORE SYMBOL NAME AGAIN
	HRRZM	W3,EI.VAL(T4)	;VALUE
	AOS	T3,INTCNT	;COUNT NO. IN TABLE
	HLL	T3,W3		;START OF TABLE
	MOVSM	T3,EI.INT(T4)
	PUSHJ	P,GS.RET##	;GIVE BACK OLD BLOCK
	JRST	OVR4C		;AND RETURN

;ROUTINE EI.CNT - TO COUNT LENGTH OF EI SYMBOL BLOCK
;ENTER WITH
;P1 = POINTS TO SYMBOL
;RETURNS
;LENGTH IN T2
;USES T1
EI.CNT:	MOVE	T3,P1		;GET A COPY
	MOVEI	T2,EI.LEN	;LENGTH OF SYMBOL
EICNT1:	MOVE	T1,0(T3)	;GET FLAGS
	TXNN	T1,PT.EXT	;IS IT EXTENDED?
	POPJ	P,		;NO, ALL DONE
	ADDI	T2,EI.LEN		;YES
	ADDI	T3,EI.LEN
	JRST	EICNT1		;ACCOUNT FOR IT AND TRY AGAIN
OVR5:	MOVE	T1,LS.LB	;GET BASE
	SETZM	(T1)
	MOVEM	T1,LS.PT	;MAKE IT ALL FREE
	HRLZ	T2,T1
	HRRI	T2,1(T1)
	BLT	T2,@LS.AB	;CLEAR ALL OF CORE
	IORI	T1,.IPM
	MOVEM	T1,LS.AB	;ALLOCATE ONE BLOCK
	MOVEI	T1,.IPS
	MOVEM	T1,LS.FR	;KEEP FREE SPACE COUNT RIGHT

	SETOM	LNKNO.		;START BACK ON LINK 0
	AOS	T2,BRNMAX	;NEED TABLE OF 1/2 WORD PER LINK ON PATH
	LSH	T2,-1
	ADDI	T2,PH.ZZ	;PLUS SPACE FOR PREAMBLE
	MOVEM	T2,BRNLEN
	PUSHJ	P,DY.GET##
	HRLI	T1,(POINT 18)
	MOVEM	T1,BRNTBL	;STORE ORIGINAL PTR
OVR6:	AOS	P1,LNKNO.	;GET NEXT LINK
	CAMLE	P1,LNKMAX	;SEE IF FINISHED
	JRST	OVR7		;YES
	PUSHJ	P,RDCST		;READ IN BLOCK CONTAINING CONTROL SEC.
	  JRST	[PUSHJ	P,RDREL	;[573] NEITHER EXTTAB NOR INTTAB
		JRST	OVR6G]	;[573] SO SETUP RT AREA & SKIP ON
	PUSHJ	P,RDREL		;IF RELOCATABLE SETUP RT.PT
	ADD	R2,LC.LB	;CORE WILL NOT MOVE NOW
	SETZB	W1,W3		;SAVE CONFUSION
	HLL	R2,CS.EXT
	JUMPGE	R2,OVR6D	;NO EXTTAB
	HRRZ	P3,CS.EXT	;GET START ADDRESS
	SKIPE	T2,RT.PT	;IS IT RELOCATABLE?
	CAMN	T2,RT.LB	;NOT IF AREA IS EMPTY
	CAIA			;EMPTY, DON'T CALL RT.P3
	PUSHJ	P,RT.P3##	;SET UP RT.PT
OVR6C:	MOVE	W2,ET.NAM(R2)	;GET NAME
	PUSHJ	P,TRYSYM##	;LOOK IT UP
	  JRST	E$$USC		;[1174]
	  JRST	E$$USC		;[1174]
	MOVE	T2,EI.FLG(P1)	;GET LINK#
	TXNE	T2,IT.MDF	;MULTIPLY-DEFINED?
	JRST	OVR6M		;YES
	SPUSH	<FSTPTR,P3>
	MOVE	P3,P1		;SAVE SYMBOL PTR
	SKIPN	P1,CS.NUM	;ONLY WANT TO LOOK AT TREE ABOVE US
	JRST	OVR6CA		;ALL IS ABOVE ROOT
	PUSHJ	P,TR.WLK##	;THESE ARE ONLY LINKS WE CAN REACH
	JUMPE	P2,[MOVE P2,CS.NUM	;SHOULD NOT HAPPEN
		  PUSHJ P,E$$LNM##]	;[1174] BUT!!!
	HLRZ	T1,P1		;GET POINTER
	HRRZ	T1,(T1)		;GET LINK# OF HEAD OF NODE
	CAIE	T1,(P1)		;IF NOT EQUAL THEN REQUIRED NODE IS A TERMINAL ONE
	JRST	OVR6CN		; IN WHICH CASE IT HAS NO SONS
	HLRZM	P1,FSTPTR	;CREATE SUB-TREE PTR
	HRRZ	P1,EI.FLG(P3)	;LINK# WE WANT
	PUSHJ	P,TR.WLK##	;SEE IF WE CAN SEE IT
	JUMPE	P2,OVR6CN	;NOT VISIBLE
;HERE IF DESIRED LINK IS VISIBLE

OVR6CA:	MOVE	P1,P3		;PUT P1 BACK
	SPOP	<P3,FSTPTR>
OVR6CB:	MOVE	T2,EI.FLG(P1)	;GET LINK #
	HRLM	T2,ET.CST(R2)	;SAVE IT
	HLRZ	T1,EI.INT(P1)	;GET ITEM NO. IN INTTAB
	LSH	T1,1		;2 WORDS PER ITEM
	ADD	T1,EI.INT(P1)	;FIX IT
	HRRZM	T1,ET.INC(R2)	;STORE IT WITH 0 FLAGS
OVR6CC:	SETZM	ET.NAM(R2)	;CLEAR NAME NOW
OVR6CD:	SETBIT	<0,0,1,0>
	ADDI	R2,ET.ZZ-1
	AOBJN	R2,OVR6C	;LOOP FOR ALL OF EXTTAB
	JRST	OVR6D

E$$USC::.ERR.	(MS,.EC,V%L,L%F,S%W,USC,<Undefined subroutine >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2)
	.ETC.	(STR,.EC,,,,,< called from>) ;[1174]
	.ETC.	(JMP,,,,,.ETLNN##) ;[1174]
OVR6CE:	MOVE	T1,ADDOVU	;ADDRESS OF UNDEFINED ROUTINE
	HLRZM	T1,ET.CST(R2)	; AND ROOT CST
	HRLI	T1,(F.LIC)	;ALWAYS IN CORE
	MOVEM	T1,ET.INC(R2)	;TO SAVE TIME AND EFFORT
	JRST	OVR6CD		;IN OVERLAY HANDLER


OVR6CN:	HRRZ	P1,EI.FLG(P3)	;GET LINK #
E$$SNP::.ERR.	(MS,.EC,V%L,L%W,S%W,SNP,<Subroutine >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2)
	.ETC.	(STR,.EC,,,,,< in link number >)
	.ETC.	(DEC,.EC!.EP,,,,P1)
	.ETC.	(STR,.EC,,,,,< not on path for call from>) ;[1174]
	.ETC.	(JMP,,,,,.ETLNN##) ;[1174]
	MOVE	P1,P3		;RESTORE P1
	SPOP	<P3,FSTPTR>
	JRST	OVR6CE		;AND MAKE IT UNDEFINED AT RUN TIME
;HERE ON A MULTIPLY-DEFINED ENTRY POINT

OVR6M:	SPUSH	<FSTPTR,P3,P4>
	MOVE	P3,P1		;SAVE SYMBOL PTR
	SETZ	P4,		;KEEP POINTER TO FIRST AVAILABLE SYMBOL
	SKIPN	P1,CS.NUM	;WE ONLY WANT TO LOOK AT TREE ABOVE US
	JRST	OVR6MA		;ALL OF TREE IS ABOVE ROOT
	PUSHJ	P,TR.WLK##	;SINCE THESE ARE THE ONLY LINKS WE
				;CAN REACH, ALL OTHERS ARE NOT AVAILABLE
	JUMPE	P2,[MOVE P2,CS.NUM	;CANNOT HAPPEN
		    PUSHJ P,E$$LNM##]	;[1174] BUT!
	HLRZ	T1,P1		;GET POINTER
	HRRZ	T1,(T1)		;GET LINK# OF HEAD OF NODE
	CAIE	T1,(P1)		;IF NOT EQUAL THEN REQUIRED NODE IS A TERMINAL ONE
	SETZB	P1,P2		; IN WHICH CASE IT HAS NO SONS
	HLRZM	P1,FSTPTR	;USE THIS AS START OF SUB TREE
OVR6MA:	HRRZ	P1,EI.FLG(P3)	;GET LINK#
	SKIPE	FSTPTR		;INDICATES NO POSSIBLE SONS
	PUSHJ	P,TR.WLK##	;SEE IF WE CAN GET TO IT
	JUMPE	P2,OVR6MB	;NO, TRY NEXT
	JUMPN	P4,OVR6MC	;NOT FIRST, SO ERROR
	MOVE	P4,P3		;SAVE PTR TO FIRST AVAILABLE
OVR6MB:	MOVE	T1,EI.FLG(P3)	;GET FLAGS
	TXNN	T1,PT.EXT	;MORE TO COME?
	JRST	OVR6MZ		;NO, ITS THE END
	ADDI	P3,4		;GET NEXT
	JRST	OVR6MA

OVR6MZ:	MOVE	P1,P4		;UNIQUE SYMBOL
	POP	P,P4
	JUMPE	P1,OVR6CN	;NONE CAN BE REACHED
	SPOP	<P3,FSTPTR>
	JRST	OVR6CB		;RETURN WITH P1 SETUP
OVR6MC:	MOVX	T1,F.MDL	;MARK IT MULTIPLY DEFINED
	IORM	T1,ET.INC(R2)	;IN EXTTAB
	SUB	P4,GS.LB	;INCASE WE MOVE
	SUB	P3,GS.LB
	PUSH	P,P4		;SAVE ORIGINAL
	PUSH	P,P3		;SAVE SECOND DEF
	ADD	P3,GS.LB	;PUT BASE BACK
	MOVEI	P4,2		;COUNT NUMBER IN P4
	JRST	OVR6ME		;GET NEXT

OVR6MD:	HRRZ	P1,EI.FLG(P3)	;GET LINK#
	PUSHJ	P,TR.WLK##	;SEE IF WE CAN GET TO IT
	JUMPE	P2,OVR6ME	;NO, TRY NEXT
	SUB	P3,GS.LB
	PUSH	P,P3		;SAVE IT
	ADD	P3,GS.LB	;RESTORE GS BASE
	ADDI	P4,1		;ONE MORE
OVR6ME:	MOVE	T1,EI.FLG(P3)	;GET FLAGS
	TXNN	T1,PT.EXT	;MORE TO COME?
	JRST	OVR6MF		;NO, ITS THE END
	ADDI	P3,4		;GET NEXT
	JRST	OVR6MD

OVR6MF:	SUB	R2,LC.LB	;CORE MIGHT MOVE
	MOVE	T2,P4		;NO. OF DEFINITIONS
	LSH	T2,1		;2 WORDS EACH
	ADDI	T2,2		;PLUS LINK TO NEXT & NAME
	PUSHJ	P,DY.GET##	;SPACE TO BUILD THE TABLE
	MOVN	P3,P4
	HRLZ	P3,P3
	HRR	P3,T1		;AOBJN WORD
	HRRZ	T1,CS.RLC	;USE THIS TO POINT TO LIST
	HRL	T1,R2		;POINT TO WHICH ONE
	MOVEM	T1,(P3)		;STORE IN FIRST WORD
	HRRZM	P3,CS.RLC	;RESET TO POINT TO THIS FIRST
	ADDI	P3,2		;BYPASS FIRST TWO WORD
	MOVE	T2,P4		;ALSO NEED SPACE TO STORE ERROR MESSAGE
	IMULI	T2,7		;6 CHAR NAME PLUS COMMA
	IDIVI	T2,5		;STORED AS ASCII
	ADDI	T2,1		;FOR PARTIAL WORD
	PUSHJ	P,DY.GET##	;GET SPACE
;HERE TO PRINT ERROR MESSAGE. GENERATE PART OF MESSAGE IN DY AREA.

	MOVE	P1,T1		;PUT IN SAFE PLACE (CANNOT USE STACK)
	HRLI	P1,(POINT 7,)	;FORM BYTE PTR
	HRLZ	P2,T2
	HRR	P2,T1		;SO WE CAN GIVE IT BACK
	ADD	R2,LC.LB	;PUT BASE BACK
	HLLM	P3,ET.CST(R2)	;STORE COUNT BACK IN EXTTAB
	MOVE	T2,ET.NAM(R2)	;GET NAME
	MOVEM	T2,-1(P3)	;STORE IN SECOND WORD
OVR6MG:	POP	P,T4		;GET ADDRESS  BACK
	ADD	T4,GS.LB	;FIX IN CORE
	HRL	T1,EI.FLG(T4)	;GET LINK #
	HRR	T1,ET.CST(R2)	;AND CONTROL SECTION (WILL GET DESTROYED)
	HLRZ	T2,T1		;GET LINK #
	PUSHJ	P,[IDIVI T2,^D10	;USUAL RADIX PRINTER
		HRLM	T3,0(P)		;STORE ON STACK
		SKIPE	T2		;DONE?
		PUSHJ	P,@.		;NOT YET
		HLRZ	T2,0(P)		;RECOVER CHAR
		ADDI	T2,"0"		;MAKE ASCII
		IDPB	T2,P1		;STORE
		POPJ	P,]		;RETURN
	MOVEI	T2,","
	IDPB	T2,P1		;SEPARATOR
	HLRZ	T2,EI.INT(T4)	;GET ITEM NO. IN INTTAB
	LSH	T2,1		;2 WORDS PER ITEM
	ADD	T2,EI.INT(T4)	;FIX IT
	HLL	T2,ET.INC(R2)	;COPY FLAGS
	MOVEM	T2,0(P3)	;STORE
	MOVEM	T1,1(P3)	;...
	ADDI	P3,1
	AOBJN	P3,OVR6MG	;MORE TO DO

	SETZ	T1,		;STORE A NULL
	DPB	T1,P1		;AT END OF STRING
	HRRZ	P1,P2		;[627] POINT BACK TO START OF STRING
E$$ARL::.ERR.	(MS,.EC,V%L,L%W,S%W,ARL,<Ambiguous request in>) ;[1174]
	.ETC.	(JMP,.EC,,,,.ETLNN##) ;[1174]
	.ETC.	(STR,.EC,,,,,< for symbol >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2)
	.ETC.	(STR,.EC,,,,,<, defined in links >)
	.ETC.	(STR,.EP,,,,P1)

	HRRZ	T1,P2
	HLRZ	T2,P2
	PUSHJ	P,DY.RET##	;GIVE SPACE BACK
	SPOP	<P4,P3,FSTPTR>
	JRST	OVR6CC		;GET NEXT SYMBOL
OVR6D:	HLRE	R3,CS.INT	;[635] GET NO. OF INTTAB ENTRIES
	IMUL	R3,[-2]		;[635] CONVERT TO WORDS
	ADD	R3,CS.INT	;[635] MAKE FIRST FREE AFTER INTTAB
	JUMPN	R3,OVR6DA	;[635] USE IT IF INTTAB EXISTS
	HLRE	R3,CS.EXT	;[635] OTHERWISE USE END OF EXTTAB
	IMUL	R3,[-ET.ZZ]	;[635] WORDS IN EXTTAB
	ADD	R3,CS.EXT	;[635] THENCE TO FIRST WORD BEYOND IT
OVR6DA:	HRRZ	T1,OV.S1	;[635] FIRST FREE BEYOND /ARSIZE
	SUBI	T1,0(R3)	;[635] MINUS FIRST WORD OF /ARSIZE AREA
	HRRM	T1,ARSIZE	;[635] IS THIS LINK'S ARSIZE
	HLL	R2,CS.INT	;GET NO. OF INTTABS
	JUMPGE	R2,OVR6FA	;NONE
	HRRZ	R3,R2		;USED TO STORE BACK IF REQUIRED
	HRRZ	P3,CS.INT	;GET START ADDRESS
	SKIPE	T1,RT.PT	;IS IT RELOCATABLE?
	CAMN	T1,RT.LB	;MAYBE, IS IT?
	CAIA			;NO
	PUSHJ	P,RT.P3##	;SET UP RT.PT
OVR6E:	DMOVE	W2,(R2)		;GET SYMBOL & VALUE
	PUSHJ	P,TRYSYM##	;SEE IF WANTED
	  JRST	OVR6F		;NOT IN TABLE SO NOT WANTED
	  HALT
	MOVE	T1,0(P1)	;GET FLAGS
	TXNN	T1,IT.DEF	;SEE IF ITS WANTED
	JRST	OVR6F		;NO
	HRRZM	W3,0(R3)	;STORE PTR AS VALUE
	SETZM	1(R3)		;NO REFS YET
	ADDI	R3,2
	SETBIT	<1,0>,OVR6F
OVR6F:	ADDI	R2,1
	AOBJN	R2,OVR6E	;LOOP
	HRRZ	R2,R2
	CAML	R3,R2		;DID WE REDUCE?
	JRST	OVR6FA		;NO
	HRLZI	T1,0(R3)
	HRRI	T1,1(R3)	;FORM BLT PTR
	SETZM	(R3)		;CLEAR FIRST WORD
	BLT	T1,-1(R2)	;AND REST
	SUB	R3,R2		;SEE BY HOW MUCH WE REDUCED
	MOVM	T1,R3		;+DIFF
	ADD	R2,R3		;BACKUP NEXT FREE PTR
	LSH	T1,^D17		;CUT IN HALF AND PUT IN LHS
	ADDM	T1,CS.INT	;MAKE THIS RIGHT
OVR6FA:	SKIPN	P1,CS.RLC	;ANY MULTIPLY DEF GLOBALS?
	JRST	OVR6G		;NO
	SETZ	P3,		;[635] INDICATE NO TMA ERROR YET
	HLRE	R3,CS.INT	;THESE WILL GO AT END OF TABLES
	IMUL	R3,[-2]
	ADD	R3,CS.INT
	JUMPN	R3,OVR6FB	;BUT IF NO INTTAB
	HLRE	R3,CS.EXT	; USE EXTTAB
	IMUL	R3,[-ET.ZZ]
	ADD	R3,CS.EXT
OVR6FB:	MOVE	T1,0(P1)	;GET NEXT PTR
	HRRZM	T1,CS.RLC	;AND SET IT
	HLRZ	P2,T1		;PTR TO EXTTAB BLOCK
	ADD	P2,LC.LB	;IN CORE
	HRRM	R3,ET.CST(P2)	;POINT TO BLOCK OF DEFINITIONS
	HLRE	T1,ET.CST(P2)	;GET LENGTH
	MOVM	T2,T1		;+ LENGTH
	LSH	T2,1		;WORD PAIRS
	ADDI	T2,1		;PLUS ONE FOR NAME
	JUMPE	P3,OVR6FD	;[635] IF NO ERROR YET, CHECK IF ONE NOW
	ADD	P3,T2		;[635] ERROR--JUST ACCUMULATE TOTAL NEED
	JRST	OVR6FG		;[635] GO FREE THIS BLOCK & CHECK NEXT

;HERE IF ARL TABLE STILL WITHIN OVERLAY. SEE IF OVERFLOW IMMINENT.
OVR6FD:	HRRZ	T1,OV.S1	;[635] GET FIRST FREE AFTER LINK
	SUB	T1,T2		;[635] COMPUTE MAX FF AFTER ARL TABLE
	CAIL	T1,(R3)		;[635] STILL WITHIN LIMITS?
	JRST	OVR6FE		;[635] YES, GO BLT INFO INTO TABLE
	SUBI	T1,(R3)		;[635] NO, FIND OUT HOW MUCH OVER
	HRRZ	P3,ARSIZE	;[635] FLAG ERROR, START WITH /ARSIZE
	SUB	P3,T1		;[635] ADD THIS OVERAGE (IS NEGATIVE)
	JRST	OVR6FG		;[635] GO RETURN BLOCK WITHOUT BLT
;HERE WHEN THIS BLOCK WILL FIT TOO. COPY IT ONTO END OF OVERLAY.
OVR6FE:	HRLZI	T1,1(P1)	;[635] FROM (EXCLUDING PTR WORD)
	HRR	T1,R2		; TO
	ADD	R2,T2
	HRRZ	T3,LC.AB	;[635] HIGHEST WORD ALLOCATED TO LC
	CAIL	T3,-1(R2)	;[635] IS BLT GOING BEYOND LC?
	JRST	OVR6FF		;[635] NO, PROCEED
	SUB	T1,LC.LB	;[635] CORE MIGHT MOVE
	SUB	P2,LC.LB	;[635] ..
	SUB	R2,LC.LB	;[635] ..
	SPUSH	<T1,T2,P1,P2>	;[635] SAVE ACCS LNKCOR WILL USE
	MOVEI	P1,LC.IX	;[635] EXPAND LC AREA
	MOVEI	P2,.IPS		;[635] ONE BLOCK IS ENOUGH FOR NOW
	PUSHJ	P,LNKCOR##	;[635] EXPAND LC AREA
	  PUSHJ	P,E$$MEF##	;[1174] TOO BAD
	SPOP	<P2,P1,T2,T1>	;[635] RESTORE NEEDED ACCS
	ADD	R2,LC.LB	;[635] FIX ADDRESSES AGAIN
	ADD	P2,LC.LB	;[635] ..
	ADD	T1,LC.LB	;[635] ..
OVR6FF:	BLT	T1,-1(R2)	;[635] BLT BLOCK
OVR6FG:	MOVE	T1,P1		;[635]
	ADD	R3,T2		;SET FOR NEXT BLOCK
	ADDI	T2,1		;PTR WORD IN FRONT ALSO
	PUSHJ	P,DY.RET##	;RETURN SPACE
	SUBI	T2,1
	JUMPN	P3,OVR6FC	;[635] IF HAD AN ERROR, DON'T SETUP RT
	SKIPE	T1,RT.PT	;RELOCATABLE?
	CAMN	T1,RT.LB	;NOT IF AREA IS EMPTY
	JRST	OVR6FC		;NO
	MOVEI	T1,1		;SET BIT
	HLRE	T2,ET.CST(P2)	;NO. OF PAIRS
	IBP	RT.PT		;ACCOUNT FOR NAME
	IBP	RT.PT		;INTTAB
	IDPB	T1,RT.PT	;CS IS RELOCATABLE
	AOJL	T2,.-2		;LOOP FOR ALL TABLE
OVR6FC:	SKIPE	P1,CS.RLC	;MORE TO DO?
	JRST	OVR6FB		;TRY AGAIN
	JUMPE	P3,OVR6G	;[635] PROCEED IF NO ERROR DETECTED
E$$TMA::.ERR.	(MS,.EC,V%L,L%F,S%W,TMA,<Too many ambiguous requests in>) ;[1174]
	.ETC.	(JMP,.EC,,,,.ETLNN##) ;[1174]
	.ETC.	(STR,.EC,,,,,<, use /ARSIZE:>)
	.ETC.	(DEC,.EP,,,,P3)
	CAMLE	P3,TMAMAX	;[635] LARGEST SEEN YET?
	MOVEM	P3,TMAMAX	;[635] YES, SAVE FOR FATAL ERROR AT END
;	JRST	OVR6G		;[635] CONTINUE TO NEXT LINK
OVR6G:	MOVE	T1,PH.LEN	;GET LENGTH
	HRLM	T1,CS.COR	;INTO CONTROL SECTION
	MOVE	T1,PH.CST	;NOW TO COPY CS BACK
	SUB	T1,PH.ADD
	ANDI	T1,.DBM		;[743] MAKE REL TO THIS BLOCK
	ADD	T1,LC.LB	;FIX IN CORE
	MOVEI	T2,CS.ZZ-1(T1)	;END OF BLT
	HRLI	T1,CS.HDR
	BLT	T1,(T2)		;MOVE IT ALL
	SKIPN	P1,CS.NUM	;NOW SET TO WRITE BACK THIS LINK
	JRST	OVR6GC		;DON'T BOTHER IF LINK 0
	PUSHJ	P,TR.WLK##	;GET PATH
	JUMPE	P2,OVR6GC	;DONE IF NONE LINKED TO IT
	ROT	P2,-1		;STORE 2 LINK# PER WORD
	SKIPGE	P2		;IF A REMAINDER
	ADDI	P2,1		;ADD ONE FOR IT
	MOVEI	T1,PH.ZZ
	HLL	T1,OVLBLK	;AND BLOCK#
	ADDI	P2,-1(T1)	;GET BYTE POINTER TO END
	MOVSM	T1,PH.FPT	;LIST IN FORWARDS DIRECTION
	HRLZM	P2,PH.BPT	;AND IN BACKWARDS DIRECTION
	ADD	P2,BRNTBL	;SO WE CAN STORE BACKWARDS
	TLOE	P2,(1B0)	;SEE WHICH HALF WORD TO START WITH
	IBP	P2		;STORE IN RIGHT HALF ON EVEN P2
	MOVS	T1,P1		;GET POINTER BACK
	HRRZ	T2,(T1)		;GET LINK #
	CAIN	T2,(P1)		;POINTING TO NON-TERMINAL LINK?
	MOVE	T1,1(T1)	;YES, GET BACK POINTER
	SETZM	(P2)		;MAKE SURE LAST LINK IS 0
OVR6GA:	HRRZ	T2,(T1)		;LINK#
	JUMPE	T2,OVR6GB	;DONE WHEN BACK TO 0
	IDPB	T2,P2		;STORE IT
	MOVE	T1,1(T1)	;GET BACK POINTER
	SOJA	P2,OVR6GA	;LOOP
OVR6GB:	HLRZ	T2,PH.BPT	;REL START IN BACK DIRECTION
	LSH	T2,-.DBS2W	;[650] IN BLOCKS
	HLRZ	T1,OVLBLK	;GET STARTING BLOCK#
	ADDI	T2,(T1)		;ACCOUNT FOR EXTRA BLOCKS USED (PERHAPS)
	HRRM	T2,PH.BPT	;AND STORE BLOCK#
OVR6GC:	USETO	OC,(R1)		;RESET BACK TO BLOCK WE NEED
	MOVE	T1,LC.LB
	SUBI	T1,1
	MOVE	T2,PH.CST	;[635] ADDR OF CONTROL SECTION
	SUB	T2,PH.ADD	;[635] OFFSET FROM START OF LINK
	ANDI	T2,.DBM		;[635] # WORDS BEFORE CS IN LC AREA
	ADD	T2,PH.ADD	;[635] PLUS LENGTH OF CS, INTTAB,
	ADD	T2,PH.LEN	;[635]   EXTTAB, AND ARL TABLE
	SUB	T2,PH.CST	;[635] ..
	IORI	T2,.DBM		;[635] TOTAL SIZE IN LC AREA TO OUTPUT
	MOVNI	T2,1(T2)	;[635] NEGATIVE FOR IOWD
	HRL	T1,T2		;IOWD
	SETZ	T2,
	OUT	OC,T1		;OUTPUT IT
	  JRST	OVR6H
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR
OVR6H:	SKIPE	T1,RT.PT	;RELOC TABLE TO PUT OUT?
	CAMN	T1,RT.LB	;..?
	JRST	OVR6S		;NO
	HRRZ	P3,PH.CST
	ADDI	P3,CS.PTR-CS.HDR+1	;BYPASS KNOWN ZEROS AND FIRST IBP
	PUSHJ	P,RT.P3##	;RESET IT
	MOVEI	T1,1		;RELOC BIT
	MOVE	T2,[CS.PTR-CS.HDR+1-CS.ZZ,,CS.PTR]	;AOBJN PTR
	SKIPE	0(T2)		;NEED TO RELOC
	DPB	T1,RT.PT	;YES
	IBP	RT.PT		;ADVANCE
	AOBJN	T2,.-3		;FOR ALL TABLE
	MOVE	T1,PH.ADD	;WHERE ADDRESS WOULD BE
	MOVE	T2,PH.CST	;BUT THIS IS LOWEST ADDRESS WE CARE ABOUT
	SUB	T2,T1		;I.E CST PLUS TABLES
	IDIVI	T2,.DBS*^D18	;[650] BYTES PER DSK BLOCK
	MOVE	T3,T2		;NO. OF WHOLE BLOCKS TO SKIP
	ADD	T3,PH.REL	;PLUS FIRST
	USETO	OC,(T3)		;SET ON IT
	IMULI	T2,.DBS		;[650] NO. OF WORDS TO SKIP
	HLRE	T1,PH.REL	;NO. OF WORDS ORIGINALLY
	ADD	T1,T2		;NO. LEFT
	HRLZ	T1,T1		;LHS OF IOWD
	HRR	T1,RT.LB
	HRRI	T1,-1(T1)	;IOWD AT LAST
	SETZ	T2,
	OUT	OC,T1
	  JRST	OVR6S		;OK
	PUSHJ	P,E$$OOV##	;[1174] THIS IS AN OUTPUT ERROR
;HERE TO CHECK IF SYMBOLS NEEDED, AND READ THEM IN IF SO.
;WE DO THIS BY FILLING THE LS AREA WITH TRIPLETS, CLEARING THE LC AREA,
;AND CALLING LSLOOP IN LNKXIT TO GENERATE A RUNTIME SYMBOL TABLE IN THE
;LC AREA.  WE DON'T ALLOW EITHER AREA TO PAGE.

OVR6S:	SKIPE	R,SYMSEG	;WANT TO KEEP SYMBOLS?
	SKIPN	T1,PH.SYM	;YES, BUT MAKE SURE THERE ARE SOME
	JRST	OVR6P		;NO
	SETZM	USYM		;THERE ARE NO UNDEFINED SYMBOLS IN THIS TABLE
	SETZM	NAMPTR		;THIS COULN'T BE VALID
	SETOM	LS.PP		;CAN'T PAGE LS NOW
	USETI	OC,(T1)		;SET ON SYMBOL BLOCK
	HLRE	T1,T1		;SIZE WE NEED
	MOVE	P2,LS.UB
	MOVEM	P2,LS.AB	;USE IT ALL
	SUB	P2,LS.LB	;SIZE WE HAVE
	ADD	P2,T1		;GET DIFF
	JUMPGE	P2,OVR6S1	;IS IT ENOUGH
	MOVEI	P1,LS.IX	;NO, GET AREA
	MOVM	P2,P2		;AND SIZE
	PUSHJ	P,LNKCOR##	;EXPAND
	  PUSHJ	P,E$$MEF##	;[1174] TOO BAD
OVR6S1:	HLRE	T1,PH.SYM	;GET -LENGTH AGAIN
	MOVM	T1,T1
	MOVE	T2,LS.UB	;TOP
	MOVEM	T2,LS.AB	;MAKE SURE THE SAME
	IORI	T1,.IPM		;ROUND UP
	SUB	T2,T1		;FIND WHERE LOWER BOUND SHOULD BE
	CAMN	T2,LS.LB	;ARE WE USING IT ALL
	JRST	.+3		;YES
	MOVEI	T1,-1(T2)	;HIGHEST TO GIVE BACK
	PUSHJ	P,GBCK.L##	;WILL RESET LS.LB
	SETZM	LS.PP		;LSLOOP KNOWS HOW TO PAGE
	MOVE	T1,LS.LB	;WHERE TO READ INTO
	SUBI	T1,1
	HLL	T1,PH.SYM	;IOWD
	SETZ	T2,
	IN	OC,T1		;READ BACK SYMBOLS
	  SKIPA	T1,LSYM		;OK, NOW TO RESET LAST SYM PTR
	PUSHJ	P,E$$IOV##	;[1174] ERROR
	SUB	T1,LW.LS	;SHOULD BE 0
	ADD	T1,LS.LB	;OFFSET IN CORE
	MOVEM	T1,LS.PT
				;NOW FOR LC AREA
				;WE ACTUALLY NEED ABOUT 2/3 THE LS SPACE
				;JUST ALLOCATE 1 BLOCK WE WILL EXPAND AS REQUIRED
	HRRZ	T1,TAB.LB(R)
	HRL	T1,T1
	HRRI	T1,1(T1)	;FORM BLT PTR
	SETZM	-1(T1)
	BLT	T1,@TAB.AB(R)	;ZERO AREA
	MOVE	T1,TAB.LB(R)	;NOW RESET ACTUAL BOUND
	MOVEM	T1,TAB.PT(R)	;ALSO FREE POINTER
	IORI	T1,.IPM		;USING ONLY ONE BLOCK
	MOVEM	T1,TAB.AB(R)
	MOVE	P3,PH.ADD	;SYMBOL TABLE STARTS AT REL 0
	SETZM	OVLOFF		; TO FAKE OUT RT.P3
	SKIPE	T1,RT.PT	;RELOCATABLE?
	CAMN	T1,RT.LB	;..
	JRST	OVR6L		;NO
	PUSHJ	P,RT.P3##	;YES, SETUP PTR
	MOVE	T1,RT.LB	;YES, MUST ZERO PREVIOUS JUNK
	HRL	T1,T1
	ADDI	T1,1
	SETZM	-1(T1)
	BLT	T1,@RT.AB	;AT LAST ITS DONE
OVR6L:	PUSHJ	P,LSOVX##	;[1172] INITIALIZE LNKXIT FOR LSLOOP CALL
	PUSHJ	P,LSLOOP##	;YES
	MOVE	T2,TAB.PT(R)	;FINAL LENGTH
	SUB	T2,TAB.LB(R)
	MOVN	T1,T2		;- LENGTH OF SYMBOLS
	HRLZ	T1,T1		; IN LHS FOR IOWD
	HRR	T1,OVLBLK	;BLOCK NUMBER
	MOVEM	T1,PH.RDX	;POINTER TO RADIX-50 SYMBOLS
	USETO	OC,(T1)		;SET ON IT
	ADDI	T2,.IPS
	LSH	T2,-.DBS2W	;[650] NO. OF BLOCKS
	ADDM	T2,OVLBLK	;ACCOUNT FOR THEM
	HRR	T1,TAB.LB(R)	;START OF CORE TO OUTPUT
	HRRI	T1,-1(T1)	;-1 OF COURSE
	SETZ	T2,		;TERMINATOR
	OUT	OC,T1		;OUTPUT IT
	  JRST	OVR6R		;OK
	PUSHJ	P,E$$OOV##	;[1174] FAILED
OVR6R:	SKIPE	T1,RT.PT	;ANY RELOCATION TABLES?
	CAMN	T1,RT.LB	;..
	JRST	OVR6P		;NO
	MOVEI	T1,1(T1)	;TOP
	SUB	T1,RT.LB	;- BOTTOM
	MOVEI	T2,.DBS(T1)	;[650] MAKE INTO BLOCKS (+ REMAINDER)
	MOVN	T1,T1		;-LENGTH
	HRLZ	T1,T1		; IN LHS FOR IOWD
	HRR	T1,OVLBLK	;POINT TO NEXT FREE BLOCK
	MOVEM	T1,PH.RDR	;STORE PTR
	USETO	OC,(T1)		;SET ON IT
	LSH	T2,-.DBS2W	;[650] INTO BLOCKS
	ADDM	T2,OVLBLK	;ACCOUNT FOR THEM
	HRR	T1,RT.LB	;BASE
	HRRI	T1,-1(T1)	;IOWD
	SETZ	T2,
	OUT	OC,T1		;OUTPUT
	  JRST	OVR6P		;FINISHED
	PUSHJ	P,E$$OOV##	;[1174] ERROR
OVR6P:	HLRZ	T1,OVLBLK	;BLOCK # OF PREAMBLE
	USETO	OC,(T1)		;SET BACK TO IT
	DMOVE	T1,PHIOWD
	SKIPN	T3,PH.BPT	;DO WE HAVE TO OUTPUT THE PATH?
	JRST	OVR6Z		;NO
	MOVN	T1,T3		;NEGATE
	HRLI	T3,PH.HDR	;SINCE GATHER WRITE DOESN'T WORK
	HRR	T3,BRNTBL	;WE MUST BLT THE STUFF TOGETHER
	HRRI	T1,-1(T3)	;COMPLETE IOWD
	BLT	T3,PH.ZZ(T1)
OVR6Z:	OUT	OC,T1
	  JRST	OVR6X		;NOW FIXUP CS.DDT IF REQUIRED
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR

OVR6X:	SKIPN	PH.RDX		;ANY RADIX-50 SYMBOLS
	JRST	OVR6		;NO, LOOP FOR ALL LINKS
	HRRZ	R1,PH.OVL	;BLOCK# OF CODE SECTION
	MOVE	T3,PH.CST	;ADDRESS OF HEADER
	SUB	T3,PH.ADD	;MINUS BASE
	ROT	T3,-.DBS2W	;[650] CONVERT TO BLOCKS
	ADDI	R1,(T3)		;POINT TO IT
	USETI	OC,(R1)		;SET ON IT
	LSH	T3,.DBS2W-^D36	;ANDI 177 WITH ORIGINAL T3
	MOVEI	T1,CS.DDT-CS.HDR(T3)	;GET NO. OF WORDS TO END
	IORI	T1,.DBM		;[650] INCASE IT CROSSES BLOCK BOUND
	MOVNI	T1,1(T1)	;IOWD
	HRL	T1,T1
	HRR	T1,LC.LB
	HRRI	T1,-1(T1)	;AT LAST
	SETZ	T2,
	IN	OC,T1
	  TDOA	T3,LC.LB		;ADDRESS OF CS.HDR
	PUSHJ	P,E$$IOV##	;[1174]
	MOVE	T2,PH.RDX	;GET SYMBOL TABLE PTR
	MOVEM	T2,CS.DDT-CS.HDR(T3)	;STORE
	USETO	OC,(R1)		;SET BACK
	SETZ	T2,
	OUT	OC,T1		;WRITE IT BACK
	  JRST	OVR6		;LOOP
	PUSHJ	P,E$$OOV##	;[1174]
OVR7:	SKIPN	TMAMAX		;[635] ANY %LNKTMA MESSAGES OUTPUT?
	JRST	OVR7C		;[635] NO, CONTINUE
E$$ABT::.ERR.	(MS,.EC,V%L,L%F,S%F,ABT,<Load aborted due to %LNKTMA errors, max. /ARSIZE: needed was >) ;[1174]
	.ETC.	(DEC,.EP,,,,TMAMAX)


;HERE TO OUTPUT THE DIRECTORY BLOCK
OVR7C:	MOVE	T1,[0,,DI.ZZ]	;[635] CODE ,, LENGTH
	MOVEM	T1,DI.HDR
	MOVE	T1,VERNUM	;GET VERSION#
	MOVEM	T1,DI.VER	;INTO DIRECTORY
	USETO	OC,1		;NOW FOR DIRECTORY BLOCK
	SKIPA	T1,.+1
	IOWD	DI.ZZ,DI.HDR	;VERY LOCAL CODE
	SETZ	T2,
	OUT	OC,T1
	  CAIA
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR
	MOVN	T1,L.MAX	;GET MAX LINKS ALLOWED
	HRLZ	T1,T1
	HRR	T1,LNKTBL	;ADDRESS OF IT
	HRRI	T1,-1(T1)	;IOWD
	SETZ	T2,
	OUT	OC,T1
	  CAIA
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR
;NOW FOR LINK NAMES, THERE WILL BE AT LEAST ONE (ROOT)
	MOVE	T1,DI.NPT	;GET AOBJN/USETO PTR
	USETO	OC,(T1)		;WHERE WE WILL START OUTPUT
	HLRE	T1,T1		;- NO. OF WORDS
	MOVM	T2,T1
	PUSHJ	P,DY.GET##	;GET BUFFER
	SUBI	T1,1		;BACKUP
	HLL	T1,DI.NPT	;FORM IOWD
	PUSH	P,T1		;SAVE I/O WORD FOR LATER
	MOVS	T2,LNMPTR	;GET INITIAL PTR TO NAMES
OVR7A:	DMOVE	T3,(T2)		;GET NAME AND LINK #
	HRRZ	T2,T4		;GET NEXT
	HLRZM	T4,1(T1)	;STORE NUMBER
	MOVEM	T3,2(T1)	; AND NAME
	JUMPE	T2,OVR7B	;END
	AOBJN	T1,.+1		;INCREMENT 
	AOBJN	T1,OVR7A	;TWICE
	HALT			;ERROR
OVR7B:	POP	P,T1		;GET BACK IOWD
	SETZ	T2,
	OUT	OC,T1		;OUTPUT IT
	  CAIA			;OK
	PUSHJ	P,E$$OOV##	;[1174] ERROR
	HLRE	T2,T1		;GET BACK LENGTH
	MOVM	T2,T2
	HRRZI	T1,1(T1)	;ADDRESS
	PUSHJ	P,DY.RET##
	SKIPE	IO.PTR+%VC	;SAVE SWITCH SEEN?
	JRST	OVR8		;YES
	MOVEI	T2,F.LEN	;NO, FAKE IT
	PUSHJ	P,DY.GET##	;SPACE FOR FILE SPEC
	MOVEM	T1,IO.PTR+%VC
	HRLZ	T2,IO.PTR+%OC
	HRR	T2,T1
	BLT	T2,F.LEN-1(T1)	;COPY OVERLAY SPEC
IFN FTEXE,<	MOVSI	T2,'EXE'>
IFE FTEXE,<	MOVSI	T2,'HGH'>	;ASSUME NOT SHAREABLE
	MOVEM	T2,I.EXT(T1)	; BUT MIGHT BE TWO SEG
	MOVEM	T2,SSEXT
	MOVE	T2,I.NAM(T1)	;GET OVERLAY NAME
	MOVEM	T2,SSNAME
	SETZM	I.EST(T1)
OVR8:	MOVE	T2,BRNLEN
	HRRZ	T1,BRNTBL
	PUSHJ	P,DY.RET##	;GIVE SPACE BACK
	MOVEI	T1,RT.IX	;DESTROY RT AREA NOW
	PUSHJ	P,XX.ZAP	;SO LNKMAP WILL HAVE MORE ROOM
	MOVE	T1,MAPSW	;SEE IF WE WANT A MAP
	CAMN	T1,[$MAPEND]	;AT THE END
	PUSHJ	P,LNKMAP	;YES
	MOVEI	T1,GS.IX	;WE CAN NOW REDUCE CORE
	PUSHJ	P,XX.ZAP##	;DELETE GLOBALS
	MOVEI	T1,FX.IX
	PUSHJ	P,XX.ZAP##	;AND FIXUP SPACE
	SETZ	P1,		;ALWAYS READ BACK
	PUSHJ	P,INPH		;ROOT PREAMBLE
	SKIPE	R,SYMSEG	;SAVING DDT SYMBOLS?
	SKIPN	T1,PH.RDX	;MAKE SURE ITS SETUP
	JRST	OVR8B		;NO?
	USETI	OC,(T1)		;SET ON BLOCK
	HLRE	T1,T1		;-SIZE WE NEED
	MOVE	P2,LS.UB
	MOVEM	P2,LS.AB	;USE IT ALL
	SUB	P2,LS.LB	;SIZE WE HAVE
	ADD	P2,T1		;GET DIFF
	JUMPGE	P2,OVR8A	;IS IT ENOUGH
	MOVEI	P1,LS.IX	;NO, GET AREA
	MOVM	P2,P2		;AND SIZE
	PUSHJ	P,LNKCOR##	;EXPAND
	  PUSHJ	P,E$$MEF##	;[1174] TOO BAD
OVR8A:	MOVE	T2,LS.UB	;GET TOP
	MOVEM	T2,LS.AB	;ALLOCATE IT ALL
	HLRE	T1,PH.RDX	;GET -LENGTH
	MOVM	T1,T1		;+
	MOVEM	T1,LSYM		;SET SIZE OF SYMBOL AREA
	MOVEM	T1,NAMPTR	;SET START OF CURRENT SYM
	IORI	T1,.IPM		;ROUND UP
	SUB	T2,T1		;FIND WHERE BOUND SHOULD BE
	CAMN	T2,LS.LB	;USED IT ALL?
	JRST	.+3		;YES
	MOVEI	T1,-1(T2)	;HIGHEST TO GIVE BACK
	PUSHJ	P,GBCK.L##
	MOVE	T1,LSYM		;LENGTH OF SYMBOLS
	SUB	T1,LW.LS	; - PART NOT IN CORE
	ADD	T1,LS.LB	;  + BASE OF AREA
	MOVEM	T1,LS.PT	;  YIELDS POINTER TO END
	SUB	T1,LS.AB	;= -AMOUNT LEFT TO TOP
	MOVMM	T1,LS.FR	;POSITIVE AMT FREE
	MOVE	T1,LS.LB	;BASE
	SUBI	T1,1
	HLL	T1,PH.RDX	;IOWD
	SETZ	T2,
	IN	OC,T1
	  JRST	LNKXIT		;OK, NOW EXIT
	PUSHJ	P,E$$IOV##	;[1174] ERROR

OVR8B:	MOVEI	T1,LS.IX	;NOW DELETE LOCAL SYMBOLS
	PUSHJ	P,XX.ZAP##	;TO GET AS MUCH SPACE AS POSSIBLE
	JRST	LNKXIT		;EXIT
RDCST::	PUSHJ	P,INPH		;READ IN PREAMBLE
	HRRZ	R1,PH.OVL	;BLOCK# OF CODE SECTION
	MOVE	T3,PH.CST	;ADDRESS OF CONTROL SECTION
	SUB	T3,PH.ADD	;MINUS BASE
	ROT	T3,-.DBS2W	;[650] CONVERT INTO BLOCKS
	ADDI	R1,(T3)		;POINT TO BLOCK CONTAINING THE CONTROL SECTION
	USETI	OC,(R1)		;SET ON IT
	LSH	T3,.DBS2W-^D36	;EQUIVALENT TO ANDI 177 WITH ORIGINAL T3
	MOVEI	T1,CS.ZZ(T3)	;GET NO. OF WORDS TO END
	IORI	T1,.DBM		;[650] INCASE CROSSES BLOCK BOUND
	HRLI	R1,1(T1)	;HOW MANY WORDS WE WILL READ
	MOVNI	T1,1(T1)
	HRL	T1,T1		;LH OF IOWD
	HRR	T1,LC.LB	;SAFE PLACE TO READ IT INTO
	HRRI	T1,-1(T1)	;AN IOWD AT LAST
	SETZ	T2,
	IN	OC,T1		;NOW FOR DATA
	  CAIA
	PUSHJ	P,E$$IOV##	;[1174] INPUT ERROR
	ADD	T3,LC.LB	;POINT TO FIRST CS WORD
	HRLZ	T1,T3
	HRRI	T1,CS.HDR	;FORM BLT WORD
	BLT	T1,CS.HDR+CS.ZZ-1
	HLRE	T1,CS.EXT	;NO. OF EXTTAB
	HLRE	T2,CS.INT	;SAME FOR INTTAB
	IMUL	T1,[-ET.ZZ]	;+ NUMBER OF WORDS
	IMUL	T2,[-2]
	ADD	T1,T2		;TOTAL NO. WE NEED
	HRRZ	T2,CS.EXT	;START OF EXTTABS
	JUMPN	T2,.+3		;MIGHT BE ZERO IF END OF PATH
	HRRZ	T2,CS.INT	;SO TRY INTTAB
	JUMPE	T2,CPOPJ	;GIVE UP IF NEITHER!
	SUB	T2,PH.ADD	;REL TO START OF FIRST BLOCK
	MOVE	R2,T2		;REL START OF EXTTAB
	ADD	T1,T2		;TOTAL WORDS WE NEED
	IORI	T1,.DBM		;[650] UPTO DSK BLOCK BOUND
	MOVE	T2,PH.CST	;NOW GET ADDRESS OF CS
	SUB	T2,PH.ADD	;REL TO LINK ORIGIN
	ANDCMI	T2,.DBM		;[650] ADDRESS OF FIRST LOC IN CORE
	SUB	R2,T2		;THENCE OFFSET TO EXTTAB
	HLRZ	T3,R1		;WORDS ALREADY READ
	ADDI	T2,-1(T3)	;WE HAVE THIS MUCH IN CORE ALREADY
	SUB	T1,T2		;SEE IF WE HAVE IT ALL
	JUMPE	T1,CPOPJ1	;YES
	ADD	T3,T1		;NEW WORDS COUNT
	HLRZ	P3,R1		;SAVE PREVIOUS SIZE
	HRL	R1,T3		;SAVE EXCESS
	MOVE	P2,LC.AB	;NOW SEE IF WE HAVE ENOUGH ROOM
	SUB	P2,LC.LB
	SUBI	P2,-1(P3)	;NOT COUNTING ALREADY USED
	CAMG	T1,P2		;WILL IT FIT?
	JRST	RDCST1		;YES
	SUBB	T1,P2		;NO, PUT DIFF IN P2 FOR LNKCOR
	MOVEI	P1,LC.IX
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,E$$MEF##	;[1174]
	HLRZ	T1,R1		;RESET EXCESS SIZE
	SUBI	T1,(P3)		;ONLY WANT EXTRA NEEDED
RDCST1:	MOVN	T1,T1		;USUAL CODE TO MAKE IOWD PTR
	HRL	T1,T1
	HRR	T1,LC.LB
	ADDI	T1,-1(P3)	;BYPASS WHAT WE ALREADY HAVE
	SETZ	T2,
	IN	OC,T1		;INPUT EXTTAB & INTTAB
CPOPJ1:	  AOSA	(P)
	PUSHJ	P,E$$IOV##	;[1174] INPUT ERROR
CPOPJ:	POPJ	P,

INPH::	ROT	P1,-1		;CUT IN HALF
	MOVE	T1,@LNKTBL	;PICKUP BLOCK #
	SKIPL	P1		;PICK CORRECT HALF
	MOVS	T1,T1
	ROT	P1,1		;PUT IT BACK
	USETI	OC,(T1)
	HRLM	T1,OVLBLK	;STORE BLOCK# OF PREAMBLE
	DMOVE	T1,PHIOWD
	IN	OC,T1		;INPUT PREAMBLE
	  POPJ	P,
	PUSHJ	P,E$$IOV##	;[1174] INPUT ERROR
RDREL:	MOVE	T1,RT.LB	;MAKE RT.PT SAME AS RT.LB
	MOVEM	T1,RT.PT	;TO INDICATE RT AREA EMPTY
	SKIPN	PH.REL		;IS IT RELOCATABLE?
	POPJ	P,		;NO
	MOVE	T1,PH.ADD	;WHERE ADDRESS WOULD BE
	MOVE	T2,PH.CST	;BUT THIS IS LOWEST ADDRESS WE CARE ABOUT
	SUB	T2,T1		;I.E CST PLUS TABLES
	IDIVI	T2,.DBS*^D18	;[650] BYTES PER DSK BLOCK
	MOVE	T3,T2		;NO. OF WHOLE BLOCKS TO SKIP
	ADD	T3,PH.REL	;PLUS FIRST
	USETI	OC,(T3)		;SET ON IT
	IMULI	T2,.DBS		;[650] NO. OF WORDS TO SKIP
	MOVEM	T2,OVLOFF	;SET BASE OFFSET
	HLRE	T1,PH.REL	;NO. OF WORDS ORIGINALLY
	ADD	T1,T2		;NO. LEFT
	JUMPGE	T1,[HALT .]	;ERROR
	MOVM	T2,T1		;+ NO.
	ADDM	T2,RT.PT	;UPDATE RT.PT TO SIZE USED
	HRLZ	T1,T1		;LHS OF IOWD
	SUB	T2,RT.AB
	ADD	T2,RT.LB	;SEE IF ENOUGH SPACE
	JUMPLE	T2,RDREL1	;YES
	DMOVE	P1,T1		;SAFE PLACE FOR IOWD & COUNT
	PUSHJ	P,RT.INC##	;EXPAND BY 1 BLOCK
	SUBI	P2,.IPS		;SHOULD BE ENOUGH
	JUMPG	P2,.-2		;LOOP IF NOT
	MOVE	T1,P1		;RECOVER IOWD
RDREL1:	HRR	T1,RT.LB
	HRRI	T1,-1(T1)	;IOWD AT LAST
	SETZ	T2,
	IN	OC,T1
	  POPJ	P,		;AREA IS NOW SETUP
	PJRST	E$$IOV##	;[1174] I/O ERROR
SUBTTL	THE END


OV2LIT:	END	LNKOV2