Google
 

Trailing-Edge - PDP-10 Archives - BB-BT99U-BB_1990 - 10,7/link/lnkov1.mac
There are 48 other files named lnkov1.mac in the archive. Click here to see a list.
TITLE LNKOV1 - PHASE 1 OVERLAY MODULE FOR LINK
SUBTTL	D.M.NIXON/DMN/JLd/RKH/JBC/JNG/MCHC/DZN/PY/PAH/HD/RJF 30-MAR-90


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


SEARCH	LNKPAR,LNKLOW,OVRPAR,MACTEN,UUOSYM,SCNMAC
IFN TOPS20,<	SEARCH MONSYM	>	;[1506]
SALL

ENTRY	LNKOV1
EXTERN	LNKLOD,LNKWLD,LNKOV2


CUSTVR==0		;CUSTOMER VERSION
DECVER==6		;DEC VERSION
DECMVR==0		;DEC MINOR VERSION
DECEVR==2424		;DEC EDIT VERSION

VERSION


SEGMENT


;LOCAL ACC DEFINITIONS

R=:R1		;CURRENT RELOCATION COUNTER
SUBTTL	REVISION HISTORY


;START OF VERSION 2
;135	ADD OVERLAY FACILITY
;136	FIX VARIOUS BUGS
;170	MAKE PLOT SWITCH WORK
;174	FIX RELOCATABLE OVERLAY BUGS
;175	REPLACE /RESET WITH /NODE
;200	LOAD REENTRANT OVERLAY HANDLER
;207	REDUCE SIZE OF OVERHEAD TABLES
;216	(13559) ADD ZSV ERROR CHECKS

;START OF VERSION 2B
;237	(13931) CHANGE RPR ERROR TO NBR
;245	MAKE OVERLAY FILE STAY ON SAME STRUCTURE ON SUPERSEDE
;	MODIFY OC.OPN ROUTINE TO CHECK THIS CASE
;262	Force a /LINK on encountering /NODE, if needed
;300	Fix copy of permanent excludes on /OVERLAY
;331	Set size of segment correctly so don't loose
;	EXTTAB and ENTTAB'S.
;352	LABEL EDIT 237
;404	Put edit 316 back in to LINK.
;407	Correct problem with /NODE:-1
;413	Fix some small bugs with ELN message.
;414	Make sure FUNCT. is loaded in the root link.
;416	Update GS.FR instead of GS.PT when creating bound globals.
;425	Improve FSN error detect to not bomb users unnecessarily.

;START OF VERSION 2C
;466	Avoid loop on /NODE when loading relocatable overlays.
;504	Get output IOWD right when putting symbols in overlay file.
;505	Fix absolute addresses after call to LNKCOR via SY.CHR.
;511	Overlap by 1 page when copying LS to overlay file for fixups.
;521	Zap MNSEEN and MNTYPE on /LINK.
;530	Get triplet flag definitions right.
;534	Make multiple /LINK switches work on one line.
;557	Clean up the 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
;605	Use OUTSTR in LNKRER message.
;623	Handle multiple /PLOT switches (delete data block)
;625	Print blank line after LNKELN message
;631	Print correct file spec with LNKEOV message.
;632	Implement $FIXUP.
;635	Add code to handle /ARSIZE switch, and count any
;	ambiguous request table space in previous link.
;650	Use VM on TOPS-10 if available.
;651	Put the overlay file where the user wants it.
;660	Clear .LINK storage at the end of an overlay.
;664	Don't destroy last word of BG area on /NODE:0.
;665	Fix core management problem broken by edit 650.
;666	Fix edits 650 and 665, this time for sure.
;671	Don't leave junk in PH.ORL.
;677	Don't default to /SYMSEG:LOW if loading overlays.
;730	Check for /DEBUG, do it before /LINK.
;731	SEARCH MACTEN,UUOSYM
;765	Release on both TOPS-10 and TOPS-20 as LINK version 4(765)

;START OF VERSION 4A
;1152	Set up RC.HL correctly on /LINK and /NODE.
;1172	Allocate PAT.. in the root.
;1174	Label and clean up all error messages.
;1201	Change $SEGxxx to $SSGxxx.
;1204	Say LNKPTL if /SPACE or /PATCHSIZE exceeds 777777.
;1205	Don't waste blocks in the overlay file.
;1214	Fix mismatched angle bracket bugs.
;1217	Clean up the listings for release.
;1220	Release on both TOPS-10 and TOPS-20 as version 4A(1220).


;START OF VERSION 4B
;1226	Default /SEGMENT:LOW after loading the root.
;1230	Really put the overlay file where the user wants it (see edit 651).
;1232	Handle symbolic start address in LINKGT.
;1247	Add check for /SYMSEG:HIGH or /SYMSEG:PSECT: with overlays.
;1257	Store RC.HL from absolute code after loading root node.
;1263	Don't change LSTSYM if not new symbol.
;1265	Put .SYM file name in OWN block in Algol program.
;1266	Fix loop when local symbols can't all be read in at once.
;1310	Make LNKOFS message use long error text.

;START OF VERSION 5
;1400	Use OVRPAR.MAC and implement writable overlays.
;1424	Implement /MAXNODE.
;1447   Move /MAXNODE support into LNKWLD.

;START OF VERSION 5.1
;1506	Conditionalize TOPS-10 specific code and nativize LS overflow area
;1514	Unmap, don't BLT to zero the LC area excess when shrinking LC
;1537	Remove unnecessary AOSA when setting up PMAP arguments.
;1541	Unmap overflow windows before deleting overflow files (TOPS-20)
;1704	Writable overlay support work.
;1710	Don't miss last writable overlay link.
;2002	Implement /PLTTYP switch.
;2007	Give LNKTML a long message.
;2011	Remove /PLTTYP code, put it in LNKWLD.
;2026	Update copyright notices, cleanup listing.
;2033	Keep LW.LS page aligned on TOPS-20.
;2053	Argcheck the BG area, and build deferred character fixups.
;2076	Check IO.PTR+%PC not NULSPC for previously seen file spec in %PLOT.

;Start of version 6
;2202	Use 30 bit addresses when calling xx.IN and xx.OUT, remove bare PMAPs.
;2214	Add 30 bit fixups, which relocate like halfwords in overlays.
;2235	Give error if overlays used with extended addressing.
;2247	Use inferior fork on TOPS-20.
;2251	Set PM%CNT before mapping out pages.
;2255	Use LSTLCL and LSTGBL instead of LSTSYM.
;2262	Check for PG.LSG returning all memory asked for.
;2316	Don't check lower bound after PG.LSG, just upper.  Lower is always OK.
;2366	Check for overlays outside section zero on TOPS-10.
;2403	New corporate copywrite statement.
;2417	Update copywrite statement to 1988.
;2420	Reset LC.UP when a .TMP file is discarded.
;2424	Edit 2423 broke some switches on the -10 & -20  since we make dummy
;	scan blocks that have no spec but never turn on FX.NDV in F.MOD.
;	Hence, we did not ignore then as null specs.

SUBTTL	ENTRY POINT


LNKOV1:	JFCL	.+1		;NORMAL ENTRY
	JRST	LNKLOD

;IOWD FOR PREAMBLE SECTION

IFE FTKIONLY,<
PHIOWD:	IOWD	PH.ZZ,PH	;[1400]
	0
>
IFN FTKIONLY,<EXTERN	PHIOWD>		;BUG IN DMOVE MACRO
SUBTTL	SWITCH ACTION -- /OVERLAY:key


.OVERLAY::
	HRLZ	T1,(P2)		;GET NEXT SWITCH
	HLLM	T1,1(P1)	;FIX LIST OF SWITCHES TO DO
	JRST	OVRLAY

%OVERLAY::
	HRRZ	T1,(P2)		;GET NEXT SWITCH
	HRRM	T1,1(P1)	;FIX LIST OF SWITCHES TO DO
;	JRST	OVRLAY

OVRLAY: 
IFN TOPS20,<			;[2366]
	MOVE	T1,FXSBIT	;[2235] GET THE SECTION BITS
	TDNE	T1,[^-1B0]	;[2235] ANY NON-ZERO SECTIONS?
	 PUSHJ	P,E$$CBO##	;[2235] YES, GIVE ERROR
>;[2366] IFN TOPS20

IFE TOPS20,<			;[2366]
	MOVE	T1,HL.S1	;[2366] GET THE HIGHEST LOADED
	TLNE	T1,-1		;[2366] OUTSIDE OF SECTION ZERO?
	 PUSHJ	P,E$$CBO##	;[2366] YES, GIVE ERROR
>;[2366] IFE TOPS20

	MOVE	T1,OVLTBL-1(T2)	;GET BIT
	IORM	T1,OVERLW	;SET IN MEMORY
	SKIPE	IO.PTR+%OC	;ALREADY SET ONCE?
	JRST	OVRLA1		;YES, JUST RETURN
	MOVEI	T1,.DBS		;[1424] SET MAXIMUM LINK NUMBER
	SKIPN	L.MAX		;[1424] UNLESS ALREADY SET
	MOVEM	T1,L.MAX	;[1424] ...
	MOVE	T1,SYMSEG	;[1247] GET SYMBOL SEGMENT LOCATION
	JUMPL	T1,.+3		;[1247] /SYMSEG:PSECT?
	CAIE	T1,$SSGHIGH	;[1247] /SYMSEG:HIGH?
	JRST	OVSYMS		;[1247] NO - IT'S OK
E01OSL::.ERR.	(MS,,V%L,L%W,S%W,OSL,) ;[1247]
	MOVEI	T1,$SSGLOW	;[1247]	GET /SYMSEG:LOW
	MOVEM	T1,SYMSEG	;[1247] FORCE SYMBOLS THERE
OVSYMS:	MOVSI	T1,'OVL'	;[1247] FORCE EXTENSION
	MOVEM	T1,F.EXT(P1)
	PUSHJ	P,DVOUT.##	;SETUP DATA BLOCK
	  %OC,,.IODPR
	MOVE	T1,IO.CHR	;[1230] MAKE SURE DEVICE IS A DISK
	TLC	T1,-1-<(DV.TTA)>;[1230]   ..
	TLCE	T1,-1-<(DV.TTA)>;[1230]   ..
	TXNN	T1,DV.DSK	;[1230]   ..
	JRST	E$$OFS		;[1230] OVERLAY HANDLER ASSUMES A DISK
	HRLZI	T1,2(P1)	;CLEAR ALL BUT LINK AND SWITCH
	HRRI	T1,3(P1)
	SETZM	2(P1)
	BLT	T1,F.LEN-1(P1)
	MOVX	T1,FX.NDV	;[2424] REMEMBER USER DIDN'T REALY
	IORM	T1,F.MOD(P1)	;[2424] TYPE ANY SPEC HERE (IE. NO DEVICE).
	PUSHJ	P,OVRTST	;PUT REQUEST IN SYMBOL TABLE
	HLLZ	T1,INCPTR	;SEE IF ANY VERY PERM INCLUDES
	JUMPE	T1,OVRLA0	;NO INCLUDES, TRY EXCLUDES
	MOVEI	T2,.EXC		;YES, GET SPACE
	PUSHJ	P,DY.GET##
	HRLZM	T1,OVINEX	;SAVE START OF LIST
	HLLZ	T2,INCPTR	;START OF LIST
	HRR	T2,T1		;WHERE TO PUT IT
	BLT	T2,.EXC-1(T1)	;DO MOVE
	HRRZ	T2,(T1)		;SEE IF MORE
	JUMPE	T2,OVRLA0	;NO
	PUSHJ	P,OVRINX	;YES, COPY REST
;HERE TO SAVE SUPER-GLOBAL EXCLUDES, IF ANY EXIST.

OVRLA0:	HLLZ	T1,EXCPTR	;ANY EXCLUDES
	JUMPE	T1,OVRLA1	;NO
	MOVEI	T2,.EXC		;YES, GET SPACE
	PUSHJ	P,DY.GET##
	HRRM	T1,OVINEX	;SAVE START OF LIST
	HLLZ	T2,EXCPTR	;START OF LIST
	HRR	T2,T1		;WHERE TO PUT IT
	BLT	T2,.EXC-1(T1)	;DO MOVE
	HRRZ	T2,(T1)		;SEE IF MORE
	JUMPE	T2,OVRLA1	;NO
	PUSHJ	P,OVRINX	;YES, COPY REST
OVRLA1:	HRLS	ARSIZE		;[635] STORE STICKY /ARSIZE
	SUB	P,[2,,2]	;ADJUST STACK
	MOVE	T1,P2		;ADDRESS OF SWITCH BLOCK
	HLRZ	T2,(P2)		;SIZE
	PUSHJ	P,DY.RET##	;GIVE IT BACK
	HLLZ	T1,FL		;GET PERMANENT FLAGS TO DATE
	IORM	T1,FLAGS	;SAVE SO AS TO AFFECT ALL LINKS
	JRST	LNKWLD		;RETURN & TRY AGAIN

OVRTST:	PUSHJ	P,.SAVE4##	;SAVE THE P'S
	MOVX	W1,PT.SGN!PT.SYM
	MOVE	W2,['.OVRLA']	;ENTRY POINT
	SETZ	W3,
	PUSHJ	P,TRYSYM##	;SEE IF DEFINED
	  PJRST	SY.RQ##		;UNDEF, ENTER REQUEST
	  POPJ	P,		;ALREADY UNDEFINED
	POPJ	P,		;ALREADY DEFINED

OVRINX:	SPUSH	<T2,T1>		;SAVE THE POINTERS
	MOVEI	T2,.EXC		;GET ANOTHER BLOCK
	PUSHJ	P,DY.GET##
	POP	P,T2		;GET LAST NEW BLOCK
	HRRM	T1,(T2)		;LINK THIS TO IT
	POP	P,T2		;NEXT BLOCK IN ORIGINAL LIST
	HRLZ	T3,T2		;FROM
	HRR	T3,T1		;TO
	BLT	T3,.EXC-1(T1)
	HRRZ	T2,(T1)		;GET NEXT
	JUMPN	T2,OVRINX	;YES THERE IS
	POPJ	P,		;RETURN

E$$OFS::.ERR.	(MS,0,V%L,L%F,S%F,OFS,<Overlay file must be created on a file structure>) ;[1310]

DEFINE KEYMAC (A,B)<
 IFIDN <A><OVL>,<
  A'TBL:
  IRP B,<
   EXP $OV'B
>>>

	XALL
	KEYWORDS
	SALL
SUBTTL	SWITCH ACTION -- /LINK:name


%LINK::
	SKIPN	T1,S.DEBG	;[730] HAVE WE SEEN A /DEBUG?
	JRST 	%LINK1		;[730] NO, JUMP
	SETZM	S.DEBG		;[730] YES, CLEAR FLAG
	MOVEI	T2,0(P2)	;[730] GET CURRENT /LINK SWITCH PTR
	HRRM	T2,1(T1)	;[730] CHAIN INTO /DEBUG FILE SPEC AS LOCAL SW
	HRRZ	T2,(P2)		;[730] MOVE PTR OF NEXT SWITCH INTO AN AC
	HLLZS	0(P2)		;[730] BEFORE IT GET CLEARED
	MOVE	P2,T2		;[730] UPDATE CURRENT SWTICH PTR WITH IT
	POPJ	P,		;[730] RETURN
%LINK1:				;[730] 
	JUMPN	T2,.+3		;NAME ALREADY SET?
	SKIPGE	LNKMAX		;NO, SO IS IT FIRST TIME?
	MOVE	T2,['ROOT  ']	;YES, PREEMPT NAME "ROOT"
	MOVEM	T2,LNKNAM	;STORE NAME OR ZERO
	MOVEI	T1,LINKTO	;HERE ON TERMINATION
	MOVEM	T1,GOTO
	SETOM	S.INZR		;FLAG RETFSP TO END LINE IN LNKWLD
	JUMPE	T2,CPOPJ	;NO NAME
	PUSHJ	P,.SAVE2##	;NEED TWO SAFE ACCS
	MOVE	P1,T2		;SAVE NAME
	MOVS	P2,LNMPTR	;GET START OF NAME CHAIN
	JUMPE	P2,LINKB	;NOT SETUP YET
LINKA:	CAMN	P1,(P2)		;SAME NAME
	JRST	LNKLNA		;YES, ERROR
	HRRZ	T1,1(P2)	;SEE IF ANY MORE
	JUMPE	T1,LINKB	;NO
	MOVE	P2,T1
	JRST	LINKA		;YES

LINKB:	MOVEI	T2,2		;USE 2 WORDS
	PUSHJ	P,DY.GET##
	JUMPE	P2,[HRLZM T1,LNMPTR
		JRST	.+2]
	HRRM	T1,1(P2)	;LINK TO NEW BLOCK
	MOVE	P2,LNKMAX	;LINK NUMBER OF PREVIOUS
	HRLZI	P2,1(P2)	;ONE MORE IS # OF THIS ONE
	DMOVEM	P1,(T1)		;STORE
	AOS	LNMPTR		;COUNT ONE MORE
	SKIPL	WRTDAT		;[1704] LINK MARKED WRITABLE?
	POPJ	P,		;[1704] NO, FINISHED	
	HRLOI	T1,377777	;[1704] CLEAR MARKER BIT NOW
	ANDM	T1,WRTDAT	;[1704]
	HLRZ	T1,P2		;[1704] CURRENT LINK IS WRITABLE
	PUSHJ	P,WRTPTR##	;[1704]	GET BYTE PTR TO LINK DATA
	MOVX	T2,OW.WRT	;[1704] MARK IT WRITABLE
	DPB	T2,T1		;[1704] ...
	POPJ	P,

LNKLNA:	HLRZ	P2,1(P2)	;GET LINK#
E$$LNA::.ERR.	(MS,.EC,V%L,L%W,S%W,LNA,<Link name >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,P1)
	.ETC.	(STR,.EC,,,,,< already assigned to link number >)
	.ETC.	(DEC,.EP,,,,P2)
	POPJ	P,
E$$TML::.ERR.	(MS,,V%L,L%F,S%F,TML,<Too many links, use /MAXNODE >) ;[2007]
	POPJ	P,	;[1424]
SUBTTL	SWITCH ACTION -- /ARSIZE:n, /MAXNODE:n, /NOENTRY:sym, /NOREQUIRE:sym


%ARSIZE::
	HRRM	T2,ARSIZE	;[635] STORE VALUE FOR THIS LINK
	POPJ	P,		;[635] RETURN TO LNKWLD


%NOENTRY::
	PUSHJ	P,STRLSW##	;WAIT 'TIL FILE IS LOADED
.NOENTRY::
	PUSHJ	P,.SAVE4##	;SAVE P1-P4
	MOVX	W1,PT.SGN!PT.SYM	;FLAGS
	SKIPN	W2,T2		;SYMBOL
	JRST	E$$ZSV##	;[1174] ZERO IS ILLEGAL
	SETZ	W3,		;VALUE
	PUSHJ	P,TRYSYM##	;SEE IF DEFINED
	  POPJ	P,		;IGNORE
	  JFCL			;UNDEFINED
	MOVX	W1,PS.NOE	;NOT AN ENTRY FLAG
	IORM	W1,0(P1)	;SET IN SYMBOL TRIPLET
	POPJ	P,

%NOREQUEST::
	PUSHJ	P,STRLSW##	;WAIT 'TIL FILE IS LOADED
.NOREQUEST::
	PUSHJ	P,.SAVE4##	;SAVE P1-P4
	MOVX	W1,PT.SGN!PT.SYM	;FLAGS
	SKIPN	W2,T2		;SYMBOL
	JRST	E$$ZSV##	;[1174] ZERO IS ILLEGAL
	SETZ	W3,		;VALUE
	PUSHJ	P,TRYSYM##	;SEE IF DEFINED
	  POPJ	P,		;IGNORE
	  JFCL			;UNDEFINED
	MOVX	W1,PS.NRQ	;NOT A REQUEST FLAG
	IORM	W1,0(P1)	;SET IN SYMBOL TRIPLET
	POPJ	P,
SUBTTL	SWITCH ACTION -- /PLOT:(INCHES:n,LEAVES:n,STEPS:n)

%PLOT::
	SETOM	PLOTSW		;MAKE SURE WE DO IT
	SKIPE	T1,3(P2)	;GET SWITCH VALUE
	MOVEM	T1,PLTTAB-1(T2)	;STORE FOR LNKPLT
	SKIPE	IO.PTR+%PC	;[2076] FIRST CALL THIS FILE SPEC?
	POPJ	P,		;NO
	PUSHJ	P,COPYP1##	;MAKE A NEW DATA BLOCK
	PUSHJ	P,DVOUT.##	;SETUP OUTPUT BLOCK
	  %PC,,-1		;WILL BE EITHER ASCII LINE OR IMAGE AT RUN TIME
	PJRST	RESTP1##	;DELETE DATA BLOCK


SUBTTL	SWITCH ACTION --  /REGION, /SPACE:n
%REGION::
	JUMPE	T2,CPOPJ	;ALLOW /REGION:0
E$$MRN::.ERR.	(MS,0,V%L,L%I,S%I,MRN,<Multiple regions not yet implemented>) ;[1174]
	POPJ	P,


%SPACE::
	MOVEM	T2,SPACE	;SAVE VALUE
	POPJ	P,
SUBTTL	LINK SWITCHES -- /REQUEST


%REQUEST::
	PUSHJ	P,STRLSW	;WAIT TIL AFTER FILE LOADED
.REQUEST::
	MOVE	T1,[PUSHJ P,REQNXT] ;[1174] SET UP NEXT SYMBOL ROUTINE
	MOVEM	T1,NXTGLB	;[1174]   ..
	MOVE	W3,HT.PRM	;[1174] SET UP HASH TABLE INDEX
	ADDI	W3,1		;[1174] START UP BY 1 FOR SOSGE BELOW
	PUSHJ	P,REQNXT	;[1174] GET NEXT (FIRST) ENTRY
	  PJRST	E01RER		;[1174] NONE--GO SAY SO SPECIALLY
E$$RER::.ERR.	(MS,.EC!.EN,V%L,L%F,S%I,RER) ;[1174]
	.ETC.	(STR,.EC,,,,,<Request external references (inter link entry points)>) ;[1174]
	.ETC.	(JMP,,,,,.ETSAV##) ;[1174] GO PRINT THE LIST


;REQNXT RETURNS THE NEXT INTER-LINK ENTRY POINT FOR USE BY THE ABOVE .ERR..
;
;CALL:
;	W3/	NEXT HASH TABLE INDEX TO CHECK
;RETURNS  WITH  A NON-SKIP RETURN IF THERE ARE NO MORE SUCH SYMBOLS.  OTHERWISE,
;GIVES A SKIP RETURN WITH:
;	W1/	NEXT SYMBOL
;	W2/	OCTAL VALUE
;	W3/	UPDATED

REQNXT:	PUSHJ	P,.SAVE4##	;[1174] SAVE LNKLOG'S P ACS
REQLUP:	SOSGE	P2,W3		;[1174] CHECK NEXT HASH TABLE ENTRY
	POPJ	P,		;[1174] NONE LEFT--GIVE NON-SKIP RETURN
	SKIPN	P3,@HT.PTR	;[1174] IGNORE IF NO SYMBOL HERE
	JRST	REQLUP		;[1174]   ..
	ADD	P3,GS.LB	;[1174] RELOCATE IN CASE GS AREA MOVED
	MOVE	T1,0(P3)	;[1174] MUST BE UNDEFINED LINK ENTRY SYMBOL
	TXNE	T1,PT.SYM	;[1174]   ..
	TXNN	T1,PS.ENT	;[1174]   ..
	JRST	REQLUP		;[1174] NO--TRY NEXT
	TXNN	T1,PS.NRQ	;[1174] DID USER SAY NO FOR THIS SYMBOL?
	SKIPN	2(P3)		;[1174]   OR ZERO VALUE (I.E. NOT A CALL FOO)
	JRST	REQLUP		;[1174] YES--TRY NEXT
	MOVE	W1,1(P3)	;[1174] NO--A WINNER! LOAD UP SYMBOL AND VALUE
	MOVE	W2,2(P3)	;[1174]   ..
	JRST	CPOPJ1		;[1174] DONE--GIVE SKIP RETURN
E01RER::.ERR.	(MS,.EC,V%L,L%F,S%I,RER) ;[1174]
	.ETC.	(STR,,,,,,<No request external references (inter-link entry points)>) ;[1174]
	POPJ	P,		;[1174]

REQHDR:	ASCIZ	\[LNKRER \
REQMES:	ASCIZ	\Request External References (Inter-Link Entry points)]
\
SUBTTL	HERE TO TERMINATE LINK


LINKGO::SKIPN	PRGNO		;LOAD ANYTHING?
	JRST	LNKOV2		;NO, DO PASS2
	PUSHJ	P,LIBRARY##	;LOAD DEFAULT LIBS
	PUSH	P,.+1		;LOAD RETURN ADDRESS
	CAI	LNKOV2
	JRST	LINKGT		;COMMON CODE

LINKTO::PUSHJ	P,LIBRARY##	;LOAD DEFAULT LIBS
	PUSH	P,.+1		;LOAD RETURN ADDRESS
	CAI	LNKOV1

LINKGT:
IFE TOPS20,<
	MOVE	T1,HL.S1	;[2366] GET THE HIGHEST LOADED
	TLNE	T1,-1		;[2366] OUTSIDE OF SECTION ZERO?
	 PUSHJ	P,E$$CBO##	;[2235] YES, GIVE ERROR
>;[2366] IFE TOPS20
	SETOM	LINKSEEN	;END OF SEGMENT SPECIFIED
	AOS	T1,LNKMAX	;INCREMENT NUMBER SEEN
	MOVEM	T1,CS+CS.NUM	;[1400]STORE CURRENT IN HEADER
	CAMLE	T1,L.MAX	;[1424] TOO MANY?
	PUSHJ	P,E$$TML	;[1424] TOO MANY
	SKIPL	WRTDAT		;[1710] LINK MARKED WRITABLE?
	JRST	LNKGT0		;[1710]
	HRLOI	T2,377777	;[1710] CLEAR MARKER BIT NOW
	ANDM	T2,WRTDAT	;[1710]
	PUSHJ	P,WRTPTR##	;[1710]	GET BYTE PTR TO LINK DATA
	MOVX	T2,OW.WRT	;[1710] MARK IT WRITABLE
	DPB	T2,T1		;[1710] ...
LNKGT0:	SKIPN	W2,STADDR+1	;[1232] IS START ADDRESS STILL SYMBOLIC?
	JRST	LNKT0		;NO
	MOVX	W1,PT.SGN!PT.SYM
	SETZ	W3,
	PUSHJ	P,TRYSYM##	;SEE IF DEFINED BY NOW
	  JRST	LKSTER		;CANNOT HAPPEN
	  JRST	LKSTER		;UNDEFINED
	MOVE	W3,2(P1)	;GET VALUE
	ADDM	W3,STADDR	;[1232] CALCULATE VALUE
LNKT0:	SKIPE	CS+CS.NUM	;[1400]LINK 0?
	JRST	LNKT1		;NO
	PUSHJ	P,ALGCHK##	;[1265] DO SPECIAL CHECK FOR ALGOL
	HRRZ	T1,RC.TB	;[1257] GET POINTER
	MOVE	T1,0(T1)	;[1257] GET POINTER TO .ABS. BLOCK
	MOVE	T1,RC.HL(T1)	;[1257] GET ROOT NODE HIGH ABS LOC.
	MOVEM	T1,ROOTAB	;[1257] STORE IT FOR EXIT TIME
	MOVSI	T1,L.FNS!L.FHS	;[1226] TURN OFF /SEG:DEF AND /SEG:HIGH
	ANDCAM	T1,FLAGS	;[1226]   IN GLOBAL (ACCROSS LINES) SWITCHES
	ANDCAM	T1,S.LHFL	;[1226]   AND GLOBAL KLUDGE FLAGS
	MOVSI	T1,L.FLS	;[1226] TURN ON /SEGMENT:LOW FOR DURATION
	IORM	T1,FLAGS	;[1226]   ..
	IORM	T1,S.LHFL	;[1226]   ..
	TXZ	FL,<L.FNS!L.FHS,,R.FNS!R.FHS> ;[1226] FIX /SEG:LOW NOW TOO
	TXO	FL,<L.FLS,,R.FLS> ;[1226]   ..
	MOVX	W1,PT.SGN!PT.SYM ;FLAG BITS FOR A SYMBOL
	MOVE	W2,['FUNCT.']	;THE SYMBOL'S NAME
	SETZ	W3,
	PUSHJ	P,TRYSYM	;IT MUST BE THERE OR OVRLAY
				;WILL RECURSE HORRIBLY
	  SKIPA			;NOT NEEDED IS OK
	  JRST	E$$FSN		;[1174] OVRLAY NEEDS IT, MUST BE THERE
	MOVX	W1,PT.SGN!PT.SYM
	MOVE	W2,['.OVRLA']	;NEED TO KNOW WHERE IT IS
	SETZ	W3,
	PUSHJ	P,TRYSYM##
	  JRST	E$$OHN		;[1174] MUST BE THERE
	  JRST	E$$OHN		;[1174] BUT WARN USER
	MOVE	T1,2(P1)	;GET ADDRESS
	HRLI	T1,(JSP	1,)	;COMPLETE INST
	MOVEM	T1,ET+ET.OVL	;[1400] AND STORE IN PROTOTYPE EXTTAB
	HRRI	W2,'RLU'	;WHERE UNDEFINED REQUESTS GO
	PUSHJ	P,TRYSYM##
	  JRST	E$$OHN		;[1174]
	  JRST	E$$OHN		;[1174]
;HERE TO SET UP FRONT OF OVERLAY FILE.

	MOVE	T1,2(P1)	;GET ADDRESS
	MOVEM	T1,ADDOVU	;SO WE CAN DO FIXUPS
	PUSHJ	P,OC.OPN	;SETUP OVERLAY FILE
	MOVEI	T2,.DBS		;[1424] START TABLE WITH 256 LINKS
	SKIPN	T2,L.MAX	;[1424] BUT NOT IF SET BY /MAXNODE
	MOVEM	T2,L.MAX	;STORE NUMBER FOR CHECKS
	PUSHJ	P,DY.GET##	;GET SOME SPACE
	HRLI	T1,P1		;PUT INDEX IN P1 FOR @
	MOVEM	T1,LNKTBL	;FOR DISC BLOCKS
	MOVEI	T1,LN.OVL/<.DBS*2>	;[650]
	MOVEM	T1,OVLBLK	;FIRST FREE BLOCK FOR LINKS
	SKIPN	LW.S1		;SEE IF PAGING AND BASE NOT IN CORE
	JRST	LNKT0A		;OK IT IS
	MOVEI	P2,.JBVER	;HIGHEST ADDRESS WE NEED
	SETZ	P3,		;LOWER
	PUSHJ	P,PG.LSG##	;MAKE SURE WINDOW IS IN CORE
LNKT0A:	MOVE	T1,LC.LB	;BASE OF LOW SEG
	MOVE	T2,SYMSEG	;GET SYMSEG VALUE
	CAIE	T2,$SSGNONE	;[1201] USER SAYS NO?
	SKIPE	NOSYMS		;HOWEVER IF USER SAID NO
	JRST	[SETZM	SYMSEG	;MAKE SURE NONE
		JRST LNKT0C]	;[1172] CONTINUE
	JUMPN	T2,LNKT0B	;OK IF USER ALREADY SAID /SYMSEG
	SKIPN	.JBDDT(T1)	;IS DDT LOADED
	JRST	LNKT0C		;[1172] NO, CONTINUE
	MOVEI	T2,$SSGLOW	;[1201] SYMBOLS IN LOW SEG INDEX
	MOVEM	T2,SYMSEG	;SET VALUE SO WE CAN SAVE SYMBOLS


;HERE IF WE'RE GOING TO HAVE A RUNTIME SYMBOL TABLE.  ALLOCATE PAT..
;AT THE END OF THE ROOT.

LNKT0B:	MOVE	T2,SYMSEG	;[1172] GET INDEX TO SYMBOL SEGMENT
	SKIPN	T3,PATSPC	;[1172] GET PATCHING SPACE
	MOVEI	T3,PATSP.	;[1172] DEFAULT
	EXCH	T3,HL.S0(T2)	;[1172] GET LOCATION OF PAT..
	MOVEM	T3,PATLOC	;[1172] SAVE FOR LSOVX
	ADDM	T3,HL.S0(T2)	;[1172] ALLOCATE THE PAT.. AREA
	; ..
	; ..

LNKT0C:	MOVE	T2,.JBVER(T1)	;[1172] GET VERSION N0.
	SKIPN	VERNUM
	MOVEM	T2,VERNUM	;SET FOR OVERLAY FILE
	MOVX	W1,PT.SGN!PT.SYM
	MOVE	W2,['.OVRLO']
	SETO	W3,
	MOVE	T1,OVERLW	;GET FLAGS
	TXNE	T1,$OVLOG	;WANT A LOG FILE?
	PUSHJ	P,SETVAL	;YES
	SETZ	W3,
	TXNE	T1,$OVNOLOG	;SPECIFICALLY NOT?
	PUSHJ	P,SETVAL
	HRRI	W2,'RWA'	;NOW FOR WARNINGS
	TXNE	T1,$OVWARN
	PUSHJ	P,SETVAL
	SETO	W3,
	TXNE	T1,$OVNOWARN
	PUSHJ	P,SETVAL
	JRST	LNKT1B

SETVAL:	PUSHJ	P,TRYSYM##
	  JRST	E$$OHN		;[1174]
	  JRST	E$$OHN		;[1174]
	HRRZ	P2,2(P1)	;GET ADDRESS
	MOVE	P3,P2		;FOR ADDRESS CHECK
	SKIPE	PAG.S1		;ON DSK
	PUSHJ	P,PG.LSG##	;YES
	ADD	P3,LC.LB
	MOVEM	W3,(P3)		;STORE BACK
	MOVE	T1,OVERLW	;RESET SWITCH
	POPJ	P,


LKSTER:	PUSHJ	P,E$$USA##	;[1232] UNDEFINED MESSAGE
	JRST	LNKT0		;[1232] CONTINUE END-OF-LINK PROCESSING
LNKT1:	SKIPN	P1,LSTPTR	;FIRST TIME (LINK# 1)?
	JRST	[MOVEI	T2,4		;NEED 4 WORDS
		PUSHJ	P,DY.GET##
		MOVEM	T1,FSTPTR	;STORE START OF TREE
		MOVSI	T2,-4		;-4 ,, 0
		JRST	LNKT1A]
	SKIPN	(P1)		;JUST DONE A RESET (0 WORD)
	JRST	[MOVS	T2,CS+CS.NUM	;[1400]
		MOVEM	T2,(P1)
		JRST	LNKT1B]	;REPLACE WITH LINK#
	MOVEI	T2,4		;ASSUME AT LEAST 2 FORWARD PATHS FROM THIS LINK
	PUSHJ	P,DY.GET##
	HRRM	T1,(P1)		;LINK BACK TO PREVIOUS
	HLRZ	T2,P1		;PTR TO START OF BLOCK
	HRL	T2,(T2)		;GET ITS LINK#
	MOVEM	T2,1(T1)	;STORE BACK POINTER
	MOVSI	T2,-4
	HLR	T2,(P1)		;THIS LINK#
LNKT1A:	MOVEM	T2,(T1)
	MOVS	T2,CS+CS.NUM	;[1400]
	MOVEM	T2,2(T1)	;STORE LINK # WITH ZERO PTR
	HRLI	T1,2(T1)	;POINT TO NULL PTR
	MOVSM	T1,LSTPTR
LNKT1B:	SKIPN	T1,HL.S1	;GET CURRENT HIGHEST LOC
	JRST	[SKIPN	T1,PH+PH.ADD	;[1400] NEVER SETUP, SO NO LOW SEG
		MOVEI	T1,.JBDA	;NOT POSSIBLE, BUT !!1
		MOVEM	T1,HL.S1	;JUST STORE TABLES, ETC.
		JRST	.+1]
	MOVEM	T1,PH+PH.CST	;[1400] WILL BE START OF HEADER SECTION
	SKIPN	CS+CS.NUM	;[1400] IF ROOT
	HRLM	T1,ADDOVU	;STORE FOR UNDEF SYMBOL
	HRL	T1,CS+CS.NUM	;[1400] PUT NUMBER IN LH
	MOVEM	T1,ET+ET.CST	;[1400] ALSO IN EXTTAB
	MOVE	T1,PH+PH.ADD	;[1400] GET THIS LINK'S ORIGIN
	MOVEM	T1,CS+CS.COR	;[1400] SAVE AS START OF LINK
	MOVEI	T1,CS.LEN	;[1400] ALLOCATE SPACE FOR HEADER
	ADDB	T1,HL.S1	;AND ACCOUNT FOR IT
	MOVE	T1,[CS+CS.HDR,,PH+PH.HDR] ;[1400]
	BLT	T1,PH+PH.NAM	;[1400] COPY COMMON INFO
	MOVE	T1,STADDR	;COPY START ADDRESS
	HRRZM	T1,CS+CS.STA	;[1400]
	SETZM	CS+CS.EXT	;[1400] INCASE NO UNDEFS
	SKIPN	P2,USYM		;NO. OF UNDEFS
	JRST	LNKT3		;NONE
	MOVN	T1,P2		;- NUMBER
	HRL	T1,HL.S1	;,,ADDRESS
	MOVSM	T1,CS+CS.EXT	;[1400] POINT TO TABLE
	IMULI	P2,ET.LEN	;[1400] 4 WORDS EACH
	MOVE	P3,HL.S1	;LOWER BOUND
	ADD	P2,HL.S1	;ACCOUNT FOR THEM
	PUSHJ	P,LNKTCK	;MAKE SURE IT'S IN CORE
;HERE TO SET EXTTAB

LNKT2:	HRLI	P3,ET		;[1400] FORM BLT PTR IN P3
	MOVE	P4,USYM		;GET UNDEFINED SYMBOL COUNT AGAIN
	MOVE	P2,HT.PRM	;GET INDEX INTO HASH TABLE
LNKT2A:	SKIPN	P1,@HT.PTR	;GET POINTER TO SYMBOL
	JRST	LNKT2B		;NO POINTER, NO SYMBOL
	ADD	P1,GS.LB	;ADD IN BASE
	MOVE	T1,0(P1)	;GET FLAGS
	TXNE	T1,PT.SYM	;WE ONLY WANT SYMBOLS
	TXNN	T1,PS.UDF!PS.REQ	;SEE IF UNDEFINED STILL
	JRST	LNKT2B		;NO
	AOS	EXTCNT		;COUNT ONE MORE
	DMOVE	T1,1(P1)	;GET SYMBOL AND VALUE (POINTER)
	MOVEM	T1,ET+ET.NAM	;[1400] STORE NAME
	MOVE	T1,P3		;GET BYTE PTR
	ADDI	P3,ET.LEN	;[1400] INCR P3
	BLT	T1,-1(P3)	;MOVE PROTOTYPE BLOCK
	MOVEI	W3,ET.LEN	;[1400]
	ADD	W3,HL.S1	;NEW TOP
	EXCH	W3,HL.S1	;OLD BASE
	HRLI	R,(1B1)		;RELOCATE RHS
	SETZ	P1,		;NOT SYMBOLIC THOUGH
	SUB	P3,LC.LB	;MAKE RELATIVE IN CASE CORE MOVES
	PUSHJ	P,SY.CHR##	;LINK ALL REQUESTS TO EXTTAB
	ADD	P3,LC.LB	;CAN HAPPEN IF PAGING LC AREA
	SOJLE	P4,LNKT3	;DONE IF NO MORE UNDEFS
LNKT2B:	SOJGE	P2,LNKT2A	;LOOP IF MORE SYMBOLS TO LOOK AT
;HERE TO SET INTTAB

LNKT3:	SETZM	CS+CS.INT	;[1400] INCASE 0 ENTRIES
	SKIPN	CS+CS.NUM	;[1400] NOT REQUIRED IF LINK 0
	JRST	LNKT4		
	MOVEI	T1,100		;MAKE SURE ENOUGH SPACE FOR 100 ENTRIES
	MOVEM	T1,INTCNT
	MOVE	P3,HL.S1	;LOWER BOUND
	MOVEI	P2,2*100(P3)	;ALLOCATE SPACE FOR WORD PAIRS
	PUSHJ	P,LNKTCK	;MAKE SURE IN CORE
	MOVE	P2,HT.PRM	;GET INDEX INTO HASH TABLE
LNKT3A:	SKIPN	T4,@HT.PTR	;GET POINTER TO SYMBOL
	JRST	LNKT3B		;NO POINTER, NO SYMBOL
	ADD	T4,GS.LB	;ADD IN BASE
	MOVE	T1,0(T4)	;GET FLAGS
	TXNE	T1,PT.SYM	;WE ONLY WANT SYMBOLS
	TXNN	T1,PS.ENT	;SEE IF AN ENTRY
	JRST	LNKT3B		;NOT AN ENTRY
	TXNE	T1,PS.BGS!PS.NOE	;BUT ONLY IF NOT BOUND AND USER DIDN'T SAY NO
	JRST	LNKT3B		;NO
	SOSGE	INTCNT		;ENOUGH SPACE
	JRST	[MOVEI	T1,100		;GET ANOTHER 100 WORDS WORTH
		MOVEM	T1,INTCNT
		ADDB	T1,CS+CS.INT	;[1400] ACCOUNT FOR THEM
		LSH	T1,1		;WORD PAIRS
		PUSH	P,P2		;SAVE INDEX INTO HASH TABLE
		MOVE	P3,HL.S1	;BASE AGAIN
		MOVEI	P2,2*100(P3)
		ADD	P2,T1		;ADDRESS BOUNDS
		PUSHJ	P,LNKTCK	;ADDRESS CHECK IT
		ADD	P3,CS+CS.INT	;[1400] ACCOUNT FOR PREVIOUS
		ADD	P3,CS+CS.INT	;[1400]   IN PAIRS
		POP	P,P2
		JRST	LNKT3A]		;KEEP ON TRYING
	DMOVE	T1,1(T4)	;GET NAME + VALUE
	HRL	T2,HL.S1	;BASE OF TABLE
	DMOVEM	T1,(P3)		;STORE IN CORE
	ADDI	P3,2		;INCREMENT
LNKT3B:	SOJGE	P2,LNKT3A	;LOOP IF MORE SYMBOLS TO LOOK AT
	MOVEI	T1,100
	SUB	T1,INTCNT	;SEE HOW MANY ENTRY POINTS
	ADD	T1,CS+CS.INT	;[1400] INCASE MORE THAN 100
	MOVN	T2,T1		;-NUMBER
	HRL	T2,HL.S1	;,, ADDRESS
	MOVSM	T2,CS+CS.INT	;[1400] POINTER TO TABLE
	LSH	T1,1		;2 WORDS EACH
	ADDM	T1,HL.S1	;ACCOUNT FOR THEM
;	JRST	LNKT4
LNKT4:	DMOVE	T1,OV.S1	;SAVE CURRENT
	HRR	T1,PH+PH.ADD	;[1400] HOWEVER LOW REALLY STARTS AFTER SPACE
	DMOVEM	T1,PV.S1	;AS PREVIOUS SO MAP CAN COMPUTE LENGTHS
	HRRZ	T1,ARSIZE	;[635] RESERVE SPACE AFTER INTTAB FOR
	ADDB	T1,HL.S1	;[635]   ARL'S, PICK UP NEW HL.S1
	MOVE	T2,HL.S2	;[635] NEED HI SEG HIGHEST ALSO
	HRL	T1,T1		;MAKE THE HIGEST CODE THE
	HRL	T2,T2		;  HIGHEST SEEN TO HERE
	DMOVEM	T1,OV.S1	;SAVE FOR MAP AND EXIT
	MOVE	T1,HL.S1	;HIGHEST USED
	MOVE	T2,T1
	SUB	T2,PH+PH.ADD	;[1400] REMOVE BASE
	HRLM	T2,CS+CS.COR	;[1400] SAVE LENGTH REQUIRED
	HRRZM	T2,PH+PH.LLN	;[1400]
	MOVE	P1,CS+CS.NUM	;[1400] GET THIS LINK #
	ROT	P1,-1		;CUT IN HALF AND MAKE REM SIGN BIT
	HRLS	T2,OVLBLK	;THIS TRICK PUTS RH(OVLBLK) INTO LH(OVLBLK)
				;AND BOTH HALVES IN T2
	JUMPL	P1,[HRRM T2,@LNKTBL
		JRST	.+2]
	HRLZM	T2,@LNKTBL	;DISC BLOCK # OF PREAMBLE
	AOS	T1,OVLBLK	;ACCOUNT FOR PREAMBLE (OUTPUT IT LATER)
	HRRZM	T1,PH+PH.OVL	;[1400] USE THIS BLOCK FOR CODE
LNKT4A:	MOVE	P3,PH+PH.CST	;[1400] ADDRESS OF CONTROL SECTION
	MOVEI	P2,CS.LEN-1(P3)	;[1400] UPPER BOUND
	PUSHJ	P,LNKTCK	;MAKE SURE ITS IN CORE
	MOVN	T2,PH+PH.LLN	;[1400] TOTAL NO. OF WORDS
	HRLM	T2,PH+PH.OVL	;[1400] IN IOWD FORM
	MOVE	T2,PH+PH.OVL	;[1400] COPY POINTER TO CS FOR SPEED
	MOVEM	T2,CS+CS.OVL	;[1400]   AT RUNTIME WITH WRITABLE OVERLAYS
	HRLI	P3,CS		;[1400] COPY FINAL CONTROL SECTION TO
	MOVEI	P2,CS.LEN-1(P3)	;[1400]   THE MEMORY IMAGE
	BLT	P3,(P2)		;[1400]   ..
	MOVE	T1,HL.S1	;TOP OF CORE
	ADD	T1,SPACE	;PLUS BUFFER SPACE
	CAMLE	T1,[1,,0]	;[1204] STILL IN BOUNDS?
	PUSHJ	P,E$$PTL##	;[1204] NO, COMPLAIN
	MOVEM	T1,PH+PH.NFL	;[1400] FOR NEXT LINK
	PUSHJ	P,LODFIX##	;DO ALL CORE FIXCUPS ETC.
	SKIPN	PAG.S1		;PAGING?
	JRST	LNKT4B		;NO
	MOVE	T1,LW.S1	;[2202] LOWER BOUND
	MOVE	T2,UW.S1	;[2202] UPPER BOUND
	PUSHJ	P,LC.OUT##	;MAKE SURE FILE IS CORRECT
	SETZB	T1,LW.S1	;[2202] NOW START AT FRONT
	MOVE	T2,LC.UB	;[2202] GET TOP
	MOVEM	T2,LC.AB	;[2202] USE ALL SPACE WE CAN
	SUB	T2,LC.LB	;[2202] GET THE SIZE
	MOVEM	T2,UW.S1	;[2202] MAKE IT UPPER BOUND
	PUSHJ	P,LC.IN##	;READ BACK
;HERE TO SETUP .JBOVL AND UPDATE OVERLAY FILE

LNKT4B:	HRRZ	T1,OVLBLK	;[666] BLOCK TO START STASHING CODE
	USETO	OC,(T1)		;SET ON IT
	SKIPE	CS+CS.NUM	;[1400] IF LINK# 0
	JRST	LNKT4C		;NO
	MOVE	T1,LC.LB	;BASE
	MOVE	T2,PH+PH.CST	;[1400] START OF CONTROL BLOCK
	MOVEM	T2,.JBOVL(T1)	;STORE INITIAL PTR


;HERE TO DUMP LC AREA IF NOT PAGING OR ON EACH BUFFER IF PAGING.

LNKT4C:	MOVE	T1,LC.AB	;[666] USUALLY WILL WANT TO DUMP
	SUB	T1,LC.LB	;[666]   ENTIRE LC AREA, SO CALCULATE
	ADDI	T1,1		;[666]   SIZE TO DUMP
	MOVE	T3,PH+PH.LLN	;[1400] NUMBER OF WORDS TO DUMP TOTAL
	SKIPN	PAG.S1		;[666] HAS LC AREA OVERFLOWED TO DISK?
	SKIPA	T1,T3		;[666] NO, DUMP ALL WORDS AT ONCE
	CAML	T3,UW.S1	;[666] YES, IF NOT LAST BUF DUMP ALL LC
	JRST	LNKT4G		;[666] T1 HAS CORRECT # WORDS TO DUMP
	SUB	T1,UW.S1	;[666] LAST BUF WHEN PAGING, ONLY DUMP
	SUBI	T1,1		;[666]   LAST PARTIAL BUFFER
	ADD	T1,PH+PH.LLN	;[1400]   GET LENGTH EXACT
LNKT4G:	HRLZ	T1,T1		;[666] GENERATE IOWD TO DUMP LC AREA
	SETCA	T1,		;[666] ..
	ADD	T1,LC.LB	;[666] ..
	SETZ	T2,		;TERMINATOR
	OUT	OC,T1		;OUTPUT WHOLE AREA
	  JRST	LNKT4D		;OK
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR
LNKT4D:	SKIPE	PAG.S1		;[666] PAGING?
	CAMG	T3,UW.S1	;[666] YES, FINISHED LAST BUFFER?
	JRST	LNKT4F		;[666] DON'T NEED TO DUMP ANOTHER BUF
	MOVE	T1,LC.AB	;GET TOP OF WHATS IN USE
	SUB	T1,LC.LB	;GET DIFF	
	MOVEI	T1,1(T1)	;SO WE CAN ADD NO.
	ADDM	T1,LW.S1	;ADJUST WINDOWS
	ADDB	T1,UW.S1
	IORI	T3,.IPM		;[666] MAKE SUB COME OUT EVEN .IPS'S
	SUB	T3,T1		;[666] DO WE STILL NEED IT ALL?
	JUMPGE	T3,LNKT4E	;[666] YES, USE ALL OF SPACE AVAILABLE
	ADDM	T3,UW.S1	;[666]
IFE TOPS20,<
	ADDB	T3,LC.AB	;[666] REDUCE WINDOW NOW
	HRLI	T3,1(T3)	;[666] FORM BLT PTR
	HRRI	T3,2(T3)	;[666]
	SETZM	-1(T3)		;[666] CLEAR FROM (LC.AB)+1
	BLT	T3,@LC.UB	;[666] THROUGH ALL OF FREE SPACE
>  ;[1514]IFE TOPS20
IFN TOPS20,<
	MOVE	T2,LC.AB	;[2202] Get upper bound
	SUB	T2,LC.LB	;[2202] Get the current size
	ADD	T2,LW.LC	;[2202] Current window area		
	MOVE	T1,T2		;[2202] Get the upper window
	ADD	T1,T3		;[2202] Get new upper window (T3 is negative)
	ADDI	T1,1		;[2202] Start of piece to remove
	ADDM	T3,LC.AB	;[1514] Set new upper limit
	PUSHJ	P,LC.OUT##	;[2202] Unmap excess area
> ;[1514] IFN TOPS20
LNKT4E:	MOVE	T1,LW.S1	;[2202] GET LOWER BOUND
	MOVE	T2,UW.S1	;[2202] SETUP NEW WINDOW
	PUSHJ	P,LC.IN##	;INPUT NEW AREA
	JRST	LNKT4C		;[666] AND OUTPUT IT

LNKT4F:	MOVE	T1,PH+PH.LLN	;[1400] GET LENGTH WE NEED
	ADDI	T1,.DBM		;[650] FILL OUT BLOCK
	LSH	T1,-.DBS2W	;[650] INTO BLOCKS
	ADDM	T1,OVLBLK	;ACCOUNT FOR THEM
;	JRST	LNKT5
;HERE FOR LOCAL SYMBOLS

LNKT5:	MOVN	T1,LSYM		;[666] NEGATED # SYMBOLS FOR IOWD
	HRL	T1,OVLBLK	;GET FREE BLOCK
	MOVS	T1,T1
	MOVEM	T1,PH+PH.SYM	;[1400] HOLD LOCAL IN THIS AREA
	MOVE	T1,LSYM		;CALCULATE # OF BLOCKS LS WILL USE
	ADDI	T1,.DBM		;[650] ROUND WORDS UP TO NEXT BLOCK
	LSH	T1,-.DBS2W	;[1214] WORDS TO BLOCKS
	ADDM	T1,OVLBLK	;UPDATE OVLBLK TO END OF SYMBOLS
	SKIPN	T1,PAG.LS	;PAGING?
	JRST	LNKT5B		;NO
	JUMPG	T1,LNKT5A	;IS UPPER WINDOW SET?
	MOVE	T2,LSYM		;[2202] NO
;**;[2033] Replace at LNKT5+12 Lines	PY	14-Feb-83
IFN TOPS20,<			;[2033]
	IORI	T2,.IPM		;[2202] PUT ON PAGE BOUND
>;[2033] IFN TOPS20
IFE TOPS20,<			;[2033]
	IORI	T2,.DBM		;[2202] PUT ON BLOCK BOUND
>;[2033] IFE TOPS20
LNKT5A:	MOVE	T1,LW.LS	;[2202] GET LOWER BOUND
	PUSHJ	P,LS.OUT##	;WRITE OUT SYMBOLS
	MOVEI	P1,LS.IX	;EXPAND LS AREA AS MUCH AS WE CAN
	MOVE	P2,LSYM		;HOW MUCH WE NEED
	ADD	P2,LS.LB	;MINUS HOW MUCH WE ALREADY HAVE
	SUB	P2,LS.AB	;GIVES HOW MUCH WE NEED
	JUMPLE	P2,LNKT5E	;SKIP LNKCOR CALL IF ALREADY ENUF
	PUSHJ	P,FR.CNT##	;SEE HOW MUCH IS FREE
	CAMLE	P2,T1		;AS MUCH AS WE NEED?
	MOVE	P2,T1		;NO, USE WHAT WE CAN
	PUSHJ	P,LNKCOR##	;NEED MORE - TRY FOR IT
	  PUSHJ	P,E$$MEF##	;[1174] TOO BAD
LNKT5E:	SETZB	T1,LW.LS	;[2202] START BACK AT FRONT OF FILE
	MOVE	T2,LS.AB	;[2202] CALCULATE THE
	SUB	T2,LS.LB	;[2202] LENGTH
IFL .IPS-2*.DBS,<
	CAIGE	T2,2*.DBS	;[650] MUST HAVE THIS MUCH FOR FIXUPS
	  PUSHJ	P,E$$MEF##	;[1174] TOO BAD
> ;END IFL .IPS-2*.DBS
	MOVEM	T2,UW.LS	;[2202] NEW END OF WINDOW
	PUSHJ	P,LS.IN##	;INPUT IT
;HERE IF NOT PAGING OR ON EACH BUFFER OF SYMBOLS IF PAGING

LNKT5B:	MOVE	T1,LS.AB	;SAME AS FOR LC
	SUB	T1,LS.LB
	ADDI	T1,1		;[666] WILL USUALLY WANT TO DUMP ALL LS
	MOVE	T3,LSYM		;[666] GET # WORDS TO DUMP TOTAL
	SKIPE	PAG.LS		;[666] IS LS AREA ON DISK?
	JRST	LNKT5F		;[666] YES, T1 MAY BE OK
	MOVE	T1,T3		;[666] DO ONE DUMP, EXACT RIGHT # WORDS
	JRST	LNKT5H		;[666] GO DUMP THE LS AREA

LNKT5F:	CAMG	T3,UW.LS	;[666] IS THIS THE LAST BUF OF SYMBOLS?
	JRST	LNKT5G		;[666] YES, SPECIAL STUFF
;**;[2033] Replace at LNKT5F+2 Lines	PY	14-Feb-83
IFN TOPS20,<			;[2033]
	SUBI	T1,.IPS		;[2033] NO, DON'T DUMP LAST WORDS TILL
>;[2033] IFN TOPS20
IFE TOPS20,<			;[2033]
	SUBI	T1,.DBS		;[666] NO, DON'T DUMP LAST WORDS TILL
>;[2033] IFE TOPS20
	JRST	LNKT5H		;[666]   NEXT TIME SO FIXUPS CAN BE DONE

LNKT5G:	SUB	T1,UW.LS	;[666] LAST BUF IF PAGING, REDUCE COUNT
	SUBI	T1,1		;[666] DON'T BE OFF BY ONE
	ADD	T1,LSYM		;[666] WE DON'T WANT TO DUMP TOO MUCH

LNKT5H:	HRLZ	T1,T1		;[666] GENERATE IOWD TO DUMP LS AREA
	SETCA	T1,		;[666] ..
	ADD	T1,LS.LB	;[666] ..
	SETZ	T2,
	OUT	OC,T1
	  JRST	LNKT5C
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR
LNKT5C:	SKIPE	PAG.LS		;PAGING?
	CAMG	T3,UW.LS	;YES, SEE IF MORE TO DO
	JRST	LNKT6		;NO, ALL DONE
	MOVE	T1,LS.AB	;[666] WINDOW MOVES UP BY SIZE OF
	SUB	T1,LS.LB	;[666]   LS AREA MINUS .DBM
;**;[2033] Replace at LNKT5C+5 Lines	PY	14-Feb-83
IFN TOPS20,<			;[2033]
	ANDCMI	T1,.IPM		;[2033] FIGURE WINDOW OFFSET INTO T1
>;[2033] IFN TOPS20
IFE TOPS20,<			;[2033]
	ANDCMI	T1,.DBM		;[666] FIGURE WINDOW OFFSET INTO T1
>;[2033] IFE TOPS20
	ADDM	T1,LW.LS	;[666] MOVE THE WINDOW UP
	ADDB	T1,UW.LS	;[666] ..
IFE TOPS20,<
	IORI	T3,.IPM		;[666] MAKE SUB BELOW COME OUT .IPS'S
	SUB	T3,T1		;[666] ARE WE DUMPING FINAL PART WINDOW?
	JUMPGE	T3,LNKT5D	;[666] NO, PROCEED AS USUAL
	MOVE	T3,LSYM		;[1266] GET NUMBER OF SYMBOLS
	MOVEM	T3,UW.LS	;[1266] SINCE LAST BUFFER, MUST BE TOP
	SUB	T3,LW.LS	;[1266] FIGURE SIZE OF CURRENT BUFFER
	ADD	T3,LS.LB	;[1266] GET TOP OF NEW BUFFER
	IORI	T3,.IPM		;[1266] MUST BE ON END OF PAGE
	MOVEM	T3,LS.AB	;[1266] SET HIGHEST ADDRESS IN USE
	HRLI	T3,1(T3)
	HRRI	T3,2(T3)	;FORM BLT PTR
	SETZM	-1(T3)
	BLT	T3,@LS.UB	;TO CLEAR ALL EXCESS CORE
>	;[1506] IFE TOPS20
LNKT5D:	MOVE	T1,LW.LS	;[2202] LOWER WINDOW ADDR TO FILL
	MOVE	T2,UW.LS	;[2202] UPPER WINDOW ADDR
	PUSHJ	P,LS.IN##	;GET WINDOW
	JRST	LNKT5B		;AND OUTPUT IT
;HERE FOR RELOCATION TABLES
LNKT6:	SETZM	PH+PH.REL	;[1400] ASSUME NO RELOCATION
	SETZM	PH+PH.ORL	;[1400] AND NO "OTHER" RELOCATION
	SKIPN	RT.LB		;SETUP YET?
	JRST	LNKT7		;NO
	HRRZ	P3,HL.S1	;GET HIGHEST LOC USED
	PUSHJ	P,RT.P3##	;SETUP RT.PT TO IT
	MOVE	T1,RT.LB
	HRRZ	T2,RT.PT
	SUBI	T1,1(T2)	;- LENGTH ACTUALLY USED
	HRL	T1,OVLBLK
	MOVSM	T1,PH+PH.REL	;[1400] -LENGTH ,, BLOCK NUMBER
	MOVE	T1,RT.AB
	SUB	T1,RT.LB	;LENGTH
	AOS	T2,T1		;ACTUALLY ONE LARGER
	LSH	T2,-.DBS2W	;[650] NO. OF BLOCKS
	ADDM	T2,OVLBLK
	MOVN	T1,T1
	HRLZ	T1,T1
	HRR	T1,RT.LB
	HRRI	T1,-1(T1)	;IOWD AT LAST
	SETZ	T2,
	OUT	OC,T1
	  CAIA
	PUSHJ	P,E$$OOV##	;[1174]

	SKIPN	RBGPTR		;ANY OTHER RELOCATION
	JRST	LNKT7		;NO
	MOVE	T1,RT.LB	;YES, GET AREA TO HOLD IT IN
	MOVEM	T1,RT.PT	;POINT TO FIRST FREE
	HRL	T1,T1
	ADDI	T1,1		;BLT PTR
	SETZM	-1(T1)		;CLEAR FIRST WORD
	BLT	T1,@RT.AB	;AND  REST
	MOVE	T1,RT.LB
	IORI	T1,.IPM
	MOVEM	T1,RT.AB	;ALLOCATE ONE BLOCK
	SUB	T1,RT.LB	;FREE SPACE
	MOVEM	T1,RT.FR	;IN THIS BLOCK
;USES ACCS AS FOLLOWS
;P1 = TO HOLD RBGPTR TO WHATS LEFT
;P2 = CURRENT LINK #
;P3 = TO HOLD LIST FOR THIS LINK

LNKT6A:	MOVE	P1,RBGPTR	;GET START OF LIST
	HRRZ	P3,P1		;SET INITIAL PTR
	SETZM	RBGPTR		;WILL PUT BACK THOSE NOT REQUIRED
	MOVE	T1,P1		;GET FIRST ITEM IN LIST
	ADD	T1,FX.LB	;FIX IN CORE
	HLRZ	P2,(T1)		;GET LINK#
	HRRZ	P1,(T1)		;GET NEXT ITEM PTR
	HLLZS	(T1)		;CLEAR THIS PTR
LNKT6B:	SKIPN	T1,P1		;GET NEXT ITEM
	JRST	LNKT6L		;LIST EMPTY
	ADD	T1,FX.LB	;FIX IN CORE
	HRRZ	P1,(T1)		;GET PTR TO NEXT
	HLLZS	(T1)		;CLEAR PTR
	HLRZ	T2,(T1)		;GET LINK#
	CAMN	T2,P2		;THIS THE ONE WE WANT?
	JRST	LNKT6C		;YES
	MOVE	T2,T1
	SUB	T2,FX.LB	;REMOVE BASE
	EXCH	T2,RBGPTR
	HRRM	T2,(T1)		;PUT BACK IN LIST
	JUMPN	P1,LNKT6B	;IF NOT END
	JRST	LNKT6L		;END OF THIS CHAIN

LNKT6C:	HRRZ	T2,1(T1)	;GET ADDRESS WE WANT TO ADD
	MOVE	T3,P3		;START OF CHAIN
LNKT6M:	ADD	T3,FX.LB	;MAKE ABS
	HRRZ	T4,1(T3)	;ADDRESS IN CHAIN
	CAML	T2,T4		;FOUND OUR PLACE YET?
	JRST	LNKT6G		;NO
	HLRZ	T3,T3		;PUT LAST ADDRESS BACK
	JUMPE	T3,[HRRM P3,0(T1)	;PUT IN FRONT OF LIST
		SUB	T1,FX.LB
		MOVE	P3,T1		;RESET BASE PTR
		JRST	LNKT6B]		;GET NEXT
	MOVE	T4,0(T3)	;GET FORWARD PTR
	HRRM	T4,0(T1)	;PUT INTO NEW BLOCK
LNKT6D:	SUB	T1,FX.LB	;MAKE REL
	HRRM	T1,0(T3)	;AND MAKE LAST POINT TO IT
	JRST	LNKT6B		;GET NEXT

LNKT6G:	HRL	T3,T3		;SAVE LAST PTR
	HRR	T3,0(T3)	;GET NEXT
	TRNE	T3,-1		;0 IS END OF LIST
	JRST	LNKT6M		;NO, MORE TO COME
	MOVS	T3,T3		;SWAP BACK
	JRST	LNKT6D		;PUT LAST IN LIST
LNKT6L:	MOVE	T1,RT.PT	;GET PTR
	SUB	T1,RT.LB	;MAKE RELATIVE
	PUSH	P,T1		;SAVE PTR SO WE CAN ADD COUNT LATER
	AOS	RT.PT
	SOS	RT.FR		;ACCOUNT FOR WORD
	MOVE	T1,BRNADD	;GET START OF ADDRESS TABLE
	HRLI	T1,-^D128	;MAX SIZE?
	MOVS	T2,(T1)		;GET LINK#
	CAIN	P2,(T2)		;ONE WE WANT?
	JRST	.+3		;YES
	AOBJN	T1,.-3		;NO
	HALT
	MOVS	P1,T2		;LINK# ,, ADDRESS
	SETZ	T1,		;NO PREVIOUS
	PUSHJ	P,RT.DPB	;STORE IT
LNKT6K:	SKIPN	T1,P3		;COPY OF PTR
	JRST	LNKT6R		;END OF LIST
	ADD	T1,FX.LB
	HRRZ	P3,0(T1)	;GET NEXT
	JUMPE	P1,[MOVE P1,1(T1)	;NO PREVIOUS
		JRST	LNKT6K]		;GET NEXT
	HRRZ	T2,1(T1)	;ADDRESS OF THIS RELOC WORD
	SUBI	T2,(P1)		;- PREVIOUS
	CAIL	T2,^D9		;WITHIN RANGE?
	JRST	[PUSH	P,1(T1)		;GET THIS VALUE
		PUSHJ	P,RT.DPB	;DUMP CURRENT
		POP	P,P1		;RESET THIS ONE
		JRST	LNKT6K]		;GET NEXT
	HLLZ	T3,1(T1)	;GET RELOC BITS
	IMULI	T2,-2		;2 BITS PER WORD
	LSH	T3,(T2)		;SHIFT INTO POSSITION
	IOR	P1,T3
	JUMPN	P3,LNKT6K	;TRY NEXT WORD
;HERE TO CHECK TO SEE IF MORE TO DO AND OUTPUT RT AREA IF NOT.

LNKT6R:	SKIPE	P1		;PREVIOUS TO STORE STILL?
	PUSHJ	P,RT.DPB	;YES
	POP	P,P1		;GET PTR TO START OF TABLE
	ADD	P1,RT.LB	;MAKE ABS
	MOVE	T1,RT.PT	;PTR TO END
	SUBI	T1,1(P1)	;LENGTH
	MOVEM	T1,(P1)		;PUT IT IN
	SKIPE	P1,RBGPTR	;MORE TO DO?
	JRST	LNKT6A		;YES
LNKT6Z:	MOVE	T1,RT.LB
	HRRZ	T2,RT.PT
	SUBI	T1,1(T2)	;- LENGTH ACTUALLY USED
	HRL	T1,OVLBLK
	MOVSM	T1,PH+PH.ORL	;[1400] -LENGTH ,, BLOCK NUMBER
	MOVE	T1,RT.AB
	SUB	T1,RT.LB	;LENGTH
	AOS	T2,T1		;ACTUALLY ONE LARGER
	LSH	T2,-.DBS2W	;[650] NO. OF BLOCKS
	ADDM	T2,OVLBLK
	MOVN	T1,T1
	HRLZ	T1,T1
	HRR	T1,RT.LB
	HRRI	T1,-1(T1)	;IOWD AT LAST
	SETZ	T2,
	OUT	OC,T1
	  JRST	LNKT7
	PUSHJ	P,E$$OOV##	;[1174]
RT.DPB:	SOSL	RT.FR		;ANY ROOM
	JRST	RTDPB1		;YES
	SPUSH	<T1,P1,P2>
	MOVEI	P1,RT.IX	;NEED MORE ROOM
	MOVEI	P2,.IPS
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,E$$MEF##	;[1174]
	SPOP	<P2,P1,T1>
RTDPB1:	MOVEM	P1,@RT.PT
	AOS	RT.PT
	MOVE	P1,T1		;STORE NEW AS PREVIOUS
	POPJ	P,
;HERE FOR GLOBAL SYMBOLS
LNKT7:	MOVE	T1,HT.PTR	;ABS ADDRESS OF HASH TABLE
	SUB	T1,GS.LB	;RELATIVE
	HRL	T1,HT.PRM	;NEED TO SAVE THE HASH NUMBER
	MOVEM	T1,@GS.LB	;IN A SAFE PLACE
	MOVE	T1,OVLBLK
	HRRZM	T1,PH+PH.GLB	;[1400] POINT TO BLOCK
	MOVE	T1,GS.AB	;SAME AS FOR LC
	SUB	T1,GS.LB
	ADDI	T1,1		;[1205] SIZE REQUIRED
	MOVEI	T2,.DBM(T1)	;[1205] ROUND UP TO BLOCK BOUND
	LSH	T2,-.DBS2W	;[650]
	ADDM	T2,OVLBLK
	MOVN	T1,T1
	HRLZ	T1,T1
	HRR	T1,GS.LB
	HRRI	T1,-1(T1)
	HLLM	T1,PH+PH.GLB	;[1400]
	SETZ	T2,
	OUT	OC,T1
	  JRST	LNKT8
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR

;HERE TO OUTPUT PREAMBLE - MUST BE LAST
LNKT8:	HLRZ	T1,OVLBLK	;GET BLOCK RESERVED FOR PREAMBLE
	USETO	OC,(T1)		;SET ON IT
	DMOVE	T1,PHIOWD	;SINCE IOWD CAN NOT BE IN HIGH SEG YET
	OUT	OC,T1
	  JRST	LNKT9
	PUSHJ	P,E$$OOV##	;[1174] OUTPUT ERROR

LNKT9:	MOVE	T1,CS+CS.NUM	;[1400] GET THIS LINK
	MOVEM	T1,PH+PH.BPT	;[1400] AS BACK POINTER FOR NEXT LINK
;HERE TO ZERO VARIOUS AREAS

;HERE TO ZERO LOW CODE AREA
LNKZLC:
IFE TOPS20,<			;[2247]
	MOVE	T1,LC.LB	;BASE
	HRL	T1,T1
	ADDI	T1,1		;BLT PTR
	SETZM	-1(T1)		;CLEAR FIRST WORD
	BLT	T1,@LC.AB	;AND  REST
	MOVE	T1,LC.LB
	IORI	T1,.IPM		;PRE-ALLOCATE ONE BLOCK ONLY
	MOVEM	T1,LC.AB
	SKIPN	PAG.S1		;PAGING?
	JRST	LNKZRT		;NO
	MOVEI	T1,LC		;CHAN# IF ON DSK
	MOVEM	T1,IO.CHN
	PUSHJ	P,DVDEL.##	;DELETE FILE
	  JFCL			;INCASE OF ERRORS
	PUSHJ	P,DVZAP.##	;GET RID OF DATA BLOCK
	SETZM	LW.S1		;ZERO ALL PAGING INFO
	SETZM	UW.S1
	SETZM	HB.S1
	SETZM	LC.UP		;[2420] RESET HIGHEST BLOCK NUMBER
>;[2247] IFE TOPS20
IFN TOPS20,<			;[1541]
	MOVE	T1,LW.LC	;[2202] GET THE BOTTOM
	MOVE	T2,UW.LC	;[2202] AND THE TOP
	PUSHJ	P,LC.OUT##	;[1541] UNMAP IT SO IT CAN CLOSE
	MOVE	T3,HL.S1	;[2247] GET THE UPPER BOUND
	LSH	T3,-9		;[2247] IN PAGES
	ADDI	T3,1		;[2247] NEED COUNT OF PAGES
	TXO	T3,PM%CNT	;[2251] TELL THE MONITOR ABOUT IT
	HRLZ	T2,LC.JF	;[2247] GET THE FORK HANDLE
	SETO	T1,		;[2247] WANT TO UNMAP THE PAGES
	PMAP%			;[2247] MAKE THEM GO AWAY
	 ERCAL	E$$OLC##	;[2247] UNEXPECTED FAILURE
	MOVE	T1,LC.LB
	IORI	T1,.IPM		;PRE-ALLOCATE ONE BLOCK ONLY
	MOVEM	T1,LC.AB
	SETZB	T1,LW.S1	;[2247] RESET LOWER WINDOW
	MOVEI	T2,.IPM		;[2247] NEED ONE PAGE
	MOVEM	T2,UW.S1	;[2247] MAPPED IN FOR WINDOW
	PUSHJ	P,LC.IN##	;[2247] MAP IT IN
>	;[1541] IFN TOPS20

;HERE TO ZERO THE RELOCATION TABLE
LNKZRT:	SKIPN	T1,RT.LB	;DO WE HAVE SPACE ALLOCATED?
	JRST	LNKZLS		;NO
	HRL	T1,T1
	ADDI	T1,1		;BLT PTR
	SETZM	-1(T1)		;CLEAR FIRST WORD
	BLT	T1,@RT.AB	;AND  REST
	MOVE	T1,RT.LB
	IORI	T1,.IPM		;PRE-ALLOCATE ONE BLOCK ONLY
	MOVEM	T1,RT.AB
	SKIPN	PAG.RT		;PAGING
	JRST	LNKZLS		;NO
	HALT
;HERE TO ZERO LOCAL SYMBOL AREA
LNKZLS:
IFN TOPS20,<			;[2202] 
	SKIPE	PAG.LS		;[2202] Paging?
	 JRST	LSNPAG		;[2202] Yes, Don't bother to BLT
  >	;[2202] IFN TOPS20

	MOVE	T1,LS.LB	;BASE
	HRL	T1,T1
	ADDI	T1,1		;BLT PTR
	SETZM	-1(T1)		;CLEAR FIRST WORD
	BLT	T1,@LS.AB	;AND  REST
LSNPAG:				;[1506]
	MOVE	T1,LS.LB
	ADDI	T1,1		;PRE-ALLOCATE FIRST WORD
	MOVEM	T1,LS.PT	;SO USER CAN NOT GET IT
	IORI	T1,.IPM		;PRE-ALLOCATE ONE BLOCK ONLY
	MOVEM	T1,LS.AB
	MOVEI	T1,.IPM		;NO. OF WORDS FREE
	MOVEM	T1,LS.FR	;IN THIS BLOCK
	SKIPN	PAG.LS		;PAGING?
	JRST	LNKZFX		;NO
IFN TOPS20,<			;[1541]
	MOVE	T1,LW.LS	;[2202] GET THE BOTTOM
	MOVE	T2,UW.LS	;[2202] AND THE TOP
	PUSHJ	P,LS.OUT##	;[1541] UNMAP IT SO IT CAN CLOSE
>	;[1541] IFN TOPS20
	MOVEI	T1,SC		;CHAN# IF ON DSK
	MOVEM	T1,IO.CHN
	PUSHJ	P,DVDEL.##	;DELETE FILE
	  JFCL			;INCASE OF ERRORS
	PUSHJ	P,DVZAP.##	;GET RID OF DATA BLOCK
	SETZM	LW.LS		;ZERO ALL PAGING INFO
	SETZM	UW.LS
	SETZM	HB.LS

;HERE TO ZERO AND REMOVE THE FIXUP AREA
LNKZFX:	MOVEI	T1,FX.IX	;AREA#
	SKIPE	TAB.LB(T1)	;SET UP?
	PUSHJ	P,XX.ZAP##	;YES, DELETE WHOLE AREA
	MOVE	T1,[FX.S1,,FX.S2]
	SETZM	FX.S1
	BLT	T1,FXC.SS	;CLEAR ALL POINTERS
;HERE TO ADD GS TO BG AND ZERO GS
LNKZBG:	SKIPE	BG.LB		;BOUND GLOBAL TABLE SET UP
	JRST	LNKZGS		;YES
	SETOM	BG.SCH		;WILL BE ALLOWED TO SEARCH THEM
	MOVEI	T2,^D128	;SETUP BRANCH TABLES
	PUSHJ	P,DY.GET##
	HRLI	T1,P1		;PUT INDEX IN P1 FOR @
	MOVEM	T1,BRNTBL	;LINK # ,, REL ADDRESS
	MOVEI	T2,^D128
	PUSHJ	P,DY.GET##
	HRLI	T1,P1		;PUT INDEX IN P1 FOR @
	MOVEM	T1,BRNADD	;LINK# ,, LOWEST ADDRESS
	MOVEI	T2,^D128
	PUSHJ	P,DY.GET##
	HRLI	T1,P1		;PUT INDEX IN P1 FOR @
	MOVEM	T1,BRNDSK	;LENGTH ,, DSK BLOCK #
	MOVE	T2,GS.PT	;LAST LOC USED
	SUB	T2,GS.LB	;- FIRST = LENGTH
	MOVSM	T2,(T1)		;STORE LENGTH
	MOVSI	T1,-^D127	;AOBJN WORD FOR NUMBER LEFT
	MOVEM	T1,BRNLEN
	MOVE	T1,GS.AB	;TOP IN ACTUAL USE
	CAML	T1,GS.UB	;ANY FREE?
	JRST	[MOVEI	P1,GS.IX	;EASIEST WAY IS TO EXPAND
		MOVEI	P2,.IPS		;BY ONE BLOCK
		PUSHJ	P,LNKCOR##
		  PUSHJ	P,E$$MEF##	;[1174]
		MOVNI	T1,.IPS		;NOW TAKE BACK EXTRA
		ADDM	T1,GS.FR	;NO MORE FREE THAN BEFORE
		ADDB	T1,GS.AB
		JRST	.+1]		;AND CONTINUE
	MOVEM	T1,BG.AB	;MOVE AREA
	MOVEM	T1,BG.UB	; BY MOVING THE POINTERS
	MOVE	T2,GS.LB
	MOVEM	T2,BG.LB
	MOVE	T2,GS.PT
	MOVEM	T2,BG.PT	;POINT TO NEXT FREE
	MOVE	T2,GS.FR
	MOVEM	T2,BG.FR	;AND FREE SPACE IN IT
	ADDI	T1,1		;NEXT FREE WILL BE START OF NEW GS
	MOVEM	T1,GS.LB
	JRST	LNKZHT		;NOW SET UP HASH TABLES ETC.
LNKZGS:	MOVE	T1,BG.UB	;SEE IF ENOUGH CORE
	SUB	T1,BG.PT
	ADD	T1,GS.UB	;IN GS +BG
	SUB	T1,GS.PT
	CAIL	T1,.IPS		;SO WE CAN MOVE AND ALLOCATE 1 BLOCK
	JRST	LNKZG1		;OK, NO PROBLEM
	MOVEI	P1,BG.IX
	MOVEI	P2,.IPS
	PUSHJ	P,LNKCOR##	;EXPAND
	  PUSHJ	P,E$$MEF##	;[1174] TOO BAD
	MOVNI	T1,.IPS
	ADDM	T1,BG.AB	;DON'T REALLY WANT IT
LNKZG1:	MOVE	P1,BRNLEN	;GET NO. OF LINKS IN BRANCH
	AOBJP	P1,[HALT]
	MOVEM	P1,BRNLEN	;ALL OK
	HRRZ	P1,P1		;INDEX ONLY
	CAMLE	P1,BRNMAX	;DEEPEST YET?
	MOVEM	P1,BRNMAX	;YES, STORE FOR LATER
	MOVE	T2,BG.PT	;NEXT FREE LOC
	SUB	T2,BG.LB	;REMOVE BASE
	HRL	T2,CS+CS.NUM	;[1400] LINK # IN LEFT 
	MOVEM	T2,@BRNTBL
	HLLZ	T3,T2		;LINK#
	HRR	T3,PH+PH.ADD	;[1400] STARTING ADDRESS
	MOVEM	T3,@BRNADD	;IN CASE RELOCATABLE
	MOVE	T3,GS.PT	;NOW FOR LENGTH OF NEW GLOBAL
	SUB	T3,GS.LB
	ADDM	T3,BG.PT	;ACCOUNT FOR IT
	MOVSM	T3,@BRNDSK
	ADD	T2,BG.LB	;PUT BACK BASE
	HRL	T2,GS.LB	;FORM BLT PTR
	BLT	T2,@BG.PT	;MOVE ALL WORDS
	HRRZ	T1,BG.PT	;NOW CLEAN UP
	SETZM	(T1)
	HRL	T1,T1
	ADDI	T1,1
	BLT	T1,@GS.AB	;ALL OF GS AREA
	MOVE	T1,BG.PT
	MOVE	T2,T1
	IORI	T1,.IPM		;THIS IS TOP
	MOVEM	T1,BG.AB
	MOVEM	T1,BG.UB	;NO WASTED SPACE
	SUB	T2,T1		;SEE WHATS LEFT
	MOVMM	T2,BG.FR
	ADDI	T1,1		;START OF GS
	MOVEM	T1,GS.LB
;HERE TO SET UP HASH TABLE
LNKZHT:	IORI	T1,.IPM		;MUST ALLOCATE 1 BLOCK
	MOVEM	T1,GS.AB	;TO KEEP LNKCOR HAPPY
	ANDCMI	T1,.IPM-1	;PRE-ALLOCATE FIRST WORD
	HRLI	T1,P2		;USES P2 AS INDEX
	MOVEM	T1,HT.PTR	;START OF NEW HASH TABLE
	MOVEI	T2,I.PRM	;INITIAL HASH TABLE
	MOVEM	T2,HT.PRM	; PRIME NUMBER
	HRRZI	T1,I.PRM(T1)	;SEE IF ENOUGH SPACE FOR WHAT WE NEED
	CAMG	T1,GS.UB	;WELL?
	JRST	LNKZB1
	SUB	T1,GS.UB	;EXTRA WE NEED
	MOVEI	P1,GS.IX
	MOVE	P2,T1
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,E$$MEF##	;[1174] FAILED
LNKZB1:	MOVE	T1,GS.LB	;GET BASE
	SETOM	(T1)		;MAKE NON-ZERO SO WE DON'T LOAD JOBDAT AGAIN
	ADDI	T1,1+<I.PRM+.L-1>/.L*.L	;SPACE RESERVED FOR HASH TABLE
	MOVEM	T1,GS.PT	;MAKE SURE CORRECT
	MOVE	T2,T1
	IORI	T2,.IPM		;NOW RESET TO WHAT IT SHOULD BE
	MOVEM	T2,GS.AB	;INCASE MORE THAN ONE BLOCK LONG
	SUB	T1,T2		;- WHATS FREE
	MOVNM	T1,GS.FR	;IN GS BLOCK
	MOVEI	T1,I.PRM*.HS%/^D100	;INITIAL AMOUNT FREE
	MOVEM	T1,HSPACE	;BEFORE WE REHASH
	MOVSI	T1,(POINT 18,0)
	MOVEM	T1,PRMPTR	;START HASH POINTER AT REL 0
	SETZM	GS.LNK		;NO FREE SPACE IN LINKED LISTS
	SETZM	GS.FSP
;HERE TO INITIALIZE THE REST OF LOW CORE
E$$ELN::.ERR.	(MS,.EC,V%L,L%I6,S%I,ELN,<End of>) ;[1174]
	.ETC.	(JMP,.EC,,,,.ETLNN##) ;[1174]
	.ETC.	(BKL)		;[1174] BLANK LINE IN THE LOG FILE
LNKZA:	MOVEI	R,1		;POINT TO RELOC TABLE 1
	MOVE	R,@RC.TB
	MOVE	T1,PH+PH.NFL	;[1400] NEXT FREE LOC
	MOVEM	T1,PH+PH.ADD	;[1400] SET ORIGIN OF NEXT LINK
	MOVEM	T1,RC.CV(R)	;SET AS NEW CURRENT VALUE
	MOVEM	T1,RC.HL(R)	;[1152] AND AS NEW FIRST FREE
	PUSHJ	P,Z.INEX##	;CLEAR INCLUDE/EXCLUDE STORAGE
	MOVSS	INCPTR		;BOTH HALVES
	MOVSS	EXCPTR
	PUSHJ	P,Z.INEX##
	MOVE	T1,[OV1.Z0,,OV1.Z0+1]
	SETZM	OV1.Z0		;CLEAR PASS1 DATA
	BLT	T1,OV1.ZE
	MOVE	T1,[CS+CS.NUM,,CS+CS.NUM+1] ;[1400]
	SETZM	CS+CS.NUM	;[1400]
	BLT	T1,CS+CS.LEN-1	;[1400]
	SKIPN	T1,LINKTB	;[660] .LINK TABLE SET UP?
	JRST	LNKZA0		;[660] NO
	SETZM	LINKTB		;[660] YES, DELETE IT
	HRRZ	T1,T1		;[660] ADDRESS TO GIVE BACK ONLY
	MOVEI	T2,LN.12	;[660] LENGTH
	PUSHJ	P,DY.RET##	;[660] RETURN THE BLOCK
LNKZA0:	SETZM	%OWN		;[660] CANNOT LINK ALGOL OWN YET
	SETZM	HL.S1
	SETZM	MNSEEN		;NO MAIN PROGRAMS SEEN YET
	SETZM	MNTYPE		;SO DON'T KNOW LIBRARIES, CPU ETC.
	SETZM	NOLIBS
	SETZM	NAMPTR
	SETZM	PRGNAM
	SETZM	LSTGBL		;[2255] ZERO GLOBAL POINTER
	SETZM	LSTLCL		;[2255] AND LOCAL POINTER

;CONTINUED ON NEXT PAGE
;FALL IN FROM PREVIOUS PAGE

	SETZM	GOTO		;SO WE DON'T LOOP
	HLRS	ARSIZE		;[635] RESET STICKY SIZE FOR ARL TABLE
	MOVEI	T1,.SPL		;SET DEFAULT SPACE
	MOVEM	T1,SPACE	;[635] FOR NON-ROOT LINKS
	AOS	LSYM		;ALLOCATE FIRST WORD
	HLLZ	T1,OVINEX	;SEE IF ANY INCLUDES TO SETUP
	JUMPE	T1,LNKZA1	;NO
	MOVEI	T2,.EXC		;GET SPACE
	PUSHJ	P,DY.GET##
	HRLZM	T1,INCPTR	;SET IT UP
	HLLZ	T2,OVINEX	;FROM
	HRR	T2,T1		;TO
	BLT	T2,.EXC-1(T1)	;MOVE
	HRRZ	T2,(T1)		;SEE IF MORE
	SKIPE	T2		;NO
	PUSHJ	P,OVRINX	;YES
LNKZA1:	HRRZ	T1,OVINEX	;SEE IF EXCLUDES
	JUMPE	T1,LNKZA2	;NO
	MOVEI	T2,.EXC		;GET SPACE
	PUSHJ	P,DY.GET##
	HRLZM	T1,EXCPTR	;SET IT UP
	HRLZ	T2,OVINEX	;FROM
	HRR	T2,T1		;TO
	BLT	T2,.EXC-1(T1)	;MOVE
	HRRZ	T2,(T1)		;GET NEXT
	SKIPE	T2		;IF NONE
	PUSHJ	P,OVRINX	;OTHERWISE MOVE REST
LNKZA2:	MOVE	T1,OVERLW	;GET OVERLAY SWITCHES
	SKIPN	RT.LB		;ALREADY SETUP?
	TXNN	T1,$OVRELOC	;NO, BUT DO WE NEED IT
	POPJ	P,		;NO, RETURN TO EITHER LNKOV1 OR LNKOV2
	MOVEI	P1,RT.IX	;AREA WE WANT
	PJRST	XX.INI##	;SET IT UP
LNKTCK:	SKIPE	RT.LB		;RELOCATABLE?
	PUSHJ	P,RT.P2##	;YES, SETUP BYTE PTR
	SUB	P2,PH+PH.ADD	;[1400] REMOVE BASE ADDRESS INCASE ABS
	SUB	P3,PH+PH.ADD	;[1400] ...
	SKIPE	PAG.S1		;PAGING?
	JRST	LNKTC2		;YES
	ADD	P2,LC.LB	;RELOCATE
	CAMG	P2,LC.AB	;FIT IN WHAT WE HAVE?
	JRST	LNKTC1		;YES
	SUB	P2,LC.AB	;GET EXTRA REQUIRED
	MOVEI	P1,LC.IX
	PUSHJ	P,LNKCOR##
	  JRST	LNKTC2		;MUST BE ON DSK NOW
	SUB	P3,LW.S1	;INCASE WE DUMPED CORE
LNKTC1:	ADD	P3,LC.LB	;RELOCATE
	POPJ	P,

LNKTC2:	PUSHJ	P,PG.LSG##	;MAKE SURE IN CORE
	 CAMLE	P2,UW.LC	;[2262] HIGH ADDRESS IN WINDOW?
	 PUSHJ	P,E$$MEF	;[2262] NO, NOT ENOUGH MEMORY
	JRST	LNKTC1		;IS BY NOW
SUBTTL	DO OPEN & ENTER FOR OV FILE


OC.OPN:	MOVEI	T1,%OC			;[1230] NOW THAT ROOT IS DONE, FIND OUT
	MOVEM	T1,IO.CHN		;[1230]   WHAT TO CALL THE OVERLAY FILE
	PUSHJ	P,DVNAM.##		;[1230]   ..
	MOVEI	T2,LN.IO		;[1230] GET SPACE FOR OVERFLOW SPEC'S
	PUSHJ	P,DY.GET##		;[1230]   BLOCK
	MOVEM	T1,IO.PTR+OC		;[1230] SAVE ITS ADDRESS FOR LATER
	MOVE	T2,T1			;[1230] POINTER TO OVERFLOW BLOCK IN T2
	MOVE	T1,IO.PTR+%OC		;[1230] POINTER TO USER'S BLOCK IN T1
	MOVEI	T3,.IODPR		;[1230] SET UP OVERFLOW BLOCK WITH
	MOVEM	T3,I.MOD(T2)		;[1230]   PROPER DATA--FIRST, DATA MODE
	MOVEI	T3,LN.RIB-1		;[1230] SIZE OF EXTENDED RIB
	MOVEM	T3,I.RIB+.RBCNT(T2)	;[1230]   ..
	MOVE	T3,JOBNUM		;[1230] FILE NAME nnnOVL
	HRRI	T3,'OVL'		;[1230]   ..
	MOVEM	T3,I.RIB+.RBNAM(T2)	;[1230]   ..
	MOVSI	T3,'TMP'		;[1230] EXTENSION .TMP
	MOVEM	T3,I.RIB+.RBEXT(T2)	;[1230]   ..
	MOVX	T3,<INSVL. 077,RB.PRV>	;[1230] HIGH PROT FOR OVERFLOW FILES
	MOVEM	T3,I.RIB+.RBPRV(T2)	;[1230]   ..
	SKIPN	T3,I.RIB+.RBEST(T1)	;[1230] USE USER'S ESTIMATE
	MOVEI	T3,1000			;[1230]   OR LARGE DEFAULT (REAL PROGS
	MOVEM	T3,I.RIB+.RBEST(T2)	;[1230]   ARE BIG)
	MOVEI	T1,%OC			;[1230] CHANNEL OF USER'S OVERLAY FILE
	MOVEI	T2,OC			;[1230] CHANNEL OF LINK'S OVERFLOW FILE
	PUSHJ	P,DVSUP.##		;[1230] PUT OVERFLOW FILE IN RIGHT PLACE
	  JRST	E$$EOV			;[1230] FAILED
	POPJ	P,			;[1230] DONE

E$$EOV::PUSH	P,[OC]		;[1230] TELL ERROR ROUTINE CHANNEL NUMBER
	.ERR.	(LRE,.EC,V%L,L%F,S%F,EOV,<Error creating overlay file>) ;[1174]
SUBTTL	SWITCH ACTION -- /NODE:name


%NODE::
%RESET::
	PUSHJ	P,.SAVE4##
	SKIPN	LINKSEEN	;PREVIOUS SEGMENT COMPLETED?
	PUSHJ	P,[PUSHJ P,.SAVE4##	;WILL NEED P2
		MOVE	P2,LNKMAX	;OVERLAY COUNT
		ADDI	P2,1		;OVERLAY NUMBER
	E$$LSM::.ERR.	(MS,.EC,V%L,L%W,S%W,LSM,</LINK switch missing while loading link number >) ;[1174]
		.ETC.	(DEC,.EC!.EP,,,,P2) ;LINK NUM
		.ETC.	(STR,,,,,,< -- assumed>)
		PUSHJ	P,SYSLB1##	;SEARCH LIBRARIES
		SETZM	LNKNAM		;/LINK:<LNKNAM>
		PJRST	LINKGT]		;FORCE /LINK
	SETZM	LINKSEEN	;STARTING NEW SEGMENT
	MOVE	T2,2(P2)	;RESTORE /NODE VALUE
	TLNN	T2,-1		;TEST FOR NAME
	JRST	RSTA		;CERTAINLY NOT
	TLC	T2,-1		;BUT MIGHT BE NEGATIVE NO.
	TLCE	T2,-1
	JRST	RSTL		;NO, ITS A NAME
RSTA:	CAMN	T2,LNKMAX	;TEST FOR TRIVIAL CASE
	POPJ	P,		;IT WAS, LEAVE AS IS
	CAMLE	T2,LNKMAX	;IS IT IN RANGE?
	JRST	E$$LNL		;[1174] NO
	MOVEM	T2,CS+CS.NUM	;[1400] NO, STORE SO WE KNOW WHO TO LINK TO
	MOVE	P2,T2		;SAFER PLACE FOR LINK#
	JUMPE	P2,RESET0	;RESET TO ROOT IS SPECIAL
	JUMPL	P2,RSTN		;STILL A NEGATIVE NO.?
	MOVS	T1,LSTPTR	;SEE IF SPECIAL CASE
	MOVE	T2,(T1)		;OF WANTING PENULTIMATE LINK
	CAIE	P2,(T2)
	JRST	RST2		;NO, GENERAL CASE
;HERE ON A /NODE TO THE ROOT LINK.

RSTB:	HLL	T1,(T1)		;FORM AOBJN PTR
	ADD	T1,[2,,2]	;BYPASS LINK# AND BACK PTR
	SKIPN	(T1)		;BLANK?
	JRST	RST1		;YES
	AOBJN	T1,.-2
	HLRZ	T1,LSTPTR	;GET NODE BLOCK
	HLRE	T2,(T1)		;GET LENGTH
	MOVM	T2,T2
	ADDI	T2,1		;MAKE ONE MORE
	PUSHJ	P,DY.GET##
	HLLZ	T3,LSTPTR	;FROM
	HRR	T3,T1		;TO, BLT PTR
	MOVN	T4,T2		;- LENGTH
	HLL	T2,LSTPTR	;SAVE START OF OLD BLOCK
	HRLM	T1,LSTPTR
	ADDI	T1,-2(T2)	;END OF BLT
	BLT	T3,(T1)		;MOVE DATA
	HRRM	T1,LSTPTR	;RESET LAST POINTER
	SUBI	T1,-2(T2)	;BACKUP
	HRLM	T4,(T1)		;SET NEW COUNT
	HLRZ	T1,T2		;OLD ORIGIN
	HRRZI	T2,-1(T2)	;OLD BLOCK SIZE
	PUSHJ	P,DY.RET##
	HLRZ	T1,LSTPTR	;GET NEW BLOCK AGAIN
	HRRZ	T2,(T1)		;THIS LINK#
	SKIPN	T3,1(T1)	;BACK POINTER
	JRST	[MOVEM	T1,FSTPTR	;MUST BE LINK# 0
		JRST	RSTBB]
	MOVS	T4,2(T3)	;GET LINK#
	CAIE	T2,(T4)		;ONE WE WANT
	AOJA	T3,.-2		;MUST BE THERE
	HRRM	T1,2(T3)	;MAKE IT POINT TO NEW BLOCK
RSTBB:	MOVEI	T3,2(T1)	;NOW LOOK AT POSSIBLE FORWARD PTRS
RSTC:	SKIPN	T2,(T3)		;GET POINTER
	JRST	RST1		;ALL DONE
	TRNE	T2,-1		;FORWARD PTR?
	HRRM	T1,1(T2)	;YES
	AOJA	T3,RSTC
;THIS CASE IS SPECIAL IN THAT ALL THAT HAS TO BE DONE IS TO DELETE
;THE LAST LINK STORED AND ADJUST THE POINTERS ACCORDINGLY
RST1:	AOS	LSTPTR		;MAKE ROOM IN CURRENT BLOCK
RST1A:	HRRZ	P1,BRNLEN	;GET POINTER TO LAST LINK STORED
	PUSHJ	P,CHKBRN	;SEE IF LINK AS AT TOP OF TABLE
	  JRST	RST1C		;ON DSK SO NOTHING TO DO

RST1B:	SETZM	(T1)		;ZERO FIRST WORD
	HRLZ	T2,T1
	HRRI	T2,1(T1)	;BLT PTR
	BLT	T2,@BG.AB	;DELETE ALL AREA
	MOVEM	T1,BG.PT	;NEW TOP OF AREA USED
	IORI	T1,.IPM		;PUT ON BLOCK BOUND
	MOVEM	T1,BG.AB	;MAKE NEW TOP
	MOVEM	T1,BG.UB
	ADDI	T1,1		;NEW START OF GS AREA
	HRLZ	T2,GS.LB
	HRR	T2,T1		;BLT PTR
	SUB	T1,GS.LB	;- DIFF
	JUMPE	T1,RST1C	;SHOULD NOT HAPPEN
	ADDM	T1,GS.LB	;FIXUP PTR
	ADDM	T1,GS.AB
	ADDM	T1,GS.PT
	ADDM	T1,HT.PTR
	BLT	T2,@GS.AB	;MOVE AREA DOWN
	MOVM	T1,T1		;+ DIFF
	ADD	T1,GS.AB	;GET OLD END AGAIN
	HRRZ	T2,GS.AB
	HRLI	T2,1(T2)
	HRRI	T2,2(T2)	;BLT PTR
	SETZM	-1(T2)
	BLT	T2,(T1)		;CLEAR ALL OF AREA LEFT
RST1C:	MOVE	T1,BRNLEN	;GET OLD LENGTH
	HRRZ	P1,T1		;INDEX INTO BRANCH TABLES
	SETZM	@BRNTBL		;AVIODS CONFUSION
	SETZM	@BRNDSK
	SETZM	@BRNADD
	SUB	T1,[1,,1]	;BACKUP
	MOVEM	T1,BRNLEN	;AND RESET IT
	MOVE	P1,CS+CS.NUM	;[1400] GET NUMBER WE WANT
	JRST	RST06		;AND READ IN THE PREAMBLE
;HERE TO RESET TO SOME LINK ON THE CURRENT PATH
;THE LINKS ABOVE THE REQUIRED ONE MUST BE DELETED
;AND ALL POINTERS ADJUSTED

RST2:	PUSHJ	P,DLTDSK	;DELETE POSSIBLE DSK FILE
	PUSHJ	P,MRKLNK	;MARK IT AS REQUIRED
	  JRST	RST3		;NOT IN BRANCH
	PUSHJ	P,.SAVE2##	;NEED P2
	MOVS	P1,LSTPTR	;WALK BACKWARDS THROUGH TREE
	HRRZ	T1,(P1)		;GET LINK#
	MOVE	P1,1(P1)	;AND NEXT PTR
	CAME	P2,T1		;BACK TO ONE WE WANT?
	JRST	.-3		;NOT YET
RST2A:	HRRZ	P2,(P1)		;LINK#
	PUSHJ	P,MRKLNK	;WE NEED THIS ONE
	  PUSHJ	P,E$$LNM##	;[1174] MUST BE IN MEMORY
	MOVE	P1,1(P1)	;GET PREVIOUS
	JUMPN	P2,RST2A	;END AT 0
	PUSHJ	P,ADJBRN	;NOW REMOVE WHATS NOT NEEDED
RST2B:	PUSHJ	P,BKPBRN	;DELETE AREA AND BACKUP BRNTBL
	SUBI	P1,1
	CAME	P1,P2		;DONE THEM ALL YET?
	JRST	RST2B		;NO, LOOP
	HLRZ	P2,@BRNTBL	;GET LINK# WE REALLY WANTED
	MOVS	T1,LSTPTR	;GET NODE PTR
	HRRZ	T2,(T1)		;GET NUMBER
	CAMN	T2,P2		;WHAT WE WANTED?
	JRST	RST2D		;YES
	HLL	T1,(T1)		;AOBJN
	ADD	T1,[2,,2]	;BYPASS HEADER & BACK PTR
	MOVS	T2,(T1)		;GET LINK#
	CAIN	P2,(T2)		;ONE WE WANTED?
	JRST	.+3
	AOBJN	T1,.-3		;NOT YET
	PUSHJ	P,E$$LNM##	;[1174] MUST BE IN MEMORY
	TLNN	T2,-1		;FORWARD PTR?
	JRST	RST2D		;NO?
	MOVS	T2,T2		;GET PTR
	HRLM	T2,LSTPTR	;POINT TO NEW
	HLL	T2,(T2)		;AOBJN PTR
	ADD	T2,[2,,2]	;BYPASS LINK# AND BACK PTR
	SKIPE	(T2)		;LOOK FOR BLANK
	AOBJN	T2,.-1		;OR END OF LIST
	SUBI	T2,1		;BACKUP 1 TO POINT TO LAST USED
	HRRM	T2,LSTPTR
RST2D:	MOVE	T1,[1,,1]	;FAKE OUT BRNLEN
	ADDM	T1,BRNLEN	;SO WE CAN REMOVE NON-EXISTENT TOP
	MOVS	T1,LSTPTR
	JRST	RSTB		;YES, NOW MOVE GS DOWN
;HERE TO RESET TO SOME LINK NOT ON THE CURRENT PATH
;ALL THE LINKS NOT REQUIRED MUST BE DELETED
;THEN ALL OTHER LINKS ON THE PATH READ IN

RST3:	MOVE	P1,P2		;WE WANTED THIS LINK
	PUSHJ	P,TR.WLK##	;FIND NODE
	HLRZ	T1,P1		;GET ADDRESS OF START OF NODE
	HRRZ	T2,(T1)		;GET LINK#
	CAIN	T2,(P1)		;ONE WE WANTED?
	JRST	RST3A		;YES, AS EXPECTED
	MOVEI	T2,4		;NO, MUST BE A NEW NODE
	PUSHJ	P,DY.GET##	;SO GET SPACE FOR IT
	HRRZ	T2,P1		;LINK #
	HRLI	T2,-4		;LENGTH
	MOVEM	T2,(T1)		;HEADER WORD
	HLRZM	P1,1(T1)	;BACK POINTER
	HRLI	T1,1(T1)	;MAKE LSTPTR
	MOVSM	T1,LSTPTR
	HLRZ	T2,P1		;NOW LOOK BACK TO FIND FATHER
	HLRZ	T3,2(T2)
	CAIE	T3,(P1)		;MATCHING ONE WE WANT?
	AOJA	T2,.-2		;MUST BE THERE
	HRRM	T1,2(T2)	;POINT TO IT
	JRST	RST3B		;NOW CONTINUE

RST3A:	HRLM	T1,LSTPTR	;START OF NODE
	ADD	T1,[2,,2]	;BYPASS LINK# AND BACK PTR
	HLL	T1,(T1)		;FORM AOBJN PTR
	SKIPN	(T1)		;LOOK FOR BLANK
	JRST	.+3
	AOBJN	T1,.-2		;OR END OF LIST
	SUBI	T1,1		;END SO BACKUP TO LAST
	HRRM	T1,LSTPTR	;LSTPTR IS NOW POINTING TO NODE WE WANT
RST3B:	MOVS	P1,LSTPTR
	PUSH	P,P2		;DEPTH WE FINALLY WANT
	CAIA
RST3C:	MOVE	P1,1(P1)	;GET BACK PTR
	HRRZ	P2,(P1)		;GET LINK #
	PUSHJ	P,MRKLNK	;MARK AS REQUIRED
	  JFCL			;TOO BAD, WILL HAVE TO READ IT IN LATER
	JUMPN	P2,RST3C	;FINISH ON 0
	PUSHJ	P,ADJBRN	;REMOVE WHATS NOT NEEDED
RST3D:	CAMN	P1,P2		;NOTHING TO REMOVE?
	JRST	RST3E
	PUSHJ	P,DLTBRN	;REMOVE SYMBOL TABLE
	SOJA	P1,RST3D	;SEE IF DONE
;HERE WHEN ALL OLD SYMBOL TABLES DELETED. READ IN NEW ONES.

RST3E:	POP	P,P2		;RECOVER DEPTH
	MOVE	T1,BRNLEN	;DEPTH WE NOW HAVE
	SUBI	P2,(T1)		;DIFFERENCE
	HRL	P2,P2		;IN BOTH HALVES
	ADDB	P2,BRNLEN	;MAKE IT WHAT WE WANT
	HRRZS	P1,P2
	HLRZ	T1,LSTPTR	;START OF BACK PATH
RST3F:	HRRZ	T2,(T1)		;GET LINK#
	SKIPE	@BRNDSK		;IF 0 THEN ITS NOT YET SETUP
	JRST	RST3G		;ALL DONE
	HRLZM	T2,@BRNTBL	;STORE # WE NEED
	MOVE	T1,1(T1)	;GET NEXT PTR
	SOJG	P1,RST3F	;LINK# IS ALWAYS IN CORE

;HERE TO READ IN ALL REQUIRED SYMBOL TABLES
RST3G:	MOVNI	P2,1(P2)
	HRLZ	P2,P2		;FORM AOBJN WORD
RST3H:	HRRZ	P1,P2		;INDEX FOR TABLE LOOKUPS
	SKIPE	@BRNDSK		;SEE IF ALREADY SET
	AOBJN	P2,.-2		;WILL EVENTUALLY SKIP
	HLRZ	P1,@BRNTBL	;GET LINK#
	ROT	P1,-1		;USUAL METHOD TO PICK CORRECT HALF
	JUMPL	P1,[HRRZ T1,@LNKTBL
		JRST	.+2]
	HLRZ	T1,@LNKTBL	;FOR USETI TO GET PREAMBLE
	USETI	OC,(T1)		;SET ON BLOCK
	DMOVE	T1,PHIOWD
	IN	OC,T1		;READ IT IN
	  CAIA			;OK
	PUSHJ	P,E$$IOV##	;[1174] INPUT ERROR
	HRRZ	P1,P2		;INDEX INTO BRANCH TABLES
	HRRZ	T1,PH+PH.ADD	;[1400] LOWER ADDRESS
	HLL	T1,@BRNTBL	;LINK #
	MOVEM	T1,@BRNADD	;INCASE RELOCATED

RST3I:	MOVE	T1,PH+PH.GLB	;[1400] POINTER TO GLOBAL SYMBOLS
	HLRE	T2,T1		;WORD COUNT (FROM IOWD)
	MOVM	T2,T2
	ADD	T2,BG.PT	;TOP WE NEED
	CAMG	T2,BG.AB	;IS THERE ENOUGH?
	JRST	RST3J		;YES
	SUB	T2,BG.AB	;EXCESS
	PUSH	P,P2		;SAVE AOBJN COUNTER
	MOVEI	P1,BG.IX
	MOVE	P2,T2		;WHAT WE NEED
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,E$$MEF##	;[1174]
	POP	P,P2
	JRST	RST3I		;TRY AGAIN
;HERE WHEN ENOUGH ROOM. READ IN REQUIRED GLOBAL TABLE.

RST3J:	USETI	OC,(T1)		;SET ON BLOCK
	HRR	T1,BG.PT	;IOWD (ALMOST)
	HRRI	T1,-1(T1)
	SETZ	T2,
	IN	OC,T1		;READ IN GLOBAL TABLE
	  CAIA
	PUSHJ	P,E$$IOV##	;[1174] INPUT ERROR
	HRRZ	P1,P2		;TO HOLD BRN DEPTH
	HRRZI	T2,1(T1)	;GET LOWER ADDRESS BACK
	SUB	T2,BG.LB	;MAKE RELATIVE
	HRRM	T2,@BRNTBL	;START OF SYMBOL AREA
	HLRE	T2,T1		;- LENGTH
	MOVM	T2,T2
	HRLM	T2,@BRNDSK	;STORE LENGTH
	ADDM	T2,BG.PT	;ACCOUNT FOR AREA
	AOBJN	P2,RST3H	;GET NEXT
	JRST	RST2D		;NOW CORRECT PTRS
RSTN0:	PUSHJ	P,BKPBRN	;BACKUP ONE LINK
	AOS	P2,CS+CS.NUM	;[1400] GET ITS FATHER
;	JRST	RSTN		;AND SEE IF ALL DONE

RSTN:	MOVN	T1,LNKMAX	;CHECK FOR INRANGE LINK
	CAMGE	P2,T1		;NODE REQUESTED BEFORE ROOT?
	JRST	E$$NBR		;[1174] YES - ERROR
	MOVS	T1,LSTPTR	;MUST BACKUP BY ONE LEVEL
	CAME	P2,[-1]		;BACK TO LAST YET?
	JRST	RSTN0		;NO, KEEP TRYING
	HRRZ	P2,(T1)		;GET LINK#	
	MOVEM	P2,CS+CS.NUM	;[1400] SET IT
	JUMPE	P2,RESET0	;ROOT IS SPECIAL
	JRST	RST2		;DO IT


RSTL:	MOVS	T1,LNMPTR	;GET POINTER
	JUMPE	T1,E$$LNN	;[1174] ERROR
RSTLA:	CAMN	T2,(T1)		;IS THIS IT
	JRST	RSTLF		;YES
	HRRZ	T1,1(T1)	;GET FORWARD PTR
	JUMPN	T1,RSTLA	;TRY AGAIN
E$$LNN::.ERR.	(MS,.EC,V%L,L%W,S%W,LNN,<Link name >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,T2)
	.ETC.	(STR,,,,,,< not assigned>)
	POPJ	P,

E$$LNL::.ERR.	(MS,.EC,V%L,L%W,S%W,LNL,<Link number >) ;[1174]
	.ETC.	(DEC,.EC!.EP,,,,T2)
	.ETC.	(STR,,,,,,< not loaded>)
	POPJ	P,

RSTLF:	HLRZ	T2,1(T1)	;GET NUMBER
	JRST	RSTA		;AND RETURN

E$$NBR::.ERR.	(MS,,V%L,L%F,S%F,NBR,<Attempt to position to node before the root>) ;[1174]
;HERE IF RESET IS ALL THE WAY BACK TO THE ROOT
RESET0:	MOVE	T1,FSTPTR
	HLL	T1,(T1)		;FORM AOBJN
	ADD	T1,[2,,2]	;BYPASS LINK# AND BACK PTR
	SKIPN	(T1)		;LOOK FOR NULL IN CURRENT BLOCK
	JRST	RST0A		;FOUND IT
	AOBJN	T1,.-2
	HLRE	T2,@FSTPTR	;GET LENGTH
	MOVM	T2,T2
	ADDI	T2,1		;MAKE ONE MORE
	PUSHJ	P,DY.GET##
	HRLZ	T3,FSTPTR	;FROM
	HRR	T3,T1		;TO, BLT PTR
	MOVN	T4,T2		;- LENGTH
	ADDI	T1,-2(T2)	;END OF BLT
	BLT	T3,(T1)		;MOVE DATA
	SUBI	T1,-2(T2)	;BACKUP
	HRLM	T4,(T1)		;SET NEW COUNT
	EXCH	T1,FSTPTR	;EXCH OLD WITH NEW
	HRRZI	T2,-1(T2)	;OLD BLOCK SIZE
	PUSHJ	P,DY.RET##
	HRRZ	T3,FSTPTR	;GET NEW BLOCK AGAIN
	MOVEI	T1,2(T3)	;NOW LOOK AT POSSIBLE FORWARD PTRS
RST0C:	SKIPN	T2,(T1)		;GET POINTER
	JRST	RST0A		;ALL DONE
	TRNE	T2,-1		;FORWARD PTR?
	HRRM	T3,1(T2)	;YES
	AOJA	T1,RST0C

RST0A:	HRL	T1,FSTPTR
	MOVEM	T1,LSTPTR	;RESET TREE PTR
	PUSHJ	P,DLTDSK	;DELETE DSK FILE, MARK LINKS NOT IN CORE
	HRRZ	P1,BRNLEN	;NO. OF LINKS TO SCAN
RST01:	HLRZ	T2,@BRNTBL	;GET LINK #
	JUMPE	T2,RST02	;FOUND IT
	SETZM	@BRNTBL		;ZERO THE TABLE SLOTS
	SETZM	@BRNDSK
	SETZM	@BRNADD
	SOJGE	P1,RST01	;LOOP
	  PUSHJ	P,E$$LNM##	;[1174] MUST BE IN MEMORY

RST02:	HRRZ	T1,@BRNTBL	;GET ORIGIN OF TABLE
	JUMPE	T1,RST03	;ALREADY AT BOTTOM
	HRLZ	T2,T1
	HRR	T2,BG.LB	;BLT PTR
	HLRZ	T3,@BRNDSK	;GET LENGTH OF THIS TABLE
	ADDB	T1,T3		;NEXT FREE WORD
	MOVEM	T1,BG.PT	;RESET NEXT FREE PTR
	BLT	T2,-1(T2)	;MOVE DOWN
	JRST	RST04		;NOW ZERO THE REST AND GIVE IT AWAY
RST03:	HLRZ	T3,@BRNDSK	;GET LENGTH
	ADD	T3,BG.LB	;+ BASE
	MOVEM	T3,BG.PT	;NEW PTR TO NEXT FREE
RST04:	HRLZ	T1,T3
	HRRI	T1,1(T3)	;BLT PTR
	SETZM	-1(T1)		;[664] CLEAR CORE
	BLT	T1,@BG.AB	;BEFORE WE GIVE IT AWAY
	MOVE	T1,T3
	IORI	T1,.IPM
	MOVEM	T1,BG.AB	;HIGHEST IN ACTUAL USE
	SUBM	T1,T3		;GET FREE SPACE
	MOVEM	T3,BG.FR	;NO. OF WORDS FREE IN LAST BLOCK
	CAML	T1,BG.UB	;JUST INCASE NOTHING TO GIVE AWAY
	JRST	RST05		;NOT VERY LIKELY!
	MOVEM	T1,BG.UB
	AOS	T3,T1		;WHERE IT WILL GO
	HRL	T1,GS.LB	;FROM
	SUB	T3,GS.LB	;- NEGATIVE DIFF
	ADDM	T3,GS.LB	;FIXUP ALL GS PTR
	ADDM	T3,GS.PT
	ADDM	T3,HT.PTR
	MOVE	T2,GS.PT	;NEXT FREE
	HRLI	T2,1(T2)	;BLT PTR (SWAPPED)
	BLT	T1,-1(T2)	;MOVE DOWN
	SETZM	(T2)		;CLEAR REST
	MOVS	T2,T2		;PUT BLT PTR RIGHT WAY ROUND
	BLT	T2,@GS.AB	;CLEAR CORE
	ADDM	T3,GS.AB	;SET LOWER
RST05:	MOVE	T1,BRNLEN	;GET AOBJN POINTER
	HRLS	T2,BRNLEN	;PUTINDEX IN BOTH SIDES
	SUB	T1,T2		;GET ORIGINAL PTR
	HLLZM	T1,BRNLEN	;ONLY LINK 0 IN TABLE
	SETZ	P1,		;INDEX FOR LINK # 0
RST06:	ROT	P1,-1		;CUT IN HALF
	JUMPL	P1,[HRRZ T1,@LNKTBL
		JRST	.+2]
	HLRZ	T1,@LNKTBL	;GET BLOCK
	USETI	OC,(T1)		;OF PREAMBLE
	DMOVE	T1,PHIOWD
	IN	OC,T1
	  PJRST	LNKZA		;NOW ZERO WHAT WE DON'T NEED
	PUSHJ	P,E$$IOV##	;[1174] INPUT ERROR
SUBTTL	COMMON SUBROUTINES


;CHKBRN - CHECKS TO SEE IF LINK IS AT TOP OF BG AREA
;IF NOT IT MOVES ALL LINKS ABOVE DOWN AND PUTS ADDRESS OF
;THIS LINK AT TOP. NOTE ACTUAL LINK IS NOT MOVED UP.
;IF LINK IS ON DSK NOTHING IS DONE
;ENTERS WITH
;	P1 CONTAINS DEPTH IN BRANCH OF REQUIRED LINK #
;RETURNS
;+1	LINK IS ON DSK
;+2	LINK IS NOW AT TOP OF BG

CHKBRN:	HRRZ	T1,@BRNTBL	;GET ITS ADDRESS
	ADD	T1,BG.LB	;FIX IT
	MOVS	T2,@BRNDSK	;GET LENGTH
	SKIPE	T2		;DOES NOT REALLY EXIST IF 0
	TLNE	T2,-1		;IS CURRENTLY ON DSK
	POPJ	P,		;JUST BACKUP PTR
	ADD	T2,T1		;GET END
	CAMN	T2,BG.PT	;MAKE SURE ITS THE LAST ITEM
	JRST	CPOPJ1		;YES, SIMPLE CASE
	HRL	T1,T2
	MOVS	T1,T1		;FORM BLT PTR
	HRRZ	T3,T2		;ALL AT OR ABOVE THIS ADDRESS MUST BE ADJUSTED
	SUB	T2,BG.LB
	MOVN	T2,T2		;- NO. OF WORDS TO REMOVE
	ADD	T2,BG.PT	;TOP OF SYMBOLS LEFT
	HRRM	T2,@BRNTBL	;SO POINT TO WHERE IT WOULD BE MOVED TO
	BLT	T1,(T2)		;MOVE REQUIRED SYMBOLS DOWN
	SUB	T2,BG.PT	;GET - COUNT BACK
	PUSH	P,P1
	SUBI	P1,1		;NOW FIXUP POINTERS
	HRRZ	T1,@BRNTBL	;GET POINTER
	CAIL	T3,(T1)		;NEED TO ADJUST?
	ADDM	T2,@BRNTBL	;YES
	SOJGE	P1,.-3
	POP	P,P1
	JRST	CHKBRN		;NOW TRY
MRKLNK:	PUSHJ	P,.SAVE1##
	HRRZ	P1,BRNLEN	;NO. OF LINKS TO SCAN
MRKLN1:	HLRZ	T1,@BRNTBL	;GET LINK#
	CAMN	T1,P2		;ONE WE WANT
	JRST	MRKLN2		;FOUND IT
	SOJGE	P1,MRKLN1	;NO
	POPJ	P,		;NOT IN BRANCH

MRKLN2:	HLLOS	@BRNDSK		;MARK BY -1 IN RIGHT HALF
	JRST	CPOPJ1		;FOUND IT

DLTDSK:	PUSHJ	P,.SAVE1##	;NEED P1
	HRRZ	P1,BRNLEN	;NO. OF LINKS IN BRANCH
	HLLZS	@BRNDSK		;ZERO RH MEANS NOT NEEDED YET
	SOJGE	P1,.-1
	POPJ	P,

ADJBRN:	HRRZ	T4,BRNLEN	;MAX NO. WE HAVE
	SETZ	P1,		;START AT ZERO
	SETO	P2,		;SAFE SINCE LINK# 0 IS ALWAYS WANTED
ADJBR1:	MOVE	T1,@BRNDSK
	TRNN	T1,-1		;DO WE NEED IT?
	JRST	ADJBR2		;NO, SEE IF ALL DONE
	ADDI	P2,1		;INCRENENT SINCE WE NEED TO STORE THIS ONE
	MOVE	T2,@BRNTBL	;GET ADDRESS AND NUMBER
	MOVE	T3,@BRNADD	;LINK # AND LOWER BOUND
	EXCH	P1,P2		;SWAP PTRS
	HLLZM	T1,@BRNDSK
	MOVEM	T2,@BRNTBL	;MOVE BACK
	MOVEM	T3,@BRNADD
	EXCH	P1,P2
ADJBR2:	CAMGE	P1,T4		;DONE THEM ALL?
	AOJA	P1,ADJBR1	;NOT YET
	POPJ	P,
BKPBRN:	MOVS	T1,LSTPTR
	HRRZ	T2,(T1)		;GET FATHER LINK
	SKIPN	T1,1(T1)	;BACK POINTER
	JRST	E$$NBR		;[1174] ERROR
	HRLM	T1,LSTPTR	;BACK UP
	HLL	T1,(T1)		;FORM AOBJN POINTER
	ADD	T1,[2,,2]	;BYPASS LINK# AND BACK PTR
	SKIPN	(T1)		;BLANK YET?
	JRST	BKPB1		;YES
	AOBJN	T1,.-2
	SUBI	T1,1		;NO SPACE, SO BACKUP
BKPB1:	HRRM	T1,LSTPTR	;RESET NOW
;	JRST	DLTBRN

DLTBRN:	HRRZ	P1,BRNLEN	;GET DEPTH IN BRANCH
	PUSHJ	P,CHKBRN	;MAKE SURE ITS AT TOP
	  JFCL			;OK IF ON DSK
	HLRZ	T1,@BRNDSK	;GET LENGTH
	MOVN	T1,T1
	ADDM	T1,BG.PT	;AND BACK UP
	MOVE	T1,BRNLEN	;ONE LESS BRANCH IN CORE
	SUB	T1,[1,,1]	;SO BACKUP
	MOVEM	T1,BRNLEN
	SETZM	@BRNTBL		;AVOIDS CONFUSION
	SETZM	@BRNDSK
	SETZM	@BRNADD
	JUMPL	T1,CPOPJ	;STILL VALID POINTER
	PUSHJ	P,E$$LNM##	;[1174] MUST BE IN MEMORY
SUBTTL	SEARCH BOUND GLOBALS


TRY.BG::SPUSH	<P1,P2,P3>	;SAVE HASH ACCS
	SPUSH	<NAMLOC,HSPACE,HT.PRM,HT.PTR>	;GS PARAMETERS
	.JDDT	LNKOV1,TRY.BG,<<CAMN	W2,$SYMBOL##>>
	SETZM	HSPACE		;PREVENT REHASHING
	HRRZ	T1,BRNLEN	; NO. OF BOUND GLOBAL TABLES
	MOVEM	T1,BG.SCH	;SAFE PLACE TO PUT IT
TRYBG1:				;START AT LINK 0 AND READ IN ASCENDING ORDER
				; SINCE MOST GLOBALS WILL BE IN ROOT
	HRRZ	T1,BRNLEN	;TOTAL
	SUB	T1,BG.SCH	;MINUS WHATS LEFT GIVES INDEX
	ADD	T1,BRNTBL	;INDEX   INTO TABLE
	SKIPN	T2,(T1)		;GET LINK #,,ADDRESS
	JRST	.+3		;LINK 0 IS ALWAYS IN CORE
	TRNN	T2,-1		;ON DSK?
	  PUSHJ	P,E$$LNM##	;[1174] MUST BE IN MEMORY
	ADD	T2,BG.LB	;ADD IN BASE
	HRRZM	T2,NAMLOC	;WHERE IT IS
	MOVE	T1,(T2)		;FIRST WORD IS SPECIAL
	HLRZM	T1,HT.PRM	;CONTAINS HASH SIZE
	ADDI	T2,(T1)		;ADD OFFSET FOR HASH TABLE
	HRRM	T2,HT.PTR
	PUSHJ	P,TRYSYM##	;TRY AGAIN
	  JRST	TRYBG3		;FAILED
	  JRST	TRYBG3		;ALSO FAILED
	SPOP	<HT.PTR,HT.PRM,HSPACE,NAMLOC>
	MOVE	P4,P1		;SAVE POINTER TO THIS SYMBOL
	MOVE	W1,0(P1)	;GET FLAGS
	TXO	W1,PS.BGS	;TURN ON BOUND BIT
	TXZ	W1,PS.ENT	;MAKE SURE ENTRY FLAG OFF IN COPY 
				; ALSO NOT RELOC WRT THIS LINK
	SPOP	<P3,P2,P1>	;PREV VALUES
	PUSH	P,W3		;SAVE CURRENT VALUE (REQUEST CHAIN)
	MOVE	W3,2(P4)	;GET BOUND VALUE
	HRRZ	T1,BRNLEN	;NO. OF POSSIBLE LINKS
	SUB	T1,BG.SCH	;CURRENT INDEX
	TXZN	W1,PS.REL	;IS THE SYMBOL RELOCATABLE
	JRST	.+3		;NO, SO NO RELOC PROBLEM
	SKIPE	RT.LB		;LINK RELOCATABLE?
	JUMPN	T1,TRYBG4	;YES, UNLESS LINK 0
	TXNN	W1,PT.EXT	;IS IT EXTENDED?
	JRST	TRYBG2		;NO
	EXCH	P1,P4		;PTR BACK IN P1
	PUSHJ	P,SY.CHK##	;SEE HOW LONG
	SUB	P1,BG.LB	;IN CASE CORE MOVES
	PUSHJ	P,GS.GET##	;GET SPACE
	ADDI	T2,-1(T1)	;END OF BLT
	ADD	P1,BG.LB
	MOVE	W3,T1		;SYMBOL LOCATION
	HRL	T1,P1		;BLT PTR
	BLT	T1,(T2)		;COPY SYMBOL
	MOVEM	W1,0(W3)	;RESET POSSIBLE CHANGED VALUE OF FLAGS
	SUB	W3,GS.LB	;RELATIVE
	EXCH	P1,P4		;RESTORE P1
TRYBG2:	PUSH	P,LSTGBL	;[2255] SAVE GLOBAL PTR IN CASE PART OF FIXUP
	PUSH	P,LSTLCL	;[2255] SAVE LOCAL POINTER TOO
	PUSHJ	P,INSRT##	;PUT IN CURRENT TABLE
	POP	P,LSTLCL	;[2255] RESTORE POINTERS
	POP	P,LSTGBL	;[2255] THIS SYMBOL ALREADY EXISTS
	SOS	GSYM		;NOT REALLY A NEW GLOBAL SO REDUCE COUNT
	AOS	BSYM		;INCREASE COUNT FROM BOUND TABLES
	POP	P,W3		;GET REQUEST CHAIN BACK
	HRRZ	P1,@HT.PTR	;GET REL ADDRESS OF SYMBOL
	ADD	P1,NAMLOC	;MAKE ABS
	SETOM	BG.SCH		;PUT BACK NORMAL VALUE
	HRRZ	R,R		;NOT RELOCATABLE WITH RESPECT TO THIS LINK
CPOPJ2:	AOS	(P)
CPOPJ1:	AOS	(P)
CPOPJ:	POPJ	P,

TRYBG3:	SOSL	T1,BG.SCH	;MORE TO LOOK AT?
	JRST	TRYBG1		;YES
	SPOP	<HT.PTR,HT.PRM,HSPACE,NAMLOC>	;PUT THINGS BACK
	SPOP	<P3,P2,P1>
	SETOM	BG.SCH		;AS IT WAS
	POPJ	P,		;NOT FOUND RETURN
TRYBG4:	TXO	W1,PS.RBG	;TURN ON REL BOUND GLOBAL
	EXCH	P1,P4		;GET POINTER BACK
	PUSHJ	P,SY.CHK##	;SEE HOW LONG
	SUB	P1,BG.LB	;IN CASE CORE MOVES
	ADDI	T2,.L		;NEED EXTRA BLOCK
	PUSHJ	P,GS.GET##	;GET SPACE FOR COPY
	ADDI	T2,-<1+.L>(T1)	;END OF BLT
	ADD	P1,BG.LB
	MOVE	W3,T1		;SYMBOL LOCATION
	HRL	T1,P1		;FORM BLT PTR
	BLT	T1,(T2)		;MOVE IT
	MOVEM	W1,0(W3)	;SET NEW FLAGS
	MOVX	T1,PT.EXT	;MUST BE EXTENDED BY NOW
	IORM	T1,(W3)		;SET BIT
	SUB	W3,GS.LB	;RELATIVE
	MOVX	T1,S.LST	;CLEAR LAST TRIPLET BIT IF SET
	TXOE	W1,PT.EXT	;SET AS EXTENDED
	ANDCAM	T1,-.L+1(T2)	;IT WAS
	MOVX	T1,S.SYM!S.LST!S.RBG
	MOVEM	T1,1(T2)	;STORE  NEW TRIPLET
	MOVEM	W2,2(T2)	;STORE NAME FOR NOW
	HRRZ	T1,BRNLEN	;GET POSSIBLE MAX INDEX
	SUB	T1,BG.SCH	;GET INDEX INTO TABLE
	ADD	T1,BRNTBL	;PLUS BASE
	HLRZ	T1,(T1)		;LINK#
	MOVEM	T1,3(T2)	;CRUCIAL ITEM IN THIS TRIPLET
	JRST	TRYBG2		;PUT IN TABLE
;**;[2053] Insert after TRYBG4+26 Lines	PY	8-Nov-83
SUBTTL	Argument check the BG area [2053]

TYP.BG::SKIPL	BG.SCH		;[2053] Any bound globals we can look at?
	POPJ	P,		;[2053] No, return
	SPUSH	<NAMLOC,HSPACE,HT.PRM,HT.PTR,BG.SCH> ;[2053] GS Parameters
	SETOM	ARGOVL		;[2053] Remember that BG area is being checked
	.JDDT	LNKOV1,TYP.BG,<<CAMN	W2,$SYMBOL##>> ;[2053]
	SETZM	HSPACE		;[2053] Prevent rehashing
	HRRZ	T1,BRNLEN	;[2053] No. of bound global tables
	MOVEM	T1,BG.SCH	;[2053] Safe place to put it
	PUSH	P,W3		;[2053] Save the arg block pointer
TYPBG1:				;[2053] Start at link 0 so typout will
				;[2053] be in correct order
	HRRZ	T1,BRNLEN	;[2053] Total
	SUB	T1,BG.SCH	;[2053] Minus whats left gives index
	ADD	T1,BRNTBL	;[2053] Index into table
	SKIPN	T2,(T1)		;[2053] Get LINK #,,ADDRESS
	JRST	TYPBG2		;[2053] Link 0 is always in core
	TRNN	T2,-1		;[2053] On DSK?
	  PUSHJ	P,E$$LNM##	;[2053] Must be in memory
TYPBG2:	ADD	T2,BG.LB	;[2053] Add in base
	HRRZM	T2,NAMLOC	;[2053] Where it is
	MOVE	T1,(T2)		;[2053] First word is special
	HLRZM	T1,HT.PRM	;[2053] Contains hash size
	ADDI	T2,(T1)		;[2053] Add offset for hash table
	HRRM	T2,HT.PTR	;[2053]
	MOVE	W3,0(P)		;[2053] Get the callee argblock pointer
	PUSHJ	P,SYTYP##	;[2053] Typecheck this table
	SOSL	T1,BG.SCH	;[2053] More to look at?
	JRST	TYPBG1		;[2053] Yes
	SETZM	ARGOVL		;[2053] Back to typechecking GS area
	POP	P,W3		;[2053] Recover the arg block pointer
	SPOP	<BG.SCH,HT.PTR,HT.PRM,HSPACE,NAMLOC> ;[2053] Put things back
	POPJ	P,		;[2053] Return to process current overlay

;[2053] Here to build a deferred fixup block.  The block is two words
;[2053] long, and looks like:
;
; 	-----------------------------
;	!      Pointer to next      !
;	-----------------------------
;	!overlay index,,user address!
;	-----------------------------
;
;[2053] These blocks are stored in ascending order by overlay index
;[2053] and address.  Note that the address is 18 bits because this
;[2053] only occur in the overlay case, and that is restricted to
;[2053] section zero.  On entry, P3 contains the user address.

COEOVL::HRRZ	T2,BRNLEN	;[2053] Total
	SUB	T2,BG.SCH	;[2053] Minus whats left gives index
	JUMPN	T2,COEOV0	;[2053] Check for not root node
	HRRZ	P2,LL.S2	;[2053] Get the root node highseg origin
	JUMPE	P2,COEOV0	;[2053] No root node high segment
	CAML	P3,P2		;[2053] In the high segment?
	 JRST	COESP0##	;[2053] Yes, do this fixup now. SGCHK.
				;[2053] will use the root node high seg.
COEOV0:	HRL	P3,T2		;[2053] Put the index with the address
	MOVEI	T2,TPCBK	;[2053] Get the length
	PUSH	P,T4		;[2053] Save over DY.GET call
	PUSHJ	P,DY.GET##	;[2053] Get a block
	POP	P,T4		;[2053] Restore AC
	MOVEM	P3,TPCAD(T1)	;[2053] Store the address info
	MOVEI	P1,ARGFXP	;[2053] Get the pointer to the chain
COEOV1:	MOVE	T2,TPCLK(P1)	;[2053] Get the new pointer
	JUMPE	T2,COEOV2	;[2053] At end of chain?
	CAMG	P3,TPCAD(T2)	;[2053] Is this one bigger than last?
	 JRST	COEOV2		;[2053] Yes, link it in here
	MOVE	P1,T2		;[2053] Point to the current block
	JRST	COEOV1		;[2053] Try the next block

COEOV2:	MOVEM	T2,TPCLK(T1)	;[2053] Link this one into the chain
	MOVEM	T1,TPCLK(P1)	;[2053] Complete the chain
	PJRST	COESP1##	;[2053] Return to coersion code

SUBTTL	STORE INTO USER CORE IMAGE


;HERE TO STORE BLOCK TYPE 1 (AND 21)
;ENTER WITH DATA IN W1 (RESULT FROM RB.1)
;STORE ADDRESS IN P3
;THIS BLOCK IS NOT GENERALIZED BECAUSE OF SPEED CONSIDERATIONS
;CALLED BY
;	MOVE	W1,DATA WORD
;	CSTORE
;WHICH IS
;	JSP	T1,CS.RHS##
;
CS.LHS==:(JSP T1,)		;BUILD THE INSTRUCTION UP
CS.RHS::MOVEM	W1,(P3)		;STORE IN CORE
	SKIPN	RT.LB		;LOADING RELOCATABLE OVERLAYS?
	JRSTF	(T1)		;NO
	ROT	R,2		;PUT RELOC BITS IN 34-35
	IDPB	R,RT.PT		;STORE
	ROT	R,-2		;PUT BACK
	JRSTF	(T1)		;RETURN
SUBTTL	RELOCATABLE OVERLAY ROUTINES


;RT.FX - ROUTINE TO STORE RELOCATION FOR BOUND GLOBAL IN A RELOCATABLE LINK
;ENTER WITH
;P1 = POINTER TO SYMBOL
;W1 = FIXUP FLAGS (WHICH HALF)
;W3 = FIXUP VALUE
;USES T1-T4

RT.FX::	MOVEI	T2,2		;USES 2 WORDS
	SUB	P1,GS.LB	;IN CASE CORE MOVES
	PUSHJ	P,FX.GET##	;IN FIXUP AREA
	ADD	P1,GS.LB
	MOVE	T2,P1		;COPY PTR TO SYMBOL
	MOVE	T3,0(T2)	;GET PRIMARY FLAGS
	TXNN	T3,PT.EXT	;IT BETTER BE EXTENDED
	HALT
RT.FX1:	ADDI	T2,.L		;GET NEXT TRIPLET
	MOVE	T3,0(T2)	;GET SECONDARY FLAGS
	TXNE	T3,S.RBG	;BOUND GLOBAL?
	JRST	RT.FX2		;YES
	TXNN	T3,S.LST	;LAST TRIPLET?
	JRST	RT.FX1		;NOT YET
	HALT

RT.FX2:	MOVS	T2,2(T2)	;GET LINK#
	HRR	T2,RBGPTR	;LAST ONE TO LINK IN
	SETZ	T3,		;START WITH NO RELOCATION
	TXNN	W1,FS.FXR	;[2214] RIGHT ONLY?
	TXNE	W1,FS.FXE	;[2214] OR THIRTY BIT?
	TXO	T3,1B1		;YES
	TXNE	W1,FS.FXL	;OR LEFT ONLY?
	TXO	T3,1B0		;YES
	TXNE	W1,FS.FXF	;OR BOTH?
	TXO	T3,3B1		;YES
	TXNE	W1,FS.FXS	;SYMBOL TABLE?
	HALT			;NOT YET
	HRR	T3,W3		;VALUE
	DMOVEM	T2,(T1)		;STORE
	SUB	T1,FX.LB	;REMOVE BASE
	.JDDT	LNKOV1,RT.FX2,<<CAMN T1,$FIXUP##>>	;[632]
	MOVEM	T1,RBGPTR	;POINT TO IT
	POPJ	P,
;RT.FXC - ROUTINE SAME AS RT.FX BUT USES PREVIOUS RELOCATION
;I.E. FOR CHAINED REFERENCES
;ENTER WITH
;P1 = POINTER TO SYMBOL
;W1 = FIXUP FLAGS (WHICH HALF)
;W3 = FIXUP VALUE
;USES T1-T4

RT.FXC::MOVEI	T2,2		;SAME 2 WORDS AS ABOVE
	PUSHJ	P,FX.GET##
	MOVE	T2,RBGPTR	;GET ADDRESS OF LAST
	ADD	T2,FX.LB	;FIX IN CORE
	DMOVE	T3,(T2)		;GET LAST
	HRR	T3,RBGPTR	;LINK TO LAST ADDRESS
	HRR	T4,W3		;CHANGE VALUE
	DMOVEM	T3,(T1)		;STORE IN NEW BLOCK
	SUB	T1,FX.LB	;REMOVE BASE
	.JDDT	LNKOV1,RT.FXC,<<CAMN T1,$FIXUP##>>	;[632]
	MOVEM	T1,RBGPTR	;STORE POINTER TO LIST
	POPJ	P,
;RT.T2R - ROUTINE TO SET RELOC BITS CORRECT FOR RIGHT HALF CHAINED REFERENCES
;ENTER WITH
;T2 = ADDRESS
;R  = RELOC BITS (BITS 0 & 1)
;P1 = PTR TO SYMBOL
;W1 = FLAGS OF PRIMARY SYMBOL

RT.T2R::PUSHJ	P,RT.T2H	;CHECK NOT IN HISEG
	POPJ	P,		;IN HIGH
	PUSH	P,P3		;NEED P3 FOR ADDRESS CHECK
	MOVE	P3,T2
	PUSHJ	P,RT.P3##	;SETUP RT.PT
	TXNN	R,1B1		;IS IT RELOCATED?
	TDZA	T2,T2		;NO
	MOVEI	T2,1		;YES
	MOVE	T1,RT.PT	;GET BYTE PTR
	TLC	T1,(<POINT 3,>-<POINT 0,>)
	IBP	T1		;BYPASS LHS
	IDPB	T2,T1		;NEW BYTE
	JUMPE	P1,POPP3	;NOT SYMBOLIC
	PUSH	P,W1		;SAVE FLAGS
	MOVX	W1,FS.FXR	;RH IN CASE BOUND
RT.T2Z:	MOVE	T2,0(P1)	;GET FLAGS
	TXNN	T2,PS.RBG	;BOUND?
	JRST	.+4		;NO
	EXCH	W3,P3		;PUT ADDRESS IN W3
	PUSHJ	P,RT.FX		;STORE FIXUP
	EXCH	W3,P3
	POP	P,W1		;RESTORE FLAGS
POPP3:	MOVE	T2,P3		;RESET T2
	SETZ	T1,		;[2214] ZERO SECTION FOR CHAINED FIXUPS
	POP	P,P3
	POPJ	P,

;RT.T2H - ROUTINE TO CHECK ADDRESS NOT IN HISEG
;ENTER WITH
;T2 = ADDRESS
;RETURNS
;+1 IN HISEG
;+2 IN LOW SEG

RT.T2H:	SKIPE	HC.LB		;NO HIGH SEG
	CAMGE	T2,LL.S2	;IS IT IN HIGH?
	AOS	(P)		;NO
	POPJ	P,
;RT.T2L - ROUTINE TO SET RELOC BITS CORRECT FOR LEFT HALF CHAINED REFERENCES
;ENTER WITH
;T2 = ADDRESS
;R  = RELOC BITS (BITS 0 & 1)

RT.T2L::PUSHJ	P,RT.T2H	;CHECK NOT IN HISEG
	POPJ	P,		;IN HIGH
	PUSH	P,P3		;NEED P3 FOR ADDRESS CHECK
	MOVE	P3,T2
	PUSHJ	P,RT.P3##	;SETUP RT.PT
	TXNN	R,1B0		;IS IT RELOCATED?
	TDZA	T2,T2		;NO
	MOVEI	T2,1		;YES
	MOVE	T1,RT.PT	;GET BYTE PTR
	TLC	T1,(<POINT 3,>-<POINT 0,>)
	IDPB	T2,T1		;NEW BYTE
	JUMPE	P1,POPP3	;NOT SYMBOLIC
	PUSH	P,W1		;SAVE FLAGS
	MOVX	W1,FS.FXL	;LH IN CASE BOUND
	JRST	RT.T2Z		;RESET T2,P3, AND RETURN

;RT.T2F - ROUTINE TO SET RELOC BITS CORRECT FOR FULL WORD CHAINED REFERENCES
;ENTER WITH
;T2 = ADDRESS
;R  = RELOC BITS (BITS 0 & 1)

RT.T2F::PUSHJ	P,RT.T2H	;CHECK NOT IN HISEG
	POPJ	P,		;IN HIGH
	PUSH	P,P3		;NEED P3 FOR ADDRESS CHECK
	MOVE	P3,T2
	PUSHJ	P,RT.P3##	;SETUP RT.PT
	TXNN	R,3B1		;IS IT RELOCATED?
	TDZA	T2,T2		;NO
	MOVEI	T2,1		;YES
	MOVE	T1,RT.PT	;GET BYTE PTR
	IDPB	T2,T1		;NEW BYTE
	JUMPE	P1,POPP3	;NOT SYMBOLIC
	PUSH	P,W1		;SAVE FLAGS
	MOVX	W1,FS.FXF	;FULL WORD IN CASE BOUND
	JRST	RT.T2Z		;RESET T2,P3, AND RETURN

;RT.T2E - Routine to set reloc bits correct for thirty bit chained references
;Enter with
;T2 = Address
;R  = Reloc bits (BITS 0 & 1)

RT.T2E::PUSHJ	P,RT.T2H	;[2214] Check not in hiseg
	POPJ	P,		;[2214] In high
	PUSH	P,P3		;[2214] NEED P3 FOR ADDRESS CHECK
	MOVE	P3,T2		;[2214] 
	PUSHJ	P,RT.P3##	;[2214] Setup RT.PT
	TXNN	R,3B1		;[2214] Is it relocated?
	TDZA	T2,T2		;[2214] No
	MOVEI	T2,1		;[2214] Yes
	MOVE	T1,RT.PT	;[2214] Get byte ptr
	IDPB	T2,T1		;[2214] New byte
	JUMPE	P1,POPP3	;[2214] Not symbolic
	PUSH	P,W1		;[2214] Save flags
	MOVX	W1,FS.FXE	;[2214] Full word in case bound
	JRST	RT.T2Z		;[2214] Reset T2, P3, and return

E$$OHN::.ERR.	(MS,,V%L,L%F,S%F,OHN,<Overlay handler not loaded>) ;[1174]
E$$FSN::.ERR.	(MS,,V%L,L%F,S%F,FSN,<FUNCT. subroutine not loaded>) ;[1174]
SUBTTL	THE END


OV1LIT:	END	LNKOV1