Google
 

Trailing-Edge - PDP-10 Archives - BB-H138A-BM - 3a-sources/lnkxit.mac
There are 38 other files named lnkxit.mac in the archive. Click here to see a list.
TITLE LNKXIT - EXIT MODULE FOR LINK
SUBTTL	D.M.NIXON/DMN/JLd/RKH/JBC/JNG/MCHC	27-Feb-78

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

ENTRY	LNKXIT
SEARCH	LNKPAR,LNKLOW,MACTEN,UUOSYM
EXTERN	LNKCOR,LNKLOG,LNKFIO
EXTERN	.JB41


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



VERSION


SEGMENT

;LOCAL ACC DEFINITION
R==R1


SALL
SUBTTL	REVISION HISTORY

;START OF VERSION 1A
;50	HANDLE PAGING DURING LOCAL SYMBOL OUTPUT CORRECTLY
;51	FIX BUG IF UNDEF SYMBOLS BUT DON'T WANT TO KEEP LOCAL SYMS
;53	FIX RETURNS FROM DVMOV. ROUTINE
;54	ADD KIONLY D.P. INST.
;55	STORE VERSION NUMBER (.JBVER) IN .RBVER OF SAVE FILE
;56	FIX LOOP AT JBEX2A IF CORE IMAGE IS MULTIPLE OF 2000
;57	SETUP VESTIGIAL JOB DATA AREA EVEN IF NOT A SAVE FILE
;63	REMOVE MULTIPLY-DEFINED SYMBOLS FROM SYMBOL TABLE (IN CORE)
;65	TENEX SPEEDUPS
;66	SAVE JOB DATA AREA ON /SAVE IF DDT, SYMBOLS AND ALL CODE IN HIGH SEG
;67	PUT ADDITIVE GLOBAL REQUESTS IN UNDEF TABLE
;70	FIX ADDRESS CHECK PROBLEM
;71	MAKE ALL INFO MESSAGES STANDARD FORM
;73	(11314) PREVENT EXECUTION IF UNDEF SYMBOLS
;100	FIX ILL MEM REL ON /SAVE IF LAST BLOCK FILLS ALL OF CORE
;104	OUTPUT FAIL BLOCK HEADER IN LOCAL SYMBOL TABLE
;106	REMOVE HIORG, REPLACE BY LL.S2
;115	MAKE /NOSYMBOLS WORK CORRECTLY

;START OF VERSION 2
;135	ADD OVERLAY FACILITY
;136	FIX VARIOUS BUGS
;140	(12617) FIX ?IO TO UNASSIGNED CHANNEL ON /SYMBOL:TRIPLET FILE
;154	(12991) ONLY LOOK AT RIGHT HALF OF .JBERR TO DELETE EXECUTION
;155	(12988) FIX TEST FOR COBDDT AT RUN UUO TIME
;166	MAKE RADIX50 SYMBOL FILE TYPE 776
;177	FIX ADDRESS CHECK BUG IF PAGING SYMBOLS
;211	FIX ZEROS IN MONITOR SYMBOL TABLE
;213	(12531) LOW SEG OF TWOSEG CORE IMAGE  BAD
;221	GET PROTECTION CODE RIGHT ON XPN FILE

;START OF VERSION 2A
;244	DATE75 FIX TO MAKE LOW SEG FILE HAVE CORRECT DATE
;START OF VERSION 2B
;224	PUT SECOND SYMBOL FOR COMMON BLOCK IN RADIX50 SYMBOL TABLE
;226	FIX UNDEFINED SYMBOL BUG (117 NOT SET UP)
;234	FIX VARIOUS BUGS IF HIGH FILE IS MADE RATHER THAN RENAMED
;235	(13845) FIX ZERO COMPRESSOR IF PAGED AND READING ZEROS
;241	USE LARGER OF ABS OR LOW REL BREAK FOR .JBFF
;242	HANDLE USER PAGE FAULT HANDLER CORRECTLY
;244	DATE75 FIX TO MAKE LOW SEG FILE HAVE CORRECT DATE
;247	Change all references to DEBUGSW. Now lh is -1 if set,
;	rh is table index  for either /DEBUG or /TEST
;266	Correct problems with loading symbols when LS area
;	overflows to the DSK.
;267	Get symbol table offest right when core window
;	changes.
;270	Use the correct initialization routine when high
;	core overflows to the disk during this phase.
;322	Get LSYM and other core management variables right
;	so LNKCOR doesn't fail
;324	Don't release the symbol channel if still needed,
;	when loading symbols into root of an overlay program.
;330	Release the correct channel when done with symbols
;	being loaded into the root of an overlay program.
;335	Keep LSYM from being clobbered when loading symbols
;	into root of overlay program.  Don't confuse LNKCOR
;336	Fix /RUN switch to work properly
;337	Insert check for no core to zero before BLT and
;	prevent possible ILL MEM REF
;353	REMOVE EDIT 225
;357	LABEL EDITS 224,226,234,235,241,242
;360	REMOVE EDIT 336
;401	Remove 5.06 compatability hack setting up vestigial jobdat.
;403	Fix HALT if generating new style symbol file.
;423	Fix ?ILL ADDR IN UUO when the zero compressor tried to use
;	the LS area after it had done a CORE UUO to get rid of it.
;433	Support the /RUN switch.
;START OF VERSION 2C
;442	Fix the DVMOV. routine to either RENAME or copy,
;	and delete copy routines called if DVMOV. fails.
;443	Don't lose part of local symbols if overflowing to disk.
;467	Correct RT.PT check at SYMO1
;471	Add code for ALGOL debugging system.
;476	Insert missing FTOVERLAY conditional.
;517	Make first word of ALGOL symbol file be 1044,,count.
;524	Check for symseg area reduced to one page & don't zero rest.
;530	Get triplet flag definitions right.
;544	SOUP in LINK version 3 stuff for TOPS-20.
;547	Make LINK assemble with MACRO 51.
;555	Don't round .RBSIZ up to block bound for symbol files.
;557	Clean up the listing for release.

;START OF VERSION 3
;446	CHANGES FOR TENEX

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

;START OF VERSION 4
;570	Don't lose local symbols when undefined globals exist.
;575	On /EXECUTE/SAVE to a two segment program, always run xxx.LOW
;606	Get the protection of .HGH and .XPN files right.
;616	Give appropriate error messages when RENAMEs fail
;621	/SAVE AND /SSAVE GENERATE EXE FILE.  
;	/SAVE AND /SSAVE NO LONGER TAKES ANY ARGUMENT.  IF THE CORE
;	SIZE IS SPECIFIED, LINK WILL IGNORE IT.
;	THE CODE TO GENERATE .HGH/.SHR/.LOW FILES ARE UNDER THE 
;	CONDITIONAL ASSEMBLY SWITCH FTEXE==0.
;622	Don't set up vestigal JOBDAT unless there's a high segment.
;641	IF HIGH SEG IS PAGED, WRITE OUT WHAT'S IN CORE BEFORE UPDATING
;	VESTIGAL JOBDAT AND DUMP TO EXE FILE.
;642	EXE FILE EXTENSION FOR DISK FILE GENERATED FOR NOT HAVING
;	ENOUGH CORE
;643	FIX BUG WITH SWITCH SETTING FOR P4 IN XCMPRL.
;644	DON'T DO JSYS 147(RESET) IF WE DO EXIT.
;645	Loop back topage lc if not more core in LSREQ.
;646	Don't touch a high seg page again after high seg is removed
;	in %LOW.
;647	Don't zero unneeded memory (better VM performance).
;650	Use VM on TOPS-10 if available.
;652	Avoid bad .SAV file when paging to disk.
;704	Don't write EXE-directory entries for psect gaps.
;713	Fix bug with sparse EXE-directory.
;715	Modify SYMSEG to take psect name.
;724	Check for symbol table range in INGAP.
;725	Fix bug with incrementing process page in XCMPOV.
;726	Fix bug in INGAP routine.
;727	Give Insufficient space error message when symbol table truncated.
;731	SEARCH MACTEN,UUOSYM instead of C.
;732	Use LOWLOC and fix bugs related to page 777.
;733	Fix bug with allocated high seg pages causing bad EXE format.
;742	Don't BLT JOBDAT if process page 0 not the first page.
;744	Fix bug with calculation of EXE file size.
;754	Don't page LS area when doing symbol table output, if paging is needed for the first time for LC(or HC).
;762	Page in the LOWLOC page before generating EXE file.
;764	Update LOWLOC in GETSST incase symbol table is lower than code.
;	Also, corrects a bug in updating upper window in XCMPRS routine.
;765	Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
SUBTTL	ENTER HERE

LNKXIT:	JFCL	.+1		;IN CASE CCL ENTRY
	.ERR.	(MS,0,V%L,L%I,S%I,EXS,<EXIT segment>)
	ZAPTMP			;CLEAR ALL TEMP SPACE
	MOVE	T1,HC.S0	;GET ABS BREAK
	CAMLE	T1,HC.S1	;LARGER THAN LOW SEG?
	MOVEM	T1,HC.S1	;USE LARGER
	MOVE	T1,HL.S0	;GET ABS BREAK
	CAMLE	T1,HL.S1	;LARGER THAN LOW SEG?
	MOVEM	T1,HL.S1	;USE LARGER
IFN FTOVERLAY,<
	SKIPGE	LNKMAX		;DID WE LOAD ANY OVERLAYS?
	JRST	LNKX1		;NO
	MOVE	T1,PH.OVL	;GET START OF CODE FOR ROOT
	USETI	OC,(T1)		;POSITION ON THE BLOCK
	MOVE	P2,PH.LEN	;LENGTH WE NEED
	ADD	P2,LC.LB
	SUB	P2,LC.AB	;SEE IF ENOUGH
	JUMPLE	P2,LNKX0A	;YES
	MOVEI	P1,LC.IX
	PUSHJ	P,LNKCOR##	;MUST EXPAND
	  JRST	LNKX0C		;DO IT THE HARD WAY
LNKX0A:	MOVE	T1,LC.LB
	SUBI	T1,1
	HLL	T1,PH.OVL	;SETUP IOWD
	SETZ	T2,
	IN	OC,T1		;READ BACK CORE
LNKX0B:	  SKIPA	T1,OV.S1	;CORE BOUNDS
	PUSHJ	P,ER.IOV##	;INPUT ERROR
	HRRZM	T1,HL.S1	;
	HLRZM	T1,HC.S1
	JRST	LNKX1		;

;NOW TO READ BACK FIRST FEW BLOCK
LNKX0F:	SETZM	LW.S1		;STARTS AT ZERO
	MOVE	T1,LC.UB
	MOVEM	T1,LC.AB	;USE IT ALL AGAIN
	SUB	T1,LC.LB
	MOVEM	T1,UW.S1	;UPPER BOUND
	PUSHJ	P,LC.IN##	;READ IT BACK
	JRST	LNKX0B		;FIXUP VARIOUS POINTERS
LNKX0C:	SETZM	LW.S1		;SET BACK TO START
	MOVE	T1,PH.OVL
	USETI	OC,(T1)		;SET ON BLOCK
	MOVE	T1,LC.UB
	MOVEM	T1,LC.AB	;USE ALL AVAILABLE SPACE
	SUB	T1,LC.LB	;GET SIZE OF WINDOW
	MOVEM	T1,UW.S1	;UPPER WINDOW
	ADDI	T1,1
LNKX0D:	MOVN	T1,T1
	HRLZ	T1,T1
	HRR	T1,LC.LB	;IOWD
	SUBI	T1,1		;AT LAST
	SETZ	T2,
	IN	OC,T1
	  SKIPA	T1,LC.AB
	PUSHJ	P,ER.IOV##
	SUB	T1,LC.LB
	ADD	T1,LW.S1	;ADD BASE
	CAMG	T1,PH.LEN	;REACHED END YET?
	JRST	LNKX0E		;NO
	MOVE	T1,PH.LEN	;YES, GET WHAT WE REALLY NEED
	IORI	T1,.IPM
	MOVE	T2,T1
	SUB	T2,LW.S1
	ADD	T2,LC.LB
	CAMN	T2,LC.UB	;ARE WE IN LAST BLOCK
	JRST	LNKX0E		;YES, NO CHANGE
	MOVEM	T2,LC.AB	;RESET UPPER BOUND IN USE
	SETZM	1(T2)		;ZERO FIRST WORD
	HRLI	T2,1(T2)
	HRRI	T2,2(T2)
	BLT	T2,@LC.UB	;AND THROUGH REST
LNKX0E:	HRL	T1,LW.S1	;ORIGIN
	PUSHJ	P,LC.OUT##	;WRITE OUT THIS MUCH
	MOVE	T1,LC.AB	;
	SUB	T1,LC.LB	;GET SIZE OF WINDOW
	MOVE	T2,T1
	ADD	T2,LW.S1
	CAML	T2,PH.LEN	;MORE TO DO?
	JRST	LNKX0F		;NO
	AOS	T2,T1		;PUT COPY IN T2
	ADDM	T1,LW.S1	;NEW WINDOW BASE
	ADDB	T2,UW.S1	;GET NEXT UPPER BOUND
	CAMG	T2,PH.LEN	;DO WE NEED TO READ IT ALL IN?
	JRST	LNKX0D		;YES
	MOVE	T1,PH.LEN	;NO, GET HIGHEST WE NEED
	ADDI	T1,.DBM		;[650] UP TO NEXT BLOCK
	ANDCMI	T1,.DBM		;[650] INCASE WAS ALREADY THERE
	SUB	T1,LW.S1	;NO. OF WORDS
	JRST	LNKX0D		;TO INPUT

>;END OF IFN FTOVERLAY
LNKX1:	MOVEI	R,1		;SETUP TO POINT TO LOW SEG
	MOVE	R,@SG.TB
IFN FTOVERLAY,<
	SKIPL	LNKMAX		;IF LOADING OVERLAYS
	SETZM	USYM		;IGNORE UNDEFINED SYMBOLS TIL RUN TIME
>
	MOVEI	T1,PATSP.	;IF NOT ALREADY
	SKIPN	PATSPC		;SETUP PATCHING SIZE
	MOVEM	T1,PATSPC	;IN CASE REQUIRED
	SETZM	FRECOR		;NO NEED NOW
	SKIPN	FS.SS		;THESE ARE THE ONLY FIXUPS WE CAN DO NOW
	SKIPE	USYM		;BUT MAY HAVE GLOBAL REQUESTS
	CAIA
	PUSHJ	P,FX.ZAP	;NONE, SO GET RID OF AREA
				;NOW TEST FOR CASE INWHICH SYMBOL FILE WAS
				;OPENED BUT NOT USED (NOT VERY LIKELY)
	SKIPE	UW.LS		;NEVER OPENED
	SKIPE	LW.LS		;NEVER USED IF STILL ZERO
	JRST	CLSMAP		;STILL IN USE, OR NEVER WAS
IFN FTOVERLAY,<
	SKIPL	LNKMAX		;IF LOADING OVERLAYS
	SKIPN	UW.LS		; AND PAGING SYMBOLS
	CAIA			;NO
	JRST	CLSMAP		;KEEP FILE OPEN RATHER THAN READ IN
>
	SETZM	UW.LS		;CLEAR UNWANTED POINTER
	MOVEI	T1,SC		;SYMBOL FILE CHAN #
	PUSHJ	P,DVDEL.##	;DELETE FILE AND REMOVE ALL TRACES
	  JFCL
	SETZM	IO.PTR+SC	;AND FORGET ABOUT IT
CLSMAP:	SKIPN	IO.PTR+MC	;AN OPEN MAP?
	JRST	RDJBDA		;NO
	MOVEI	T1,MC		;SET CHAN#
	MOVEM	T1,IO.CHN	;IN ACTIVE STATE
	PUSHJ	P,DVRLS.##	;CLOSE FILL AND DO POSITIONING
	PUSHJ	P,DVZAP.##	;RETURN BUFFERS AND DATA BLOCK
RDJBDA:	SKIPE	PAG.S2		;HIGH SEG PAGING?
	PUSHJ	P,RDJBH		;YES, READ IN .JBHDA
	SKIPE	PAG.S1		;LOW SEG PAGING?
	PUSHJ	P,RDJBL		;YES
	HRRZ	T1,.JBERR	;GET ERRORS FOR THIS PROCESS
	ADD	T1,USYM		;EACH UNDEF COUNTS ONE
	HRRM	T1,.JBERR	;WILL STOP EXECUTION IF NON-ZERO
	JRST	UDF0		;NOW FOR UNDEFINED SYMBOLS
;HERE TO READ IN FIRST 10 WORDS OF HIGH SEGMENT

RDJBH:	MOVEI	T2,.JBHDA	;NO OF WORDS WE NEED
	PUSHJ	P,DY.GET	;GET THEM
	MOVEM	T1,JBHPTR	;STORE LOCATION
	SUBI	T1,1		;IOWD IS 1 LESS
	HRLI	T1,-10		;SHOULD BE -.JBHDA BUT MACRO 50 NOT YET OUT
	SETZ	T2,		;TERMINATE LIST
	USETI	HC,1		;SET ON BLOCK 1
	IN	HC,T1		;READ FIRST 10 WORDS ONLY
	  POPJ	P,		;OK
	PUSH	P,[HC]
	.ERR.	(ST,,V%L,L%F,S%F,IHC)

;HERE IF LOWSEG PAGED, WE NEED BOTH ENDS OF FILE AT ONCE
;THEREFORE PUT JOBDAT (0-137) IN DY AREA, POINTER IS JOBPTR
;AND TOP OF FILE IN LC AREA

RDJBL:	MOVEI	T2,.JBDA	;NEED ONE BLOCK
	PUSHJ	P,DY.GET
	MOVEM	T1,JOBPTR	;HOLD OFFSET IN CORE SO WE CAN FIXUP
				; REFERENCES TO JOBDAT SYMBOLS
	SKIPN	LW.S1		;HOWEVER IF 1ST PAGE IS IN CORE
	JRST	BLTJBL		;JUST MOVE IT
	SUBI	T1,1		;IOWD IS ONE LESS
	HRLI	T1,-140		;WORD COUNT
	SETZ	T2,		;TERMINATE LIST
	USETI	LC,1		;READ BLOCK 1
	IN	LC,T1		;AT LEAST FIRST 140 WORDS
	  POPJ	P,		;NONE
	PUSH	P,[LC]
	.ERR.	(ST,,V%L,L%F,S%F,ILC)


;HERE TO JUST BLT JOBDAT AREA TO SAFE PLACE
BLTJBL:	HRL	T1,LC.LB	;FROM HERE
	HRRI	T2,.JBDA(T1)	;TO HERE
	BLT	T1,-1(T2)	;WELL ALMOST THERE
	POPJ	P,
SUBTTL	UNDEFINED SYMBOLS

;HERE TO PUT UNDEFINED GLOBALS INTO UNDEF TABLE IN CORE
;THIS IS OLD FORMAT (2 WORD SYMBOLS)
UDF0:	SKIPN	R,SYMSEG	;LOAD OFFSET TO EITHER LC OR HC
	MOVEI	R,LC.IX		;ASSUME LOWSEG FOR SYMBOLS
	SKIPN	NOSYMS		;DON'T WANT UNDEFS IF /NOSYM
	SKIPN	P2,USYM		;ANY UNDEFINED SYMBOLS?
	JRST	NOUNDF		;NO, GET RID OF AREA
				;BUT DO WE REALLY NEED UNDEFS?
	SKIPE	PAG.S1		;PAGING?
	SKIPA	T1,JOBPTR	;YES, LOAD CORRECT POINTER
	MOVE	T1,LC.LB	;NO
	SKIPN	.JBDDT(T1)	;JOBDDT NON-ZERO
	SKIPE	SYMSEG		;OR SYMBOLS REQUESTED
	JRST	UDF0A		;YES
	SKIPE	IO.PTR+%SC	;BUT DO WE WANT SYMBOL FILE
	SKIPL	SYMFRM		; OLD STYLE?
	JRST	NOUNDF		;NO, GET RID OF THEM
UDF0A:	LSH	P2,1		;2 WORDS PER SYMBOL
	MOVE	P4,PATSPC	;NEED TO LEAVE A HOLE FOR PATCHING
	PUSHJ	P,GETSST	;[715] GET FINAL SYMBOL START ADDR
	SKIPE	PAG.S0(R)	;PAGING?
	PUSHJ	P,LSYP		;YES, GET RIGHT PAGE IN CORE
	ADDB	P4,P2		;SPACE WE NEED
	ADD	P2,TAB.LB(R)	;IN CORE
	SUB	P2,LW.S0(R)	;REMOVE WINDOW OFFSET
	CAMG	P2,TAB.AB(R)	;ENOUGH CORE?
	JRST	UDF1		;YES,
	SUB	P2,TAB.AB(R)	;GET EXTRA WE NEED
	MOVEI	P1,(R)		;FROM WHERE
	PUSHJ	P,LNKCOR##	;GET IT
	  PUSHJ	P,NO.COR##	;TOTAL FAILURE
	SKIPN	TAB.PG(R)	;[570] PAGING?
	JRST	UDF0B		;[570] NO, SKIP THIS
	MOVE	T1,P4		;[570] YES, UPDATE UW
	IORI	T1,.IPM		;[570] SINCE PAGING ROUTINES DON'T
	MOVEM	T1,TAB.UW(R)	;[570] WHEN MAKING WINDOW BIGGER
UDF0B:	PUSHJ	P,CHKPAG	;[570] JUST INCASE WE STARTED PAGING
	MOVE	P2,P4		;RELATIVE
	ADD	P2,TAB.LB(R)	;FIX IN CORE
	SUB	P2,LW.S0(R)	;REMOVE WINDOW OFFSET
UDF1:	SKIPGE	SYMSEG		;[715] PSECT NAME USED?
	JRST	.+3		;[715] YES, JUMP
	MOVEM	P4,HC.S0(R)	;FOR .JBCOR
;NOW LOOP THROUGH GS AREA LOOKING FOR UNDEFINED SYMBOLS

	EXCH	P4,HL.S0(R)	;GET BASE OF UNDFS
	MOVN	T2,USYM		;NUMBER OF UNDEF SYMBOLS
	MOVMM	T2,JOB117	;WILL FIX IT LATER, JUST NO. NOW
	HRL	P4,T2		;AOBJN POINTER TO UNDEFS
	LSH	T2,^D18+1	;PUT 2*COUNT IN LEFT HALF
	HRR	T2,P4		;ADDRESS
	ADD	T2,LL.S0(R)	;+OFFSET
	SKIPE	PAG.S1		;PAGING?
	SKIPA	T1,JOBPTR	;YES, LOAD CORRECT OFFSET
	MOVE	T1,LC.LB	;CODE OFFSET
	MOVEM	T2,.JBUSY(T1)	;FIXUP POINTER
	ADD	P4,TAB.LB(R)	;FIX IN CORE
	SUB	P4,LW.S0(R)	;REMOVE WINDOW OFFSET
	MOVE	P2,HT.PRM	;GET HASH SIZE
	SKIPE	T1,@HT.PTR	;GET POINTER IF NON-ZERO
	JRST	UDFTRY		;SEE IF A REQUEST
UDFNXT:	SOJGE	P2,.-2		;MORE?
	JRST	UDFDN		;NO

UDFTRY:	ADD	T1,GS.LB	;ADD IN BASE
	MOVE	W1,(T1)		;GET FLAGS
	TXNN	W1,PS.REQ	;GLOBAL REQUEST
	JRST	UDFNXT		;NO, TRY NEXT SYMBOL
	DMOVE	W2,1(T1)	;GET SIXBIT SYMBOL & VALUE (REQUEST POINTER)
	PUSHJ	P,SXBR50	;CONVERT TO SIXBIT
	TXO	W2,R5.GLB	;MAKE GLOBAL DEFINITION
	ADDI	P4,1		;WILL BUMP LOCATION BY 2 (LATER)
	HRRZ	T1,P4		;ADDRESS ONLY
	CAMLE	T1,TAB.AB(R)	;WILL IT FIT IN WHAT WE HAVE?
	PUSHJ	P,UDFEXP	;NO, EXPAND AREA
	DMOVEM	W2,-1(P4)	;STORE NAME & VALUE
	TXNE	W1,PS.FXP	;ANY ADDITIVE GLOBAL FIXUPS
	JRST	UDFGB		;YES, RECREATE THE REQUESTS
UDFLUP:	AOBJN	P4,UDFNXT	;AND COUNT BY 1
UDFDN:				;UNLESS FINISHED
	SKIPE	PAG.S1		;PAGING?
	SKIPA	T1,JOBPTR	;YES, LOAD CORRECT OFFSET
	MOVE	T1,LC.LB	;CODE OFFSET
	MOVE	T2,JOB117	;GET NUMBER OF UNDEFS
	LSH	T2,1		;2 WORDS PER SYMBOL
	MOVN	T2,T2
	HRLM	T2,.JBUSY(T1)	;FIXUP POINTER
	MOVE	T2,.JBUSY(T1)	;GET A COPY
	MOVEM	T2,JOB117	;FOR LATER
	JRST	GSDLT		;DELETE GLOBAL SYMBOL TABLE
UDFGB0:	TXNE	W1,S.LST	;IS THIS THE LAST BLOCK
	JRST	UDFLUP		;YES
	ADDI	T1,.L		;NO, GET NEXT TRIPLET
UDFGB:	HRRZ	T1,@HT.PTR	;GET POINTER AGAIN
	ADD	T1,GS.LB	;ADD IN BASE
	SKIPG	W1,.L(T1)	;GET NEXT FLAG WORD
	JRST	UDFERR		;MUST HAVE SIGN BIT ON
	TXNN	W1,S.FXP	;AND A FIXUP
	JRST	UDFGB0		;NOT YET
	MOVE	W3,.L+2(T1)	;GET VALUE
	MOVE	T1,W3
UDFGB1:	ADD	T1,FX.LB	;RELOCATE IN FIXUP TABLE
	SKIPL	W1,0(T1)	;GET FLAGS
	JRST	UDFERR		;JUST INCASE
	TXNN	W1,FP.SYM	;ADDITIVE GLOBAL FIXUP?
	JRST	UDFGB2		;NO
	DMOVE	W2,1(T1)	;GET DATA WORDS
	TXNE	W1,FS.FXS	;SYMBOL FIXUP?
	JRST	UDFGB2		;*** DON'T KNOW HOW TO DO IT YET ***
	PUSHJ	P,SXBR50	;CONVERT TO RADIX-50
	TXO	W2,R5.GLB	;MAKE INTO A GLOBAL DEFINITION
	TXO	W3,R5.FXA	;AND TURN ON ADDITIVE BIT
	TXNE	W1,FS.FXL	;LEFT HALF?
	TXO	W3,R5.FXL	;YES
	ADDI	P4,2		;USES 2 WORDS
	HRRZ	T1,P4		;ADDRESS ONLY
	CAMLE	T1,TAB.AB(R)	;WILL IT FIT
	PUSHJ	P,UDFEXP	;NO
	DMOVEM	W2,-1(P4)	;STORE
	AOS	JOB117		;COUNT 1 MORE WORD PAIR
	SKIPGE	SYMSEG		;[715]
	JRST	UDFGB2		;[715] JUMP IF PSECT SPCIFIED
	MOVEI	T1,2		;AND INCLUDE IN SPACE ASSIGNED
	ADDM	T1,HL.S0(R)	;SINCE WE DIDN'T ACCOUNT FOR IT EARLIER

;FALL THROUGH TO NEXT PAGE
;	JRST	UDFGB2
;FALL IN FROM PREVIOUS PAGE

UDFGB2:	HRRZ	T1,W1		;GET POINTER
	JUMPE	T1,UDFLUP	;ALL DONE IF ZERO
	JRST	UDFGB1		;GET NEXT BLOCK

UDFEXP:	PUSH	P,P2		;SAVE P2 BEFORE EXPANDING CORE
	MOVEI	P1,(R)
	MOVEI	P2,2		;AT LEAST 2 WORDS EXTRA
	SUB	P4,TAB.LB(R)	;REMOVE BASE INCASE WE MOVE
	ADD	P4,LW.S0(R)	;INCASE PAGES CHANGE
	PUSHJ	P,LNKCOR##
	  PUSHJ	P,NO.COR##	;FAILED
	SKIPN	TAB.PG(R)	;[570] PAGING THIS AREA?
	JRST	UDFEX1		;[570] NO, FORGET IT
	MOVE	T1,P4		;[570] YES, MUST UPDATE UW OURSELVES
	IORI	T1,.IPM		;[570] ONLY EXPANDED TO THIS PAGE
	MOVEM	T1,TAB.UW(R)	;[570] UPDATE THE WORD
UDFEX1:	PUSHJ	P,CHKPAG	;[570] INCASE WE STARTED PAGING
	SUB	P4,LW.S0(R)	;BACK AS IT WAS
	ADD	P4,TAB.LB(R)
	POP	P,P2		;RESTORE P2 TO BEFORE UDFEXP
	POPJ	P,

UDFERR:	JRST	UDFLUP		;SYMBOL TABLE FOULED UP
;HERE TO GET RID OF GLOBAL TABLE AND IF POSSIBLE CUT BACK CORE
NOUNDF:	SETZM	USYM		;MAKE SURE ITS CLEAR
	SKIPE	PAG.S1		;PAGING?
	SKIPA	T1,JOBPTR	;YES, LOAD CORRECT OFFSET
	MOVE	T1,LC.LB	;BASE OF LOW SEG
	SETZM	.JBUSY(T1)	;CLEAR UNDF POINTER
GSDLT:	SKIPN	.JBDDT(T1)	;SEE IF WE NEED LOCAL SYMBOLS
	SKIPE	SYMSEG		;EITHER FOR /DEB OR /SYMSEG
	JRST	GSNRED		;YES, DON'T CUT BACK CORE YET
	MOVEI	T1,GS.IX-1	;START AT AREA JUST LOWER
	SKIPN	TAB.LB(T1)	;FIND HIGHEST AREA IN USE
	SOJA	T1,.-1		;WILL GET THERE EVENTUALLY
	MOVE	T2,TAB.AB(T1)	;GET HIGHEST LOC IN USE IN IT
	IORI	T2,1777		;K BOUND
	ADDI	T2,2000		;EXTRA K FOR SAFETY
	CAML	T2,.JBREL	;ANYTHING TO GIVE BACK?
	JRST	GSNRED		;NO, REDUCED ALREADY
	CORE	T2,		;DELETE TOP PART
	  JRST	GSNRED		;NEVER CAN HAPPEN
	MOVE	T2,.JBREL	;GET NEW TOP
	MOVEM	T2,GS.AB	;RESET TABLE
	MOVEM	T2,GS.UB
	CAMLE	T2,GS.LB	;INCASE WE REDUCED IT ALL
	JRST	GSRED		;NO, ALL IS WELL
	MOVEM	T2,TAB.UB(T1)	;RESET HIGHEST FREE LOC AGAIN
	SETZM	GS.LB		;SO XX.ZAP CAN WORK
GSRED:	.ERR.	(MS,.EC,V%L,L%I,S%I,RED,<Reducing low segment to >)
	.ETC.	(COR,.EP,,,,.JBREL)
GSNRED:	PUSHJ	P,GS.ZAP	;GET RID OF GS
	JRST	LSY0		;[715] GO DO LOCAL SYMBOLS
;HERE TO SETUP THE SPECIFIED PSECT FOR SYMBOL TABLE

GETSST:	PUSH	P,T1		;[727]
	SKIPL	SYMSEG		;[715] A PSECT WAS SPECIFIED?
	JRST	[SKIPGE	T1,SYMLIM	;[727] HAVE A DEFAULT LIMIT?
		HRRZM	T1,SYMLIM	;[727] YES, MAKE IT THE LIMIT
		SKIPN	HL.S0(R)	;[715] NO, NULL SEGMENT?
		ADD	P4,[EXP .JBDA,.JBHDA]-1(R) ;[715] SAVE JOBDAT
		ADDB	P4,HL.S0(R)	;[715]  HIGHEST LOADED FOR SEG
		POP	P,T1		;[727] RESTORE T1
		POPJ	P,]		;[715] RETURN FROM HERE IF HIGH/LOW
	SETZ	R,		;[727] YES, HAVE PSECT NAME
GETS1:	MOVE	T1,@RC.TB	;[715]
	MOVE	T2,RC.NM(T1)	;[715] GET PSECT NAME
	CAMN	T2,SSGNAM	;[715] IS THIS THE ONE?
	JRST	GETS2		;[715] YES,
	ADDI	R,1		;[715] NEXT ONE
	CAMG	R,RC.NO		;[715] ANY MORE?
	JRST	GETS1		;[715] YES, LOOP
	.ERR.	(MS,,V%M,L%W,S%W,NPS,<NON-EXISTENT PSECT SPECIFIED>)
	SETZM	SSGNAM		;[715]
	MOVEI	R,1		;[715] SET TO LOW
	MOVEM	SYMSEG		;[715]
	POP	P,T1		;[715] RESTORE AC'S
	JRST	GETSST+1	;[715] AND LOOP BACK

GETS2:	MOVE	T2,RC.CV(T1)	;[715] GET HIGHEST LOCATION
	ADDB	P4,T2		;[715] GET SYMBOL START ADDR
	CAMLE	P4,HL.S1	;[715] GREATER THAN HIGHT LOCATION?
	MOVEM	P4,HL.S1	;[715] UPDATE IT IN THAT CASE
	SKIPLE	SYMLIM		;[727] DO WE HAVE A LIMIT
	JRST	GETS3		;[715]  FROM THE LAST CALL TO HERE
GETS4:	ADDI	R,1		;[715] NEXT PSECT
	CAMG	R,RC.NO		;[715] SKIP IF NO MORE
	JRST	[MOVE	T1,@RC.TB	;[715] THERE IS ONE
		MOVE	T2,RC.IV(T1)	;[715] GET ITS ORIGIN
		SUBI	T2,1		;[727] ONE LESS
		MOVEM	T2,SYMLIM	;[715] MAKE IT THE SYMBOL LIMIT
		JRST	GETS3]		;[715]
	SETOM	SYMLIM		;[715] NO LIMIT AND BEEN HERE BEFORE
GETS3:	MOVE	T1,P4		;[764] GET START OF THE SYMBOL TABLE
	TRZ	T1,777		;[764] ROUND DOWN TO PAGE BOUND
	CAMGE	T1,LOWLOC	;[764] LOWER THAN ANY CODE?
	MOVEM	T1,LOWLOC	;[764] YES, UPDATE LOWEST LOCATION
	MOVEI	R,1		;[715] UPDATE SEGMENT#
	POP	P,T1		;[715] RESTORE AC'S
	POPJ	P,		;[715]
SUBTTL	LOCAL SYMBOLS

;IF LOCAL SYMBOLS AREA REQUIRED IN CORE STORE THEM  ON TOP
; OF LOW SEG OR HIGH SEG CODE
;IF LOWSEG LEAVE A GAP (PATSPC) FOR MORE SYMBOLS OR PATCHING
; IF HIGH PUT AGAINST PAGE BOUND (0.5K)
;
;IF LOCAL SYMBOLS NOT REQUIRED JUST FLUSH SPACE
;IF SYMBOLS ON DSK READ BACK IN FIRST

LSY0:	SKIPE	PAG.S1		;PAGING?
	SKIPA	T1,JOBPTR	;YES, LOAD CORRECT OFFSET
	MOVE	T1,LC.LB	;LOAD UP OFFSET
	SKIPN	T2,VERNUM	;GET VERSION# SET BY SWITCH
	SKIPA	T2,.JBVER(T1)	;GET VERSION FROM LOC .JBVER
	MOVEM	T2,.JBVER(T1)	;STORE BACK IN CORE IMAGE
	MOVEM	T2,VERNUM	;SAVE FOR .RBVER OF FILES
	SKIPE	NOSYMS		;NOT IF /NOSYMS
	JRST	LSY00
	SKIPN	.JBDDT(T1)	;IF DDT WE NEED LOCALS
	SKIPE	SYMSEG		;OR IF USER SPECIFIED WHERE TO PUT THEM
	JRST	LSREQ		;YES,
LSY00:	SETZM	.JBSYM(T1)	;CLEAR POINTER
	SKIPE	IO.PTR+%SC	;HOWEVER IF WE WANT OLD SYMBOL FILE
	SKIPL	SYMFRM		;WE STILL NEED TO CONVERT SYMBOLS
	JRST	NOLOCS		;NO, DONT BOTHER
;HERE IF /SYMSEG, /SYFILE:RADIX50, OR C(.JBDDT) <> 0.
;CONVERT THE SYMBOLS IN THE LS AREA TO RADIX50 AND PUT THEM IN CORE.

LSREQ:
IFN FTOVERLAY,<
	SKIPL	LNKMAX		;DID WE SEE ANY OVERLAYS?
	JRST	LSOVS		;YES, SPECIAL
>
	.ERR.	(MS,0,V%L,L%I,S%I,SST,<Sorting symbol table>)
	PUSHJ	P,SYMINI	;DO THE MAGIC TO MOVE SYMBOLS UP IN CORE
LSREQ1:	PUSHJ	P,CHKPAG	;[645] INCASE PAGE FOR THE FIRST TIME
	SKIPE	USYM		;IF NO UNDEFINED SYMBOLS
	TDZA	P4,P4		;YES, DONE ALREADY
	MOVE	P4,PATSPC	;NEED TO LEAVE A HOLE FOR PATCHING
	PUSHJ	P,GETSST	;[715] GET FINAL SYMBOL START ADDR
	MOVE	P2,P4		;COPY INCASE NOT ENOUGH
	SKIPE	PAG.S0(R)	;PAGING THIS AREA?
	SKIPE	USYM		;YES, BUT ALREADY SETUP IF UNDEFS
	CAIA			;DON'T HAVE TO WORRY
	PUSHJ	P,LSYP		;YES, GET RIGHT PAGES IN CORE
	SUB	P2,LW.S0(R)	;REMOVE PAGED BASE
	ADD	P2,TAB.LB(R)	;IN CORE
	CAMG	P2,TAB.AB(R)	;ENOUGH CORE?
	JRST	LSY1		;YES,
	SUB	P2,TAB.AB(R)	;GET EXTRA WE NEED
	MOVEI	P1,(R)		;FROM WHERE
	SETOM	LS.PP		;[754] PROHIBIT PAGING OF SYMBOLS
	PUSHJ	P,LNKCOR##	;GET IT
	  JRST	LSREQ1		;[645] NO CORE, LOOP BACK AND PAGE
	SKIPN	TAB.PG(R)	;[570] PAGING?
	JRST	LSREQ0		;[570] NO, FORGET IT
	MOVE	T1,P4		;[570] YES, UPDATE UW
	IORI	T1,.IPM		;[570] FROM MAX VIRT ADDR, IN P4
	MOVEM	T1,TAB.UW(R)	;[570]
LSREQ0:	MOVE	P2,P4		;[570] RELATIVE
	SUB	P2,LW.S0(R)	;REMOVE PAGED BASE
	ADD	P2,TAB.LB(R)	;FIX IN CORE
LSY1:	SETZM	LS.PP		;[754]
	SKIPGE	SYMSEG		;[715]
	JRST	.+3		;[715] JUMP IF PSECT SPCIFIED
	MOVEM	P4,HC.S0(R)	;FOR .JBCOR
	EXCH	P4,HL.S0(R)	;GET BASE OF UNDFS
	SKIPE	PAG.S1		;PAGING?
	SKIPA	T1,JOBPTR	;YES, LOAD CORRECT OFFSET
	MOVE	T1,LC.LB	;CODE OFFSET
	ADD	P4,LL.S0(R)	;PLUS STARTING OFFSET
	HRRZM	P4,.JBSYM(T1)	;FIXUP POINTER (ADDRESS ONLY)
	HRRZM	P4,JOB116	;AND FOR .SYM FILE
	MOVEI	T1,.IPS		;SIZE WE CARE ABOUT
	SUB	T1,LS.FR	;MINUS FREE
	MOVEM	T1,LSCNT	;LEFT IN THIS BLOCK
	SKIPGE	SYMSEG		;[715] PSECT NAME USED?
	SKIPA	T1,P4		;[715] YES, USED P4 INSTEAD
	MOVE	T1,HL.S0(R)	;SETUP CORE POINTER
	MOVEI	T2,2(T1)	;REL ADDRESS OF "TITLE" FOR PAT..
	MOVEM	T2,TTLPTR
	SUB	T1,LW.S0(R)	;REMOVED PAGED BASE
	ADD	T1,TAB.LB(R)	;ADD FIXED BASE
	MOVEM	T1,TAB.PT(R)	;ABS POINTER TO NEXT FREE LOC


;NOW OUTPUT THE SYMBOL PAT.. IN MODULE PAT.. AS THE LAST SYMBOL

	MOVE	W2,[RADIX50 04,PAT..]	;BE COMPATIBLE (ALMOST)
	SKIPGE	SYMSEG		;[715] PSECT NAME USED?
	SKIPA	W3,P4		;[715] YES, USE P4 INSTEAD
	HRRZ	W3,HL.S0(R)	;VALUE
	SUB	W3,PATSPC	;POINT TO BOTTOM OF AREA
	HLRE	T1,JOB117	;BUT TAKE INTO ACCOUNT UNDEFINED SYMBOLS
	ADD	W3,T1		;WHICH ARE BETWEEN PAT.. AND .JBSYM
	ADD	W3,LL.S0(R)	;ADD IN OFFSET TO SEGMENT
	PUSHJ	P,SYMOUT	;LAST SYMBOL
	  JRST	SYDONE		;[715] EXCEEDED SPACE, ALL DONE
	TLZ	W2,740000	;MAKE RADIX50 0,PAT.. BE THE TITLE
	PUSHJ	P,SYMOUT
	  SKIPA			;[715] EXCEEDED SPACE, ALL DONE
	PUSHJ	P,LSLOOP	;READ ALL OF SYMBOLS
	JRST	SYDONE		;ALL DONE
IFN FTOVERLAY,<
LSOVX::	MOVEM	T1,LSCNT	;STORE WORDS LEFT IN THIS BLOCK
	SETZM	TTLPTR		;START AFRESH
	POPJ	P,

LSOVS:	HLRE	T2,PH.RDX	;GET - NO. OF SYMBOLS
	MOVM	T3,T2		;+
	ADD	T3,HL.S1	;HIGHEST LOCATION
	ADD	T3,SPACE	;PLUS BUFFER SPACE
	ADD	T3,PATSPC	;AND PATCHING SPACE
	IOR.	T3,.PGSIZ	;UP TO PAGE BOUND
	ADDI	T3,1		;NEXT FREE
	ADD	T3,T2		;START OF SYMBOLS
	HLL	T3,PH.RDX	;- COUNT
	MOVEM	T3,JOB116
	MOVEM	T3,.JBSYM(T1)	;STORE SYMBOL TABLE PTR
	JRST	NOLOCS		;BUT DON'T READ IN
>
;HERE TO SETUP CORRECT LC/HC PAGES
;WRITE OUT ALL OF CURRENT (UPTO START OF LAST LOC IN USE)
;ALLOCATE INITIALLY 1 BLOCK (IT WILL EXPAND AS REQUIRED)

LSYP:	HRLZ	T1,LW.S0(R)	;BASE
	HRR	T1,UW.S0(R)	;UPPER LIMIT
	PUSHJ	P,@[EXP LC.OUT##,HC.OUT##]-1(R)	;GO TO CORRECT ROUTINE
	SKIPGE	SYMSEG		;[715] PSECT SPECIFIED?
	SKIPA	T2,P4		;[715] YES,
	HRRZ	T2,HL.S0(R)	;THIS IS THE LOCATION WE REQUIRE
	ANDCMI	T2,.IPM		;WILL BE LOWER PAGE BOUND
	MOVEM	T2,LW.S0(R)	;STORE IT NOW
	IORI	T2,.IPM		;THENCE UPPER BOUND
	EXCH	T2,UW.S0(R)	;SWAP WITH CURRENT
	CAME	T2,UW.S0(R)	;IF IDENTICAL
	JRST	[MOVE	T1,UW.S0(R)	;GET UPPER LIMIT
		HRLI	T1,-.IPM(T1)	;GET LOWER LIMIT FOR THIS BLOCK
		PUSHJ	P,@[EXP LC.IN##,HC.IN##]-1(R)	;READ IN TOP BLOCK
		JRST	LSYP1]		;AND CONTINUE
	HRLZ	T2,TAB.AB(R)	;WE MUST BLT DOWN THE LAST BLOCK
	TLZ	T2,.IPM		;AS IT MAY CONTAIN DATA
	HRR	T2,TAB.LB(R)
	MOVEI	T1,.IPS(T2)	;BASE OF FREE
	BLT	T2,-1(T1)	;MOVE IT
LSYP1:	HRRZ	T1,TAB.LB(R)	;LOWEST LOC IN CORE
	ADDI	T1,.IPS		;FIRST BLOCK NOW CONTAINS DATA
	CAML	T1,TAB.AB(R)	;AREA ONLY ONE PAGE LONG?
	JRST	LSYP2		;YES, DON'T ZERO NEXT AREA
	HRL	T1,T1
	SETZM	(T1)		;ZERO IT
	ADDI	T1,1		;FORM BLT PTR
	BLT	T1,@TAB.AB(R)	;CLEAR ALL OF THIS CORE
;NOW GIVE REST TO NEXT LOWER AREA

LSYP2:	MOVE	T1,TAB.LB(R)	;GET BASE
	IORI	T1,.IPM		;MAKE IT ONE BLOCK LONG
	MOVEM	T1,TAB.AB(R)	;SO WE CAN CORRECTLY COUNT
	MOVEI	T1,-1(R)	;GET INDEX TO NEXT AREA
	SKIPN	TAB.LB(T1)	;FIND ONE SETUP (MUST BE)
	SOJA	T1,.-1		;SHOULD NEVER GET HERE ANYWAY
	MOVE	T2,TAB.AB(T1)	;GET HIGHEST IN USE
	ADDI	T2,1		;POINT TO NEXT FREE
	CAML	T2,TAB.LB(R)	;ALREADY HERE?
	POPJ	P,		;YES, NOTHING WE CAN DO ABOUT IT
	SUBI	T2,1		;UPPER LIMIT AGAIN
	MOVEM	T2,TAB.UB(T1)	;RESET IT FOR LOWER AREA
	HRRZI	T1,1(T2)	;NEXT FREE WHERE BLOCK WILL GOTO
	HRL	T1,TAB.LB(R)	;FROM WHERE IN LEFT
	HRRZM	T1,TAB.LB(R)	;NOW RESET IT
	MOVE	T2,T1		;GET A COPY
	BLT	T1,.IPM(T2)	;THIS BLOCK DOWN
	MOVS	T2,T2		;PUT FROM ADDR. IN RIGHT
	HRLI	T1,(T2)		;NOW FOR ZERO BLT
	HRRI	T1,1(T2)
	SETZM	(T2)
	TLO	T2,.IPM		;STILL HAVE TO SET TOP INUSE
	HLRZM	T2,TAB.AB(R)	;FOR 1 BLOCK
	BLT	T1,.IPM(T2)	;THROUGH THIS BLOCK
	POPJ	P,
LSLOOP::PUSHJ	P,GETSYM	;GET SYMBOL IN W1,W2,W3
	  POPJ	P,		;ALL DONE
	JUMPGE	W1,LSLOOP	;IGNORE ALL EXTENDED BLOCK
	TXNE	W1,PT.TTL	;SPECIAL IF TITLE BLOCK
	JRST	LTITLE		;NEED TO KEEP POINTERS ETC
	TXNE	W1,PT.SYM	;ONLY WANT REAL SYMBOLS
	TXNE	W1,PS.MDF	;BUT NOT MULTIPLE DEFINITION
	JRST	LSLOOP		;MUST BE SOME THING ELSE
	PUSHJ	P,SXBR50	;CONVERT TO RADIX-50
	TXNE	W1,PS.GLB	;GLOBAL?
	TXO	W2,R5.GLB	;YES
	TXNE	W1,PS.COM	;COMMON?
	JRST	LSLUPC		;YES, NEEDS TWO SYMBOLS
	TXNE	W1,PS.LCL	;THEN LOCAL?
	TXO	W2,R5.LCL	;YES
	TXNE	W1,PS.DDT	;NO DDT OUTPUT?
	TXO	W2,R5.DDT	;YES SET BIT
LSLUP1:	PUSHJ	P,SYMOUT	;PUT SYMBOL IN CORE
	  POPJ	P,		;[715] EXCEEDED SPACE, RETURN
	SKIPGE	LSCNT		;DO WE HAVE SOMETHING TO GIVE BACK?
	PUSHJ	P,RDUSYM	;YES, SAFE TO DO SO NOW
	JRST	LSLOOP		;AND BACK FOR MORE

LSLUPC:	PUSHJ	P,SYMOUT	;OUTPUT IT
	  POPJ	P,		;[715] EXCEEDED SPACE, RETURN
	PUSH	P,W3		;SAVE ADDRESS
	MOVX	T1,S.COM	;PART WE WANT
	PUSHJ	P,GETAST	;GET REST OF SYMBOL
	  JRST	[POP	P,W3		;TOO BAD
		JRST	LSLOOP]		;JUST IGNORE
	PUSHJ	P,SXBR50	;IN RADIX50
	TXO	W2,R5.DDT!R5.GLB	;CODE 44
	POP	P,T1		;GET ADDRESS
	HRL	T1,W3		;LENGTH ,, ADDRESS
	MOVE	W3,T1		;...
	JRST	LSLUP1		;OUTPUT IT
;HERE TO GET NEXT SYMBOL BLOCK
;CALLED BY
;	PUSHJ	P,GETSYM
;RETURNS
;W1, W2, W3 WITH SYMBOL INFO
;USES T1
;READS SYMBOL TABLE IN REVERSE ORDER

GTSYM1:	PUSHJ	P,PAGSYM	;SEE IF PAGING
	  POPJ	P,		;NO, ALL DONE
				;FALL INTO GETSYM


GETSYM:	MOVNI	T1,3		;BACKUP POINTET TO
	ADD	T1,LS.PT	;GET NEXT TRIPLET
	CAMGE	T1,LS.LB	;DON'T GO TOO FAR
	JRST	GTSYM1		;SEE IF PAGING
	MOVEM	T1,LS.PT	;SAFE TO STORE NOW
	TMOVE	W1,0(T1)	;FLAGS, SYMBOL, VALUE
	MOVNI	T1,3
	ADDB	T1,LSCNT	;REDUCE COUNT IN THIS BLOCK
	JRST	CPOPJ1		;SKIP RETURN

;HERE TO GIVE BACK TOP BLOCK OF SYMBOLS
;CAN ONLY BE DONE IF WE HAVE FINISHED WITH CURRENT SYMBOL
;AND ITS SECONDARY TRIPLETS
;SPECIFICALLY TITLE SECONDARIES MUST NOT BE DELETED UNTIL
;TITLE IS OUTPUT

RDUSYM:	MOVE	T1,LS.PT	;GET LOWEST ADDRESS WE STILL NEED
	IORI	T1,.IPM		;FORM BLOCK BOUND
	MOVE	T2,LS.AB	;PREV TOP
	SUBI	T2,(T1)		;LENGTH
	JUMPE	T2,CPOPJ	;JUST IN CASE 
	HRLZ	T3,T1		;FORM BLT PTP
	HRRI	T3,1(T1)
	SETZM	(T1)		;CLEAR FIRST WORD
	EXCH	T1,LS.AB	;SET IT SO
	BLT	T3,(T1)
	MOVEI	T1,.IPS		;RESET COUNT
	ADDM	T2,LSCNT	;RESET WORD COUNT
	MOVN	T2,T2		;NEGATE IT
	SKIPE	UW.LS		;LEAVE ALONE IF NOT PAGING
	ADDM	T2,UW.LS	;ADJUST UPPER WINDOW
	POPJ	P,
;HERE TO READ MORE SYMBOLS IF THEY ARE ON DSK

PAGSYM:	SKIPE	UW.LS		;NEVER WERE
	SKIPN	LW.LS		;WERE BUT ALL DONE
	POPJ	P,		;IN EITHER CASE JUST RETURN CPOPJ
	SKIPE	T1,FX.LB	;ANY FIXUPS LEFT
	SOJA	T1,.+2		;YES, BETTER LEAVE AREA WHERE IT IS
	MOVE	T1,.JBREL	;MOVE LAST BLOCK TO A SAFE PLACE
	MOVE	T2,T1		;GET A COPY FOR END OF BLT
	ANDCMI	T1,.IPM		;AT TOP OF CORE
	CAMG	T1,LS.LB	;SAME AREA BLT FROM/TO?
	JRST	PAGSY2		;YES, DON'T CLEAR IT!
	MOVEI	T3,-1(T1)	;END OF VACATED AREA
	CAMLE	T3,LS.AB	;CLEAR ALL OF IT?
	MOVE	T3,LS.AB	;NO, JUST PART NOT DONE
	HRL	T1,LS.LB	;SO WE HAVE THE HOLE IN THE MIDDLE
	BLT	T1,(T2)		;GO
	HRRZ	T1,LS.LB	;NOW TO ZERO THE JUNK WE LEFT BEHIND
	SETZM	(T1)		;FIRST WORD
	HRL	T1,T1
	ADDI	T1,1		;BLT PTR
	BLT	T1,(T3)		;CLEAR 200 WORDS (USUALLY)
PAGSY2:	MOVE	T1,T2		;
	MOVEM	T1,LS.UB	;ABSOLUTE NEW TOP
	MOVEM	T1,LS.AB	;NO FREE SPACE (AB SAME)
	SUB	T1,LS.LB	;+DIFF (TOTAL AREA - 1)
	ANDCMI	T1,.IPM		;DON'T COUNT PART IN USE
	ADDM	T1,LS.LB	;FIXUP PTRS
	ADDM	T1,LS.PT
	MOVEI	T1,LS.IX	;ACCOUNT FOR NEW FREE SPACE
	PUSHJ	P,ADJ.L		;BY GIVING IT TO NEXT LOWER AREA
;NOW CHECK TO SEE IF AREA IS BIG ENOUGH

PAGSY1:	PUSHJ	P,FR.CNT##	;SEE WHATS FREE
	LSH	T1,-1		;CUT IN HALF
	ANDCMI	T1,.IPM		;BUT KEEP ON A BLOCK BOUND
	JUMPE	T1,[MOVEI T1,(R)	;AREA
		MOVEI	T2,2*.IPS	;SIZE
		PUSHJ	P,EXPSYM	;INCREASE SYMBOL SIZE
		MOVNI	T1,2*.IPS	;NOW GIVE BACK SPACE
		ADDM	T1,TAB.AB(R)
		JRST	PAGSY1]		;AND TRY AGAIN
	CAMLE	T1,LW.LS	;DO WE NEED ALL OF THIS SPACE
	MOVE	T1,LW.LS	;NO, JUST USE ENOUGH
	MOVN	T1,T1		;-INCREASE IN SIZE
	ADDM	T1,LS.LB	;ADJUST LOWER BOUND
	MOVEI	T2,LS.IX-1	;NOW TO FIND NEXT LOWER BOUND
	SKIPN	TAB.LB(T2)	;IN USE
	SOJA	T2,.-1
	MOVE	T3,TAB.AB(T2)	;GET UPPER BOUND OF NEXT LOWER
	CAML	T3,LS.LB	;IS THERE ENOUGH ROOM?
	AOJA	T3,[SPUSH <P1,P2>	;SAVE
		MOVEI	P1,LS.IX	;AREA TO EXPAND
		MOVM	P2,T1		;  AND SIZE
		ADDM	P2,LS.LB	;ADD BACK
		PUSHJ	P,LNKCOR##	;GET THE SPACE
		  PJRST	NO.COR##	;SHOULD NEVER OCCUR
		SPOP	<P2,P1>		;RESTORE
		PJRST	PAGSYM]		;GO GET SYMBOLS
	MOVE	T3,LS.LB	;BOTTOM OF THIS AREA
	SUBI	T3,1		;-1 IS TOP OF NEXT
	MOVEM	T3,TAB.UB(T2)	;TAKE IT ALL (SHUFFLER WILL GET US OUT OF TROUBLE)
	ADDM	T1,LW.LS	;BACKUP WINDOW
	HRLZ	T1,LW.LS	;FORM INPUT PTR
	HRR	T1,UW.LS	;LOWER ,, UPPER
	PUSHJ	P,LS.IN##	;INPUT AREA
	JRST	CPOPJ1		;SKIP RETURN
;HERE TO GET ASSOCIATED SECONDARY TRIPLET
;CALLED BY
;	MOVE	T1,FLAGS
;	PUSHJ	P,GETAST
;RETURNS
;+1	FAILED
;+2	SUCCESS
;USES T1, T2, T3
;SETS UP W1, W2, W3

GETAST:	MOVE	T2,LS.PT	;GET POINTER
GETNAS:	ADDI	T2,.L		;ENTER HERE WITH T2 SETUP
	CAMLE	T2,LS.AB	;STILL IN CORE?
	JRST	FNDNIC		;NOT IN CORE
	SKIPGE	T3,(T2)		;GET FLAGS
	POPJ	P,		;FOUND A PRIMARY (FAILED)
	XOR	T3,T1		;IFF ALL BITS MATCH
	TXZ	T3,S.LST	;IGNORE THIS BIT HOWEVER
	JUMPN	T3,GETNAS	;TRY AGAIN
	TMOVE	W1,(T2)		;FLAGS, SYMBOL, VALUE
CPOPJ1:	AOS	(P)
CPOPJ:	POPJ	P,


FNDNIC:	SKIPN	UW.LS
	POPJ	P,		;ALL DONE
	.ERR.	(MS,.EC,V%L,L%F,S%F,CNW)
	.ETC.	(STR,,,,,,<FNDNIC>)
SYMOUT:	AOS	T1,TAB.PT(R)	;SEE IF ENOUGH TO STORE 2 WORDS
	SKIPG	T2,SYMLIM	;[715] IS IT LIMITED BY NEXT PSECT?
	JRST	SYMO4		;[715] NO,
	PUSH	P,T1		;[715] YES, SAV T1
	SUB	T1,LC.LB	;[715] MINUS WINDOW
	ADD	T1,LW.LC	;[715] CONVERT TO VIRTUAL ADDR
	CAMGE	T1,SYMLIM	;[715] EXCEEDED THE LIMIT
	JRST	[POP	P,T1		;[715] RESTURE T1
		JRST	SYMO4]	;[715] AND RETURN
	SKIPN	SSGNAM		;[727] HAVE A NAME TO OUTPUT?
	JRST	SYMOE1		;[727] NO, JUMP OVER OUTPUTTING NAME
	.ERR.	(MS,.EC,V%L,L%W,S%W,ISS,<Insufficient space for symbol table>)
	.ETC.	(STR,.EC,,,,,< after PSECT >)
	.ETC.	(SBX,.EP!.EC,,,,SSGNAM)
	.ETC.	(STR,,,,,,<--Table truncated>)
	JRST	SYMOE2		;[727]
SYMOE1:	.ERR.	(MS,.EC,V%L,L%W,S%W,ISS)
	.ETC.	(STR,,,,,,<--table truncated>)
SYMOE2:	SOS	TAB.PT(R)	;[727] DECREMENT ONE
	POP	P,T1		;[715]
	POPJ	P,		;[715] ERROR RETURN
SYMO4:	CAMG	T1,TAB.AB(R)
	JRST	SYMO1		;YES
				;SEE IF WE CAN JUST EXPAND
	CAML	T1,TAB.UB(R)	;INTO FREE SPACE?
	JRST	SYMO2		;NO, EXPAND OR WRITE PAGE OUT
	MOVEI	T2,.IPS		;PAGE SIZE
	ADDM	T2,TAB.AB(R)	;ACCOUNT FOR IT
	SKIPE	UW.S0(R)	;IF PAGING THIS SEGMENT
	ADDM	T2,UW.S0(R)	;INCREASE WINDOW
				;FALL INTO SYMO1

SYMO1:	AOS	T1,TAB.PT(R)	;POINT TO NEXT FREE
	DMOVEM	W2,-2(T1)	;STORE SYMBOL & VALUE
IFN FTOVERLAY,<
	SKIPE	T1,RT.PT	;RELOCATABLE?
	CAMN	T1,RT.LB	;MAYBE, IS IT?
	JRST	CPOPJ1		;[715] NO, SKIP RETURN
	IBP	RT.PT		;SYMBOL IS NOT
	TXNN	W1,PS.REL	;IS IT RELOCATABLE?
	TDZA	T1,T1		;NO
	MOVEI	T1,1		;YES
	IDPB	T1,RT.PT	;SET BIT
>
	JRST	CPOPJ1		;[715] SKIP RETURN
	POPJ	P,

;HERE WHEN NOT ENOUGH ROOM
SYMO2:	SKIPE	PAG.S0(R)	;PAGING?
	JRST	SYMO3		;YES, NOT WORTH EXPANDING, JUST OUTPUT IT
	MOVE	T1,R		;EITHER LC.IX OR HC.IX
	MOVEI	T2,.IPS		;EXPAND THIS MUCH
	PUSHJ	P,EXPSYM	;GET SPACE
	JRST	SYMO1		;AND STORE
;SUBROUTINE TO EXPAND CORE, BUT NOT TO PAGE SYMBOLS
;USUALLY CALLED TO CAUSE OTHER AREA TO START PAGING
;CALLED BY
;	MOVEI	T1,AREA
;	MOVEI	T2,SIZE
;	PUSHJ	P,EXPSYM

EXPSYM:	PUSHJ	P,.SAVE2##	;USES P1, P2
	SETOM	LS.PP		;PROHIBIT PAGING OF SYMBOLS
	DMOVE	P1,T1		;GET ARGS
	PUSHJ	P,LNKCOR##	;MUST BE ABLE TO GET IT
	  JRST	NO.COR##	;SHOULD NEVER HAPPEN


;HERE TO SEE IF WE JUST STARTED PAGING AND IF SO, COPY
;JOBDAT OR VESTIGAL JOBDAT INTO DY AREA, SO WE CAN ALWAYS
;REFERENCE THEM EVEN IF THEY ARE PAGED OUT.

CHKPAG:	SKIPE	PAG.S1		;IF WE ARE PAGING
	SKIPE	JOBPTR		;FOR FIRST TIME
	CAIA			;NO
	PUSHJ	P,RDJBL		;MUST SETUP JOB DATA AREA
	SKIPE	PAG.S2		;SAME FOR HIGH SEG
	SKIPE	JBHPTR
	CAIA
	PUSHJ	P,RDJBH		;SET UP JOBDAT IN HIGH
	SETZM	LS.PP		;BACK AS BEFORE
	POPJ	P,
;HERE WHEN WE HAVE TO OUTPUT CORE
;THERE IS NO NEED TO KEEP ANY OF IT SO OUTPUT IT ALL

SYMO3:	AOS	T1,TAB.PT(R)	;POINT TO NEXT FREE
	TRNE	T1,1		;SEE IF 1 FREE LOC
	MOVEM	W2,-2(T1)	;YES, OUTPUT HALF OF SYMBOL
	HRLZ	T1,LW.S0(R)	;OUTPUT ALL OF WINDOW
	HRR	T1,UW.S0(R)
	PUSHJ	P,@[EXP LC.OUT##,HC.OUT##]-1(R)	;GO TO CORRECT ROUTINE
	SKIPGE	SYMFRM		;NEED OLD SYMBOLS (RADIX50)
	PUSHJ	P,OLDSYM	;YES
	HRRZ	T1,TAB.LB(R)	;NOW TO CLEAR JUNK
	HRLI	T1,(T1)
	ADDI	T1,1		;LOW,,LOW+1
	SETZM	-1(T1)
	BLT	T1,@TAB.AB(R)	;TO HIGH
	MOVE	T1,UW.S0(R)	;PREVIOUS HIGH WINDOW
	ADDI	T1,1		;NEW LOW
	MOVEM	T1,LW.S0(R)
	IORI	T1,.IPM		;NEW HIGH IS END OF PAGE
	MOVEM	T1,UW.S0(R)
	MOVE	T1,TAB.PT(R)	;GET POINTER (JUST BEYOND END OF CORE)
	ANDI	T1,.IPM		;SO JUST KEEP OFFSET IN THIS PAGE
	IOR	T1,TAB.LB(R)	;ADD IN BASE
	MOVEM	T1,TAB.PT(R)	;AND STORE
	TRNN	T1,1		;DID WE STORE 1 WORD BEFORE?
	MOVEM	W2,-2(T1)	;NO, DO SO NOW
	MOVEM	W3,-1(T1)
	IORI	T1,.IPM		;LAST ADDRESS IN BLOCK
	MOVEM	T1,TAB.AB(R)	;NOW WINDOWS MATCH
	JRST	CPOPJ1		;[715] SKIP RETURN



;HERE TO GET RID OF VARIOUS AREAS

GS.ZAP:	MOVEI	T1,GS.IX	;GET AREA
	PJRST	XX.ZAP##	;GENERAL ROUTINE

FX.ZAP:	MOVEI	T1,FX.IX
	PJRST	XX.ZAP##

LS.ZAP:	MOVEI	T1,LS.IX
	PJRST	XX.ZAP##

AS.ZAP:	MOVEI	T1,AS.IX	;
	PJRST	XX.ZAP##	;
;HERE TO MOVE SYMBOLS TO TOP OF CORE
;IF SORTING PUT SORT BUFFER IN AREA GS

SYMINI:	SKIPE	FX.LB		;ANY FIXUPS LEFT?
	PUSHJ	P,MOVFX		;YES, MUST MOVE THEM UP
	SKIPN	UW.LS		;IF LOCAL SYMBOLS ON DSK?
	PJRST	MOVSYM		;NO, JUST MOVE UP
;	PJRST	LKPSYM		;READ BACK INTO CORE

;HERE TO WRITE OUT END OF SYMBOL TABLE AND SET IT UP FOR SORTING
LKPSYM:	SKIPL	UW.LS		;IF -1 THEN SYMBOL TABLE NOT OUTPUT YET
	JRST	RDSYM		;JUST READ IT BACK IN
	MOVE	T1,LSYM		;ADRESS OF LAST SYMBOL STORED +1
	SUBI	T1,1
	IORI	T1,.IPM		;BLOCK BOUND
	HRL	T1,LW.LS	;FORM  BLT WORD
	HRRZM	T1,UW.LS	;SIGNAL ALL OF SYMBOLS ON DSK
	PUSHJ	P,LS.OUT##	;AND OUTPUT IT
				;FALL INTO RDSYM TO READ IT BACK


RDSYM:	PUSHJ	P,MOVSYM	;MOVE WHAT WE HAVE UP IN CORE
				;AT THIS POINT THERE IS NO NEED TO READ
				;MORE SYMBOLS, THAT WILL HAPPEN NEXT TIME ANYWAY
				;UNLESS WE ONLY HAVE ONE BLOCK IN CORE
				;THIS CASES PROBLEMS SO READ IN MORE
	MOVE	T1,UW.LS	;UPPER LIMIT
	ANDCMI	T1,.IPM		;START OF THIS PAGE
	CAME	T1,LW.LS	;IS IT THE LOWER PAGE BOUND?
	POPJ	P,		;NO, JUST RETURN
	MOVEI	T1,LS.IX-1	;YES, SEE HOW MUCH SPACE WE HAVE WITHOUT SHUFFLING
	SKIPN	TAB.LB(T1)	;USUAL LOOK FOR LOWER AREA
	SOJA	T1,.-1
	MOVE	T2,LS.LB	;WHERE WE START AT
	SUB	T2,TAB.AB(T1)	;MINUS WHATS IN USE
	SUBI	T2,1		;COUNT OF WHATS FREE
	LSH	T2,-1		;CUT IN HALF
	ANDCMI	T2,.IPM		;ON BLOCK BOUND
	CAMLE	T2,LW.LS	;BUT DON'T GET TOO MUCH
	MOVE	T2,LW.LS	;IF WE DON'T HAVE ENOUGH SYMBOLS
	MOVN	T2,T2		;GET NEG SO WE CAN BACKUP
	ADDM	T2,LS.LB	;MOVE DOWN IN CORE
	ADDM	T2,TAB.UB(T1)	;AND TAKE THIS SPACE
	ADDM	T2,LW.LS	;OPEN WINDOW WIDER
	MOVE	T1,UW.LS	;GET TOP OF WINDOW
	SUBI	T1,.IPS		;BUT WE ALREADY HAVE THIS PAGE
	HRL	T1,LW.LS	;FORM TRANS WORD
	PJRST	LS.IN##		;READ IT IN
;HERE IF TOP OF SYMBOL TABLE IS ALREADY IN CORE
;HOWEVER IT IS NOT AT TOP OF CORE WHERE WE WOULD LIKE IT
;THEREFOR MOVE ALL LS UP TO .JBREL
;USE REVERSE BLT IN ACCS

MOVSYM:
IFN FTOVERLAY,<
	SKIPLE	LNKMAX		;ANY OVERLAYS
	SKIPN	LNKNO.		;BUT NOT ROOT
	JRST	.+3		;NO
	MOVE	T1,LS.UB	;CAN NOT USE TOP OF CORE
	JRST	.+4
>
	SKIPE	T1,FX.LB	;STILL FIXUPS TO DO?
	SOJA	T1,.+2		;YES, MAKE T1 POINT TO HIGHEST FREE
	MOVE	T1,.JBREL	;NO, GET TOP OF CORE
	CAMN	T1,LS.AB	;AT ACTUAL TOP OF LS?
	POPJ	P,		;YES, JUST RETURN
	MOVEM	T1,LS.UB	;MAKE IT TOP
	SUB	T1,LS.AB	;GET DIFFERENCE = OFFSET
	PUSH	P,T1		;SAVE OFFSET
	MOVE	T4,LS.AB	;TOP
	SUB	T4,LS.LB	;-BOTTOM
	ADDI	T4,400001	;400000+LENGTH
	MOVS	T4,T4
	HRR	T4,LS.AB	;TOP OF OLD DATA
	HRLI	T1,(POP T4,0(T4))
	MOVE	T2,[JUMPL T4,T1]
	MOVSI	T3,(POPJ P,)	;REVERSE BLT NOW SET UP
	PUSHJ	P,T1		;DO IT
	MOVE	T2,LS.AB	;[647]
	MOVE	T1,LS.UB
	MOVEM	T1,LS.AB	;SET BOUNDS THE SAME
	POP	P,T1		;OFFSET
	ADD	T1,LS.LB	;NEW BASE
	SUBI	T1,1		;HIGHEST TO GIVE BACK
	HRL	T1,T2		;[647] HIGHEST ADDR TO ZERO
	PUSHJ	P,GBCK.L##
	MOVE	T1,LSYM		;NOW RESET LS.PT TO POINT TO LAST SYMBOL
	SUB	T1,LW.LS	;MINUS WINDOW BASE
	ADD	T1,LS.LB	;PLUS OFFSET IN CORE
	MOVEM	T1,LS.PT	;OK NOW
	POPJ	P,
;HERE TO ADD FREE SPACE TO NEXT LOWEST AREA IN USE
;CALLED BY
;	MOVEI	T1,THIS AREA
;	PUSHJ	P,ADJ.L
;USES T1, T2

ADJ.L:	MOVE	T2,TAB.LB(T1)	;GET CURRENT LOWEST SIZE
	SUBI	T2,1		;THIS IS NOW UPPER OF NEXT LOWER
	SKIPN	TAB.LB-1(T1)	;FIND ONE
	SOJA	T1,.-1		;EVENTUALLY
	MOVEM	T2,TAB.UB-1(T1)
	POPJ	P,		;RETURN
;HERE IF WE HAVE TO MOVE FIXUP AREA (IT MAY CONTAIN SYMBOL FIXUPS)
;MOVE UP TO VERY TOP OF CORE, OUT OF WAY OF  SYMBOLS
;USE REVERSE BLT IN ACCS

MOVFX:	MOVE	T1,.JBREL	;GET TOP OF CORE
	CAMN	T1,FX.AB	;AT ACTUAL TOP OF FIXUPS?
	POPJ	P,		;YES, JUST RETURN
	MOVEM	T1,FX.UB	;MAKE IT TOP
	SUB	T1,FX.AB	;GET DIFFERENCE = OFFSET
	PUSH	P,T1		;SAVE OFFSET
	MOVE	T4,FX.AB	;TOP
	SUB	T4,FX.LB	;-BOTTOM
	ADDI	T4,400001	;400000+LENGTH
	MOVS	T4,T4
	HRR	T4,FX.AB	;TOP OF OLD DATA
	HRLI	T1,(POP T4,0(T4))
	MOVE	T2,[JUMPL T4,T1]
	MOVSI	T3,(POPJ P,)	;REVERSE BLT NOW SET UP
	PUSHJ	P,T1		;DO IT
	MOVE	T1,FX.UB
	MOVEM	T1,FX.AB	;SET BOUNDS THE SAME
	POP	P,T1		;OFFSET
	ADDM	T1,FX.PT
	ADD	T1,FX.LB	;NEW BASE
	SUBI	T1,1		;HIGHEST LOC TO GIVE AWAY
	PJRST	GBCK.L##	;TO NEXT LOWER
SYDONE:	SKIPE	PAG.S1		;PAGING LOW SEG?
	SKIPA	P1,JOBPTR	;YES, LOAD CORRECT OFFSET
	MOVE	P1,LC.LB	;LOAD UP OFFSET
	SKIPE	PAG.S2		;PAGING HIGH SEG?
	SKIPA	P2,JBHPTR	;YES, LOAD CORRECT OFFSET
	MOVE	P2,HC.LB	;LOAD UP OFFSET
	MOVE	T2,.JBSYM(P1)	;GET ADDRESS OF BASE OF SYMBOLS
	HRRZ	T3,TAB.PT(R)	;AND CURRENT TOP
	SUB	T3,TAB.LB(R)	;REMOVE OFFSET
	ADD	T3,LW.S0(R)	;BUT ADD IN BASE OF INCORE WINDOW
	CAMG	T3,HC.S0(R)	;[715] PSECT NAME USED?
	JRST	.+3		;[715] YES,  DON'T UPDATE
	MOVEM	T3,HC.S0(R)	;RESET HIGHEST LOC IN USE COUNTERS
	MOVEM	T3,HL.S0(R)	;SO WE WILL PRESERVE THE SYMBOLS
	ADD	T3,LL.S0(R)	;ADD IN SEGMENT OFFSET
	SUBI	T2,0(T3)	;FIND - LENGTH
	HRLM	T2,.JBSYM(P1)	;FIXUP SYMBOL TABLE POINTER
	HRLM	T2,JOB116	;AND FOR .SYM FILE
	SKIPGE	SYMFRM		;OLD STYLE SYMBOL FILE REQUIRED?
	PUSHJ	P,OLDSYM	;YES, WRITE OR COMPLETE IT
	.ERR.	(MS,0,V%L,L%I,S%I,STC,<Symbol table completed>)
	JRST	REMVLS		;SETUP REST AND DELETE LS AREA

NOLOCS:	SKIPE	PAG.S1		;PAGING LOW SEG?
	SKIPA	P1,JOBPTR	;YES, LOAD CORRECT OFFSET
	MOVE	P1,LC.LB	;LOAD UP OFFSET
	SKIPE	PAG.S2		;PAGING HIGH SEG?
	SKIPA	P2,JBHPTR	;YES, LOAD CORRECT OFFSET
	MOVE	P2,HC.LB	;LOAD UP OFFSET

REMVLS:
	SKIPLE	T1,SYMFRM	;NEW STYLE SYMBOL FILE NEEDED?
	PUSHJ	P,SAVSYM	;YES, OUTPUT THEM NOW
	PUSHJ	P,AS.ZAP	;DONE WITH ALGOL SYMBOLS
	PUSHJ	P,FX.ZAP	;ALSO DONE WITH FIXUP BY NOW
IFN FTOVERLAY,<
	SKIPL	LNKMAX		;OVERLAYS?
	JRST	SAVTST		;KEEP UNTIL SAV FILE MADE
>
	PUSHJ	P,LS.ZAP	;GET RID OF LS
	SKIPN	PAG.LS		;IF NOT PAGING
	JRST	SAVTST		;DON'T DELETE LS FILE
	MOVEI	T1,SC		;CAN DELETE CHAN# NOW
	PUSHJ	P,DVDEL.##
	  JFCL
SAVTST:	SKIPE	IO.PTR+%VC	;SAVE FILE REQUIRED?
	JRST	JBSAVE		;YES
	JRST	JBEXIT		;NO, EXECUTE OR FORM CORE IMAGE
SUBTTL	ROUTINES FOR SYMBOLS


LTITLE:	PUSHJ	P,SXBR50	;CONVERT TO RADIX-50
	TXNE	W1,PT.BLK	;ONLY A FAIL BLOCK HEADER?
	JRST	BTITLE		;YES
	MOVE	T2,TTLPTR	;GET ADDRESS OF LAST PROG
	HRRZ	T1,TAB.PT(R)	;GET THIS ADDRESS
	SUB	T1,TAB.LB(R)	;MINUS OFFSET
	ADD	T1,TAB.LW(R)	;PLUS BASE OF WINDOW
	MOVEM	T1,TTLPTR	;SAVE FOR NEXT
	SUB	T1,T2		;GET DIFFERENCE
	MOVN	T1,T1		;NEGATE
	JUMPE	T2,.+2		;IGNORE IF FIRST TIME
	HRL	W3,T1		;FIXUP POINTER
	PUSH	P,W2		;SAVE SYMBOLS
	PUSH	P,W3
TTLLUP:	MOVX	T1,S.TTL!S.SEG	;FLAGS
	PUSHJ	P,GETAST	;GET EXTENSION TRIPLET
	  SETZB	W2,W3		;ONLY HERE IF DEFINED BY /SWITCH
	SKIPE	W3		;IF ANY HIGH SEG STUFF
	MOVE	W2,W3		;USE IT
	POP	P,W3		;GET W3 BACK
	HLR	W3,W2		;FIX IT UP
	POP	P,W2
	PUSHJ	P,SYMOUT	;OUTPUT PSEUDO SYMBOL
	  POPJ	P,		;[715] EXCEEDED SPACE, RETURN
	JRST	LSLOOP		;RETURN



BTITLE:	TXO	W2,R5.LCL!R5.GLB	;MAKE RADIX50 14,SYM
	HRRZ	W3,W3		;BLOCK LEVEL ONLY
	JRST	LSLUP1		;AND TREAT AS LOCAL SYMBOL
;SXBR50 -- SUBROUTINE TO CONVERT SIXBIT TO RADIX-50
;CALLED BY
;	MOVE	W2,SIXBIT WORD
;	PUSHJ	P,SXBR50
;RETURN
;	RADIX-50 IN W2
;USES T1, T2

SXBR50:	MOVE	T2,W2		;GET SIXBIT SYMBOL
	SETZ	W2,		;WHERE TO STORE RADIX50 SYMBOL
	SETZ	T1,		;CLEAR RECEIVING ACC
	LSHC	T1,6		;GET NEXT CHAR
	IMULI	W2,50		;MULTIPLE BY 50
	ADD	W2,SXBTAB(T1)	;ADD IN NEW CHAR
	JUMPN	T2,.-4		;NOT DONE YET
	POPJ	P,

DEFINE SXBCHR (CHR)<
 IRPC CHR,<
  RADIX50 0,CHR
>>

	XALL
SXBTAB:	SXBCHR (    $%        . 0123456789       ABCDEFGHIJKLMNOPQRSTUVWXYZ     )
	SALL
;HERE FOR OLD FORM SYMBOLS (RADIX-50)
;IF IN CORE WRITE THEM OUT WITH THREE INFORMATION WORDS AT FRONT
;HEADER, .JBSYM (116) AND .JBUSY (117)
;HEADER IS 776(TYPE) ,, LENGTH
;OTHER TWO WORDS ARE RELATIVE TO ZERO
;.JBSYM MUST HAVE A NEGATIVE LEFT HALF
;.JBUSY IS ZERO IF NO UNDEFINED SYMBOLS

OLDSYM:	MOVEI	T1,MC		;USE MAP CHAN INCASE PAGING LC
	MOVEM	T1,IO.CHN
	MOVE	T1,IO.PTR+%SC	;POINT TO CORRECT DATA
	MOVEM	T1,IO.PTR+MC
	PUSHJ	P,DVCHN.##
	MOVSI	T2,(Z MC,)	;RESET CHAN #
	MOVEM	T2,I.CHN(T1)	;SINCE %SC IS THERE CURRENTLY
	HLRO	T2,JOB116	;NUMBER OF SYMBOLS
	MOVM	T2,T2
	LSH	T2,-.DBS2W	;[650] INTO BLOCKS (ASSUME FEW UNDEFS)
	MOVEM	T2,I.EST(T1)
	MOVE	T2,VERNUM	;GET VERSION OF CORE IMAGE
	SKIPN	I.VER(T1)	;SKIP IF SET BY SWITCH
	MOVEM	T2,I.VER(T1)	;NO, SO SET IT
	PUSHJ	P,DVNAM.##	;MAKE SURE NAME SETUP
	PUSHJ	P,DVOPN.##	;INIT DEV
	PUSHJ	P,DVENT.##	;DO ENTER
				;NOW TO STORE THREE INFO WORDS
	HLRE	T1,JOB116	;NO. OF DEFINED SYMBOLS
	HLRE	T2,JOB117	;NO. OF UNDEFS
	MOVM	T1,T1		;+
	MOVM	T2,T2
	ADDI	T2,2(T1)	;PLUS TWO EXTRA WORDS
	HRLI	T2,776		;BLOCK TYPE FOR LINK
	SKIPN	T1,JOB117	;.JBUSY IF NON-ZERO
	MOVE	T1,JOB116	;OTHERWISE .JBSYM
	HRRZ	T1,T1		;REMOVE NEG LEFT HALF
	SUB	T1,LL.S0(R)	;REMOVE ORIGIN
	SUB	T1,LW.S0(R)	;INCASE PAGING
	ADD	T1,TAB.LB(R)	;FIX IN CORE
;NOW PUT HEADER WORDS IN CORE IMAGE SO WE CAN DUMP IT ALL WITH
;ONE IOWD. PUSH REAL CONTENTS OF THOSE LOCATIONS (USUALLY 0) FIRST,
;THEN RESTORE THEM LATER

	SUBI	T1,3		;BACKUP 3
	PUSH	P,0(T1)		;SAVE WORDS INCASE NOT ZERO
	PUSH	P,1(T1)
	PUSH	P,2(T1)
	MOVEM	T2,0(T1)	;SAVE HEADER
	HLLZ	T2,JOB117	;COPY  INFO WORDS
	MOVEM	T2,2(T1)	;TO NEXT 2 LOCS
	HLRE	T2,T2		;GET - LENGTH (OR 0)
	MOVM	T2,T2		;+
	HLL	T2,JOB116	;-LENGTH,,OFFSET
	MOVEM	T2,1(T1)	;FIRST INFO WORD
	HLRE	T2,JOB116	;FIND TOTAL LENGTH TO OUTPUT
	HLRE	T3,JOB117	;.JBSYM+.JBUSY
	ADD	T2,T3
	SUBI	T2,3		;+3 INFO WORDS
	HRLZ	T2,T2		;-LENGTH
	HRRI	T2,-1(T1)	;IOWD LENGTH,ADDRESS
	SETZ	T3,		;TERMINATE
	OUT	MC,T2		;DUMP IT
	  JRST	[POP	P,2(T1)		;RESTORE DATA
		POP	P,1(T1)
		POP	P,0(T1)
		PJRST	DVRLS.##]	;CLOSE FILE
	POP	P,2(T1)		;RESTORE DATA
	POP	P,1(T1)
	POP	P,0(T1)
	PUSH	P,[MC]
	.ERR.	(ST,,V%L,L%W,S%W,OES,<Output error on symbol file, file closed, job continuing>)
	POPJ	P,
;HERE TO SAVE NEW FORM SYMBOL TABLE
;IF ALL IN CORE JUST OPEN AND WRITE OUT
;IF ON DSK EITHER RENAME OR COPY THEM

SAVSYM:	PUSHJ	P,.SAVE1##	;NEED AN AC
	CAIN	T1,1		;SIXBIT SYM FILE WANTED?
	MOVEI	P1,LS.IX	;YES, STORED IN LS AREA
	CAIN	T1,2		;HOW ABOUT ALGOL .SYM FILE?
	MOVEI	P1,AS.IX	;YES, USE AS AREA INSTEAD
	SKIPN	TAB.UW(P1)	;PAGING?
	JRST	WRTSYM		;NO
	MOVE	T1,TAB.AB(P1)	;MAKE SURE UW.XX IS OK
	SUB	T1,TAB.LB(P1)	;MIGHT BE -1 IF LS AREA
	ADD	T1,TAB.LW(P1)	;NOW HAVE HIGHEST LOC IN CORE
	MOVEM	T1,TAB.UW(P1)	;UPDATE UW.XX
	SETCM	T1,TAB.LB(P1)	;ALSO MAKE SURE DISK FILE IS OK
	ADD	T1,TAB.PT(P1)	;IN CASE NEVER OUTPUT BEFORE
	JUMPE	T1,.+4		;FORGET IT IF NOTHING TO OUTPUT
	ADD	T1,TAB.LW(P1)	;NOTE WE'RE GETTING EXACT WORD CNT
	HRL	T1,TAB.LW(P1)	;ALGOL 7 NEEDS .RBSIZ EXACT
	PUSHJ	P,@TB.OUT##(P1)	;SO USE XX.PT INSTEAD OF XX.AB
	MOVE	T1,TAB.AB(P1)	;NOW READ IN FRONT OF FILE
	SUB	T1,TAB.LB(P1)	;SO CAN SET UP 10??,,COUNT
	SETZM	TAB.LW(P1)	;?W.?S MUST BE UP TO DATE
	MOVEM	T1,TAB.UW(P1)	;FOR FOLLOWING CALL
	PUSHJ	P,@TB.IN##(P1)	;AS FIRST WORD OF FILE
	CAIE	P1,AS.IX	;ALGOL?
	  JRST	SAVSY0		;NO, DO IT FOR LS AREA
	MOVE	T2,ASYM		;YES, GET SYMBOL COUNT
	HRLI	T2,1044		;AND BLOCK TYPE
	JRST	SAVSY1		;AND CONTINUE
SAVSY0:	MOVE	T2,LSYM		;COUNT FOR LS AREA
	HRLI	T2,1700		;AND BLOCK TYPE
SAVSY1:	SUBI	T2,1		;WORDS FOLLOWING IS 1 LESS
	MOVEM	T2,@TAB.LB(P1)	;STORE COUNT WORD
	PUSHJ	P,@TB.OUT##(P1)	;AND UPDATE FILE
	MOVEI	T1,SC		;FROM CHAN#
	CAIN	P1,AS.IX	;UNLESS AS AREA
	MOVEI	T1,AC		;IN WHICH CASE ALGOL CHANNEL
	MOVE	T2,IO.PTR+%SC	;TO CHANNEL
	PUSHJ	P,DVPRO.	;GET PROTECTION RIGHT
	MOVEI	T2,%SC		;TO CHAN#
	MOVE	T3,IO.PTR+%SC	;GET POINTER TO NEW FILE
	MOVE	T4,VERNUM	;GET VERSION OF PROGRAM
	SKIPN	I.VER(T3)	;UNLESS ALREADY SET BY SWITCH...
	MOVEM	T4,I.VER(T3)	;SAVE FOR ENTER
	PJRST	DVMOV.		;GO COPY PAGED FILE TO SYMBOL FILE
WRTSYM:	MOVEI	T1,DC		;USE THIS CHAN
	MOVEM	T1,IO.CHN
	MOVE	T1,IO.PTR+%SC	;HIDE DATA BLOCK HERE
	MOVEM	T1,IO.PTR+DC	;NOW BRING IT FORTH
	PUSHJ	P,DVCHN.##	;PUT ADDRESS OF BLOCK IN T1
	MOVSI	T2,(Z DC,)	;RESET CHAN # IN AC FIELD
	MOVEM	T2,I.CHN(T1)	;SINCE %SC IS THERE CURRENTLY
	CAIE	P1,AS.IX	;ALGOL?
	  JRST	WRTSY0		;NO, SETUP 1ST WORD FOR LS
	MOVE	T3,ASYM		;YES, SETUP COUNT WORD
	HRLI	T3,1044		;AND BLOCK TYPE
	JRST	WRTSY1		;CONTINUE
WRTSY0:	MOVE	T3,LSYM		;LS AREA COUNT
	HRLI	T3,1700		;BLOCK TYPE FOR TRIPLET SYMBOLS
WRTSY1:	HRRZ	T2,T3		;SAVE COUNT FOR ESTIMATE
	SUBI	T3,1		;WORDS FOLLOWING IS 1 LESS
	MOVEM	T3,@TAB.LB(P1)	;SAVE WORD COUNT IN AREA
	LSH	T2,-.DBS2W	;[650] INTO BLOCKS
	MOVEM	T2,I.EST(T1)	;WE NEED THIS MUCH
	MOVE	T2,VERNUM	;GET VERSION OF CORE IMAGE
	SKIPN	I.VER(T1)	;SKIP IF SET BY SWITCH
	MOVEM	T2,I.VER(T1)	;NO, SO SET IT
	PUSHJ	P,DVNAM.##	;MAKE SURE NAME IS SET UP
	PUSHJ	P,DVOPN.##	;INIT DEVICE
	PUSHJ	P,DVENT.##	;ENTER FILE
				;NOW FOR OUTPUT
WRTSY2:	MOVE	T1,TAB.LB(P1)	;GET BOTTOM ADDR IN CORE
	SUB	T1,TAB.PT(P1)	;-LENGTH
	HRLZ	T1,T1		;-LENGTH,,0
	HRR	T1,TAB.LB(P1)	;FIRST ADDR OF BUFFER
	HRRI	T1,-1(T1)	;-LENGT