Google
 

Trailing-Edge - PDP-10 Archives - ap-c796e-sb - lnkini.mac
There are 38 other files named lnkini.mac in the archive. Click here to see a list.
TITLE LINK 10/20 - INITIALIZATION MODULE
SUBTTL	D.M.NIXON/DMN/RKH/SRM/JBC/JNG	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.

.JBHSA==:0			;STARTING ADDRESS STORED IN HIGH SEGMENT
.JB41==:41
ENTRY	LINK10
SEARCH	LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
EXTERN	LNKSCN,LNKCOR,LNKLOG,.TYOCH

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



VERSION

SALL
SEGMENT

	LOC	.JB41
	JSR	UUOTRAP
	RELOC


;ACCUMULATORS

R==R1		;MUST MATCH LNKLOD DEFINITION
SUBTTL	REVISION HISTORY

;START OF VERSION 1A
;41	ADD PHYSICAL ONLY GETSEG
;45	HASH INITIAL SYMBOLS AT ASSEMBLY TIME
;46	ADD KLUDGE FEATURE
;64	HANDLE RUN LINK ALL OF CORE PROBLEM
;65	TENEX SPEEDUP
;71	MAKE ALL MESSAGE STANDARD FORM
;106	REMOVE HIORG & ONESEG
;107	CHANGE KLUDGE TO MIXFOR

;START OF VERSION 2
;135	ADD OVERLAY FACILITY
;145	IMPLEMENT USER LIBRARIES
;157	(12640) MAKE VALUE OF FORLIB BE -2 IF .FORLB =-1
;161	ADD LANGUAGE DEPENDENCY TO /USERLIB
;202	REMOVE CORE UUO BEFORE GETSEG

;START OF VERSION 2B
;225	ADD SUPPORT FOR PSECT (MACRO VERSION 51)
;230	ADD CHECK THAT LOW SEG DATA BASE IS SAME SIZE IN ALL SEGMENTS
;302	HANDLE TENEX IDDT CORRECTLY
;333	Add code to handle sucessful GETTAB return of zero
;346	INCLUDE EDIT 302 IN MAINTENANCE SOURCES.  LABEL EDIT 230.
;353	REMOVE EDIT 225

;START OF VERSION 2C
;444	Don't lose libraries defined with the USELIB macro.
;530	Define triplet flags correctly and use TXxx macros.
;557	Clean up listing for release.

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

;START OF VERSION 4
;600	Put phased lowseg code at PHAZLO; start DY area at .JBFF
;604	Support device NUL: correctly
;607	Reserve page 377 on TOPS-20 for HELPER so /HELP will work
;635	Initialize ARSIZE to .ARS.
;636	Make TTYIT and LOGIT preserve T1.
;650	Use VM on TOPS-10 if available.
;674	GETSEG other segments correctly if LINK is run from an SFD.
;677	Don't set /SYMSEG:LOW by default if loading overlays.
;706	Setup RC.NTB
;727	Set defualt symbol limt to .SYLIM
;731	SEARCH MACTEN,UUOSYM instead of C.
;732	Initialize lowest location to 400000,,0.
;750	Initialize LC.AB to LC.LB+.IWM
;765	Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
SUBTTL	INITIALIZE

;HERE AFTER START,  RUN, EXECUTE, LOAD OR RUN UUO

LINK10:	PORTAL	.+2		;EXECUTE ONLY
	PORTAL	.+2		;CCL
	TDZA	P1,P1		;CLEAR OFFSET
	MOVEI	P1,1		;SET OFFSET
	MOVE	R3,.SGNAM	;SAVE NAME OF INITIAL SEGMENT
	RESET			;RESET ANY EXTERNAL I/O
	JUMPE	P1,F1		;SKIP MESSAGE IF NOT CCL
	OUTSTR	CCLMES		;TELL THE WORLD WHO IS NOW RUNNING
F1:	MOVEI	T2,EZCOR+AD.FRC	;WE NEED AT LEAST THIS MUCH CORE
	CAMG	T2,.JBREL	;SEE IF WE HAVE IT
	JRST	.+3		;YES
	CORE	T2,		;NO, BUT GET IT
	  JRST	NOCORE		;YOU LOSE
	MOVEM	P1,OFFSET	;SAFE TO STORE OFFSET NOW
	MSTIME	T1,		;GET INITIAL TIME (MORE OR LESS)
	MOVEM	T1,TIMEON	;SAVE FOR LOG FILE
	MOVE	T1,[ZCOR,,ZCOR+1]
	SETZB	FL,ZCOR		;CLEAR FLAGS AND CORE
	BLT	T1,EZCOR
;DO NOT CLEAR REST OF CORE SINCE MONITOR WILL DO IT
;ON FIRST TIME, AND RESTART LOGIC ON SUBSEQUENT TIMES
;THIS IS ESPECIALLY IMPORTANT IN V/M IF RUNNING IN LARGE LOW SEG
	MOVE	P,[IOWD LN.EPD,EPDP+1]	;ESTABLISH PUSH-DOWN LIST
	MOVEM	P,EPDP		;FOR EMMERGENCY WORK
	SKIPN	OFFSET		;IF NOT CCL MODE
	SETZM	.JBERR		;CLEAR COMPILER ERRORS

IFE FTSINGLE,<
	MOVSI	T1,HICODE	;NOW FOR PHASED CODE
	HRRI	T1,PHAZLO	;INTO DYNAMIC AREA
	BLT	T1,HIEND	;FOR GETSEGS ETC
	MOVEI	T1,SEGCOD	;ADDRESS OF GETSEG ROUTINE
	MOVEM	T1,NXTSEG	;WHERE OTHER SEGMENTS CAN USE IT
	MOVEI	T1,PRVSEG	;SAME BUT FOR LAST SEGMENT
	MOVEM	T1,LSTSEG
	MOVEM	R3,FSTSEG	;SAVE SEGMENT NAME
	MOVEM	R3,SEGBLK+1	;[600] ALSO FOR RESTART LOGIC
	MOVE	T1,[-2,,.GTDEV]	;DEVICE OF HIGH SEG IF SHAREABLE
	GETTAB	T1,		;FROM MONITOR TABLES
	  SETZ	T1,		;FAILED
	JUMPE	T1,[MOVEI T1,<<GETSEG T1,>&777777>
		HRRM	T1,NGTSEG	;REMOVE UU.PHY BIT
		HRRM	T1,EGTSEG	;FROM GETSEGS
		JRST	LINK1A]
	MOVE	.SGDEV,T1	;USE DEVICE FROM GETTAB
	MOVE	T1,[-2,,.GTPPN]	;IF DEVICE WAS SHAREABLE WE NEED PPN
	GETTAB	T1,		;SINCE MOST LIKELY WAS SYS:
	  SETZ	T1,		;SHOULD NOT FAIL
	SKIPE	T1		;OR BE ZERO
	MOVE	.SGPPN,T1	;SO USE [PPN] FROM MONITOR TABLES
LINK1A:	SKIPN	T1,.SGDEV	;ALREADY SETUP BY MONITOR?
	MOVSI	T1,'DSK'	;NO, JUST LOADED ASSUME DSK
	MOVEM	T1,SEGBLK	;STORE DEVICE
	MOVEM	T1,ERRBLK	;FOR LNK999 ALSO
	MOVEM	.SGPPN,SEGBLK+4	;AND PPN
	MOVEM	.SGPPN,ERRBLK+4
	JUMPE	.SGDEV,GETHSO	;IF JUST LOADED, GETTABS POINT TO LINK
;NOW TRY TO GET WHERE WE CAME FROM (INCLUDING SFD'S) VIA GETTAB.
;IF UNAVAILABLE (OLD MONITOR), USE INFO SET UP ABOVE.

	MOVSI	T1,-<.PTMAX-.PTSFD-1>	;NUMBER OF SFD'S
	HRROI	T2,.GTRS0	;GETTAB FOR RUN FROM SFD, THIS JOB
SEGLUP:	MOVE	T3,T2		;SETUP FOR NEXT SFD
	GETTAB	T3,		;GET IT
	  JRST	[TRNN T1,-1	;FAILED, FIRST TIME?
		JRST GETHSO	;YES, NOT IMPLEMENTED, GIVE UP
		JRST GETUFD]	;NO, IMPLEMENTED, BUT WE RAN OUT
	MOVEM	T3,SEGPTH+.PTSFD(T1)	;STORE THIS SFD
	ADDI	T2,1		;INCREMENT GETTAB ARG
	AOBJN	T1,SEGLUP	;LOOP FOR ALL SFD'S

GETUFD:	SETZM	SEGPTH+.PTSFD(T1)	;FORCE A ZERO AFTER THE LAST SFD
	HRROI	T1,.GTRDI	;UFD OF PATH WE WERE RUN FROM
	GETTAB	T1,		;GET IT
	  JRST	GETHSO		;CAN'T
	SKIPN	T1		;THERE?
	JRST	GETHSO		;NO, GIVE UP
	MOVEM	T1,SEGPTH+.PTPPN	;STORE UFD TO FINISH PATH BLOCK
	HRROI	T1,.GTRDV	;GET DEVICE WE WERE RUN FROM
	GETTAB	T1,		; . . .
	  JRST	GETHSO		;NOT THERE FORGET IT
	SKIPN	T1		;AVAILABLE?
	JRST	GETHSO		;NOPE, DON'T USE THIS INFO
	MOVEM	T1,SEGBLK	;YES, STORE DEVICE
	MOVEM	T1,ERRBLK	;FOR LNK999 ALSO
	MOVEI	T1,SEGPTH	;NOW POINT GETSEG BLOCKS TO PATH BLOCK
	MOVEM	T1,SEGBLK+4	;NORMAL GETSEG BLOCK
	MOVEM	T1,ERRBLK+4	;AND LNK999'S COPY
>;END OF IFE FTSINGLE

GETHSO:	MOVE	T1,[-2,,.GTUPM]	;[650] ORIGIN OF HIGH SEG
	GETTAB	T1,		;GET START OF HIGH SEGMENT
	  MOVSI	T1,%HISEG	;ASSUME USER KNOWS WHERE IT STARTS
	SKIPN	T1		;RETURNS ZERO IF NOT IMPLEMENTED
	MOVSI	T1,%HISEG	;USE ASSEMBLY VALUE
	HLRZ	T1,T1
	ANDCMI	T1,777		;ONLY ON A FULL PAGE
	HRRZM	T1,HIORGN	;[650] SAVE HISEG ORIGIN FOR EVERYBODY
IFE FTSINGLE,<
	ADDI	T1,.JBHDA##	;ADD OFFSET NOW
	HRRZM	T1,SEGPGN	;SAVE PAGE NUMBER
> ;END OF IFE FTSINGLE
	MOVE	T1,[JRST UUOHANDLER]
	MOVEM	T1,UUOTRAP+1	;FIELD UUOS
IFN FTVM,<
	SETOM	USEVM		;[650] ASSUME VM AVAILABLE
	MOVSI	T1,.PAGCA	;[650] CHECK ACCESS OF PAGE 0
	PAGE.	T1,		;[650] TO SEE IF PAGE. UUO'S WORK
	  SETZM	USEVM		;[650] NOPE, VM NOT AVAILABLE
	MOVEI	T1,.PAGEM	;[650] PAGE. UUO FUNCTION
	MOVEM	T1,PAGFUN	;[650] STORE FOR MONITOR
> ;END IFN FTVM
IFE TOPS20,<
	MOVE	T1,[PTHLEN-1,,PTHARG]
	SETOM	PTHARG		;-1 MEANS RETURN DEFAULT PATH
	PATH.	T1,		;GET DEFAULT PATH
	  SETZM	PTHARG		;IF ERROR, CLEAR ARGUMENT
>
	GETPPN	T1,		;DETERMINE THIS JOB'S PPN
	  JFCL			;(IN CASE OF JACCT)
	MOVEM	T1,MYPPN	;SAVE FOR THE FUTURE
IFE TOPS20,<
	SKIPN	PTHDIR		;SEE IF PATH. UUO WORKED
>
	MOVEM	T1,PTHDIR	;NO, SIMULATE IT
IFE TOPS20,<
	MOVNI	T1,1		;STANDARD AOBJN TEST FOR KI-10
	AOBJN	T1,.+1		;TESTS FOR HALF-WORD ADDER
	JUMPN	T1,KSET		;KA-10 IF CARRY
>;END OF IFE TOPS20
	AOS	CPUHST		;KI, KL, TOPS-20 BECOMES 1
IFE TOPS20,<
	MOVE	T1,[115,,.GTCNF]
	GETTAB	T1,		;PAGE SIZE
	  SKIPA	T1,[%CNVER]	;FAILED, USE GETTAB FOR MONITOR VERSION
	SOJA	T1,GSET		;GET MASK FOR PAGE SIZE
	GETTAB	T1,		;
	  SETZ	T1,		;NOT 5.06 FOR SURE
	HRRZ	T1,T1		;ONLY WANT DEC HALF
	CAIGE	T1,50511	;TEST FOR 5.06 OR LATER
	JRST	KSET		;NO, USES 1K BOUNDS
PSET:	SKIPA	T1,[777]	;AND STORE SIZE
KSET:	MOVEI	T1,1777		;KA-10 PAGE SIZE
GSET:	MOVEM	T1,.PGSIZ	;USED TO MAKE SAVE FILES ETC
>;END OF IFE TOPS20
;HERE WHEN PAGE SIZE KNOWN. DO OTHER MISC. SETUP

	HRROI	T1,.GTLIM	;JOB'S TIME LIMIT AND BATCH STATUS
	GETTAB	T1,
	  JRST	.+3		;CANNOT BE BATCH JOB
	TXNE	T1,JB.LBT	;TEST FOR BATCH CONTROL
	SETOM	BATCH		;YES, IT IS
	PJOB	T1,		;GET JOB NUMBER
	HRRZM	T1,JOBNUM	;SAVE IN RIGHT HALF
	MOVEI	T4,3		;PICK UP 3 CHARS
PJLOOP:	IDIVI	T1,^D10		;ONE AT A TIME
	ADDI	T2,'0'		;MAKE SIXBIT
	LSHC	T2,-6		;SAVE CHAR
	SOJG	T4,PJLOOP
	HLLM	T3,JOBNUM	;SAVE SIXBIT FOR TMP FILES
	MOVSI	T1,'DSK'	;SET UP GLOBAL DEFAULTS
	MOVEM	T1,G.DEV	;INITIAL SETTINGS
	HRLOI	T1,'REL'
	MOVEM	T1,G.EXT
	MOVEI	T3,AD.FRC	;DEFAULT VALUE
	MOVEM	T3,FRECOR	;OF SPACE TO BE LEFT IN TABLES
	MOVE	T1,HIORGN	;MAKE SURE WE NEVER EXPAND INTO HISEG
	SUBI	T1,1001		;[607] RESERVE A PAGE FOR HELPER
	MOVEM	T1,MAXCOR	; IF USER DOES NOT SET A VALUE
IFN TOPS20,<
	CORE	T1,		;GET ALL CORE IN LOW SEGMENT
	  JRST	NOCORE		;SHOULD NEVER HAPPEN
>
IFE TOPS20,<
	SUBI	T3,3		;INCASE IT IS EXACTLY A BOUND
	IDIVI	T3,4		;NUMBER OF TABLES SETUP INITIALLY
	ADDI	T3,.IPM		;MAKE INTO BLOCK BOUND
	ANDCMI	T3,.IPM
	MOVE	P2,T3		;SAFER PLACE
>
	MOVSI	T1,.LLOC	;[732] INITIALIZE LOWEST LOCATION
	MOVEM	T1,LOWLOC	;[732]
;HERE TO SETUP RELOCATION TABLES ETC
;THE MAIN TABLE RC.TB CONSISTS OF POINTERS TO INDIVIDUAL CODE BLOCKS
;RC.TB GROWS AS REQUIRED. THE INDIVIDUAL BLOCKS CONTAIN
;RC.SG	SEGMENT NUMBER (INDEX TO SG.TB)
;RC.NM	6-BIT NAME OF R.C.
;RC.IV	INITIAL VALUE OF R.C.
;RC.CV	CURRENT VALUE OF R.C. (THIS IS WHAT IS ADDED TO RELOCATABLE WORD)
;RC.OF	OFFSET TO LOCATION IN CORE RELATIVE TO LC.LB OR HC.LB	;
;RC.HL	HIGHEST LOCATION LOADED INTO (NEXT R.C. AT END)
;RC.LB	WHICH SEGMENT (EITHER LC.LB OR HC.LB ADDRESS)
;RC.WD	POINTER TO START OF CODE WINDOW (LW.S1 OR LW.S2)
;RC.PG	POINTER TO END OF CODE WINDOW (LW.S1 OR LW.S2)


CORINI:	MOVEI	T1,RC.INC-2	;JUST A RANDOM NUMBER
	MOVEM	T1,RC.FRE	;NUMBER OF FREE SLOTS
	MOVEI	T1,1		;FIRST ONE IS SET NOW
	MOVEM	T1,RC.NO
	HRRZ	P1,.JBFF	;GET START OF DYNAMIC AREA
	SETOM	.JBFF		;STOP ANY ONE USING .JBFF UNTIL AUTHORISED
	MOVEI	T1,SG.TB	;MAKE SEG TAB POINT TO TABLES LIKE RC.TB
	HRLI	T1,R
	MOVEM	T1,SG.TB	;SO WE CAN REFERENCE IT THE SAME WAY
	MOVEM	P1,DY.LB	;STORE START OF  DYNAMIC AREA
	HRR	P,P1		;SETUP REAL PUSHDOWN STACK
	HRLI	P,-LN.PDL	;IN DYNAMIC AREA SO WE CAN MOVE IT
	MOVEM	P,PDP		;SAVE SO WE CAN RESET ON I/O ERRORS
	ADDI	P1,LN.PDL+1
	MOVEM	P1,IO.EMG	;USED FOR OPEN/ENTER WHEN CORE FULL
	ADDI	P1,LN.IO	;RESERVE SPACE BEFORE IT'S TOO LATE
	HRLI	P1,R		;PUT (R) IN INDEX FIELD
	MOVEM	P1,RC.NTB	;[706] SETUP PSECT ORDER TABLE
	ADDI	P1,RC.INC	;[706] SAME LENGTH AS RC.TB
	MOVEM	P1,RC.TB	;AND POINT TO TABLE OF POINTERS
	SETZ	R,		;START AT SLOT #0
	HRRZS	P1
	ADDI	P1,RC.INC
	MOVEM	P1,@RC.TB	;POINT TO SLOT #0
	MOVEM	P1,@RC.NTB	;[706] 
	SETZM	RC.SG(P1)	;SET TO 0 SEGMENT
	HRL	T2,P1		;BUILD BLT POINTER
	HRRI	T2,1(P1)	;TO CLEAR ALL OF ABS RC BLOCK
	BLT	T2,RC.INC-1(P1)
	MOVE	T2,['.ABS. ']	;NAME OF IT
	MOVEM	T2,RC.NM(P1)
;NOW BUILD .LOW. RELOCATION COUNTER

	ADDI	P1,RC.INC	;NOW FOR SLOT #1 (0')
	ADDI	R,1
	MOVEM	P1,@RC.TB	;POINT TO SLOT #1
	MOVEM	P1,@RC.NTB		;[706]
	MOVEM	P1,@SG.TB	;AND IN SEGMENT TABLE
	MOVEM	R,RC.SG(P1)	;POINT TO SEG #1 (0 UPWARDS)
	MOVE	T2,['.LOW. ']	;NAME OF IT
	MOVEM	T2,RC.NM(P1)
	SETZM	RC.IV(P1)	;INITIAL VALUE OF 0
	MOVEI	T2,.JBDA	;PRESET TO 140
	MOVEM	T2,RC.CV(P1)	;CURRENT VALUE
	SETZM	RC.OF(P1)	;ZERO RELATIVE TO LC.LB
	SETZM	RC.HL(P1)	;HAVEN'T LOADED ANY YET
	MOVEI	T2,LC.LB	;POINT TO LOW SEGMENT
	MOVEM	T2,RC.LB(P1)
	MOVEI	T2,LW.S1	;POINTER TO BASE OF CORE WINDOW IN PAGING
	MOVEM	T2,RC.WD(P1)
	MOVEI	T2,UW.S1	;END OF WINDOW (PAGING IF NON-ZERO)
	MOVEM	T2,RC.PG(P1)
	ADDI	P1,RC.INC
	MOVEM	P1,DY.PT	;POINTER TO NEXT FREE LOCATION IN DY
IFE TOPS20,<
	ADDI	P1,1000		;LEAVE SOME BUFFER SPACE
>
	IORI	P1,.IPM		;GET TO A GOOD BREAK
	MOVEM	P1,DY.AB	;ACTUAL TOP IN USE
	MOVE	T2,P1		;CALCULATE FREE SPACE
	SUB	T2,DY.PT	;ABOVE DY.PT
	MOVEM	T2,DY.FR	;AND STORE
IFE TOPS20,<ADDI P1,(P2)	;ALLOCATE FREE SPACE>
IFN TOPS20,<MOVEI P1,LC.ORG-1	;ONE LESS THAN START OF CODE>
	MOVEM	P1,DY.UB	;TOP OF DYNAMIC AREA (FOR NOW)
	ADDI	P1,1		;START OF CORE AREA
IFN TOPS20&FTFORK,<
	SETZB	1,2		;NOTHING IN IT
	CFORK			;CREATE INFERIOR FORK
	  HALT			;FAILED
	MOVEM	1,LC.FRK	;SAVE FORK HANDLE
	MOVEM	1,HC.FRK	;...
	HRLZ	1,1		;PAGE 0 OF SOURCE (INFERIOR FORK)
	MOVE	2,[1B0+LC.ORG_-9]	;DESTINATION IS CURRENT FORK
	SETZ	3,
	PMAP
>;END OF IFN TOPS20&FTFORK
;HERE TO SETUP ALL OTHER AREA BOUNDS, POINTERS ETC
	MOVEM	P1,LC.LB
	IORI	P1,.IWM		;[750] ALLOCATE FOR JOBDAT AREA
	MOVEM	P1,LC.AB
IFE TOPS20,<ADDI P1,(P2)	;SOME FREE SPACE>
IFN TOPS20,<MOVEI P1,LS.ORG-1	;ONE LESS THAN START OF SYMBOLS>
	MOVEM	P1,LC.UB
	ADDI	P1,1
	MOVEM	P1,LS.LB	;START OF LOCAL SYMBOL AREA
	ADDI	P1,ENDSYM-LSTBL+1	;NUMBER OF LOCAL SYMBOL LOCATIONS
	MOVEM	P1,LS.PT	;POINTS TO NEXT FREE LOCATION
	IORI	P1,.IPM		;NEXT BLOCK BOUND
	MOVEM	P1,LS.AB
	MOVE	T1,P1
	SUB	T1,LS.PT	;CALCULATE FREE SPACE IN LAST BLOCK
	MOVEM	T1,LS.FR
IFE TOPS20,<ADDI P1,(P2)	;SPACE>
IFN TOPS20,<MOVEI P1,GS.ORG-1	;ONE LESS THAN START OF GLOBAL SYMBOLS>
	MOVEM	P1,LS.UB
	ADDI	P1,1
	MOVEM	P1,GS.LB	;GLOBAL SYMBOL AREA
	ADDI	P1,ENDSYM-GSTBL+1	;END OF SYMBOLS
	MOVSI	T1,(POINT 18,0)	;RELATIVE PTR TO PRIME TABLE
	MOVEM	T1,PRMPTR	;SETUP PRIME NUMBER TABLE PTR
	MOVEI	T2,I.PRM	;INITIAL NUMBER
	MOVEM	T2,HT.PRM	;SET SIZE
	MOVEI	T2,<<I.PRM+.L-1>/.L*.L>	;ALLOCATE SPACE IN MULTIPLES OF .L
					;SO REHASHING DOES NOT WASTE SPACE
	HRLI	P1,P2		;INDEX USED IN TRYSYM COMPARES
	MOVEM	P1,HT.PTR	;STORE POINTER
	ADDI	P1,(T2)		;RESERVE SPACE FOR TABLE
	HRRZS	P1
	MOVEM	P1,GS.PT	;NEXT FREE LOCATION
	IORI	P1,.IPM		;NEXT BLOCK BOUND
	MOVEM	P1,GS.AB	;MARK THIS AS TAKEN
	MOVE	T2,P1
	SUB	T2,GS.PT	;SEE HOWMUCH ACTUALLY FREE
	MOVEM	T2,GS.FR	;SAVE IT
IFE TOPS20,<
	ADDI	P1,(P2)		;SOME FREE SPACE
	MOVEM	P1,GS.UB	;UPPER BOUND FOR NOW
	CAMGE	P1,.JBREL	;SEE IF ENOUGH
	JRST	.+3		;YES
	CORE	P1,		;NO, TRY FOR MORE
	  JRST	NOCORE		;YOU LOSE
>;END IFE TOPS20
	HRRZ	P1,.JBREL	;GET TOP OF LOW SEGMENT
	MOVEM	P1,GS.UB	;AS TOP OF GLOBAL SYMBOLS
;NOW TO STORE INITIAL SYMBOLS

	MOVEI	T1,ENDSYM-LSTBL+1	;NUMBER OF LOCAL SYMBOL LOCATIONS
	MOVE	P1,LS.LB	;BASE OF LOCAL SYMBOLS
	MOVEM	T1,LSYM		;REQUIRED UNLESS /NOINITIAL
	MOVEM	T1,(P1)		;STORE IN FIRST WORD (UNUSED)
	HRLI	T1,LSTBL	;FORM BLT POINTER
	HRRI	T1,1(P1)
	BLT	T1,ENDSYM-LSTBL(P1)	;MOVE IN

	MOVEI	T1,<ENDSYM-GSTBL>/.L	;NUMBER OF GLOBAL SYMBOLS
	MOVE	P1,GS.LB	;BASE OF GLOBAL SYMBOLS
	MOVEM	T1,GSYM		;REQUIRED UNLESS /NOINITIAL
	MOVEM	T1,(P1)		;STORE IN FIRST WORD (UNUSED)
	HRLI	T1,GSTBL	;FORM BLT POINTER
	HRRI	T1,1(P1)
	BLT	T1,ENDSYM-GSTBL(P1)	;MOVE IN

	HRLI	T1,HSTBL	;FORM BLT POINTER
	HRRZ	P1,HT.PTR	;BASE OF HASH TABLE
	HRR	T1,P1
	BLT	T1,ENDHSH-HSTBL-1(P1)	;MOVE HASH TABLE
	MOVEI	T1,.HS%		;GET % TO FILL TABLE
	MOVEM	T1,HSFACT
	MOVE	T1,HT.PRM	;GET CURRENT HASH SIZE
	IMULI	T1,.HS%		;SEE HOW MUCH TO FILL
	IDIVI	T1,^D100
	SUB	T1,GSYM		;MINUS INITIAL NO.
	MOVEM	T1,HSPACE	;HASH TABLE FULL ENOUGH AT THIS  POINT
	MOVEI	T1,.SYLIM	;[727] SET DEFAULT SYMBOL TABLE LIMIT
	TXO	T1,1B0		;[727] TO HIGH SEG ORIGIN (ON WITH 1B0)
	MOVEM	T1,SYMLIM	;[727]
;HERE TO INIT LOG FILE IF POSSIBLE
LOGINI:	MOVEI	T1,TTYIT	;LINE BUFFERING ROUTINE FOR OUTCHRS
	MOVEM	T1,TTYSUB
	PUSHJ	P,.TYOCH##	;INCASE NO LOG FILE
	MOVEI	T1,L%W		;GET TTY ERROR CUTOFF
	MOVEM	T1,ERRLVL	;INCASE NOT SET BY USER
	MOVEI	T1,S%F		;AND FATALITY
	SKIPE	BATCH		;HOWEVER IN BATCH MODE
	MOVEI	T1,S%B		;U LOSE MUCH SOONER
	MOVEM	T1,SEVLVL
	MOVEI	T1,L%W		;[604] NORMAL LOG FILE CUTOFF
	MOVEM	T1,LOGLVL
	MOVSI	T1,'LOG'	;SEE IF WE ALREADY HAVE A LOG DEVICE
	DEVCHR	T1,		;SKIP IF ASSIGNED
	JUMPE	T1,NOLOG	;NOT YET
	SETZM	LOGLVL		;[604] ASSUME USER WANTS ALL IF ASSIGNED LOG DEVICE
	TXNE	T1,DV.TTA	;YES, BUT IS IT USERS TTY?
	JRST	[SETOM	LOGTTY		;YES, NOT REALLY A LOG DEVICE
		PUSHJ	P,.ERLOG	;OUTPUT HEADER LINE
		MOVEI	T1,[ASCIZ \[LNK\]
		PUSHJ	P,.TSTRG##	;INITIALIZATION CODE
		MOVEI	T1,.ERLIM
		PUSHJ	P,.TSTRG##	;AND SPECIFIC CODE
		MOVEI	T1,.ERLIM+1	;TEXT STRING
		PUSHJ	P,.TSTRG##
		PUSHJ	P,CLSSQB	;END INFO STRING
		JRST	NOLOG]
	PUSH	P,T1		;SAVE DEVCHR WORD
	MOVEI	T2,LN.IO	;SPACE WE NEED
	PUSHJ	P,DY.GET##	; FOR ENTER BLOCK
	MOVEM	T1,IO.PTR+RC	;STORE ADDRESS IN I/O TABLE
	MOVEI	T2,.IOASC	;ASCII MODE
	MOVEM	T2,I.MOD(T1)
	MOVSI	T2,'LOG'	;DEVICE
	MOVEM	T2,I.DEV(T1)
	MOVEI	T2,RCBUF	;BUFFER HEADER
	MOVSM	T2,I.BUF(T1)	;OUTPUT ONLY
	MOVEI	T2,LN.RIB-1	;EXTENDED ENTER
	MOVEM	T2,I.RIB(T1)
	HLLZ	T2,JOBNUM	;SIXBIT JOB NUMBER
	HRRI	T2,'LNK'	;000LNK AS NAME
	MOVEM	T2,I.NAM(T1)
	MOVSI	T2,'LOG'	;EXTENSION
	MOVEM	T2,I.EXT(T1)
	OPEN	RC,@IO.PTR+RC	;OPEN IT
	  JRST	OPNERR		;FAILED
;HERE WITH LOG DEVICE OPENED. CREATE THE FILE.

	MOVE	T1,IO.PTR+RC	;GET ADDRESS
	ADDI	T1,I.RIB	;GET ENTER BLOCK
	POP	P,T2		;GET DEVCHR BACK
	TXNN	T2,DV.DSK	;ONLY DO EXTENDED ENTER ON DSK
	ADDI	T1,2		;POINT TO NAME
	ENTER	RC,(T1)
	  JRST	ENTERR		;FAILED
	MOVE	T1,IO.PTR+RC	;POINT TO OPEN BLOCK
	DEVSIZ	T1,		;GET BUFFER SIZE
	  MOVE	T1,[2,,203]	;SHOULD NOT HAPPEN, SO FAKE IT
	PUSH	P,T1		;SAVE INFO
	HLRZ	T2,T1		;NUMBER OF BUFFERS
	HRRZ	T1,T1		;SIZE
	IMULI	T2,(T1)		;TOTAL SPACE REQUIRED
	PUSHJ	P,DY.GET##
	MOVE	T3,IO.PTR+RC	;GET AREA
	POP	P,I.DVZ(T3)	;STORE DEVSIZ WORD
	MOVEM	T1,I.RNG(T3)	;POINT TO RING BUFFERS
	MOVEM	T1,.JBFF	;NOW TO SETUP BUFFER
	MOVSI	T1,(Z RC,)	;CHAN#
	MOVEM	T1,I.CHN(T3)	;FOR CLOSE
	HLRZ	T2,I.DVZ(T3)	;GET NO. OF BUFFERS
	OUTBUF	RC,(T2)		;SET THEM UP
	MOVE	T1,.JBREL	;SET .JBFF OUTSIDE CORE RANGE
	MOVEM	T1,.JBFF	;INCASE /HELP
	MOVEI	T1,LOGIT	;NOW WE CAN POINT TO IT
	MOVEM	T1,LOGSUB	;SET NON-ZERO
	PUSHJ	P,.TYOCH	; ALWATS EXCEPT WHEN IN SCAN
	PUSHJ	P,.ERLOG	;HEADER
	MOVE	T1,TIMEON	;GET TIME WE STARTED
	PUSHJ	P,.TTIME##	;INITIAL TIME STAMP
	MOVEI	T1,ER000A	;GET SEVERITY CODE ETC
	PUSHJ	P,.TSTRG##	;ON LOG DEV IF NOT TTY
	MOVEI	T1,.ERLIM	;GET CODE
	PUSHJ	P,.TSTRG##
LOGIT1:	MOVEI	T1,.ERLIM+1	;MESSAGE
	PUSHJ	P,.TSTRG##
	MOVEI	T1,CRLF		;END LINE
	PUSHJ	P,.TSTRG##
;	JRST	NOLOG		;NOW DO OTHER THINGS

;HERE TO INITIALIZE OTHER ODD ITEMS
NOLOG:	MOVE	T1,[LOGIT,,TTYIT]	;INCASE /LOG LATER
	MOVEM	T1,LOWSUB	;SO WE CAN FIND ROUTINES
	MOVEI	T1,V%M		;GET DEFAULT VALUE
	MOVEM	T1,VERLVL	;SAVE IT
	MOVEI	T1,OPENBL	;PUT ADDRESS OF INPUT I/O BLOCK
	MOVEM	T1,IO.PTR+DC	;IN I/O VECTOR INCASE OF ERRORS
	MOVEI	T1,.IOBIN	;MODE 14
	MOVEM	T1,OPENBL	;FOR INPUT DEVICE
	MOVEI	T1,DCBUF	;INPUT BUFFER HEADER
	MOVEM	T1,FSTR+1	;IN OPEN BLOCK
	MOVSI	T1,(Z DC,)	;GET CHAN# IN AC FIELD
	MOVEM	T1,OPENBL+I.CHN	;FOR OPEN/LOOKUP ETC
	MOVE	T1,[C%DEFAULT]	;DEFAULT MAP CONTENTS
	MOVEM	T1,MAPCON	;INCASE NO USER SWITCHES
IFL .FORLB,<			;.FORLB=-1 FOR FORSE, 0 FOR FORLIB
	MOVNI	T1,2		;MAKE DEFAULT VALUE BE -2
	MOVEM	T1,FORLIB	;SO WE CAN DIFFERENTIATE FROM /FORSE SWITCH
>
IFGE .FORLB,<
	SETZM	FORLIB		;NOT STRICTLY REQUIRED BUT HELPS CONVERSION>
IFL FMXFOR,<
	SETOM	MIXFOR		;TO FIXUP FORTRAN SUBROUTINES>

IFN FTOVERLAY,<
	MOVEI	T1,.SPA		;SET DEFAULT FOR LINK 0
	MOVEM	T1,SPACE	;IN CASE USER DOES'NT
	MOVEI	T1,PH.ZZ	;LENGTH OF PREAMBLE
	MOVEM	T1,PH.HDR	;FOR LINK FILES
	MOVX	T1,<.ARS,,.ARS>	;[635] SET DEFAULT /ARSIZE
	MOVEM	T1,ARSIZE	;[635] IN CASE NO /ARSIZE SWITCH
	SETOM	LNKMAX		;SO WE CAN TELL LINK #0
>
IFN TOPS20,<
	MOVSI	T1,L.SYM	;ALWAYS LOAD SYMBOLS IF TENEX
	MOVEM	T1,FLAGS	;REMEMBER OVER CR-LF
>
	MOVEI	T1,START	;RESTART CODE
	HRRM	T1,.JBSA##	;SO WE GET CORRECT SEGMENT

IFN DEBSW,<
	MOVE	T1,[JRST %DDT%]	;ENTER DDT IF LOADED
>
IFE DEBSW,<
	MOVSI	T1,(POPJ	P,)	;NO DDT
>
	MOVEM	T1,ENTDDT	;WILL HANDLE DEBUG RIGHT
	MOVEI	T2,USELEN	;ANY USER LIBS TO SETUP?
	JUMPE	T2,LNKSCN	;NO, SCAN FIRST COMMAND LINE
SUBTTL	SETUP USER LIBRARIES

SETUSE:	PUSHJ	P,DY.GET##	;GET SPACE WE NEED
	MOVEM	T1,USEPTR	;SETUP POINTER
	MOVE	T3,T1
	HRLI	T3,LIBTBL	;SETUP BYTE POINTER
	MOVE	T4,T1
	ADDI	T4,-1(T2)	;CALCULATE END
	BLT	T3,(T4)		;MOVE LIST
	SUBI	T2,F.LEN	;ANY MORE?
	JUMPLE	T2,LNKSCN	;NO, GO TO SCANNER
	ADDI	T1,F.LEN
	MOVEM	T1,-F.LEN(T1)	;POINT TO NEXT
	JRST	.-4		;TRY AGAIN
DEFINE MAKLIB (LANGUAGE,DEVICE,FILE,EXT,PRJ,PRG,SFD) <
	.ZZZ==.			;REMEMBER CURRENT POSITION
	 EXP	0		;ZERO LINK WORD (NEXT LIB)
 DEFINE X (A,B)<
  IFIDN <A>,<LANGUAGE>,<
   EXP	CT.'B
 >>
 IFIDN <ALL><LANGUAGE>,<
  EXP	0
 >
 IFB <LANGUAGE>,<
  EXP	0
 >
 PROCESSORS
IFE .-.ZZZ-1,<PRINTX ?UNKNOWN LANG. "LANGUAGE" IN USELIB MACRO
	EXP	0		;ASSUME ALL ON ERROR>
 IFNB <DEVICE>,<<SIXBIT /DEVICE/>>
 IFB  <DEVICE>,< SIXBIT /SYS/>
		<SIXBIT /FILE/>
	EXP	-1
 IFNB <EXT>,<<SIXBIT /EXT/>!777777>
 IFB  <EXT>,<<SIXBIT /REL/>!777777>
 IFNB <PRJ>,<EXP	FX.DIR>
 IFB  <PRJ>,<EXP	0>
	EXP	0
	XWD	PRJ,PRG
 IFNB <PRJ>,<EXP	-1>
 IFB  <PRJ>,<EXP	0>
IRP	SFD,<			;GENERATE ANY SFDS
	<SIXBIT	/SFD/>		;
	EXP	-1		;
>				;
REPEAT	F.BFR+.ZZZ-.,<		;FILL IN BLANK SFDS
	EXP	0		;
>				;
REPEAT	F.LEN+.ZZZ-.,<		;NOW FILL IN SWITCHES (-1)
	EXP	-1		;
>				;
>
;DEFINE USER LIBRARIES BY
;MAKLIB	DEVICE,FILE,EXT,PRJ,PRJ,<SFD LIST>
LIBTBL:				;LIST OF LIBRARIES
	USELIB
USELEN==.-LIBTBL

SUBTTL	ERROR MESSAGES

CCLMES:	ASCIZ	\LINK:	Loading
\
ER000A:	ASCIZ	/  1  1 /
.ERLIM:	ASCIZ	/LIM /
	.ASCIZ	<LINK initialization>
CRLF:	ASCIZ	/
/
NOCORE:	OUTSTR	[ASCIZ	\?LNKICI	Insufficient core to initialize LINK\]
	EXIT
OPNERR:	PUSH	P,[RC]		;PUT CHAN. INDEX ON STACK
	.ERR.	(I,0,V%L,L%I,S%I,IFD)
	JRST	NOLOG		;DO WITHOUT LOG FILE NOW

ENTERR:	PUSH	P,[%ENT+RC]	;CHAN INDEX
	.ERR.	(LRE,0,0,0,0,FEE)
	JRST	NOLOG

.ERLOG:	MOVEI	T1,[ASCIZ \	[LINK LOG file	\]
	PUSHJ	P,.TSTRG##	;HEADER
	PUSHJ	P,.TDATN##	;WITH DATE
CLSSQB:	MOVEI	T1,[ASCIZ	\]
\]
	PJRST	.TSTRG##	;END LINE

CPOPJ:	POPJ	P,		;SOMEWHERE TO PUT IT

SUBTTL	INITIAL SYMBOLS

DEFINE SYMBOL (F,S1,S2,V)<
 IFB <F>,<
  PT.SGN!PT.SYM!PS.GLB		;
 >
 IFNB <F>,<
  PT.SGN!PT.SYM!PS.GLB!'F	;
 >
 SIXBIT \S1\
 IFB <V>,<
  IFNDEF S2,<EXTERN S2>
  EXP S2
 >
 IFNB <V>,<
  EXP	V
>>

DEFINE .JB (F,S,V)<
.%%'S:	SYMBOL	F,.JB'S,.JB'S,V
 HASH	.JB,S
>

DEFINE	JOB (F,S,V)<
%%%'S:	SYMBOL	F,JOB'S,.JB'S,V
 HASH	JOB,S
>


SALL
;ZERO ALL REQUIRED SYMBOLS
IF1,<
 DEFINE GETSYM (N) <.%'N=0>
 N=0
 REPEAT I.PRM,<GETSYM \N
  N=N+1
 >

;NOW FOR HASH MACRO (PASS1 ONLY)
 DEFINE HASH (J,S)<>
>;END IF1

;ALL WORK DONE ON PASS 2
IF2 ,<
 DEFINE HASH (J,S)<
  IFIDN <J><.JB>,<
   %%%=.%%'S
   PURGE .%%'S
  >
  IFDIF <J><.JB>,<
   %%%=%%%'S
   PURGE %%%'S
  >
  HT=(<SIXBIT /S/>)
  IFN HT-''J'',<HT=<''J''!HT>&<-1-<''J''&HT>>>
  Q=HT/I.PRM
  R=HT-Q*I.PRM
  IFGE Q-I.PRM,<Q=Q-Q/I.PRM*I.PRM>
  IFE Q,<Q=1>
  TRY=1
  ITEM Q,\R
  IFL I.PRM-TRY,<PRINTX INITIAL HASH FAILURE>
 >

 DEFINE ITEM (QT,RM) <
  IFN .%'RM,<
   R=R+Q
   IFL I.PRM-R,<R=R-R/I.PRM*I.PRM>
   IFGE I.PRM-<TRY=TRY+1>,<
    ITEM Q,\R
  >>
  IFE .%'RM,<.%'RM=HT,,%%%-GSTBL+1>
 >
>;END IF2
LSTBL:
;TITLE SYMBOLS (LOCAL FILE ONLY)
	PT.SGN!PT.EXT!PT.TTL!PT.FAK	;
	'JOBDAT'
	ENDSYM-LSTBL+1

	S.TTL				;
	'-INITI'
	'AL-SYM'

	S.TTL				;
	'BOLS  '
	0

	S.TTL!S.LST!S.SEG		;
	.JBDA,,.JBDA
	0

GSTBL:
;OLD STYLE JOBDAT SYMBOLS I.E. JOBXXX
IFN .OSJOB,<			;DON'T WASTE SPACE ON OLD SYMBOLS

	JOB	,41
	JOB	,APR
	JOB	,BLT
	JOB	,CHN
IFN FTCN6,<
	JOB	,CN6
>
	JOB	,CNI
	JOB	,COR
	JOB	,DA
	JOB	,DDT
	JOB	,ERR
	JOB	,FF
	JOB	PS.DDT,HDA
	JOB	PS.DDT,HGH
	JOB	PS.DDT,HNM
	JOB	,HRL
	JOB	PS.DDT,HSM
	JOB	PS.DDT,HVR
	JOB	,INT
	JOB	,OPC
	JOB	,PFI
	JOB	,REL
	JOB	,REN
	JOB	,SA
	JOB	,SYM
	JOB	,TPC
	JOB	,USY
	JOB	,UUO
	JOB	,VER

>;END OF IFN .OSJOB

%%%BDT:	SYMBOL	PS.DDT,%JOBDT,%JOBDT
	HASH	%JO,BDT

;NEW STYLE SYMBOLS .JBXXX
	.JB	,41
	.JB	,APR
	.JB	,BLT
	.JB	,CHN
IFN FTCN6,<
	.JB	,CN6
>
	.JB	,CNI
	.JB	,COR
	.JB	,CST
	.JB	,DA
	.JB	,DDT
	.JB	,ERR
	.JB	,FF
	.JB	PS.DDT,H41
	.JB	PS.DDT,HCR
	.JB	PS.DDT,HDA
	.JB	PS.DDT,HGA
	.JB	PS.DDT,HGH
	.JB	PS.DDT,HNM
	.JB	,HRL
	.JB	PS.DDT,HRN
	.JB	PS.DDT,HSA
	.JB	PS.DDT,HSM
	.JB	PS.DDT,HVR
	.JB	,INT
	.JB	,OPC
	.JB	,OPS
	.JB	,OVL
	.JB	,PFH
	.JB	,PFI
	.JB	,REL
	.JB	,REN
	.JB	,SA
	.JB	,SYM
	.JB	,TPC
	.JB	,USY
	.JB	,UUO
	.JB	,VER


ENDSYM:!
SUBTTL	HASH TABLE

HSTBL:
IF1,<BLOCK	I.PRM>
IF2,<
 DEFINE SETVAL (N) <
	EXP	.%'N
	PURGE	.%'N
 >
 .XCREF
 N=0
 REPEAT I.PRM,<
  SETVAL \N
  N=N+1
 >
 PURGE TRY,%%%,Q,R,N,HT
 .CREF
>;END IF2
ENDHSH:!
SUBTTL	GETSEG CODE

IFE FTSINGLE,<
HICODE:
	PHASE	PHAZLO		;TOP OF FIXED DATA AREA
;HERE TO DO A GETSEG TO REQUIRED SEGMENT
;ENTERS WITH REQUIRED NAME IN T1
;GETSEG ERROR WILL CALL SEGMENT LNK999 TO HANDLE ERROR
;IF THAT FAILS A SHORT MESSAGE WILL BE OUTPUT ON TTY

SEGCOD:	SETZM	SGFLAG		;GOING FORWARDS
	EXCH	T1,SEGBLK+1	;SAVE SEGMENT NAME
	MOVEM	T1,OLDSEG	;SAVE IN
SGCOD1:	SETZM	SEGBLK+2	;CLEAR EXTENSION
	SETZM	SEGBLK+3	;AND OTHER PARAMS
	SETZM	SEGBLK+5	;AND CORE SIZE
	MOVEM	FL,SAVEAC	;NEED TO SAVE FLAGS
	MOVEM	P,SAVEAC+P	;AND P
;********************		;REMOVE WHEN MONITOR BUG IS FIXED
	MOVSI	T1,1		;GET RID OF HIGH SEGMENT FIRST
	CORE	T1,		; TO BE SURE WE HAVE ENOUGH ROOM
	  JFCL			;CAN NOT HAPPEN
;********************
	MOVEI	T1,SEGBLK	;ADDRESS OF DATA
NGTSEG:	GETSEG	T1,UU.PHY	;GET THE REQUIRED SEGMENT
	  JRST	SEGERR		;FAILED
SEGGOT:	MOVE	P,SAVEAC+P	;RESTORE P
	MOVE	FL,SAVEAC	;AND FLAGS
	MOVE	T1,OFFSET	;NORMAL OR CCL
	MOVE	T2,GTUPM	;ARG FOR GETTAB
	GETTAB	T2,		;TO FIND HIGH SEG ORIGIN
	  MOVSI	T2,%HISEG	;ASSUMED TO BE AT 400000
	SKIPN	T2		;NO NEED FOR DEFAULT ENTRY ADDRESS
				; IF NON-ZERO
	MOVSI	T2,%HISEG	;SET UP DEFAULT ADDRESS
	HLRZ	T2,T2	
	ANDCMI	T2,777		;ONLY SAVE PAGE NUMBER
	HRRZM	T2,HIORGN	;[650] SAVE FOR EVERYBODY
	ADDI	T2,.JBHDA##	;PLUS OFFSET
	MOVEM	T2,SEGPGN	;STORE IT
	MOVEI	T3,EZCOR	;SO WE CAN CHECK IF NEXT SEG IS SAME SIZE
	SKIPN	SGFLAG		;FORWARDS?
	JRST	%%ST(T2)	;YES, GO TO START CODE

	SKIPA	T3,.+1
	SAVEAC+P1,,P1
	BLT	T3,16		;RESTORE ACCS
	JRST	%%RET(T2)	;GO TO START CODE
GTUPM:	-2,,.GTUPM
OLDSEG:!	0		;STORE OLD SEG NAME
SGFLAG:!	0		;-1 IF OLDSEG WANTED
SEGPGN:!	0		;PAGE NO. OF START OF HIGH SEG

PRVSEG:	SETOM	SGFLAG		;GOING BACK
	MOVE	T1,OLDSEG	;GET NAME
	MOVEM	T1,SEGBLK+1	;STORE
	JRST	SGCOD1		;REJOIN COMMON CODE

SEGERR:	HRRM	T1,SEGBLK+2	;STORE ERROR CODE IN GETSEG BLOCK
;********************		;REMOVE WHEN MONITOR BUG IS FIXED
	MOVSI	T1,1		;GET RID OF HIGH SEGMENT FIRST
	CORE	T1,		; TO BE SURE WE HAVE ENOUGH ROOM
	  JFCL			;CAN NOT HAPPEN
;********************
	MOVEI	T1,ERRBLK	;TRY AGAIN
EGTSEG:	GETSEG	T1,UU.PHY
	  HALT			;LET MONITOR PRINT MESSAGE
	JRST	SEGGOT		;WE GOT LNK999, GO TO IT

;GETSEG BLOCK FOR LNK999
ERRBLK:	.-.		;DEVICE
	'LNK999'	;FILE NAME
	EXP	0,0,0,0	;EXT, CORE ETC

>;END IFE FTSINGLE
SUBTTL	RESTART CODE 


IFE FTSINGLE,<
;DO A RUN UUO ON FIRST SEGMENT

START:	MOVE	T1,FSTSEG	;[600] GET NAME OF INITIAL SEGMENT
	CAMN	T1,SEGBLK+1	;[600] ALREADY IN THE RIGHT SEGMENT?
	JRST	START1		;[600] RIGHT SEGMENT
	MOVEM	T1,SEGBLK+1	;STORE NAME
	SETZM	SEGBLK+2	;CLEAR EXT
	SETZM	SEGBLK+3
	SETZM	SEGBLK+5
	SKIPA	T1,.+1		;GET RID OF HIGH AND REST OF LOW SEG
		1,,.+5
	CORE	T1,		; TO BE SURE WE HAVE ENOUGH ROOM
	  JFCL			;CAN NOT HAPPEN
	MOVEI	T1,SEGBLK	;NORMAL START ADDRESS
	RUN	T1,
	  HALT			;TOO BAD
>;END IFE FTSINGLE
SUBTTL	UUO TRAP

UUOHANDLER:
	MOVEM	T1,SAVEAC+T1	;GET AN ACC
	MOVE	T1,.JBUUO	;GET UUO
	TLNN	T1,776000	;ONLY UUO 1 IS VALID
IFE FTSINGLE,<
	JRST	@SEGPGN		;ENTER HIGH SEG
>
IFN FTSINGLE,<
	JRST	%%UUO##		;WE KNOW WHERE IT IS
>
	OUTSTR	UUOMES		;ILL UUO
	SOS	T2,UUOTRAP	;PC+1
	HRLO	T2,T2		;PC IN LEFT FLAG IN RIGHT
	SETZ	T1,		;RECEIVING ACC
	LSHC	T1,3		;GET NEXT CHAR
	ADDI	T1,"0"		;TURN INTO ASCII
	OUTCHR	T1
	TRNE	T2,-1		;ZERO RH WHEN DONE
	JRST	.-5
	EXIT

UUOMES:	.ASCIZ	<?LNKIUU Illegal user UUO at PC >
SUBTTL	ENTER DDT

IFN DEBSW,<
%DDT%:
IFE TOPS20,<
	SKIPN	.JBDDT		;DDT LOADED?
	POPJ	P,		;NO
>
	POP	P,.JBOPC	;SAVE PC
	PUSH	P,T1		;GET AN ACC
	OUTSTR	%DDT1
	MOVE	T1,@.JBOPC	;GET STRING PTR
	OUTSTR	@T1		;OUTPUT IT
	OUTSTR	%DDT2
	HRRZ	T1,.JBDDT	;GET DDT ADDRESS
IFN TOPS20,<
	SKIPN	T1		;REAL DDT?
	MOVEI	T1,770000	;NO, USE IDDT
>
	EXCH	T1,0(P)		;SWAP WITH CONTENTS OF T1
	POPJ	P,		;GO TO DDT

%DDT1:	ASCIZ	\
DDT:	Called from	\

%DDT2:	ASCIZ	\
\
>
SUBTTL	TTY OUTPUT LINE BUFFERING SUBROUTINE

TTYDMP:	PUSH	P,T1		;SAVE CHAR
	PUSHJ	P,TTYOUT	;OUTPUT LINE
	POP	P,T1
				;NOW TRY

TTYIT:	SOSGE	TTYBUF+2	;ANY SPACE LEFT
	JRST	TTYDMP		;NO, FORCE OUTPUT
	IDPB	T1,TTYBUF+1	;DEPOSIT IN LINE BUFFER
	CAIG	T1,.CHFFD	;SEE IF END-OF-LINE CHAR
	CAIGE	T1,.CHLFD
IFE FTSINGLE,<
	JRST	TTYRET		;NO, JUST RETURN
>
IFN FTSINGLE,<
	POPJ	P,
>
TTYOUT:	SETZ	T1,
	IDPB	T1,TTYBUF+1	;END WITH NULL
	OUTSTR	LINBUF		;OUTPUT LINE
	MOVEI	T1,LN.CPL	;RESET
	MOVEM	T1,TTYBUF+2	;CCHAR COUNT
	SKIPA	T1,.+1
	POINT	7,LINBUF
	MOVEM	T1,TTYBUF+1	;AND BYTE PTR
	POPJ	P,		;[636] RETURN TO TTYDMP

IFE FTSINGLE,<
TTYRET:
	PUSH	P,T1		;[636] SAVE CHAR IN T1
	MOVE	T1,SEGPGN	;GET SEGMENT ORIGIN
	ADDI	T1,%%RET	;[636] POINT TO WHERE WE WANT TO GO
	EXCH	T1,0(P)		;[636] SAVE GOTO ADDR, RESTORE T1
	POPJ	P,		;[636] GO TO CPOPJ ENTRY
>
SUBTTL	LOG FILE OUTPUT SUBROUTINE

LOGIT:	SOSGE	RCBUF+2		;ANY SPACE LEFT
	JRST	LOGDMP		;NO
	IDPB	T1,RCBUF+1	;YES
IFE FTSINGLE,<
	JRST	TTYRET		;INCASE EXECUTE ONLY
>
IFN FTSINGLE,<
	POPJ	P,
>

LOGDMP:	OUT	RC,		;OUTPUT THIS BUFFER
	  JRST	LOGIT		;NO ERRORS
	MOVSI	T1,(POINT 0)	;NULL BYTE POINTER
	HLLM	T1,RCBUF+1	;INCASE CALLED AGAIN
	HRLOM	T1,RCBUF+2	;VERY LARGE WORD COUNT
	RELEASE	RC,		;SAVE WHAT WE HAVE
	OUTSTR	.EROEL		;WILL USE .ERR. IN FUTURE
IFE FTSINGLE,<
	JRST	TTYRET
>
IFN FTSINGLE,<
	POPJ	P,
>

.EROEL:	.ASCIZ	<%LNKOEL Output error on log file, file closed, job continuing.
>


IFE FTSINGLE,<
HIEND==.-1
	DEPHASE


IFL LN.PLC-<HIEND-HICODE>,<
	PRINTX	?PHASED LOWSEG AREA TOO SMALL, INCREASE LN.PLC IN LNKPAR
			>
>;END IFE FTSINGLE
SUBTTL HIGH SEGMENT PART OF RESTART CODE



;HERE TO RESTART SINGLE SEGMENT VERSION OR WHEN RESTARTING
;MULTI-SEG VERSION AND RIGHT SEGMENT IS STILL IN CORE

IFN FTSINGLE,<
START::
>
START1:
IFE FTSINGLE,<
	MOVE	.SGDEV,SEGBLK	;[600] SETUP ACS FOR INITIALIZATION
	MOVE	.SGNAM,SEGBLK+1	;[600] ..
	MOVE	.SGPPN,SEGBLK+4	;[600] ..
>
	MOVEI	T1,EZCOR	;GET RID OF JUNK IN LOW SEG
	CORE	T1,		;EASY WAY
	  JFCL			;CANNOT FAIL
	SKIPA	T1,.+1
	%LOW,,%LOW+1
	SETZM	%LOW		;CLEAR LOW SEG DATA
	BLT	T1,@.JBREL
	MOVEI	T1,LINK10	;GET ORIGINAL START ADDRESS
	HRRM	T1,.JBSA	;RESET IT
	JRST	(T1)		;AND START AGAIN


INILIT:
END	LINK10