Google
 

Trailing-Edge - PDP-10 Archives - bb-l014r-bm_tops20_v6_1_atpch_18 - autopatch/lnkov2.x18
There are 3 other files named lnkov2.x18 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/PY/PAH/HD/RJF	19-Nov-87



;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1973,1986. ALL RIGHTS RESERVED.
;[2403]
;
;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.


SEARCH	LNKPAR,LNKLOW,OVRPAR,MACTEN,UUOSYM,SCNMAC
SALL

ENTRY	LNKOV2
EXTERN	LNKMAP,LNKXIT


CUSTVR==0		;CUSTOMER VERSION
DECVER==6		;DEC VERSION
DECMVR==0		;DEC MINOR VERSION
DECEVR==2416		;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).


;START OF VERSION 5
;1316	Add code to set up RC.HL for low and high segs from HP.S1 and HP.S2
;1400	Use OVRPAR.MAC and implement writable overlays.

;START OF VERSION 5.1
;1704	Writable overlay support.
;2026	Update copyright notice.
;2042	Protect pointers to GS and LC when calling TR.WLK.
;2053	Process deferred character fixups.

;Start of version 6
;2247	Use inferior fork on TOPS-20.
;2270	Remove the argument typechecking area to gain space.
;2403	New corporate copywrite statement.
;2416	IOWD size calculation wrong at OVR6GC+11.
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

;IOWD FOR PREAMBLE SECTION

IFE FTKIONLY,<
PHIOWD:	IOWD	PH.ZZ,PH	;[1400]
	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]
	MOVEI	T1,TP.IX	;[2270] NOW DELETE TYPECHECKING AREA
	PUSHJ	P,XX.ZAP##	;[2270] GET RID OF IT
IFN TOPS20,<			;[2247]
	MOVE	T1,LW.LC	;[2247] GET THE BOTTOM OF THE WINDOW
	SKIPE	T2,UW.LC	;[2247] AND THE TOP.  IS IT PAGING?
	 PUSHJ	P,LC.OUT##	;[2247] YES, DON'T WANT IT TO HERE
	SETZM	UW.LC		;[2247] SET NOT PAGING
>;[2247] IFN TOPS20
	MOVEI	R,1		;[1316] SET UP FOR LOW SEG
	MOVE	R,@SG.TB	;[1316]
	MOVE	T1,HP.S1	;[1316] GET .LOW. PSECT BREAK
	CAMLE	T1,RC.HL(R)	;[1316] IS IT HIGHER?
	MOVEM	T1,RC.HL(R)	;[1316] PUT IT IN THE PSECT BLOCK
	SKIPN	LL.S2		;[1316] IS THERE A HIGH SEG?
	JRST	OVR1		;[1316] NO - IGNORE HP.S2
	MOVEI	R,2		;[1316] SET UP FOR HIGH SEG
	MOVE	R,@SG.TB	;[1316]
	MOVE	T1,HP.S2	;[1316] GET .HIGH. PSECT BREAK
	CAMLE	T1,RC.HL(R)	;[1316] IS IT HIGHER?
	MOVEM	T1,RC.HL(R)	;[1316] PUT IT IN THE PSECT BLOCK
OVR1:	MOVE	T1,SYMSEG	;[1316] 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+DI.LPT	;[1400] 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+DI.NPT	;[1400] STORE IN DIRECTORY
	MOVE	T2,<WR.LEN/.DBS>;[1704] CALC NEXT FREE BLOCK
	HRRZS	T1		;[1704]
	ADD	T1,T2		;[1704]
	HRLI	T1,-WR.LEN	;[1704] LENGTH OF TABLE
	SKIPE	WRTDAT		;[1704] BUT ONLY IF WRITABLE
	MOVEM	T1,DI+DI.WPT	;[1704]
	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,INPH		;[2053] READ IN PREAMBLE
	SKIPE	P1,ARGFXP	;[2053] ANY CHARACTER FIXUPS?
	 PUSHJ	P,FIXARG	;[2053] YES, DO ANY FOR THIS OVERLAY
	PUSHJ	P,RDCST0	;[2053] 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+CS.EXT	;[1400] 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.LEN-1	;[1400] 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+CS.INT	;[1400] 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+CS.INT	;[1400]
	HRR	T1,CS+CS.NUM	;[1400] -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+CS.EXT
	JUMPGE	R2,OVR6D	;[1400] NO EXTTAB
	HRRZ	P3,CS+CS.EXT	;[1400] 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+CS.NUM	;[1400] ONLY WANT TO LOOK AT TREE ABOVE US
	JRST	OVR6CA		;ALL IS ABOVE ROOT
	PUSHJ	P,OVR6TW	;[2042] THESE ARE ONLY LINKS WE CAN REACH
	JUMPE	P2,[MOVE P2,CS+CS.NUM	;[1400] 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,OVR6TW	;[2042] 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.ADR(R2)	;[1400] STORE IT WITH 0 FLAGS
OVR6CC:	SETZM	ET.NAM(R2)	;CLEAR NAME NOW
OVR6CD:	SETBIT	<0,0,1,0>
	ADDI	R2,ET.LEN-1	;[1400]
	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.ADR(R2)	;[1400] 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+CS.NUM	;[1400] WE ONLY WANT TO LOOK AT TREE ABOVE US
	JRST	OVR6MA		;ALL OF TREE IS ABOVE ROOT
	PUSHJ	P,OVR6TW	;[2042] SINCE THESE ARE THE ONLY LINKS WE
				;CAN REACH, ALL OTHERS ARE NOT AVAILABLE
	JUMPE	P2,[MOVE P2,CS+CS.NUM	;[1400] 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,OVR6TW	;[2042] 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.ADR(R2)	;[1400] 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,OVR6TW	;[2042] 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+CS.RLC	;[1400] USE THIS TO POINT TO LIST
	HRL	T1,R2		;POINT TO WHICH ONE
	MOVEM	T1,(P3)		;STORE IN FIRST WORD
	HRRZM	P3,CS+CS.RLC	;[1400] 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.ADR(R2)	;[1400] 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

OVR6TW:	SUB	P3,GS.LB	;[2042] Subtract the base addresses
	SUB	R2,LC.LB	;[2042] Because TR.WLK calls DY.GET
	PUSHJ	P,TR.WLK##	;[2042] Walk the tree
	ADD	P3,GS.LB	;[2042] Add the base addresses back
	ADD	R2,LC.LB	;[2042] LC better not be paging!
	POPJ	P,		;[2042] And return
OVR6D:	HLRE	R3,CS+CS.INT	;[1400] GET NO. OF INTTAB ENTRIES
	IMUL	R3,[-2]		;[635] CONVERT TO WORDS
	ADD	R3,CS+CS.INT	;[1400] MAKE FIRST FREE AFTER INTTAB
	JUMPN	R3,OVR6DA	;[635] USE IT IF INTTAB EXISTS
	HLRE	R3,CS+CS.EXT	;[1400] OTHERWISE USE END OF EXTTAB
	IMUL	R3,[-ET.LEN]	;[1400] WORDS IN EXTTAB
	ADD	R3,CS+CS.EXT	;[1400] 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+CS.INT	;[1400] GET NO. OF INTTABS
	JUMPGE	R2,OVR6FA	;NONE
	HRRZ	R3,R2		;USED TO STORE BACK IF REQUIRED
	HRRZ	P3,CS+CS.INT	;[1400] 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+CS.INT	;[1400] MAKE THIS RIGHT
OVR6FA:	SKIPN	P1,CS+CS.RLC	;[1400] ANY MULTIPLY DEF GLOBALS?
	JRST	OVR6G		;NO
	SETZ	P3,		;[635] INDICATE NO TMA ERROR YET
	HLRE	R3,CS+CS.INT	;[1400] THESE WILL GO AT END OF TABLES
	IMUL	R3,[-2]
	ADD	R3,CS+CS.INT	;[1400]
	JUMPN	R3,OVR6FB	;BUT IF NO INTTAB
	HLRE	R3,CS+CS.EXT	;[1400]   USE EXTTAB
	IMUL	R3,[-ET.LEN]	;[1400]
	ADD	R3,CS+CS.EXT	;[1400]
OVR6FB:	MOVE	T1,0(P1)	;GET NEXT PTR
	HRRZM	T1,CS+CS.RLC	;[1400] 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+CS.RLC	;[1400] 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+PH.LLN	;[1400] GET LENGTH
	HRLM	T1,CS+CS.COR	;[1400] INTO CONTROL SECTION
	MOVE	T1,PH+PH.CST	;[1400] NOW TO COPY CS BACK
	SUB	T1,PH+PH.ADD	;[1400]
	ANDI	T1,.DBM		;[743] MAKE REL TO THIS BLOCK
	ADD	T1,LC.LB	;FIX IN CORE
	MOVEI	T2,CS.LEN-1(T1)	;[1400] END OF BLT
	HRLI	T1,CS		;[1400]
	BLT	T1,(T2)		;MOVE IT ALL
	SKIPN	P1,CS+CS.NUM	;[1400] 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+PH.FPT	;[1400] LIST IN FORWARDS DIRECTION
	HRLZM	P2,PH+PH.BPT	;[1400] 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+PH.BPT	;[1400] 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+PH.BPT	;[1400] AND STORE BLOCK#
OVR6GC:	USETO	OC,(R1)		;RESET BACK TO BLOCK WE NEED
	MOVE	T1,LC.LB
	SUBI	T1,1
	MOVE	T2,PH+PH.CST	;[1400] ADDR OF CONTROL SECTION
	SUB	T2,PH+PH.ADD	;[1400] OFFSET FROM START OF LINK
	ANDI	T2,.DBM		;[635] # WORDS BEFORE CS IN LC AREA
	ADD	T2,PH+PH.ADD	;[1400] PLUS LENGTH OF CS, INTTAB,
	ADD	T2,PH+PH.LLN	;[1400]   EXTTAB, AND ARL TABLE
	SUB	T2,PH+PH.CST	;[1400] ..
	MOVNS	T2		;[2416] NEGATIVE FOR IOWD
	TRZ	T2,.DBM		;[2416] NEGATIVE SIZE IN FULL BLOCKS
	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+PH.CST	;[1400]
	ADDI	P3,CS.PTR+1	;[1400] BYPASS KNOWN ZEROS AND FIRST IBP
	PUSHJ	P,RT.P3##	;RESET IT
	MOVEI	T1,1		;RELOC BIT
	MOVE	T2,[CS.PTR+1-CS.LEN,,CS+CS.PTR]	;[1400] 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+PH.ADD	;[1400] WHERE ADDRESS WOULD BE
	MOVE	T2,PH+PH.CST	;[1400] 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+PH.REL	;[1400] PLUS FIRST
	USETO	OC,(T3)		;SET ON IT
	IMULI	T2,.DBS		;[650] NO. OF WORDS TO SKIP
	HLRE	T1,PH+PH.REL	;[1400] 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+PH.SYM	;[1400] 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+PH.SYM	;[1400] 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+PH.SYM	;[1400] 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+PH.ADD	;[1400] 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+PH.RDX	;[1400] 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+PH.RDR	;[1400] 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+PH.BPT	;[1400] DO WE HAVE TO OUTPUT THE PATH?
	JRST	OVR6Z		;NO
	MOVN	T1,T3		;NEGATE
	HRLI	T3,PH		;[1400] 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-1(T1)
OVR6Z:	OUT	OC,T1
	  JRST	OVR6X		;NOW FIXUP CS.DDT IF REQUIRED
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR

OVR6X:	SKIPN	PH+PH.RDX	;[1400] ANY RADIX-50 SYMBOLS
	JRST	OVR6		;NO, LOOP FOR ALL LINKS
	HRRZ	R1,PH+PH.OVL	;[1400] BLOCK# OF CODE SECTION
	MOVE	T3,PH+PH.CST	;[1400] ADDRESS OF HEADER
	SUB	T3,PH+PH.ADD	;[1400] 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(T3)	;[1400] 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	;[1400] ADDRESS OF CONTROL SECTION
	PUSHJ	P,E$$IOV##	;[1174]
	MOVE	T2,PH+PH.RDX	;[1400] GET SYMBOL TABLE PTR
	MOVEM	T2,CS.DDT(T3)	;[1400] 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,[700,,DI.LEN];[1400] CODE ,, LENGTH
	MOVEM	T1,DI+DI.HDR	;[1400]
	MOVE	T1,VERNUM	;GET VERSION#
	MOVEM	T1,DI+DI.VER	;[1400] INTO DIRECTORY
	MOVE	T1,OVERLW	;[1400] COPY IMPORTANT FLAGS TO DIRECTORY
	SETZ	T2,		;[1400]   ..
	TXNE	T1,$OVRELOCATABL;[1400]   RELOCATABLE OVERLAYS
	TXO	T2,OD.RLC	;[1400]   ..
	TXNE	T1,$OVWRITABLE	;[1400]   WRITABLE OVERLAYS
	TXO	T2,OD.WRT	;[1400]   ..
	MOVEM	T2,DI+DI.FLG	;[1400]   ..
	USETO	OC,1		;NOW FOR DIRECTORY BLOCK
	SKIPA	T1,.+1
	IOWD	DI.LEN,DI	;[1400] 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+DI.NPT	;[1400] 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+DI.NPT	;[1400] 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##
OVR7D:	SKIPN	T1,DI+DI.WPT	;[1704] WRITABLE OVERLAYS INVOLVED?
	JRST	OVR7E		;[1704] NO, GO ON
	USETO	OC,(T1)		;[1704] GET TO BLOCKBOUND
	SETZ	T2,		;[1704] TERMINATE IOWD LIST
	HRR	T1,WRTDAT	;[1704] CONSTRUCT IOWD
	SUBI	T1,1		;[1704]
	OUT	OC,T1		;[1704] WRITE IT
	  CAIA			;[1704] OKAY
	PUSHJ	P,E$$OOV##	;[1704] ERROR
	HRRZ	T1,WRTDAT	;[1704] RETURN THE BLOCK NOW
	MOVEI	T2,WR.LEN	;[1704]
	PUSHJ	P,DY.RET##	;[1704] ...
OVR7E:	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+PH.RDX	;[1400] 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+PH.RDX	;[1400] 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+PH.RDX	;[1400] 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
RDCST0:	HRRZ	R1,PH+PH.OVL	;[2053] BLOCK# OF CODE SECTION
	MOVE	T3,PH+PH.CST	;[1400] ADDRESS OF CONTROL SECTION
	SUB	T3,PH+PH.ADD	;[1400] 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.LEN(T3)	;[1400] 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		;[1400] FORM BLT WORD
	BLT	T1,CS+CS.LEN-1	;[1400]
	HLRE	T1,CS+CS.EXT	;[1400] NO. OF EXTTAB
	HLRE	T2,CS+CS.INT	;[1400] SAME FOR INTTAB
	IMUL	T1,[-ET.LEN]	;[1400] + NUMBER OF WORDS
	IMUL	T2,[-2]
	ADD	T1,T2		;TOTAL NO. WE NEED
	HRRZ	T2,CS+CS.EXT	;[1400] START OF EXTTABS
	JUMPN	T2,.+3		;MIGHT BE ZERO IF END OF PATH
	HRRZ	T2,CS+CS.INT	;[1400] SO TRY INTTAB
	JUMPE	T2,CPOPJ	;GIVE UP IF NEITHER!
	SUB	T2,PH+PH.ADD	;[1400] 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+PH.CST	;[1400] NOW GET ADDRESS OF CS
	SUB	T2,PH+PH.ADD	;[1400] 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+PH.REL	;[1400] IS IT RELOCATABLE?
	POPJ	P,		;NO
	MOVE	T1,PH+PH.ADD	;[1400] WHERE ADDRESS WOULD BE
	MOVE	T2,PH+PH.CST	;[1400] 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+PH.REL	;[1400] 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+PH.REL	;[1400] 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
;[2053] Here to do the deferred character fixups.
;[2053] P1 contains the pointer to the first character fixup block.
;[2053] Each character fixup requires two addresses. To minimize
;[2053] disk I/O, there are two buffers kept. The block number of
;[2053] the argument descriptor is in R1, and the block of the
;[2053] character string descriptor is in R2, unless they are the
;[2053] same block. The character fixup blocks are built at COEOVL
;[2053] in LNKOV1.

FIXARG:	HLRZ	T1,TPCAD(P1)	;[2053] Get the overlay number
	CAME	T1,LNKNO.	;[2053] Fixups for this overlay?
	 POPJ	P,		;[2053] No
	SETZB	R1,R2		;[2053] Remember no blocks read yet
FXARG1:	HRRZ	T1,TPCAD(P1)	;[2053] Get the address
	PUSHJ	P,FIXAD1	;[2053] Get it into memory
	MOVE	P2,T1		;[2053] Keep it safe
	HRRZ	T1,(T1)		;[2053] Get the address of the
				;[2053] string descriptor
	PUSHJ	P,FIXAD2	;[2053] Get it into memory
	HRRZ	T1,(T1)		;[2053] Get the start address of the string
	HRLI	T1,(<Z 17,>+1B0);[2053] Make it an ascii descriptor
	MOVEM	T1,(P2)		;[2053] Put it back in memory
	MOVE	T1,P1		;[2053] Get the address of this block
	MOVEI	T2,TPCBK	;[2053] And the size
	HRRZ	P1,TPCLK(P1)	;[2053] Get the next block
	PUSHJ	P,DY.RET##	;[2053] Return this block
	JUMPE	P1,FXARG2	;[2053] Check for no more blocks
	HLRZ	T1,TPCAD(P1)	;[2053] Get the overlay number
	CAMN	T1,LNKNO.	;[2053] For this overlay?
	 JRST	FXARG1		;[2053] Yes, do another
FXARG2:	MOVEM	P1,ARGFXP	;[2053] Put the chain back
	USETO	OC,(R1)		;[2053] Set to output last block
	MOVE	T1,LC.LB	;[2053] Get the location in memory
	SUBI	T1,1		;[2053] As an IOWD
	HRLI	T1,-.DBS	;[2053] One block
	SETZ	T2,		;[2053] Terminate the IO list
	OUT	OC,T1		;[2053] Write it
	POPJ	P,		;[2053] OK, Return
	PUSHJ	P,E$$OOV##	;[2053] Error

;[2053] FIXAD1 brings a location in the overlay into a read/write
;[2053] block of memory. If the block contains another page of the
;[2053] overlay file, it writes the block back into the file first.
;[2053] Accepts an address in T1. Returns with updated address
;[2053] in T1.

FIXAD1:	HRRZ	T3,PH+PH.OVL	;[2053] Block number of code section
	SUB	T1,PH+PH.ADD	;[2053] Minus base
	PUSH	P,T1		;[2053] Save the offset
	ROT	T1,-.DBS2W	;[2053] Convert into blocks
	ADDI	T3,(T1)		;[2053] Point to block desired code
	JUMPE	R1,FXAD1A	;[2053] Always read if nothing in yet
	CAIN	R1,(T3)		;[2053] Is it already in memory?
	 JRST FXAD1B		;[2053] Yes, don't read it again
	USETO	OC,(R1)		;[2053] Set on it
	MOVE	T1,LC.LB	;[2053] Get the location in memory
	SUBI	T1,1		;[2053] As an IOWD
	HRLI	T1,-.DBS	;[2053] One block
	SETZ	T2,		;[2053] Terminate the IO list
	OUT	OC,T1		;[2053] Write it
	  CAIA			;[2053] Okay
	PUSHJ	P,E$$OOV##	;[2053] Error
FXAD1A:	HRRZ	R1,T3		;[2053] Remember the new block
	USETI	OC,(R1)		;[2053] Set on it
	MOVE	T1,LC.LB	;[2053] Get the location in memory
	SUBI	T1,1		;[2053] As an IOWD
	HRLI	T1,-.DBS	;[2053] One block
	SETZ	T2,		;[2053] Terminate the IO list
	IN	OC,T1		;[2053] Read it
	 CAIA			;[2053] Okay
	PUSHJ	P,E$$IOV##	;[2053] Error
FXAD1B:	POP	P,T1		;[2053] Get back the offset
	ANDI	T1,.DBM		;[2053] Get the offset within the block
	ADD	T1,LC.LB	;[2053] The block is in the LC area
	POPJ	P,		;[2053] Done

;[2053] FIXAD2 brings a location in the overlay into memory.
;[2053] If the desired location is already in the read/write 
;[2053] block, it uses that, otherwise it reads it into a
;[2053] read only block if it is not there yet. Accepts an
;[2053] address in T1. Returns with updated address in T1.

FIXAD2:	HRRZ	T3,PH+PH.OVL	;[2053] Block number of code section
	SUB	T1,PH+PH.ADD	;[2053] Minus base
	PUSH	P,T1		;[2053] Save the offset
	ROT	T1,-.DBS2W	;[2053] Convert into blocks
	ADDI	T3,(T1)		;[2053] Point to block desired code
	CAIN	R1,(T3)		;[2053] Is it already in memory?
	 JRST	FXAD1B		;[2053] Yes, in the read/write block
	JUMPE	R2,FXAD2A	;[2053] Always read if nothing in yet
	CAIN	R2,(T3)		;[2053] Is it already in memory?
	 JRST FXAD2B		;[2053] Yes, don't read it again
FXAD2A:	MOVE	R2,T3		;[2053] Remember the new block
	USETI	OC,(R2)		;[2053] Set on it
	MOVE	T1,LC.LB	;[2053] Get the location in memory
	ADDI	T1,.DBS-1	;[2053] Second block of LC, as an IOWD
	HRLI	T1,-.DBS	;[2053] One block
	SETZ	T2,		;[2053] Terminate the IO list
	IN	OC,T1		;[2053] Read it
	 CAIA			;[2053] Okay
	PUSHJ	P,E$$IOV##	;[2053] Error
FXAD2B:	POP	P,T1		;[2053] Get back the offset
	ANDI	T1,.DBM		;[2053] Get the offset within the block
	ADD	T1,LC.LB	;[2053] The block is in the LC area
	ADDI	T1,.DBS		;[2053] In the second block
	POPJ	P,		;[2053] Done
SUBTTL	THE END


OV2LIT:	END	LNKOV2