Google
 

Trailing-Edge - PDP-10 Archives - BB-5255D-BM - language-sources/lnkwld.mac
There are 48 other files named lnkwld.mac in the archive. Click here to see a list.
TITLE	LNKWLD - SWITCH HANDLER FOR LINK
SUBTTL	D.M.NIXON/DMN/JLd/SRM/JBC/JNG/MCHC/PAH/DZN	24-Aug-79


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


SEARCH	LNKPAR,LNKLOW,MACTEN,UUOSYM,SCNMAC
IFN TOPS20,<SEARCH	MACSYM,MONSYM>
SALL

ENTRY	LNKWLD
EXTERN	LNKFIO,LNKCOR,LNKLOG,LNKMAP,TTYCHK


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


SEGMENT
;CALLING SEQUENCE
;PUSHJ P,LNKWLD

;RETURN
;END OF LIST NOTHING LEFT
;ALL I/O SETUP SO SOSGE LOOP WILL GET DATA

;CALLS LNKFIO TO TAKE CARE OF ALL OUTPUT FILE I/O
;OUTPUT FILES MUST BE FIRST IN LIST

;ALSO HANDLES ALL SWITCHES
SUBTTL	REVISION HISTORY


;START OF VERSION 1A
;41	ADD LNKFSI MESSAGE
;45	HASH INITIAL SYMBOLS AT ASSEMBLY TIME
;46	ADD KLUDGE FEATURE
;52	ADD ASCII TEXT BLOCK
;54	ADD KIONLY D.P. INST
;60	ADD /VERSION SWITCH
;63	ADD EXTERNAL START ADDRESS IN BLOCK TYPE 7
;65	TENEX SPEEDUPS
;71	MAKE ALL MESSAGES STANDARD FORM
;74	(11389) FIX ILL MEM REF ON FILE/SYSLIB
;103	RESTORE BOTH HALVES OF FL AFTER EDITED LOOKUP ERROR
;105	MAKE BLOCK TYPE 12 WORK
;106	REMOVE HIORG, REPLACE WITH EITHER LL.S2 OR SO.S2
;107	REPLACE KLUDGE BY MIXFOR
;110	ILL MEM REF ON /BASKSPACE:1
;114	MAKE /LOG WORK IF DEVICE NOT 'LOG' OR TTY
;115	MAKE /NOSYMBOLS WORK CORRECTLY
;120	/SYMSEG:HIGH WITH NO HIGH CODE GIVES ILL MEM REF

;START OF VERSION 1B
;122	(11940) ADD COPYP1 TO HANDLE /M/SSA=PROG
;124	ADD /ONLY SWITCH
;132	(12304) FIX TO EDIT 122

;START OF VERSION 2
;135	ADD OVERLAY FACILITY
;137	ADD SUPPORT FOR PLOT PACKAGE
;141	TURN ON AND FIX BUGS IN ASCII TEXT BLOCKS
;145	IMPLEMENT /USERLIB & /NOUSERLIB SWITCHES
;153	FIX BUG IN EDITS 122 AND 132
;156	MAKE FOO/DEBUG WORK RIGHT
;161	ADD LANGUAGE SPECIFICATION TO /USERLIB
;167	CHANGE ARGUMENTS TO /OTSEGMENT
;170	MAKE PLOT SWITCH WORK
;201	MAKE FORDDT WORK
;216	(13559) ADD ZSV ERROR CHECK AND MESSAGE
;START OF VERSION 2B
;225	ADD SUPPORT FOR PSECT (MACRO VERSION 51)
;245	CHANGED CALLING SEQUENCE TO DVLKP.
;247	Rework the use of the DEBUGSW; set .LOCALS before main
;	program is loaded.
;253	Make multiple line ASCII text blocks work
;254	Disconnect from the file spec. switches deferred until
;	after the file is open so won't dispatch off of PC
;	if the file spec. is edited.
;256	Add a zero entry to the key word table, incase the
;	user types "/<switch>:" without a key word
;262	Make SYSLB1 a global routine to force a LIBRARY search
;272	Correctly force rehashing if /HASHSIZE seen
;277	Control stack so can continue after editing file spec.
;302	MAKE TENEX DDT WORK RIGHT
;307	MAKE LOCAL ASCII BLOCK SWITCHES WORK RIGHT
;343	INCLUDE EDITS 302,307 IN MAINTENANCE SOURCES
;353	REMOVE EDIT 225
;377	Fix some bugs in the handling of the /SET switch.
;400	Default the PPN correctly on /DEFAULT
;406	Make DDT default for /TEST: and /DEBUG:
;411	Implement /K to correct ASCII text processing
;421	Give %LNKMSN and %LNKSSN if can't act as requested.
;431	Make the /ESTIMATE switch work.

;START OF VERSION 2C
;464	Implement the /MISSING switch.
;471	Add code for ALGOL debugging system.
;472	Update HL.S1 on the /COMMON switch, and fix the map.
;530	Define triplet flags bits correctly.
;534	Fix problems with .OSCAN and ASCII text.
;544	SOUP in LINK version 3 stuff for TOPS-20.
;551	Change /SYMBOL to /SYFILE
;557	Clean up the listing for release.

;START OF VERSION 3
;446	CHANGE TO LOAD SYS:UDDT.EXE FOR TENEX

;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's in various messages.
;610	Handle defaulting of ersatz devices correctly.
;615	Never try to load empty SCAN blocks.
;617	Fix edits 610 and 615.
;620	Don't overwrite old device when merging file specs
;621	/SAVE and /SSAVE generate an EXE file.
;653	Make /SYSLIB with an argument work.
;655	Clear start address module name on /START.
;677	Don't default to /SYMSEG:LOW if loading overlays.
;705	Wait for the file to be loaded first for /SYMSEG
;706	/SET to build RC.NTB
;714	Add psect-name as a global symbol with origin as value.
;715	Modify SYMSEG to take psect name.
;721	Implement /SYMSEG:PSECT:psectname.
;723	Add /UPTO.
;727	Adjust SYMLIM  with /SET:.HIGH. /SYMSEG:HIGH & /SYMSEG:LOW.
;730	Save /DEBUG file spec for /LINK.
;731	SEARCH MACTEN,UUOSYM
;740	Remove %VERSION code.
;757	Type out RC.HL instead of RC.CV value for overlayable PSECT for /COUNTER.
;761	Clear AT.RP(relocatable PSECT bit) in /SET switch.
;763	Common code in .SET0 for creating reloc counter for block 22,24.
;765	Release on both TOPS-10 and TOPS-20 as LINK version 4(765)
;START OF VERSION 4A
;775	Make sure /DEBUG:FORTRAN loads the starting address of FORDDT.
;1101	Set LSTBLK and DTAFLG correctly on new input files.
;1107	Fix bug with .SETEX routine to expand RC.TB and RC.NTB tables.
;1117	Add /NOINCLUDE switch and make /INCLUDE:args set include mode.
;1122	Remove edit 740.
;1132	Allow loading of PSECTs above the high segment.
;1142	Fix problems with /SET introduced by edit 1132.
;1144	Remember if we mapped in DDT as a result of /DEBUG:DDT on TOPS-20.
;1145	Load locals if /DEBUG:DDT on TOPS-20. Broken by edit 1144.
;1155	Store PSECT properties even if PSECT name is .HIGH.
;1157	Suppress the PSECT name global symbols to DDT typeout.
;1163	Fix edit 1155 to not mark .HIGH. as relocatable.
;1172	Don't change SYMLIM on /SET to .HIGH..
;1173	Update RC.HL on /COMMON.
;1174	Label and clean up all error messages.
;1175	Don't lookup symbolic argument to /START until /GO, move USA message.
;1176	Disallow /SYMSEG:PSECT:name if loading overlays.
;1177	Make global /VERSION not lose local switches.
;1201	Change $SEGxxx to $SSGxxx.
;1203	Add support for extended FORTRAN.
;1204	Check for program growing too far and give LNKPTL.
;1211	Fix typo in LNKDRC.
;1217	Clean up the listings for release.
;1220	Release on both TOPS-10 and TOPS-20 as version 4A(1220).
SUBTTL	ENTER HERE FROM LNKLOD TO GET A FILE TO LOAD


LNKWLD:	SETZM	NULSPC		;CLEAR NULL FILE SPEC FLAG
	SKIPE	P1,F.EDIT	;DID WE JUST DO AN EDIT CORRECTION?
	JRST	MERGE		;YES, BUILD THE TRUE FILE SPEC
	MOVEM	P,MARKWP	;MARK STACK INCASE LOOKUP ERROR
IFN .ASBLK,<
	SKIPE	F.ASCI		;READING INCORE TEXT?
	JRST	ASCMRG		;YES
>
	SKIPE	SWFLAG		;CHECK FOR DEFERED SWITCHES FROM LAST FILE
	PUSHJ	P,DEFLSW	;YES, GO DO THEM FIRST
	SKIPE	P1,F.INZR	;GET NEXT FILE SPEC
	JRST	NXTSPC		;YES THERE IS ONE
	SKIPE	GOTO		;NO, BUT SHOULD WE TERMINATE
	JRST	@GOTO		;YES, DO FINAL DEFAULTS ETC.
	SKIPG	P1,S.INZR	;JUST FINISH A /LINK SWITCH?
	JRST	URET		;NO, RETURN TO USER
	MOVEM	P1,F.INZR	;YES, RESTART COMMAND STRING
	HLLZ	FL,S.LHFL	;PUT THINGS BACK AS THEY WERE
	HLR	FL,FL		;DEFAULT SWITCHES FOR THIS FILE
	SETZM	S.INZR		;CLEAR SPECIAL KLUDGE FLAGS
	SETZM	S.LHFL		;..

;HERE TO LOOK FOR SWITCHES
NXTSPC:	HLRZ	P2,F.SWP(P1)	;GET LIST OF GLOBAL SWITCHES
	JUMPE	P2,.+3		;NONE THERE
	PUSHJ	P,XCTGSW	;DO SWITCH
	MOVE	P1,F.INZR	;RELOAD P1
	HRRZ	P2,F.SWP(P1)	;GET LIST OF LOCAL SWITCHES
	JUMPE	P2,.+3		;NONE
	PUSHJ	P,XCTLSW	;DO SWITCH
	MOVE	P1,F.INZR	;RELODE P1 AGAIN
IFN .ASBLK,<
	SKIPE	F.ASCI		;READING INCORE TEXT?
	JRST	ASCRET##	;YES, FINISH IT
>
	SKIPN	NULSPC		;NULL FILE SPEC (SWITCHES ONLY)
	JRST	DEFILL		;NO, REAL FILE SPEC HERE
NOTSPC:	PUSHJ	P,RETFSP	;JUST A DUMMY DATA BLOCK
	  JFCL			;INCASE NON-SKIP RETURN
	JRST	LNKWLD		;INCASE ANY DEFERED SWITCHES
;HERE TO FILL IN DEFAULTS FOR INPUT DEVICE
DEFILL:	MOVE	T3,F.MOD(P1)	;GET MODIFIER WORD
	MOVE	T2,G.NAM	;DEFAULT FILE NAME
	SKIPN	F.NAME(P1)
	MOVEM	T2,F.NAME(P1)
	MOVE	T2,G.EXT	;DEFAULT EXTENSION
	SKIPN	F.EXT(P1)	;EXT SPECIFIED?
	TXNN	T3,FX.NUL	;ONLY REPLACE NULL EXT
	CAIA			;NO IF 0 OR IF GIVEN
	MOVEM	T2,F.EXT(P1)
	MOVE	T1,F.DIR(P1)	;GET SPECIFIED [PPN]
	MOVE	T2,G.DIR	;AND DEFAULT [PPN]
	TXNN	T3,FX.DIR	;SKIP IF DIRECTORY SPECIFIED
	JRST	DEFDIR		;FILL IN FULL DEFAULT DIRECTORY
	TLNN	T1,-1		;PROJ GIVEN?
	HLL	T1,MYPPN	;[610] NO, USE DEFAULT
	TRNN	T1,-1		;PROG?
	HRR	T1,MYPPN	;[610] NO
	MOVEM	T1,F.DIR(P1)	;[610] STORE UPDATED UFD
	JRST	DEFDEV		;[610]
;HERE TO DEFAULT THE DIRECTORY. MUST NOT USE DEFAULT DIRECTORY
;IF NO DIRECTORY SPECIFIED BUT DEVICE SPECIFIED WAS ERSATZ.
DEFDIR:	MOVE	T3,F.MODM(P1)	;GET MOD MASK
	TXNE	T3,FX.DIR	;TEST FOR [-]
	JRST	DEFDEV		;[610] YES, LEAVE DIR ALONE AS ZERO
	MOVE	T1,[3,,T2]	;[610] NO DIR SPECIFIED, BUT WAS
	MOVE	T2,F.MOD(P1)	;[610]   DEVICE SPECIFIED ERSATZ?
	TXNN	T2,FX.NDV	;[610] NOT IF NO DEVICE WAS SPECIFIED!
	SKIPN	T2,F.DEV(P1)	;[610] SHOULD BE ONE, MAKE SURE
	JRST	DEFDR1		;[610] NO DEVICE, USE G.DIR PATH
	PATH.	T1,		;[610] USER TYPED A DEVICE, ERSATZ?
	  SETZ	T3,		;[610] PROBABLY NOT
	TXNE	T3,PT.IPP	;[610] WAS THE DEVICE ERSATZ?
	JRST	DEFDEV		;[610] YES, LEAVE THE PATH ALONE
DEFDR1:	HRLI	T2,G.DIR	;[610] NO, FORM BLT POINTER
	HRRI	T2,F.DIR(P1)
	BLT	T2,F.DIR+2*.FXLND-1(P1)

;HERE TO DEFAULT THE DEVICE. CAN'T USE DEFAULT DEVICE IF IT'S
;ERSATZ AND USER GAVE AN EXPLICIT PATH.
DEFDEV:	MOVSI	T2,'DSK'	;[617] UNIT DEFAULT DEVICE
	SKIPN	F.DEV(P1)	;[617] NONE SPECIFIED?
	MOVEM	T2,F.DEV(P1)	;[617] MAKE SURE THERE IS ONE
	MOVE	T2,F.MOD(P1)	;[610] PICKUP MOD WORD
	TXNE	T2,FX.NDV	;[610] USER TYPE AN EXPLICIT DEVICE?
	SKIPN	T2,G.DEV	;[610] NO, BUT IS THERE A DEFAULT?
	JRST	LDDS		;[610] EXPLICIT DEVICE OR NO DEFAULT
	MOVE	T1,[3,,T2]	;[610] BUT IS THE DEFAULT DEVICE ERSATZ?
	PATH.	T1,		;[610] FIND OUT VIA PATH UUO
	  SETZ	T3,		;[610] PROBABLY NOT
	MOVE	T2,G.DEV	;[610] RESTORE CORRECT DEVICE
	MOVE	T1,F.MODM(P1)	;[610] GET MOD MASK
	TXNE	T1,FX.DIR	;[610] WAS A DIRECTORY SPECIFIED?
	TXNN	T3,PT.IPP	;[610] YES, WAS THE DEVICE ERSATZ?
	MOVEM	T2,F.DEV(P1)	;[610] NO DIR OR G.DEV NOT ERSATZ
;HERE TO GET DEVICE AND DO OPEN IF DEVICE DIFFERENT FROM LAST ONE
LDDS:	MOVEI	T2,DC		;GET DATA CHAN
	CAME	T2,IO.CHN	;SAME AS CURRENT?
	SETZM	IO.CHR		;NO, SO DEVCHR MUST BE INVALID
	MOVEM	T2,IO.CHN	;INCASE DEFERED SWITCHES
	MOVE	T2,F.DEV(P1)	;GET DEVICE
	EXCH	T2,FSTR		;MAKE SURE NEW STORED INCASE OF ERROR
	CAMN	T2,FSTR		;SAME AS PREV DEVICE?
	JRST	LDFS		;YES, BYPASS INIT
	SETZM	FILNUM		;START AGAIN ON NEW DEVICE
	PUSHJ	P,DVCHK.##	;SEE IF DEVICE EXISTS AND CAN SUPPORT MODE
	PUSHJ	P,DVOPN.##	;DO OPEN
LDFS:	SKIPN	IO.CHR		;VALID DEVCHR YET?
	PUSHJ	P,DVCHK.##	;NO, GET IT INCASE NULL FILE NAME
	SKIPE	F.NAME(P1)	;IF NO NAME GIVEN?
	JRST	LDFS1		;OK IT WAS
	MOVE	T2,IO.CHR	;GET DEVCHR BIT
	TXNE	T2,DV.DIR	;IF NON-DIRECTORY DEVICE
	JRST	NOTSPC		;NO, SO NOT A FILE SPEC
	AOS	T1,FILNUM	;GET FILE NUMBER
	SETZ	T3,		;RECEIVE IT HERE
	IDIVI	T1,^D10
	ADDI	T2,'0'		;[617] DIGITIZE
	LSHC	T2,-6		;SHIFT IN
	JUMPN	T1,.-3		;[617] UNTIL ALL DONE
	MOVEM	T3,F.NAME(P1)	;SO WE KNOW WHICH FILE IF ERROR
LDFS1:	PUSHJ	P,DVINP.##	;BUILD INPUT SPEC
	PUSHJ	P,DVLKP.##	;AND LOOKUP
	  PUSHJ	P,E01FLE##	;[1174] GIVE ERROR MESSAGE
	SETZM	LSTBLK		;[1101] ASSUME BLOCK 0
	SETZM	DTAFLG		;[1101] AND ON DISK (NORMAL CASE)
	MOVE	T1,IO.CHR	;[1101] GET DEV CHARACTERISTICS
	TXNN	T1,DV.DTA	;[1101] ON DECtape?
	JRST	RETFSP		;RETURN SPACE
	SETOM	DTAFLG		;[1101] ON DECtape, REMEMBER THAT
	SETOM	LSTBLK		;[1101] FLAG FOR D.CNT IN LNKLOD
	JRST	RETFSP		;[1101] DONE, GO RETURN SPACE
;HERE TO MERGE NEW FILE SPEC WITH PREVIOUS ONE

MERGE:	HLRZ	T1,P1		;GET POINTER TO FLAGS
	MOVE	FL,(T1)		;RESTORE THEM AS THEY WERE
	MOVEI	T2,1		;GIVE BACK SPACE
	PUSHJ	P,DY.RET##
	MOVE	P2,F.INZR	;GET NEW SPEC
	MOVE	T4,F.MOD(P2)	;GET MODIFIER WORD
	MOVE	T1,F.DEV(P1)	;GET OLD DEVICE
	MOVE	T2,F.MOD(P1)	;[620] OLD MOD WORD
	TXNE	T2,FX.NDV	;[620] WAS THERE AN OLD DEVICE?
	JRST	.+3		;[620] NO, USE NEW ONE ALWAYS
	TXZE	T4,FX.NDV	;[620] USER SUPPLIED NEW?
	MOVEM	T1,F.DEV(P2)	;NO, USE PREVIOUS
	SKIPE	F.NAME(P2)	;NEW NAME SUPPLIED?
	JRST	MERGE0		;YES, USE IT
	DGET	T1,F.NAME(P1),F.NAMM(P1)	;NO, USE PREVIOUS & MASK
	DSTORE	T1,F.NAME(P2),F.NAMM(P2)
MERGE0:	MOVE	T1,F.EXT(P1)
	MOVE	T2,F.MOD(P1)	;GET OLD MOD WORD
	TXNE	T2,FX.NUL	;WAS OLD EXT VALID?
	JRST	.+3		;NO, USE NEW ALWAYS
	TXZE	T4,FX.NUL	;SEE IF USER SUPPLIED NEW EXT
	MOVEM	T1,F.EXT(P2)
	TXNN	T4,FX.DIR	;NEW DIRECTORY?
	JRST	[MOVE	T3,F.MODM(P2)	;NO, BUT CHECK FOR [-]
		TXNE	T3,FX.DIR	;WILL BE SET IF SO
		JRST	MERGE1		;YES, SO LEAVE PPN = 0
		HRLZI	T1,F.DIR(P1)	;NO, USE OLD PPN
		HRRI	T1,F.DIR(P2)
		BLT	T1,F.LEN-1(P2)	;COPY SFDS ALSO
		JRST	MERGE1]
	MOVE	T1,F.DIR(P1)	;GET PREVIOUS PPN
	MOVE	T2,F.DIRM(P2)	;AND THIS MASK
	TLNN	T2,-1		;PROJ SPECIFIED?
	HLLM	T1,F.DIR(P2)	;NO, USE PREV
	TRNN	T2,-1		;PROG SPECIFIED?
	HRRM	T1,F.DIR(P2)	;NO
MERGE1:	MOVEM	T4,F.MOD(P2)	;STORE MODIFIED MOD WORD
	MOVE	T2,P2		;USER MAY HAVE SUPPLIED EXTRA FILE SPECS
	SKIPN	F.NXT(T2)	;SO LOOK FOR END (0)
	JRST	.+3		;GOT IT
	MOVE	T2,F.NXT(T2)	;NOT YET
	JRST	.-3
	MOVE	T1,F.NXT(P1)	;GET NEXT FILE SPEC
	MOVEM	T1,F.NXT(T2)	;LINK IN CHAIN
				;NOW FOR SWITCHES
				;LINK OLD SWITCHES IN FIRST SO NEW ONES CAN
				;TURN THEM OFF
	HLRZ	T1,F.SWP(P1)	;GET POINTER
	JUMPE	T1,MERGE2	;NONE
	HRRZ	T2,0(T1)	;GET POINTER TO NEXT
	JUMPE	T2,.+3		;GOT LAST
	MOVE	T1,T2		;NO
	JRST	.-3		;KEEP TRYING
	HLLZ	T2,F.SWP(P2)	;GET FIRST NEW SWITCH
	HLLM	T2,0(T1)	;LINK IN
	HLLZ	T1,F.SWP(P1)	;GET START OF CHAIN
	HLLM	T1,F.SWP(P2)	;POINT TO NEW CHAINED LIST
MERGE2:				;NOW FOR AFTER SWITCHES
	HRRZ	T1,F.SWP(P1)	;GET POINTER
	JUMPE	T1,MERGE3	;NONE
	HRRZ	T2,0(T1)	;GET POINTER TO NEXT
	JUMPE	T2,.+3		;GOT LAST
	MOVE	T1,T2		;NO
	JRST	.-3		;KEEP TRYING
	HRRZ	T2,F.SWP(P2)	;GET FIRST NEW SWITCH
	HRRM	T2,0(T1)	;LINK IN
	HRRZ	T1,F.SWP(P1)	;GET START OF CHAIN
	HRRM	T1,F.SWP(P2)	;POINT TO NEW CHAINED LIST
MERGE3:	MOVEI	T1,0(P1)	;NOW REMOVE OLD
	MOVEI	T2,F.LEN
	PUSHJ	P,DY.RET##
	SETZM	F.EDIT		;SO WE DON'T LOOP
	MOVE	P,MARKWP	;RESET STACK TO POINT OF ERROR
	JRST	LNKWLD		;NOW TRY IT
SUBTTL	HERE FOR ASCII TEXT BLOCK


;ENTER HERE TO MERGE ASCII TEXT BLOCK WITH CURRENT COMMAND TREE
;THERE ARE TWO POSSIBILITIES
;IF THE FIRST BLOCK HAS NO FILE SPEC, THEN THE SWITCHES APPLY TO
;THE CURRENT FILE BEING LOADED AS IF THEY HAD BEEN TYPED AFTER
;THE FILE NAME IN THE COMMAND LINE
;IF A FILE SPEC IS SEEN THEN THE NEW TREE IS ADDED TO THE IN CORE
;ONE AFTER THE CURRENT FILE, THE GLOBAL SWITCHES OF THIS  DO NOT
;APPLY TO THE CURRENT FILE BEING LOADED

IFN .ASBLK,<
ASCMRG:	SKIPE	P1,F.INZR	;ANYTHING TO DO
	SKIPE	F.NAME(P1)	;ANY SWITCHES FOR THIS FILE?
	JRST	ASCRET##	;NO, RETURN TO FIXUP LISTS AND STACK
	HRRZ	T1,F.ASZR	;FIRST LINE OF .TEXT BLOCK?
	JUMPN	T1,ASCRET##	;NO, DON'T PROCESS IT NOW
	MOVSS	F.SWP(P1)	;FIRST MAKE THE SWITCHES LOCAL
	SETOM	NULSPC		;MAKE SURE WE DON'T LOAD ANYTHING
	JRST	NXTSPC		;YES, DO THEM NOW

>;END IFN .ASBLK
;HERE TO RETURN FILE SPACE TO POOL
;CALLS DY.RET WITH
;T1 = ADDRESS 
;T2 = LENGTH
RETFSP:	MOVE	T2,F.NXT(P1)	;GET NEXT BLOCK
	MOVEM	T2,F.INZR	;ADVANCE POINTER
	HRRZ	T1,P1		;SET ADDRESS
	MOVEI	T2,F.LEN	;SET LENGTH
	PUSHJ	P,DY.RET##	;GIVE BACK SPACE
	SKIPL	S.INZR		;LAST BLOCK CONTAIN /LINK?
	JRST	DEFGSW		;NO, PROCEED
	MOVE	T1,F.INZR	;SAVE REST OF COMMAND LINE
	HRRZM	T1,S.INZR	; UNTIL /LINK PROCESSING DONE
	MOVEM	FL,S.LHFL	;SAVE GLOBAL DEFAULTS TILL LATER
	SETZM	F.INZR		;FOR NOW, PRETEND EOL
	SETZM	F.NXZR		; SO GOTO NON-ZERO WILL BE NOTICED

;HERE TO HANDLE DEFERED SWITCHES
;SWITCHES ARE LINKED TO SWFLAG
;SKIP RETURNS ALWAYS

DEFGSW:	HLRZ	P2,SWFLAG	;GET SWITCHES BEFORE FILE NAME FIRST
	JUMPE	P2,CPOPJ1	;NONE, GIVE UP FOR NOW
	HRRZ	T1,(P2)		;GET NEXT ADDRESS
	HRLM	T1,SWFLAG	;REMOVE FROM LIST
	MOVE	T2,2(P2)	;GET VALUE
	PUSHJ	P,@1(P2)	;RETURN TO SWITCH ACTION
	HRRZ	T1,P2		;ADDRESS OF SWITCH BLOCK
	HLRZ	T2,(P2)		;SIZE
	PUSHJ	P,DY.RET##	;RESTORE SPACE TO POOL
	JRST	DEFGSW		;SEE IF ANY MORE
;HERE FOR DEFERED SWITCHES AFTER FILE NAME
;THEY GET EXECUTED JUST BEFORE NEXT FILE SPEC IS FOUND

DEFLSW:	HRRZ	P2,SWFLAG	;GET SWITCHES AFTER FILE NAME
	JUMPE	P2,CPOPJ	;NONE, GIVE UP
	HRRZ	T1,(P2)		;GET NEXT ADDRESS
	HRRM	T1,SWFLAG	;REMOVE FROM LIST
	MOVE	T2,2(P2)	;GET VALUE
	PUSHJ	P,@1(P2)	;RETURN TO SWITCH ACTION
	HRRZ	T1,P2		;ADDRESS OF SWITCH BLOCK
	HLRZ	T2,(P2)		;SIZE
	PUSHJ	P,DY.RET##	;RESTORE SPACE TO POOL
	JRST	DEFLSW		;SEE IF ANY MORE

;HERE TO GIVE GOOD RETURN ALL DONE WITH LNKFIO FOR NOW
URET1:	AOS	(P)		;SKIP RETURN
URET:	MOVE	T1,MAPSW	;SEE IF A MAP TO DO
	CAIN	T1,$MAPNOW	;ONLY CASE WE CARE ABOUT
	PJRST	LNKMAP		;YES
	POPJ	P,

;USUAL RETURN SEQUENCE
CPOPJ1:	AOS	(P)	;SKIP RETURN
CPOPJ:	POPJ	P,
;HERE TO HANDLE SWITCHES

;GLOBAL SWITCHES (LHS)
XCTGSW:	DMOVE	T1,1(P2)	;GET TOKEN # & VALUE
	HLRZ	T1,XCTSWT(T1)	;GET JUMP ADDRESS
	PUSHJ	P,(T1)		;DO SWITCH ACTION
	HRRZ	T1,P2		;SETUP ADDRESS OF THIS SWITCH
	HLRZ	T2,(P2)		;AND SIZE
	HRRZ	P2,(P2)		;GET NEXT SWITCH
	PUSHJ	P,DY.RET##	;RETURN SPACE
	HRLM	P2,F.SWP(P1)	;POINT TO NEW LINK (IN CASE REQUIRED)
	JUMPN	P2,XCTGSW	;XCT THIS SWITCH
	POPJ	P,		;RETURN END OF GLOBAL SWITCH CHAIN



;LOCAL SWITCHES (RHS)

XCTLSW:	DMOVE	T1,1(P2)	;GET TOKEN # & VALUE
	HRRZ	T1,XCTSWT(T1)	;GET JUMP ADDRESS
	PUSHJ	P,(T1)		;DO SWITCH ACTION
	JUMPE	P2,XCTLXX	;[730] JUMP IF NOTHING TO GIVE BACK
	HRRZ	T1,P2		;SETUP ADDRESS OF THIS SWITCH
	HLRZ	T2,(P2)		;AND SIZE
	HRRZ	P2,(P2)		;GET NEXT SWITCH
	PUSHJ	P,DY.RET##	;RETURN SPACE
	HRRM	P2,F.SWP(P1)	;POINT TO NEW SWITCH
	JUMPN	P2,XCTLSW	;XCT THIS SWITCH
XCTLXX:	POPJ	P,		;[730] RETURN END OF GLOBAL SWITCH CHAIN
;HERE TO STORE SWITCHES THAT CAN NOT BE EXECUTED UNTIL FILE IS OPENED
;THE SWITCHES ARE STORED IN LINKED LISTS ANCHORED TO SWFLAG
;SWITCHES BEFORE FILE NAME ARE IN LEFT HALF
;SWITCHES AFTER FILE NAME IN RIGHT HALF

STRGSW:	POP	P,1(P2)		;STORE RETURN OVER TOKEN #
	POP	P,T1		;REMOVE RETURN ADDRESS
	MOVEI	T2,SWFLAG	;START OF LIST
	MOVE	T1,T2		;SAVE LAST ADDRESS
	HLRZ	T2,(T1)		;GET FIRST LINK ADDRESS
	JUMPE	T2,[HRLM P2,(T1)	;LINK FIRST ONE TO LEFT HALF
		JRST	STRGS1]		;REST TO RIGHT HALF
	MOVE	T1,T2		;SAVE LAST
	HRRZ	T2,(T1)		;REST OF ADDRESS FROM RIGHT HALH
	JUMPN	T2,.-2		;LOOK FOR END OF LIST
	HRRM	P2,(T1)		;LINK THIS BLOCK IN
STRGS1:	MOVE	T1,P2		;SAVE ADDRESS
	HRRZ	P2,(P2)		;GET NEXT SWITCH BLOCK
	HRLM	P2,F.SWP(P1)	;ADVANCE TO NEXT SWITCH
	HLLZS	(T1)		;SET END OF CHAIN
	JUMPN	P2,XCTGSW	;HANDLE THIS ONE
	POPJ	P,		;END OF GLOBAL SWITCHES

;HERE FOR SWITCHES AFTER FILE NAME

STRLSW::POP	P,1(P2)		;STORE RETURN OVER TOKEN #
	POP	P,T1		;REMOVE RETURN ADDRESS
	MOVEI	T2,SWFLAG	;START OF LIST
	MOVE	T1,T2		;SAVE LAST ADDRESS
	HRRZ	T2,(T1)		;GET LINK ADDRESS
	JUMPN	T2,.-2		;LOOK FOR END OF LIST
	HRRM	P2,(T1)		;LINK THIS BLOCK IN
	MOVE	T1,P2		;SAVE ADDRESS
	HRRZ	P2,(P2)		;GET NEXT SWITCH BLOCK
	HRRM	P2,F.SWP(P1)	;DISCONNECT FROM THIS SWITCH
	HLLZS	(T1)		;SET END OF CHAIN
	JUMPN	P2,XCTLSW	;HANDLE THIS ONE
	POPJ	P,		;END OF GLOBAL SWITCHES
SUBTTL	DISPATCH TABLE FOR SWITCHES


;XCTSWT IS A TABLE OF DISPATCH ADDRESSES FOR SWITCHES
;ONE WORD PER TOKEN #
;LHS=GLOBAL , RHS=LOCAL

DEFINE SWMAC (A,B,C,D,E,F,G,H,I)<
 IF1,<BLOCK 1>
 IF2,<
  IFNDEF %'B,<EXTERN %'B>
  IFNB <G>,<
   IFNDEF .'B,<EXTERN .'B>
   XWD	.'B,%'B
  >
  IFB  <G>,<
   XWD	%'B,%'B
>>>
;***** MUST USE XWD NOT ,, SINCE ".COMMON" IS A PSEUDO-OP IN MACRO.50
EXTERN	.REQUEST		;SO IS .REQUEST
	XALL
XCTSWT:	SWTCHS
	SALL
SUBTTL	SWITCH ACTION -- /COMMON:name:len


%COMNM:	SIXBIT	\DEFINED-BY-SWITCH\	;AVOID FORWARD REFERENCE AT DMOVE

%COMMON:
	PUSHJ	P,STRLSW	;WAIT TIL FILE IS LOADED
.COMMON:
	PUSHJ	P,.SAVE4##	;PRESERVE P1-P4
	SKIPN	W2,T2		;SYMBOL
	MOVE	W2,['.COMM.']	;BLANK COMMON IF NULL
	MOVS	W3,3(P2)	;LENGTH OF COMMON
	TRNE	W3,-1		;[1204] MORE THAN 777777?
	PUSHJ	P,E$$PTL##	;[1204] YES, COMPLAIN
	PUSHJ	P,T.COMR##	;STORE IN GLOBAL TABLE
	  POPJ	P,		;WAS ALREADY THERE
	MOVNI	T1,2*.L		;REMOVE COMMON ENTRY FROM LS AREA
	ADDM	T1,LSYM		;T.COMR INSERTED IT, BUT WE WANT
	ADDM	T1,LS.PT	;WANT TO PUT A FAKE TITLE BEFORE
	MOVEI	T1,2*.L		;THE COMMON SYMBOL, SO THE MAP
	ADDM	T1,LS.FR	;WILL COME OUT CORRECTLY
	MOVX	W1,PT.SGN!PT.EXT!PT.TTL!PT.FAK
	MOVE	W2,%COMNM	;FIRST 6 CHARS
	MOVE	W3,LSYM		;POINT TO WHERE FIRST TRIPLET WILL GO
	ADDI	W3,4*.L		;THEN TO LAST
	PUSHJ	P,LS.ADD##	;PUT IN LOCAL TABLE
	MOVX	W1,S.TTL!S.LST	;EXTENDED TITLE
	DMOVE	W2,%COMNM+1	;REST OF NAME
	PUSHJ	P,LS.ADD##
	HRRZ	P1,@HT.PTR	;SETUP P1 TO POINT TO SYMBOL
	ADD	P1,NAMLOC	;IN CORE
	PUSH	P,.L+2(P1)	;SAVE 2ND TRIPLET INFO
	PUSH	P,.L+1(P1)
	PUSH	P,.L+0(P1)
	TMOVE	W1,0(P1)	;RESET FIRST  SYMBOL TRIPLET
	PUSHJ	P,LS.ADD##	;PUT IN LOCAL TABLE
	POP	P,W1		;GET SECONDARY
	POP	P,W2		;SAME NAME
	POP	P,W3		;LENGTH
	MOVE	T1,SG.TB+1	;GET LOW SEG RELOC TABLE
	MOVE	T2,W3		;GET A DISPOSABLE COPY
	ADDB	T2,RC.CV(T1)	;BUMP CURRENT RC
	CAMLE	T2,RC.HL(T1)	;[1173] NEVER DECREASE
	MOVEM	T2,RC.HL(T1)	;[1173] UPDATE HIGHEST LOCATION IN THIS PSECT
	CAML	T2,HL.S1	;NEVER DECREASE HL.S1
	MOVEM	T2,HL.S1	;UPDATE HIGHEST LOCATION LOADED
	PJRST	LS.ADD##	;STORE AND RETURN
SUBTTL	SWITCH ACTION -- /CORE:n


IFE TOPS20,<

%CORE:
	CAIGE	T2,1000		;IN WORDS ALREADY?
	LSH	T2,^D10		;NO, ASSUME K
	SUBI	T2,1		;GET HIGHEST ADD
	MOVE	T1,HIORGN	;[650] HISEG ORIGIN
	SUBI	T1,1001		;[650] HIGHEST LEGAL (1P FOR HELPER)
	CAMG	T2,T1		;[650] REQUEST TOO BIG?
	CAMG	T2,.JBREL	;[650] OR TOO SMALL?
	POPJ	P,		;[650] YES, DON'T DO CORE UUO
	MOVE	T1,T2		;[650] KEEP A COPY
	CORE	T2,UU.PHY	;[650] EXPAND, PHYSICALLY
	  CAIA			;[650] FAILED, SEE WHY
	JRST	E02EXP		;[1174] OK, TELL USER
	MOVE	T2,T1		;[650] NOW TRY VIRTUALLY
	PUSH	P,.JBREL##	;[650]  FIRST SAVE OLD SIZE
	CORE	T2,		;[650] CAN WE GET IT?
	JRST	[POP	P,(P)	;[650] NO, CLEAR STACK
		POPJ	P,]	;[650] AND GIVE UP
	POP	P,T2		;[650] NOW GIVE BACK VM PAGES
	CORE	T2,		;[650] TO GET SOME PHYSICALLY
	  JFCL			;[650] ??
	MOVE	T3,T1		;[650] START AT USERS REQUEST
CORE1:	SUB	T3,.PGSIZ	;[650] TRY FOR ONE LESS
	CAMG	T3,.JBREL##	;[650] MAYBE WERE ALREADY AT LIMIT
	  JRST	CORE2		;[650] YEP, GIVE UP
	MOVE	T2,T3		;[650] TEMP COPY
	CORE	T2,UU.PHY	;[650] GET IT?
	  JRST	CORE1		;[650] NO, TRY SMALLER
CORE2:	CORE	T1,		;[650] GET THE REST VIRTUALLY
	  JFCL			;[650] MONITOR BUG IF FAILS
E02EXP::.ERR.	(MS,.EC,V%L,L%I,S%I,EXP) ;[1174]
	.ETC.	(COR,.EP,,,,.JBREL)
	MOVE	T2,.JBREL	;NEW TOP OF CORE
	MOVEI	T1,HG.TAB	;START AT TOP
	SKIPN	TAB.LB(T1)	;AND FIND AREA IN USE
	SOJA	T1,.-1		;WILL FIND ONE EVENTUALLY
	MOVEM	T2,TAB.UB(T1)	;GIVE TOP AREA ALL FREE SPACE
	PUSHJ	P,.SAVE2##	;SAVE P1 AND P2
	SETZB	P1,P2		;INDICATE JUST SHUFFLING
	PUSHJ	P,LNKCOR##	;NOW ADJUST ALL AREAS
	  JFCL			;NEVER FAILS
	POPJ	P,		;RETURN

> ;END OF IFE TOPS20
SUBTTL	SWITCH ACTION -- /COUNTER


;/COUNTER  CAUSES LINK TO PRINT A LIST OF ALL CURRENT RELOCATION COUNTERS, THEIR
;INITIAL VALUES AND THEIR CURRENT VALUES.  THIS IS DONE BY USING A  .ETC.  MACRO
;LOOP TO PRINT EACH COUNTER LINE.

%COUNTER:
	PUSHJ	P,STRLSW	;WAIT TIL FILE LOADED
.COUNTER:
	MOVEI	R,1		;[1174] START AT 1 (COUNTER .LOW.)
E$$RLC::.ERR.	(MS,.EC,V%L,L%F,S%I,RLC,<Reloc. ctr.	initial value	current value>) ;[1174]
COUNEX:	.ETC.	(XCT,.EC,,,,<[PUSHJ P,COUNGT]>) ;[1174] ANY MORE TO PRINT?
	.ETC.	(JMP,.EC,,,,COUNDN) ;[1174] NO--DONE
	.ETC.	(NLN,.EC)	;[1174] YES--NEW LINE FOR IT
	.ETC.	(SBX,.EC!.EP,,,,W1) ;[1174] RELOCATION COUNTER NAME
	.ETC.	(STR,.EC,,,,,<		>) ;[1174]
	.ETC.	(OCT,.EC!.EP,,,,W2) ;[1174] INITIAL VALUE
	.ETC.	(STR,.EC,,,,,<		>) ;[1174]
	.ETC.	(OCT,.EC!.EP,,,,W3) ;[1174] CURRENT VALUE
	.ETC.	(JMP,.EC,,,,COUNEX) ;[1174] LOOP FOR REST
COUNDN:	.ETC.	(STR,,,,,<>)	;[1174] JUST A DUMMY TO JUMP TO
	POPJ	P,		;[1174] DONE


;COUNGT  IS  CALLED  FROM  THE  ABOVE LNKRLC MESSAGE TO FIND THE NEXT RELOCATION
;COUNTER VALUES, IF ANY.
;
;CALL:
;	R/	RELOCATION COUNTER TO CHECK
;RETURNS NON-SKIP IF NO MORE, OR SKIP WITH:
;	W1/	NAME OF RELOCATION COUNTER
;	W2/	INITIAL VALUE
;	W3/	CURRENT VALUE
;	R/	INCREMENTED FOR NEXT TIME

COUNGT:	CAMG	R,RC.NO		;[1174] ANY MORE?
	SKIPN	R2,@RC.TB	;[1174]   ..
	POPJ	P,		;[1174] NO--NON-SKIP RETURN
	MOVE	W1,RC.NM(R2)	;[1174] FETCH RELOCATION COUNTER NAME
	MOVE	W2,RC.IV(R2)	;[1174] FETCH INITIAL VALUE
	MOVE	T1,RC.AT(R2)	;[1174] IF OVERLAID PSECT
	TXNE	T1,AT.OV	;[1174]   ..
	SKIPN	W3,RC.HL(R2)	;[1174] THEN TRY HIGHEST SEEN SO FAR
	MOVE	W3,RC.CV(R2)	;[1174] ELSE JUST USE CURRENT VALUE
	AOJA	R,CPOPJ1	;[1174] ADV TO NEXT AND GIVE SKIP RETURN
SUBTTL	SWITCH ACTION -- /CPU:key, /CRLF:n


%CPU:
	MOVE	T1,CPUTBL-1(T2)	;GET VALUE (KA10=0, KI10=1)
	MOVEM	T2,CPUTGT	;STORE TARGET CPU
	POPJ	P,

%CRLF:
	PUSHJ	P,STRLSW	;WAIT TILL FILE IS LOADED
.CRLF:
	SKIPN	T2		;IS THIS END OF ASCII BLOCK?
	MOVE	T2,FLAGS	;NO, MIDDLE OF ASCII BLOCK.
				;RESET TO GLOBAL FLAGS (NEW LINE)
	HLLZ	FL,T2		;STORE CORRECT GLOBAL FLAGS IN FL
	HLR	FL,FL		;LOCALS SAME AS GLOBALS SO FAR
	POPJ	P,
SUBTTL	SWITCH ACTION -- /DEBUG:name, /TEST:name


.DEBUG:
	SETOM	DEBUGSW		;SIGNAL DEBUG START
	SETOM	EXECSW		;AND SIGNAL EXECUTION REQUIRED
.TEST:
	SOSG	T1,2(P2)	;NEED TO MAKE SPECIAL CASE CHECKS
	SKIPE	T1,DDEBUG	;TRY DEFAULT
	SUBI	T1,1		; FOR COBDDT AND FORDDT
	LSH	T1,-1		; SINCE THEY MUST BE LOADED AFTER MAIN
	HRRM	T1,DEBUGSW	;STORE INDEX IN THE FLAG
	MOVE	T1,DEBTBL(T1)	;NAME OF DEBUG PROGRAM
	CAME	T1,['FORDDT']
	CAMN	T1,['COBDDT']
	JRST	SPCDDT		;ITS A SPECIAL DDT
DEBUG1:	MOVEI	T2,F.LEN	;GET A BLOCK OF SPACE FOR FILE SPECS
	PUSHJ	P,DY.GET##	;IN DYNAMIC AREA
	HRRM	P1,(T1)		;LINK INTO LIST TO DO
	HRRM	T1,F.INZR	;PUT DEBUG FIRST
	HRLZ	T2,(P2)		;GET NEXT SWITCH
	HLLM	T2,1(P1)	;FIX LIST OF SWITCHES TO DO
	MOVE	P1,T1		;FORGET OTHER FILE SPEC FOR NOW
	MOVSI	T1,'SYS'
	MOVEM	T1,F.DEV(P1)	;COMES FROM SYS
	HRRZ	T1,DEBUGSW	;GET INDEX TO DEBUGGER
	MOVE	T1,DEBTBL(T1)	;PICK UP REQUIRED PROG
	MOVEM	T1,F.NAME(P1)	;STORE NAME
	SETOM	F.NAMM(P1)	;AND MASK
	MOVSI	T1,'REL'	;ASSUME EXT 
	HLLOM	T1,F.EXT(P1)	;AND MASK
	SUB	P,[2,,2]	;ADJUST STACK
	MOVE	T1,P2		;ADDRESS OF SWITCH BLOCK
	HLRZ	T2,(P2)		;SIZE
	PUSHJ	P,DY.RET##	;GIVE IT BACK
	MOVSI	T1,L.SYM	;MAKE LOCAL SYMBOLS DEFAULT
	IORM	T1,FLAGS
	PUSHJ	P,.LOCALS	;TURN ON LOAD LOCAL SYMBOLS
	MOVE	T1,F.NAME(P1)	;SEE IF ITS FORDDT
	CAMN	T1,['FORDDT']	;[775] SINCE IT NEED ITS SYMBOLS
	JRST	[MOVSI	T2,L.ISA	;[775] FORCE /NOSTART ON NEW LINES
		 IORM	T2,FLAGS	;[775]   ..
		 PUSHJ	P,.NOSTART	;[775]   AND ON THIS LINE
		 TRZ	FL,R.ISA	;[775]   BUT USE FORDDT'S START
		 JRST	.+2]		;[775] LOAD FORDDT'S LOCALS
	PUSHJ	P,%NOLOCAL	;BUT NOT FOR THIS FILE
	TRZ	FL,R.LIB	;TURN OFF LIB SEARCH MODE
IFN TOPS20,<
	CAMN	T1,['DDT   ']	;ONLY DDT IS SPECIAL
	JRST	MAPDDT		;[1144] MAP IN UDDT RIGHT NOW
>
	JRST	LNKWLD		;AND TRY AGAIN
SPCDDT:	SKIPN	MNTYPE		;HAVE WE LOADED A MAIN PROGRAM YET?
	SKIPN	F.NAME(P1)	; OR NO PROGRAM IN THIS SPEC
	JRST	DEBUG1		;YES, SO ITS OK TO LOAD ???DDT
	pushj	p,.locals	;load main prog with locals
	AOS	2(P2)		;PUT BACK TOKEN VALUE
	HRRZ	T1,(P2)		;GET NEXT SWITCH
	HRLM	T1,F.SWP(P1)	;INTO TABLE
	HRRZ	T1,F.SWP(P1)	;GET NEXT RHS SWITCH
	HRRM	T1,(P2)		;LINK IN
	HRRM	P2,F.SWP(P1)	;AND IN SWITCH LIST
	HLRZ	P2,F.SWP(P1)	;GET NEXT LHS SWITCH
	POP	P,T1		;GET RETURN OFF STACK
	JUMPN	P2,XCTGSW	;DO IT
	POPJ	P,		;ALL DONE

%DEBUG:
%TEST:
	PUSHJ	P,.LOCALS	;GET SYMBOLS FOR PROGRAM
	HLRZ	T2,0(P2)	;GET SPACE FOR SWITCH
	ADDI	T2,F.LEN	;AND FILE SPEC
	PUSHJ	P,DY.GET##	;IN DYNAMIC AREA
	HLLZ	T2,(P2)		;GET LENGTH
	MOVEM	T2,F.LEN(T1)	;STORE IN SWITCH
	DMOVE	T2,1(P2)	;GET REST OF SWITCH
	DMOVEM	T2,F.LEN+1(T1)
	MOVEI	T2,F.LEN(T1)	;ADDRESS OF SWITCH BLOCK
	MOVSM	T2,F.SWP(T1)	;STORE AS GLOBAL
	HRRZ	T2,(P1)		;GET NEXT BLOCK
	MOVEM	T2,(T1)		;PUT DEBUG BEFORE IT
	HRRM	T1,S.DEBG	;[730] SAVE IT, IN CASE OF /LINK
	HRRM	T1,(P1)		;LINK DEBUG IN
	POPJ	P,		;RETURN
;HERE FOR /DEBUG:DDT ON TOPS-20. SINCE THERE IS NO .REL FILE FOR DDT ON TOPS-20,
;WE MUST MERGE UDDT.EXE RIGHT INTO THE CORE IMAGE. IN THE EVENT THAT THE PROGRAM
;LOADS INTO MEMORY, SIMPLY MAP DDT INTO LINK'S ADDRESS SPACE NOW AND IT WILL BE
;PROPERLY PLACED WHEN LOADING IS COMPLETED. IF LINK MUST (OR IS REQUESTED TO)
;WRITE AN .EXE FILE, UDDT WILL NOT BE THERE, BUT AN EXEC DDT COMMAND WILL THEN
;MERGE IN DDT. IF DDT IS ALREADY MAPPED IN, LEAVE IT ALONE. THIS HAPPENS IF LINK
;IS BEING DEBUGGED.

IFN TOPS20,<
MAPDDT:	MOVX	T1,<.FHSLF,,770>;[1144] SEE IF PAGE 770 EXISTS
	RPACS			;[1144]   ..
	TXNN	T2,PA%EX	;[1144]   ..
	JRST	MAPDD1		;[1144] NO--CAN'T BE ANY DDT THERE
	MOVE	T1,770000	;[1144] SEE IF IT'S DDT THAT'S THERE
	CAMN	T1,[JRST 770002];[1144] CROCK, BUT THIS IS WHAT EXEC DOES
	JRST	MAPDD2		;[1144] IT'S DDT--DON'T DESTROY IT
MAPDD1:	MOVX	T1,GJ%OLD!GJ%SHT;[1144] NO DDT THERE--LOAD IT
	HRROI	T2,[ASCIZ /SYS:UDDT.EXE/]
	GTJFN			;[1144] FIND UDDT
	  ERJMP	E$$DNA		;[1174] FAILED
	PUSH	P,T1		;[1144] SAVE JFN FOR UDDT
	MOVX	T1,.FHSLF	;[1144] SAVE LINK'S CURRENT ENTRY VECTOR
	GEVEC			;[1144]   ..
	POP	P,T1		;[1144] GET BACK JFN FOR UDDT
	PUSH	P,T2		;[1144] REMEMBER LINK'S ENTRY VECTOR
	HRLI	T1,.FHSLF	;[1144] NOW BRING IN UDDT WHICH
	GET			;[1144]   DESTROYS LINK'S ENTRY VECTOR
	MOVX	T1,.FHSLF	;[1144] SO RESTORE LINK'S ENTRY VECTOR
	POP	P,T2		;[1144]   ..
	SEVEC			;[1144]   ..
MAPDD2:	TRO	FL,L.SYM	;[1145] LOAD LOCALS (TURNED OFF EARLIER)
	SETOM	NULSPC		;[1145] REMEMBER TO THROW AWAY THIS SPEC
	SETZM	F.NAME(P1)	;[1144]   ..
	SETOM	DDTMAP		;[1144] REMEMBER THAT WE'VE MAPPED DDT
	JRST	LNKWLD		;FORGET DDT REQUEST AND GET NEXT FILE

E$$DNA::.ERR.	(MS,,V%L,L%F,S%F,DNA,<DDT not available>) ;[1174]
>
;TABLE OF NAMES OF DEBUGGING AIDS
DEFINE KEYMAC (A,B)<
 IFIDN <A><DEB>,<
  .ZZ==-1
  IRP B,<
   IFGE .ZZ,<
    IFN .ZZ&1,<
     IFNB <B>,<
	SIXBIT	\B\
     >
     IFB <B>,<
	SIXBIT	\DDT\
   >>>
   .ZZ==.ZZ+1
 >>
 PURGE .ZZ
>

	XALL			;[1174]
DEBTBL:	KEYWORDS
	SALL			;[1174]
SUBTTL	SWITCH ACTION -- /DDEBUG:name,  /DEFINE:sym:val


%DDEBUG::
	JUMPE	T2,CPOPJ	;CHECK FOR NO ARGUMENT
	SUBI	T2,1		;IGNORE DEFAULT
	MOVEM	T2,DDEBUG	;SAVE VALUE
	POPJ	P,


%DEFINE:
	PUSHJ	P,.SAVE4##	;SAVE P1-P4
	MOVX	W1,PT.SGN!PT.SYM
	SKIPN	W2,T2		;GET SYMBOL
	JRST	E$$ZSV		;[1174] ZERO IS INVALID
	MOVE	W3,3(P2)	;AND VALUE
	PJRST	SY.GS##		;DEFINE SYMBOL
SUBTTL	SWITCH ACTION -- /ENTRY


%ENTRY:
	PUSHJ	P,STRLSW	;WAIT TIL AFTER FILE LOADED
.ENTRY:
	MOVE	T1,[PUSHJ P,ENTNXT] ;[1174] SET UP NEXT SYMBOL ROUTINE
	MOVEM	T1,NXTGLB	;[1174]   ..
	MOVE	W3,HT.PRM	;[1174] GET INDEX TO HASH TABLE
	ADDI	W3,1		;[1174] START 1 UP FOR SOSGE BELOW
	PUSHJ	P,ENTNXT	;[1174] GET NEXT (FIRST) ENTRY POINT
	  PJRST	E01LSS		;[1174] NONE THERE--GO SAY SO
E$$LSS::.ERR.	(MS,.EC!.EN,V%L,L%F,S%I,LSS) ;[1174]
	.ETC.	(STR,.EC,,,,,<Library search symbols (entry points)>) ;[1174]
	.ETC.	(JMP,.EC,,,,.ETSAV##) ;[1174] GO PRINT SYMBOLS AND VALUES

;ENTNXT IS CALLED FROM THE ABOVE .ERR. TO RETURN THE NEXT ENTRY POINT SYMBOL AND
;VALUE.
;
;CALL:
;	W3/	NEXT HASH TABLE INDEX TO LOOK AT
;RETURNS WITH NON-SKIP IF NO MORE, OTHERWISE SKIP RETURN WITH:
;	W1/	NAME OF NEXT ENTRY POINT
;	W2/	VALUE OF ABOVE
;	W3/	UPDATED

ENTNXT:	PUSHJ	P,.SAVE4##	;[1174] SAVE LNKLOG'S P ACS
ENTLUP:	SOSGE	P2,W3		;[1174] ANY MORE TABLE TO CHECK?
	POPJ	P,		;[1174] NO--DONE WITH NON-SKIP RETURN
	SKIPN	P3,@HT.PTR	;[1174] GET POINTER TO GS TRIPLET
	JRST	ENTLUP		;[1174] NONE THERE--TRY NEXT POINTER
	ADD	P3,GS.LB	;[1174] RELOCATE IN CASE IT MOVED
	MOVE	T1,0(P3)	;[1174] DO FLAGS SAY SYMBOL AND ENTRY?
	TXNE	T1,PT.SYM	;[1174]   ..
	TXNN	T1,PS.ENT	;[1174]   ..
	JRST	ENTLUP		;[1174] NO--TRY NEXT POINTER
	MOVE	W1,1(P3)	;[1174] YES--A WINNER! SET UP SYMBOL NAME
	MOVE	W2,2(P3)	;[1174]   AND VALUE
	JRST	CPOPJ1		;[1174] DONE WITH SKIP RETURN

E01LSS::.ERR.	(MS,.EC,V%L,L%F,S%I,LSS) ;[1174]
	.ETC.	(STR,,,,,,<No library search symbols (entry points)>) ;[1174]
	POPJ	P,		;[1174] DONE
SUBTTL	SWITCH ACTION -- /ESTIMATE:n, /ERRORLEVEL:n, /EXECUTE
SUBTTL	SWITCH ACTION -- /FRECORE:n, /FOROTS, /FORSE


%ESTIMATE:
	MOVEM	T2,FEST		;STORE ESTIMATED LENGTH
	SKIPE	T1,IO.CHN	;WE MAY BE TOO LATE
	SKIPL	T1,IO.PTR(T1)	;FILE OPENED YET?
	POPJ	P,		;YES, GIVE IT UP
	MOVEM	T2,I.EST(T1)	;NO, STORE IN ENTER BLOCK
	POPJ	P,

%ERRORLEVEL:
	MOVEM	T2,ERRLVL	;STORE ERROR LEVEL
	POPJ	P,

%EXECUTE:
	SETOM	EXECSW		;SIGNAL EXECUTION REQUIRED
	POPJ	P,

%FRECORE:
	MOVEM	T2,FRECOR
	POPJ	P,

%FOROTS:
IFN FTOVERLAY,<
	SKIPGE	LNKMAX		;CAN ONLY SET IN ROOT LINK
>
	SETZM	FORLIB		;FOROTS IS ZERO OR POSITIVE
	POPJ	P,

%FORSE:
IFN FTOVERLAY,<
	SKIPGE	LNKMAX		;CAN ONLY SET IN ROOT LINK
				; AND NOT EVEN THEN IF OVERLAYS WANTED
>
	SETOM	FORLIB		;FORSE IS NEGATIVE
IFN FMXFOR,<
	SETZM	MIXFOR		;CAN NOT MIX F40 & F-10 & USE FORSE
>
	POPJ	P,
SUBTTL	SWITCH ACTION -- /GO, /HASHSIZE:n


%GO:
	MOVEI	T1,GO##		;GET ADDRESS TO RETURN TO
IFN FTOVERLAY,<
	SKIPL	LNKMAX		;ANY OVERLAYS SEEN?
	MOVEI	T1,LINKGO##	;YES, DO FINAL STUFF
>
	MOVEM	T1,GOTO		;SIGNAL TERMINATION AFTER THIS LINE ENDS
	POPJ	P,		;RETURN

%HASHSIZE:
	CAMG	T2,HT.PRM	;SEE IF BIGGER THAN CURRENT SIZE
	POPJ	P,		;NO, LEAVE WELL ALONE
	MOVEM	T2,HASHSZ	;STORE NEW HASH SIZE
	SETOM	HSPACE		;CAUSE REHASH TO TAKE PLACE
	POPJ	P,
SUBTTL	SWITCH ACTION -- /EXCLUDE:name, /INCLUDE:name, /NOINCLUDE


;INCLUDE/EXCLUDE SWITCHES
;HAVE STORED LIST OF PERM,,TEMP NAMES
;PERMANENT NAMES LAST UNTIL CLEARED OR END OR LINK
;TEMP NAMES ARE CLEARED AT END OF FILE

.EXCLUDE:
	MOVSS	EXCPTR		;SWAP PTR TO PUT PERMANENT PART INTO RH
	MOVSS	INCPTR
	PUSHJ	P,%EXCLUDE	;STORE NAME
	MOVSS	EXCPTR		;SWAP BACK
	MOVSS	INCPTR
	MOVEI	T1,INCPTR
	PJRST	EXCL0		;REMOVE FROM TEMP ALSO

%EXCLUDE:
	SKIPN	W2,T2		;GET SYMBOL IN SAFE PLACE
	JRST	E$$ZSV		;[1174] ZERO IS INVALID
	MOVEI	T1,EXCPTR	;GET INITIAL POINTER
IFN .EXSYM,<
	PUSHJ	P,CNTLEN	;CONVERT W2 IF LONG NAME
> ;END IFN .EXSYM
	PUSHJ	P,INCL0		;ADD THIS SYMBOL TO TABLE
	MOVEI	T1,INCPTR
	PJRST	EXCL0		;AND REMOVE FROM OTHER TABLE

.INCLUDE:
	TDO	FL,[L.INC,,R.INC] ;[1117] ALWAYS SET INCLUDE MODE
	SKIPN	T2		;[1117] SEE IF ANY ARGS TO STORE
	POPJ	P,		;[1117] NO--JUST RETURN
	MOVSS	EXCPTR		;SWAP PTR TO PUT PERMANENT PART INTO RH
	MOVSS	INCPTR
	PUSHJ	P,%INCLUDE	;STORE NAME
	MOVSS	EXCPTR		;SWAP BACK
	MOVSS	INCPTR
	MOVEI	T1,EXCPTR
	PJRST	EXCL0		;REMOVE FROM TEMP ALSO

%INCLUDE:
	TRO	FL,R.INC	;TURN ON SPECIAL /INC MODE
	SKIPN	W2,T2		;GET SYMBOL IN SAFE PLACE
	POPJ	P,		;DONE IF JUST FOO/INCLUDE
	MOVEI	T1,INCPTR	;GET INITIAL POINTER
IFN .EXSYM,<
	PUSHJ	P,CNTLEN	;CONVERT W2 TO POINTER IF LONG
> ;END IFN .EXSYM
	PUSHJ	P,INCL0		;ADD THIS SYMBOL TO TABLE
	MOVEI	T1,EXCPTR
	PJRST	EXCL0		;AND REMOVE FROM OTHER TABLE
.NOINCLUDE:
	TDZ	FL,[L.INC,,R.INC] ;[1117] TURN OFF INCLUDE MODE
	POPJ	P,		;[1117] CAN BE TURNED ON BY LATER /INCLUDE

%NOINCLUDE:
	TRZ	FL,R.INC	;[1117] TURN OFF LOCAL INCLUDE MODE
	POPJ	P,		;[1117] DONE
;ROUTINES TO SEARCH THE INCLUDE/EXCLUDE BLOCKS FOR A MATCH.
;CALL IS:
;		MOVEI	T1,ADDR OF LINK TO BLOCKS TO SEARCH
;		MOVE	W2,NAME OR LEN,,ADDR IF LONG
;		PUSHJ	P,INCL0/EXCL0/EXCL.0
;		ONLY RETURN
;USES T1-T4, EXPECTS W2 SET UP. PRESERVES ALL OTHER AC'S.
;INCL0 INSERTS THE NAME IF NOT FOUND, EXCL0 DELETES IT IF FOUND.

INCL0:	HRRZ	T2,(T1)		;ANYTHING THERE?
	JUMPE	T2,INCNXT	;FIRST TIME
INCL1:	HRRZ	T1,(T1)		;GET POINTER TO NEXT BLOCK
	ADD	T1,[-.EXC+1,,1]	;FORM AOBJN PTR
INCL2:	SKIPN	T2,(T1)		;NOT IN TABLE IF ZERO
	SOJA	T1,INCL3	;JUST ENTER
IFN .EXSYM,<
	TLNN	T2,770000	;LONG TITLE IN TABLE?
	JRST	[TLNN	W2,770000	;YES, THIS ONE TOO?
		PUSHJ	P,NAMCMP	;YES, CHECK MATCH
		JRST	.+3		;NO MATCH
		POPJ	P,]		;MATCHES, ALREADY THERE
> ;END IFN .EXSYM
	CAMN	W2,T2		;MATCH?
	POPJ	P,		;YES, SO ALREADY THERE
	AOBJN	T1,INCL2	;TRY NEXT
	SUBI	T1,.EXC		;BACKUP
	HRRZ	T2,(T1)		;IF ZERO THIS IS END
	JUMPN	T2,INCL1	;TRY AGAIN
;	JRST	INCNXT		;GET NEW BLOCK

INCNXT:	PUSH	P,T1		;AND WHERE WE ARE
	MOVEI	T2,.EXC		;SIZE WE NEED
	PUSHJ	P,DY.GET##	;IN DYNAMIC AREA
	POP	P,T2		;BACK POINTER
	HRRM	T1,(T2)		;LINK TO NEW
	HRLZM	T2,(T1)		;AND BACK TO OLD
INCL3:
IFN .EXSYM,<
	TLNE	W2,770000	;NEED TO STORE A LONG NAME?
	JRST	INCL4		;NO, JUST STORE IT
	PUSH	P,T1		;YES, REMEMBER WHERE PTR GOES
	MOVE	T2,0(W2)	;GET LENGTH OF SYMBOL
	ADDI	T2,1		;ACCOUNT FOR LENGTH WORD
	PUSHJ	P,DY.GET##	;ALLOCATE SPACE
	HRLZ	T3,W2		;SETUP BLT PTR
	HRRI	T3,(T1)
	ADDI	T2,(T1)		;CALCULATE LAST DESTINATION WORD
	BLT	T3,-1(T2)	;COPY THE SYMBOL TO NEW HOME
	MOVEI	W2,(T1)		;UPDATE POINTER IN W2
	POP	P,T1		;RESTORE WHERE POINTER GOES
INCL4:	> ;END IFN .EXSYM
	MOVEM	W2,1(T1)	;AND STORE  THIS NAME
	POPJ	P,
EXCL.0::			;ENTRY FROM T.6
EXCL0:	HRRZ	T2,(T1)		;ANYTHING THERE?
	JUMPE	T2,CPOPJ	;NO
EXCL1:	HRRZ	T1,(T1)		;GET POINTER TO NEXT BLOCK
	ADD	T1,[-.EXC+1,,1]	;FORM AOBJN PTR
EXCL2:	SKIPN	T2,(T1)		;NOT IN TABLE IF ZERO
	POPJ	P,		;RETURN
IFN .EXSYM,<
	TLNN	T2,770000	;LONG NAME?
	JRST	[TLNN	W2,770000	;YES, TARGET LONG TOO?
		PUSHJ	P,NAMCMP	;YES, SEE IF MATCHES
		JRST	.+3		;NO MATCH, CONTINUE
		JRST	EXCL3]		;FOUND IT...GO REMOVE
> ;END IFN .EXSYM
	CAMN	W2,T2		;MATCH?
	JRST	EXCL3		;YES, SO REMOVE
	AOBJN	T1,EXCL2	;TRY NEXT
	SUBI	T1,.EXC		;BACKUP
	HRRZ	T2,(T1)		;IF ZERO THIS IS END
	JUMPE	T2,CPOPJ
	JRST	EXCL1		;TRY AGAIN

EXCL3:	HLRO	T2,T1		;GET NUMBER LEFT IN BLOCK
	ADDI	T2,.EXC		;AND SO NUMBER USED
	MOVN	T2,T2
	ADDI	T2,(T1)		;BACKUP TO LINK POINTER
	HRRZ	T3,(T2)		;NULL LINK IS END
	JUMPE	T3,EXCL4	;GOT IT
	HRRZ	T2,(T2)		;GET NEXT POINTER
	JRST	.-3		;LOOP
;HERE WHEN FOUND A BLANK ENTRY.
EXCL4:	SKIPN	2(T2)		;IF ONLY ONE NAME IN BLOCK
	JRST	EXCL5		;DELETE BLOCK ALSO
	ADD	T2,[-.EXC+1,,1]	;FORM AOBJN POINTER
	SKIPE	(T2)		;LOOK FOR NULL 
	AOBJN	T2,.-1		;OR END
	MOVE	T3,-1(T2)	;GET THIS MODULE NAME
	EXCH	T3,(T1)		;OVERWRITE PREV ONE
	SETZM	-1(T2)		;AND DELETE  THIS
IFN .EXSYM,<
	TLNE	T3,770000	;THIS A POINTER OR SYMBOL
	POPJ	P,		;SYMBOL, JUST RETURN
	MOVEI	T1,(T3)		;POINTER, MUST FREE BLOCK
	MOVE	T2,(T1)		;GET ADDR IN T1 AND LEN IN T2
	ADDI	T2,1		;ACCOUNT FOR LENGTH WORD
	PUSHJ	P,DY.RET##	;FREE THE BLOCK AND RETURN
> ;END IFN .EXSYM
	POPJ	P,

EXCL5:	MOVE	T3,1(T2)	;GET ONLY NAME IN BLOCK
	EXCH	T3,(T1)		;OVERWRITE OLD
	PUSH	P,T2		;SAVE POINTER TO BLOCK TO DELETE
IFN .EXSYM,<
	TLNE	T3,770000	;IS THIS A SYMBOL OR POINTER
	JRST	EXCL6		;JUST SYMBOL, DON'T DELETE SUB-BLOCK
	MOVEI	T1,(T3)		;SET UP FOR DY.RET
	MOVE	T2,(T1)
	ADDI	T2,1
	PUSHJ	P,DY.RET##	;FREE THE SUB-BLOCK
EXCL6:	> ;END IFN .EXSYM
	POP	P,T1		;RESTORE BLOCK PTR INTO T1
	HLRZ	T2,(T1)		;GET BACK LINK
	HLLZS	(T2)		;BREAK LINK
	MOVEI	T2,.EXC		;BLOCK SIZE
	PJRST	DY.RET##	;RETURN BLOCK
;SUBROUTINES FOR USE BY INCLUDE/EXCLUDE CODE.


;THIS ROUTINE CHECKS THE SWITCH BLOCK POINTED TO BY P2 AND
;UPDATES W2 TO CONTAIN A POINTER IF THE NAME
;GIVEN BY THE SWITCH WAS A LONG NAME. USES NO ACS.

IFN .EXSYM,<

CNTLEN:	SKIPN	3(P2)		;IS THIS A LONG SYMBOL?
	POPJ	P,		;NO, LEAVE W2 ALONE
	SKIPE	LN.SWV+1(P2)	;IS THIS MAX LENGTH (NO ENDING 0)
	JRST	[MOVSI	W2,LN.SWV	;YES, SET LEN TO MAX
		JRST	CNTLN1]		;AND RETURN NEW POINTER
	MOVEI	W2,2(P2)	;MAKE AOBJP PTR TO TITLE NAME
	SKIPE	(W2)		;FOUND END YET?
	AOBJP	W2,.-1		;NO, COUNT THIS & LOOK AT NEXT
CNTLN1:	HLRZM	W2,1(P2)	;PUT LENGTH OVER TOKEN #
	MOVEI	W2,1(P2)	;POINT W2 TO LEN, THEN TITLE IN SIXBIT
	POPJ	P,



;THIS ROUTINE COMPARES THE LONG NAME POINTED AT BY T2 WITH THE
;ONE POINTED AT BY W2, AND SKIPS IF THEY ARE EQUAL. DESTROYS T2-4.


NAMCMP::MOVE	T3,(W2)		;GET LENGTH OF SWITCH ARG
	MOVE	T4,(T2)		;AND LENGTH OF STORED ARG
	CAME	T3,T4		;NAMES THE SAME LENGTH?
	POPJ	P,		;NO, CAN'T BE THE SAME NAME
	MOVNS	T3		;NEGATE LENGTHS
	MOVNS	T4		;SO CAN SETUP AOBJN PTRS
	MOVSI	T3,(T3)		;NEED TO PUT MAGNITUDE IN LH
	MOVSI	T4,(T4)		;SINCE AOBJN EXPECTS IT THERE
	HRRI	T3,1(W2)	;MAKE AOBJN PTRS TO NAMES
	HRRI	T4,1(T2)	;USER'S IN T3, STORED IN T4
CMPLUP:	MOVE	T2,(T3)		;GET NEXT PART OF NAME
	CAME	T2,(T4)		;MATCH STORED PART?
	POPJ	P,		;NO, NO MATCH
	AOBJN	T3,[AOBJN T4,CMPLUP	;BOTH POINTERS BETTER JUMP
		    POPJ  P,]		;STORED ONE WAS SHORTER
	AOBJN	T4,CPOPJ	;USER'S GONE, STORED BETTER BE TOO
	JRST	CPOPJ1		;FANTASTIC, A MATCH

> ;END IFN .EXSYM
SUBTTL	SWITCH ACTION -- /K, /LOGLEVEL:n, /MAXCORE:n


%K==CPOPJ			;/K IS JUST A KOMMAND, NO ACTION

%LOGLEVEL:
	MOVEM	T2,LOGLVL	;STORE LOG FILE MESSAGE LEVEL
	POPJ	P,

%MAXCORE:
	CAIGE	T2,1000		;IN WORDS ALREADY?
IFE TOPS20,<
	LSH	T2,^D10		;NO, ASSUME K
>
IFN TOPS20,<
	LSH	T2,9		;NO, ASSUME P
>
	SUBI	T2,1		;GET HIGHEST ADDRESS
	MOVE	T1,DY.AB	;SEE HOW MUCH WE ABSOLUTELY NEED
	ADD	T1,GS.AB
	SUB	T1,GS.LB	;+GLOBAL AREA
	ADD	T1,FX.AB
	SUB	T1,FX.LB	;+FIXUPS
IFN FTOVERLAY,<
	ADD	T1,RT.AB	;[650]
	SUB	T1,RT.LB	;[650] +RELOCATION TABLES
	ADD	T1,BG.AB	;[650]
	SUB	T1,BG.LB	;[650] +BOUND GLOBALS
> ;END IFN FTOVERLAY
	ADDI	T1,2*.IPS	;SYMBOLS + LOW CODE
	SKIPE	HC.LB
	ADDI	T1,.IPS		;+ HIGH CODE
	SKIPE	AS.LB		;[650]
	ADDI	T1,.IPS		;[650]
	IOR.	T1,.PGSIZ	;[650]
	CAMGE	T2,T1		;GIVE WARNING
	JRST	E$$MTS		;[1174] AND IGNORE IF TOO SMALL
	MOVEM	T2,MAXCOR	;STORE MAXIMUM INCORE SIZE
	MOVE	T2,HIORGN	;GET START OF HISEG
	SUBI	T2,1001		;MAX LOWSEG (1P FOR HELPER)
	CAML	T2,MAXCOR	;MAXCOR TOO BIG?
	POPJ	P,		;NO
	MOVEM	T2,MAXCOR	;YES, SET TO MAX ALLOWED
E$$MTB::.ERR.	(MS,.EC,V%L,L%W,S%W,MTB,</MAXCOR: too big, >) ;[1174]
	.ETC.	(COR,.EC!.EP,,,,T2)
	.ETC.	(STR,,,,,,< used>)
	POPJ	P,

E$$MTS::.ERR.	(MS,.EC,V%L,L%W,S%W,MTS,</MAXCOR: too small, at least >) ;[1174]
	.ETC.	(COR,.EC!.EP,,,,T1)
	.ETC.	(STR,,,,,,< is required>)
	POPJ	P,
SUBTTL	SWITCH ACTION -- /MISSING


%MISSING:
	PUSHJ	P,STRLSW	;WAIT UNTIL CURRENT FILE IS LOADED

.MISSING:
	PUSHJ	P,.SAVE4##	;SAVE ALL P ACS IN CASE NEEDED
	HLRO	P1,INCPTR	;LH LT 0 MEANS NOT AN ERROR
	MOVEI	T1,[ASCIZ	\[LNKIMM \]	;POINT TO PREFIX
MISNG1::PUSH	P,T1		;SAVE PREFIX ADDRESS
	HRRZ	T1,LOWSUB	;[605] ADDRESS OF TTY OUTSTR ROUTINE
	PUSHJ	P,.TYOCH##	;TELL SCAN
	EXCH	T1,0(P)		;SAVE OLD VALUE, RESTORE PREF ADDR
	PUSHJ	P,.TSTRG##	;TYPE PREFIX
	MOVEI	P2,(P1)		;GET ADDR OF INCLUDE CHAIN
	JUMPE	P2,MISNG5	;IF NO CHAIN, NO INCLUDES
	SETZ	T1,		;INITIALIZE COUNT OF INCLUDES
	MOVEI	T2,(P1)		;T2 POINTS TO CURRENT BLOCK
MISNG2:	HRRZ	T3,(T2)		;GET THIS BLOCK'S LINK WORD
	JUMPE	T3,MISNG3	;IF NOT FULL, GO FINISH LAST BLOCK
	ADDI	T1,.EXC-1	;IT IS, ADD IN SIZE OF FULL BLOCK
	MOVEI	T2,(T3)		;POINT T2 TO NEXT BLOCK
	JRST	MISNG2		;AND KEEP COUNTING
MISNG3:	TLO	T2,-.EXC+1	;MAKE AOBJN-1 POINTER TO LAST BLOCK
MISNG4:	SKIPE	1(T2)		;NEXT LOCATION FULL?
	ADDI	T1,1		;YES, BUMP COUNT ONE MORE
	AOBJN	T2,MISNG4	;LOOP OVER ENTIRE LAST BLOCK
	SKIPE	P2,T1		;UNLESS ZERO....
	PUSHJ	P,.TDECW##	;OUTPUT NUMBER MISSING MODULES
	CAILE	P2,2		;LEAVE 0 OR 1 ALONE
	MOVEI	P2,2		;BUT MAP GT 2 INTO 2
MISNG5:	MOVE	T1,MISTAB(P2)	;GET ADDR OF CORRECT MESSAGE
	PUSHJ	P,.TSTRG##	;TYPE IT
	TLNE	P1,-1		;LH NON-ZERO MEANS NO FILE SPEC
	JRST	MISNG6		;THERE ISN'T ONE
	MOVEI	T1,[ASCIZ	\ from file \]
	PUSHJ	P,.TSTRG##	;TYPE MORE OF MESSAGE
	HRRZ	T1,IO.PTR+DC	;POINT TO LAST .REL FILE LOADED
	PUSHJ	P,.TEBLK##	;TYPE OUT THE FILESPEC
MISNG6:	JUMPGE	P1,MISNG7	;LH NON-NEG MEANS WAS AN ERROR
	MOVEI	T1,"]"		;OTHERWISE, JUST INFORMATIONAL
	PUSHJ	P,.TCHAR##	;SO TYPE A "]"

			;CONTINUED ON NEXT PAGE
			;CONTINUED FROM PREVIOUS PAGE

MISNG7:	PUSHJ	P,.TCRLF##	;END MESSAGE GRACEFULLY
	JUMPE	P2,MISNGE	;DONE IF NONE MISSING
	TLZ	P1,-1		;OTHERWISE MUST TYPE THEM ALL
MISNG8:	TLO	P1,-.EXC+1	;FORM AOBJN-1 POINTER TO THIS BLOCK
MISNG9:	SKIPN	P3,1(P1)	;PICK UP NEXT NAME OR POINTER
	JRST	MISNGD		;ZERO?? SNH---JUST IGNORE
	PUSHJ	P,.TTABC##	;TAB OVER FOR NAME
IFN .EXSYM,<
	TLNE	P3,770000	;NAME OR POINTER?
	JRST	MISNGB		;JUST A NAME -- GO TYPE IT
	MOVN	T1,(P3)		;POINTER -- GET NEGATIVE WORD COUNT
	HRL	P3,T1		;SET UP AOBJN POINTER
MISNGA:	SKIPN	T1,1(P3)	;GET NEXT PART OF NAME
	JRST	MISNGC		;NO MORE -- STOP
	PUSHJ	P,.TSIXN##	;PRINT IN SIXBIT
	AOBJN	P3,MISNGA	;LOOP FOR ENTIRE LIST
	JRST	MISNGC		;DONE -- GO PRINT CRLF
>; END IFN .EXSYM
MISNGB:	MOVE	T1,P3		;PUT NAME IN PROPER AC
	PUSHJ	P,.TSIXN##	;PRINT IN SIXBIT
MISNGC:	PUSHJ	P,.TCRLF##	;END THE LINE
MISNGD:	AOBJN	P1,MISNG9	;LOOP FOR THE ENTIRE INCLUDE BLOCK
	HRRZ	P1,-.EXC+1(P1)	;GET NEXT ADDRESS IF ANY
	JUMPN	P1,MISNG8	;ANOTHER BLOCK -- GO PROCESS
MISNGE:	POP	P,T1		;RESTORE OLD TYPE OUT ADDRESS
	PJRST	.TYOCH##	;REPLACE IT AND RETURN


;TABLE OF MESSAGES, DEPENDING ON NUMBER OF MODULES MISSING

MISTAB:	[ASCIZ	\No included modules missing\]
	[ASCIZ	\ included module missing\]
	[ASCIZ	\ included modules missing\]
SUBTTL	SWITCH ACTION -- /MPSORT:key, /NOINITIAL


%MPSORT:
	MOVEM	T2,MAPSRT	;SAVE TYPE REQUIRED
	JRST	@MPSTBL-1(T2)	;DISPATCH TO RIGHT FUNCTION


%NOINITIAL:
IFN FTOVERLAY,<
	SKIPL	LNKMAX		;CAN ONLY SET IN ROOT LINK
	POPJ	P,		;JUST IGNORE, ITS TOO LATE
>
	MOVE	T1,GSYM		;GET CURRENT COUNT OF GLOBAL SYMBOLS
	MOVE	T2,LSYM		;AND LOCALS
	CAMN	T1,@GS.LB	;TEST AGAINST INITIAL
	CAME	T2,@LS.LB	;FOR BOTH GLOBAL & LOCAL
	JRST	E$$TDS		;[1174] TOO LATE TO CHANGE NOW
;RESET GLOBAL SPACE
	MOVE	T1,GS.LB	;GET BASE OF GLOBALS
	SETZM	(T1)		;CLEAR FIRST WORD
	HRL	T2,T1
	HRRI	T2,1(T1)	;FORM BLT PTR
	BLT	T2,@GS.PT	;UP TO FREE SPACE
	ADDI	T1,1		;PRE-ALLOCATE FIRST WORD
	HRRZ	T2,HT.PTR	;START OF SPACE FOR HASH TABLE
	SUBI	T2,(T1)		;LENGTH OF ORIGINAL SYMBOL TRIPLETS
	PUSHJ	P,GS.RET##	;RETURN IT
	SETZM	GSYM		;NO SYMBOLS  NOW
	MOVEI	T1,I.PRM	;INITIAL SYMBOLS
	IMULI	T1,.HS%		;HOW MUCH TO FILL
	IDIVI	T1,^D100
	MOVEM	T1,HSPACE	;HASH TABLE FULL ENOUGH AT THIS POINT

;NOW FOR LOCAL SYMBOLS
	MOVE	T1,LS.LB	;GET BASE
	SETZM	(T1)		;CLEAR FIRST WORD
	HRL	T2,T1
	HRRI	T2,1(T1)	;FORM BLT PTR
	BLT	T2,@LS.PT	;CLEAR UPTO FREE SPACE
	MOVEI	T2,1		;PRE-ALLOCATE FIRST WORD
	MOVEM	T2,(T1)
	MOVEM	T2,LSYM
	ADDI	T1,1
	MOVEM	T1,LS.PT	;NEW FREE SPACE POINTER
	SUB	T1,LS.AB	;- FREE SPACE
	MOVMM	T1,LS.FR	;+
	POPJ	P,

E$$TDS::.ERR.	(MS,,V%L,L%W,S%W,TDS,<Too late to delete initial symbols>) ;[1174]
	POPJ	P,
SUBTTL	SWITCH ACTION -- /LOCALS, /NOLOCAL, /NOSEARCH, /NOSTART
SUBTTL	SWITCH ACTION -- /NOSYMBOL, /OTSEGMENT:key, /PATCHSIZE:n


.LOCALS:
	TLO	FL,L.SYM	;LOAD WITH LOCAL SYMBOLS
%LOCALS:
	TRO	FL,R.SYM	;LOAD WITH LOCAL SYMBOLS (1 FILE ONLY)
	SKIPN	NOSYMS		;IF /NOSYM FALL INTO .NOLOCAL
	POPJ	P,

.NOLOCAL:
	TLZ	FL,L.SYM	;DON'T LOAD LOCAL SYMBOLS
%NOLOCAL:
	TRZ	FL,R.SYM	;DON'T LOAD LOCAL SYMBOLS (1 FILE ONLY)
	POPJ	P,

.NOSEARCH:
	TLZ	FL,L.LIB	;OUT OF LIBRARY SEARCH MODE
%NOSEARCH:
	TRZ	FL,R.LIB	;OUT OF LIBRARY SEARCH MODE (1 FILE ONLY)
	POPJ	P,

.NOSTART:
	TLO	FL,L.ISA	;IGNORE STARTING ADDRESSES
%NOSTART:
	TRO	FL,R.ISA	;IGNORE THIS STARTING ADDRESS
	POPJ	P,

%NOSYMBOL:
	SETOM	NOSYMS		;DON'T WANT ANY SYMBOL TABLES
	SETZM	SYMFRM		;DON'T WANT
	SETZM	SYMSEG		;...
	HRRZ	T1,IO.PTR+%SC	;INCASE /SYMBOL
	JUMPE	T1,.NOLOCAL	;NO, BUT CLEAR FLAGS
	SETZM	IO.PTR+%SC	;SO WE DON'T OUTPUT THEM
	MOVEI	T2,F.LEN	;GIVE BACK SPACE
	PUSHJ	P,DY.RET##
	JRST	.NOLOCAL	;AND CLEAR JUST INCASE

%OTSEGMENT:
	SUBI	T2,1		;DEFAULT IS 0
	CAILE	T2,2		;NEW ARGS ARE 1 & 2
	SUBI	T2,2		;ALLOW FOR LOW & HIGH
IFN FTOVERLAY,<
	SKIPGE	LNKMAX		;CAN ONLY SET IN ROOT LINK
>
	MOVEM	T2,OTSEG	;STORE INDEX TO EITHER LC OR HC
	POPJ	P,

%PATCHSIZE:
	MOVEM	T2,PATSPC	;SAVE PATCH SIZE
	POPJ	P,
SUBTTL	SWITCH ACTION -- /REQUIRE:sym, /RUNCORE:n, /RUNAME:sym, /SEARCH, /MIXFOR


%REQUIRE:
	PUSHJ	P,.SAVE4	;SAVE P1-P4
	MOVX	W1,PT.SYM!PT.SGN	;SOME FLAGS
	SKIPN	W2,T2		;PUT SYMBOL IN  EXPECTED AC
	JRST	E$$ZSV		;[1174] ZERO IS INVALID
	SETZ	W3,		;ZERO VALUE FOR DUMMY REQUEST
	PJRST	SY.RQ##		;PUT IN REQUEST

%RUNCORE:
	CAIGE	T2,1000		;IN WORDS ALREADY?
IFE TOPS20,<
	LSH	T2,^D10		;NO, ASSUME K
>
IFN TOPS20,<
	LSH	T2,9		;NO, ASSUME P
>
	SUBI	T2,1		;HIGHEST ADDRESS
	MOVEM	T2,RUNCOR	;STORE SIZE FOR RUN UUO
	SKIPN	T2,3(P2)	;HIGH SEG SPECIFIED?
	POPJ	P,		;NO
	CAIGE	T2,1000		;IN WORDS ALREADY?
IFE TOPS20,<
	LSH	T2,^D10		;NO, ASSUME K
>
IFN TOPS20,<
	LSH	T2,9		;NO, ASSUME P
>
	SUBI	T2,1		;HIGHEST ADDRESS
	MOVEM	T2,RUNCOR+1	;STORE SIZE FOR RUN UUO
	POPJ	P,

%RUNAME:
	MOVEM	T2,RUNAME	;STORE CORE IMAGE NAME
	POPJ	P,

.SEARCH:
	TLO	FL,L.LIB	;ENTER LIBRARY SEARCH MODE
%SEARCH:
	TRO	FL,R.LIB	;ENTER LIBRARY SEARCH MODE (1 FILE ONLY)
	POPJ	P,

IFN FMXFOR,<
%MIXFOR:
	SETOM	MIXFOR		;SET REQUEST FOR MIXFOR
	POPJ	P,

%NOMIXFOR:
	SETZM	MIXFOR		;CLEAR REQUEST FOR MIXFOR
	POPJ	P,
>
SUBTTL	SWITCH ACTION -- /NEWPAGE, /ONLY:key


%NEWPAGE:
	PUSHJ	P,STRLSW	;WAIT TIL FILE IS LOADED
.NEWPAGE:
	HRRZ	R1,HYLTBL-1(T2)	;GET SEGMENT #
	MOVE	R1,@SG.TB	;POINT TO DATA BLOCK
	SKIPN	T1,RC.CV(R1)	;GET CURRENT VALUE
	POPJ	P,		;NOT YET SETUP!
	ADDI	T1,777
	ANDCMI	T1,777		;NEXT PAGE BOUND
	MOVEM	T1,RC.CV(R1)	;WRITE IT BACK
	POPJ	P,

$HYLLOW==1		;LOW SEG
$HYLHIGH==2		;HIGH SEG

.ONLY:
	PUSHJ	P,SETONL	;SET UP T1 AND T2
	TLZ	FL,(T1)		;CLEAR THESE FLAGS
	TLOA	FL,(T2)		;AND SET THESE
				;SKIP NEXT INST.
%ONLY:
	PUSHJ	P,SETONL
	TRZ	FL,(T1)		;CLEAR
	TRO	FL,(T2)		;SET
	POPJ	P,

SETONL:	HLRZ	T1,ONLTAB-1(T2)	;GET FLAGS TO CLEAR
	HRRZ	T2,ONLTAB-1(T2)	;AND SET
	POPJ	P,

;	CLEAR		SET
ONLTAB:	R.HSO!R.LSO,,	0	;0
	R.HSO,,		R.LSO	;1
	R.LSO,,		R.HSO	;2
SUBTTL	SWITCH ACTION -- /SEGMENT:key


.SEGMENT:
	PUSHJ	P,SETSEG	;SET UP T1 AND T2
	TLZ	FL,(T1)		;CLEAR THESE FLAGS
	TLOA	FL,(T2)		;AND SET THESE
				;SKIP NEXT INST.
%SEGMENT:
	PUSHJ	P,SETSEG
	TRZ	FL,(T1)	;CLEAR
	TRO	FL,(T2)		;SET
	POPJ	P,

SETSEG:	HLRZ	T1,SEGTAB-1(T2)	;GET FLAGS TO CLEAR
	HRRZ	T2,SEGTAB-1(T2)	;AND SET
IFN FTOVERLAY,<
				;***** TEMP PATCH *****
	SKIPL	LNKMAX		;CAN ONLY SET IN ROOT LINK
	CAIN	T2,R.FLS	;BUT CAN SET FORCED LOW SEG
	CAIA			;LEAVE AS IS
	SETZB	T1,T2		;OTHERWISE IT CAUSES GREAT CONFUSION
				;***** FIND BETTER FIX LATER *****
>
	POPJ	P,

;	CLEAR		SET
SEGTAB:	R.FNS!R.FHS,,R.FLS	;[1201] LOW
	R.FNS!R.FLS,,R.FHS	;[1201] HIGH
	R.FLS!R.FHS,,R.FNS	;[1201] DEFAULT
	R.FLS!R.FHS,,R.FNS	;[1201] NONE
SUBTTL	SWITCH ACTION -- /SET:name:val


%SET:
	PUSHJ	P,STRLSW	;WAIT TIL FILE LOADED
.SET:
	DMOVE	W2,2(P2)	;SYMBOL & VALUE
	SETZM	RC.SET		;[761] 0 IF COME HERE BY /SET SWITCH
	SKIPA			;[761]
.SET0::	MOVEM	W1,RC.SET	;[763] KEEP ATTRIBUTES IN RC.SET
	MOVEI	R1,1		;START AT 1 (.LOW.)
	TLNN	W3,770000	;SYMBOLIC IF LEFT JUSTIFIED
	JRST	SET1		;NO, MUST BE OCTAL
	MOVX	W1,PT.SGN!PT.SYM	;SET FLAGS (NOT PT.EXT)
	EXCH	W2,W3		;PUT SYMBOL IN W2 & SAVE W3
	PUSHJ	P,.SAVE4##	;SAVE P1-P4
	PUSHJ	P,TRYSYM##	;SEE IF DEFINED
	  JRST	SETUND		;[1174] NOT DEFINED
	  JRST	SETUND		;[1174]
	MOVE	W2,W3		;RECOVER W2
	MOVE	W3,2(P1)	;GET VALUE
SET1:	SKIPN	R2,@RC.TB	;GET POINTER TO IT
	JRST	SET3		;NON-LEFT, JUST INSERT
	CAME	W2,RC.NM(R2)	;ALREADY THERE?
	JRST	SET2		;NO
	CAMN	W3,RC.CV(R2)	;YES, BUT SAME VALUE?
	POPJ	P,		;YES, GIVE UP
	MOVE	R,R2		;SETUP RC POINTER
	CAML	W3,RC.CV(R2)	;NO, BUT ARE WE TRYING TO DECREASE VALUE?
	JRST	SET4		;NO, OK TO INCREASE IT

	MOVE	W1,RC.IV(R2)	;GET INITIAL VALUE
	CAMGE	W3,W1		;THIS /SET BELOW INITIAL?
	JRST	E$$SRB		;[1174] YES, DO NOT ALLOW IT
	MOVE	W1,RC.CV(R2)	;GET VALUE
E$$DRC::.ERR.	(MS,.EC,V%L,L%W,S%W,DRC,<Decreasing relocation counter >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2)
	.ETC.	(STR,.EC,,,,,< from >)
	.ETC.	(OCT,.EC!.EP,,,,W1)
	.ETC.	(STR,.EC,,,,,< to >)
	.ETC.	(OCT,.EC!.EP,,,,W3) ;[1211]
	.ETC.	(JMP,,,,,.ETIMF##) ;[1174]
	JRST	SET4		;AND CONTINUE
SET2:	CAMGE	R1,RC.NO	;[1132] CHECKED ALL WE'VE SET UP?
	AOJA	R1,SET1		;NO
	ADDI	R,1		;[1142] NOT THERE - INSERT IN NEXT FREE SLOT
SET3:	PUSHJ	P,.SAVE4##	;[1142] SAVE P1-P4
	MOVX	W1,PT.SGN!PT.SYM!PS.DDT	;[1157] SET FLAGS
	PUSHJ	P,SY.GS##	;[714] ADD TO GLOBAL SYMBOL TABLE.
	CAMN	W2,['.HIGH.']	;THIS IS SPECIAL
	JRST	[MOVE	W1,W3		;AS IT CAUSES HIGH SEG TO APPEAR
		PUSHJ	P,SETRC##	;[1155] SETUP HIGHSEG RC BLOCK ETC.
		MOVEI	R,2		;[1155] GET POINTER TO NEW RC BLOCK
		MOVE	R,@SG.TB	;[1155] ..
		MOVE	T1,RC.SET	;[1155] GET ATTRIBUTES
		TXZ	T1,AT.RP	;[1163] .HIGH. ALWAYS HAS AN ORIGIN
		MOVEM	T1,RC.AT(R)	;[1155] STORE
		POPJ	P,]		;[1155] RETURN
	SOSGE	RC.FRE		;ANY FREE SLOTS
	PUSHJ	P,.SETEX		;NO, ALL USED 
	AOS	RC.NO		;GET NEXT FREE
	MOVEI	T2,RC.INC	;SIZE WE WANT
	PUSHJ	P,DY.GET##	;GET IT
	MOVEM	T1,@RC.TB	;STORE POINTER
	MOVEM	T1,@RC.NTB	;[706] 
	MOVE	R,T1		;R POINTS TO RC BLOCK
	MOVEI	T1,1		;[1142] ALL PSECTS ARE IN THE LC AREA
	MOVEM	T1,RC.SG(R)	;[1132] SEGMENT NUMBER
SET4:	MOVE	T1,RC.SG(R)	;[1142] FETCH SEGMENT NUMBER
	EXCH	R,T1		;SWAP, PUT SEG # IN R
	MOVE	R,@SG.TB	;GET POINTER TO  RC TABLE (.LOW. OR .HIGH.)
	MOVE	T3,RC.AT(T1)	;[763]
	IOR	T3,RC.SET	;[763] ACCUMULATE THE ATTRIBUTES
	SKIPL	RC.SET		;[763] IF CURRENT ATTR INDICATED FIXED ORIGIN
	TXZ	T3,AT.RP	;[763] THAN CLEAR RELOC-PSECT BIT
	MOVEM	T3,RC.AT(T1)	;[763] UPDATE
	SKIPN	RC.NM(T1)	;SETTING UP A NEW RC?
	MOVEM	W3,RC.IV(T1)	;YES, SET INITIAL VALUE
	MOVEM	W2,RC.NM(T1)	;SET UP RC NAME
	MOVEM	W3,RC.CV(T1)	;ALSO CURRENT
	CAMLE	W3,RC.HL(T1)	;[1132] HIGHEST LOCATION SO FAR?
	MOVEM	W3,RC.HL(T1)	;[1132] YES, STORE IT
	MOVE	T2,RC.LB(R)	;BASE OF AREA
	MOVEM	T2,RC.LB(T1)
	DGET	T2,RC.WD(R),RC.PG(R)	;LOWER CORE WINDOW & UPPER CORE WINDOW
	DSTORE	T2,RC.WD(T1),RC.PG(T1)
	POPJ	P,
SETUND:	MOVEI	T1,[ASCIZ /SET:/] ;[1174] SIGNAL UNDEFINED SYMBOL ERROR
	PJRST	E$$USI		;[1174]   ..

E$$SRB::.ERR.	(MS,.EC,V%L,L%W,S%W,SRB,<Attempt to set relocation counter >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2)
	.ETC.	(STR,.EC,,,,,< below initial value of >)
	.ETC.	(OCT,.EC!.EP,,,,W1) ;[1174]
	.ETC.	(JMP,,,,,.ETIMF##) ;[1174]
	POPJ	P,		;IGNORE SWITCH

.SETEX::MOVE	T2,RC.NO	;GET NUMBER IN USE - 1
	ADDI	T2,RC.INC+1	;GET SOME MORE
	PUSH	P,T2		;[706]
	PUSHJ	P,DY.GET##	;[706] FROM FREE SPACE
	HRLZ	T3,RC.NTB	;[706] COPY FROM
	HRR	T3,T1		;[706] TO
	ADDI	T2,(T1)		;[706] LIMIT
	BLT	T3,-1-RC.INC(T2);[706]
	SUBI	T2,RC.INC(T1)	;[1107] GET OLD LENGTH
	MOVE	T3,RC.NTB	;[1107] CURRENT POSITION
	HRRM	T1,RC.NTB	;[1107] NEW
	HRRZ	T1,T3		;[1107] OLD
	PUSHJ	P,DY.RET	;[1107] RETURN SPACE
	POP	P,T2		;[706]
	PUSHJ	P,DY.GET##	;FROM FREE SPACE
	HRLZ	T3,RC.TB	;COPY FROM
	HRR	T3,T1		;TO
	ADDI	T2,(T1)		;LIMIT
	BLT	T3,-1-RC.INC(T2)
	SUBI	T2,RC.INC(T1)	;GET OLD LENGTH
	MOVE	T3,RC.TB	;CURRENT POSITION
	HRRM	T1,RC.TB	;NEW
	HRRZ	T1,T3		;OLD
	MOVEI	T3,RC.INC-1	;NUMBER NOW FREE
	MOVEM	T3,RC.FRE
	PJRST	DY.RET##	;RETURN SPACE
SUBTTL	SWITCH ACTION -- /SEVERITY:n, /START:n


%SEVERITY:
	MOVEM	T2,SEVLVL	;SAVE SEVERITY LEVEL
	POPJ	P,

.START:
	TLZ	FL,L.ISA	;BACK TO READING STARTING ADDRESSES

%START:
	TRZ	FL,R.ISA	;FOR THIS FILE ONLY
	JUMPE	T2,CPOPJ	;SPECIAL IF ADDRESS GIVEN
	CAIN	T2,.C		;CHECK FOR DEFAULT ARG
	POPJ	P,		;AND IGNORE IT
	SETZ	T3,		;[1175] ASSUME SYMBOL NAME IS ZERO
	TXNE	T2,77B5		;[1175] SYMBOL OR ADDRESS?
	EXCH	T2,T3		;[1175] SYMBOL, MAKE OFFSET BE ZERO
	DMOVEM	T2,STADDR	;[1175] STORE FOR END OF LOADING
	SETZM	STANAM		;[655] DON'T KNOW MODULE NAME
	PJRST	.NOSTART	;AND IGNORE ALL OTHER  STARTING ADDRESSES
SUBTTL	SWITCH ACTION -- /SYMSEG:name[:name], /SYSORT:key, /UPTO:n, /VERBOSITY:n


%SYMSEG:PUSHJ	P,STRLSW	;[705] WAIT TIL FILE LOADED
.SYMSEG:			;[705]
	CAIN	T2,$SSGDEFAULT	;[1201] /SYMSEG:DEFAULT?
	JRST	[SETZM	SYMSEG	;[1201] YES, DO IT
		POPJ	P,]	;[1201] GET OUT
IFN FTOVERLAY,<
	SKIPN	OVERLW		;[1176] USER TYPE /OVERLAY?
	JRST	%SYMSG		;[1176] NO, PROCEED
	CAIE	T2,$SSGLOW	;[1201] USER WANT LOW SEGMENT?
	CAIN	T2,$SSGNONE	;[1201] OR NO SYMBOLS?
	JRST	%SYMSG		;[1176] YES, ONLY POSSIBILITIES WITH OVERLAYS
E$$OSL::.ERR.	(MS,,V%L,L%W,S%W,OSL,<Overlaid program symbols must be in low segment>) ;[1174]
	MOVEI	T2,$SSGLOW	;[1201] PUT THEM IN LOW SEG
%SYMSG:>
	CAIN	T2,$SSGPSECT	;[1201] A PSECT SPECIFIED?
	JRST	SYMS1		;[721]
	MOVEM	T2,SYMSEG	;STORE INDEX TO EITHER LC OR HC
	CAIE	T2,$SSGHIGH	;[1201] WANT SYMBOLS IN HIGH SEGMENT?
	POPJ	P,		;[1201] NO, DONE
	SKIPE	HC.LB		;YES, IS IT SET UP YET?
	POPJ	P,		;ALL OK
	SETZ	W1,		;USE DEFAULT ORIGIN
	PUSHJ	P,.SAVE4##	;SAVE THE P'S
	PJRST	SETRC##		;AND SET UP THE HIGH SEGMENT

SYMS1:	SETOM	SYMSEG		;[721]
	MOVE	W2,3(P2)	;[721] GET PSECT NAME
	MOVEM	W2,SSGNAM	;[721] STORE IT AWAY
	POPJ	P,		;[721] RETURN

%SYSORT:
	JRST	@SYSTBL-1(T2)	;DISPATCH TO RIGHT FUNCTION
	POPJ	P,

%UPTO:
	MOVEM	T2,SYMLIM	;[723] SAVE SYMBOL TABLE UPPER LIMIT
	POPJ	P,		;[723]

%VERBOSITY:
	MOVE	T2,VERTBL-1(T2)	;GET VALUE
	MOVEM	T2,VERLVL	;SAVE VERBOSITY LEVEL
	POPJ	P,

$VERSHORT==V%S
$VERMEDIUM==V%M
$VERLONG==V%L
SUBTTL	SWITCH ACTION -- /UNDEFINED


%UNDEFINED:
	PUSHJ	P,STRLSW	;WAIT TIL AFTER FILE IS LOADED
.UNDEFINED:
	MOVE	T1,[PUSHJ P,UNDNXT] ;[1174] SET UP NEXT SYMBOL ROUTINE
	MOVEM	T1,NXTGLB	;[1174]   ..
	MOVE	W3,HT.PRM	;[1174] SET UP INDEX TO HASH TABLE
	ADDI	W3,1		;[1174] SET UP BY 1 FOR SOSGE BELOW
E$$UGS::.ERR.	(MS,.EC!.EN,V%L,L%F,S%I,UGS) ;[1174]
.ETUGS::.ETC.	(XCT,.EC,,,,<[PUSHJ P,UNDHDR]>) ;[1174] PRINT HEADER AND SEE IF ANY SYMBOLS
	  .ETC.	(JMP,.EC,,,,.ETDON##) ;[1174] NO UNDEFINED SYMBOLS
	.ETC.	(JMP,,,,,.ETSAV##) ;[1174] GO PRINT SYMBOLS AND VALUES


;UNDHDR  PRINTS THE APPROPRIATE HEADER FOR THE LNKUGS MESSAGE (EITHER NO, 1 OR N
;UNDEFINED GLOBALS).  THE CARDINALITY OF THE HEADER IS DETERMINED BY LOOKING  AT
;USYM,  WHICH  SOMETIMES  GETS OUT OF SYNC WITH THE ACTUAL GS TABLE.  BUT UNDNXT
;(BELOW) PRINTS ALL UNDEFINED GLOBALS REGARDLESS.

UNDHDR:	SKIPN	T1,USYM		;[1174] ANY SYMBOLS TO PRINT?
	JRST	UNDHD1		;[1174] NO--PRINT 'NO' INSTEAD OF '0'
	OUTVIA	.TDECW##	;[1174] PRINT NUMBER OF UNDEFINED GLOBALS
UNDHD1:	MOVE	T1,USYM		;[1174] GET NUMBER OF UNDEFS BACK
	CAILE	T1,2		;[1174] TURN MANY INTO 2 FOR HEADER MESSAGE
	MOVEI	T1,2		;[1174]   ..
	MOVE	T1,UNDTAB(T1)	;[1174] GET PROPER HEADER MESSAGE
	OUTVIA	.TSTRG##	;[1174] PRINT IT
	PJRST	UNDNXT		;[1174] RETURN, SETTING UP FIRST SYMBOL
;UNDNXT RETURNS THE NEXT UNDEFINED SYMBOL AND ITS VALUE.
;
;CALL:
;	W3/	NEXT HASH TABLE INDEX TO CHECK
;RETURNS  WITH  A  NON-SKIP RETURN IF NO MORE SYMBOLS. OTHERWISE, RETURNS WITH A
;SKIP RETURN WITH:
;	W1/	SIXBIT SYMBOL NAME
;	W2/	OCTAL VALUE
;	W3/	UPDATED

UNDNXT::PUSHJ	P,.SAVE4##	;[1174] SAVE LNKLOG'S P ACS
UGSLUP:	SOSGE	P2,W3		;[1174] ANY MORE SYMBOLS TO CHECK?
	POPJ	P,		;[1174] NO--NON-SKIP RETURN
	SKIPN	P3,@HT.PTR	;[1174] ANY SYMBOL HERE?
	JRST	UGSLUP		;[1174] NO--TRY NEXT
	ADD	P3,GS.LB	;[1174] YES--RELOCATE SO WE CAN LOOK AT IT
	MOVE	T1,0(P3)	;[1174] GET SYMBOL'S FLAGS
	TXNE	T1,PT.SYM	;[1174] MUST BE A SYMBOL AND UNDEFINED
	TXNN	T1,PS.UDF!PS.REQ;[1174]   ..
	JRST	UGSLUP		;[1174] NO--TRY NEXT
	MOVE	W1,1(P3)	;[1174] YES--A WINNER!! SET UP SYMBOL'S NAME
	MOVE	W2,2(P3)	;[1174]   AND VALUE
	JRST	CPOPJ1		;[1174] DONE--GIVE SKIP RETURN


UNDTAB:	[ASCIZ	/No undefined global symbols/]
	[ASCIZ	/ undefined global symbol/]
	[ASCIZ	/ undefined global symbols/]
SUBTTL	SWITCH ACTION -- /SYSLIBRARY, /NOSYSLIBRARY


%SYSLIBRARY:
	PUSHJ	P,STRLSW	;WAIT TIL FILE IS LOADED
.SYSLIBRARY:
	SOJE	T2,SYSLB1	;DEFAULT ACTION IF INDEX WAS 1
				;  LOAD FROM LIBRARIES AND RETURN
				;  FROM /SYSLIBRARY (SOJ/PJUMPE)
	MOVE	T1,LIBTBL(T2)	;GET REQUIRED BIT
	IORM	T1,LIBPRC	;[653] REMEMBER TO SEARCH THIS LIBRARY
	ANDCAM	T1,NOLIBS	;AND TURN OFF THIS BIT INCASE /NOSYSL
	POPJ	P,		;AND RETURN
				;WILL LOAD AT DEFAULT TIME

;ROUTINE TO CAUSE ALL SPECIFIED AND DEFAULT LIBRARIES
;TO BE SEARCHED, AND ANY MODULES WHICH MATCH TO BE LOADED.

;CALLED BY
;	PUSHJ	P,SYSLB1
;	RETURN

;NO PARAMETERS ARE PASSED OR RETURNED IN THE AC'S
;P1 THROUGH P4 ARE PRESERVED

SYSLB1::PUSHJ	P,.SAVE4##	;PRESERVE P1-P4
	PUSH	P,FL		;SAVE FLAGS
	PUSH	P,F.INZR	;AND CURRENT
	PUSH	P,F.NXZR	;AND PENDING FILE SPECS
	SETZM	F.INZR		;CLEAR LIST
	SETZM	F.NXZR		;SO WE JUST LOAD DEFAULTS
	PUSH	P,GOTO		;SAVE INCASE EOL SEEN
	PUSH	P,[LODTST##]	;FAKE RETURN TO LOAD ROUTINE
	PUSHJ	P,LIBRARY##	;LOAD DEFAULT LIBS
	POP	P,GOTO		;RESTORE EOL INTERCEPT
	POP	P,F.NXZR	;RESTORE PENDING FILE SPECS
	POP	P,F.INZR
	POP	P,FL		;AS WE WERE
	POPJ	P,

%NOSYSLIBRARY:
	SOSE	T2		;DEFAULT ACTION IF WAS 1
	SKIPA	T1,LIBTBL(T2)	;NO
	SETO	T1,		;YES, TURN THEM ALL OFF
	IORM	T1,NOLIBS	;DON'T WANT THESE DEFAULT LIBS
	POPJ	P,
SUBTTL	SWITCH ACTION -- /USERLIBRARY:key


%USERLIBRARY:
	MOVEI	T2,F.LEN	;SPACE TO STORE FILE SPEC
	PUSHJ	P,DY.GET##
	ADDI	T2,-1(T1)	;END OF BLT
	HRLZI	T3,1(P1)	;FROM
	HRRI	T3,1(T1)	;TO
	BLT	T3,(T2)		;ALL EXCEPT FIRST WORD
	SOS	T2,2(P2)	;GET TYPE (LESS 1)
	MOVEM	T2,1(T1)	;SAVE IN SWITCH FIELD
	EXCH	T1,USEPTR	;POINT TO LATEST ENTRY
	MOVEM	T1,@USEPTR	;AND LINK IT IN
ZFPOPJ:	HRLZI	T1,2(P1)
	HRRI	T1,3(P1)
	SETZM	2(P1)
	BLT	T1,F.LEN-1(P1)	;ZERO FILE SPEC
	POPJ	P,
SUBTTL	SWITCH ACTION -- /NOUSERLIBRARY


%NOUSERLIBRARY:
	MOVEI	T1,USEPTR	;START OF CHAIN
NOUSE1:	HRL	T1,T1		;SAVE LAST
	HRR	T1,(T1)		;GET NEXT
	TRNN	T1,-1		;0 IS END
	JRST	ZFPOPJ		;NOT FOUND
	SKIPN	F.NAME(P1)	;SPECIAL IF NO FILE NAME
	JRST	NOUSE3		;AS IT MEANS DELETE ALL
	DMOVE	T2,F.DEV(T1)	;GET DEV & FILE
	CAMN	T2,F.DEV(P1)
	CAME	T3,F.NAME(P1)
	JRST	NOUSE1		;NOT SAME
	MOVE	T2,F.EXT(T1)
	MOVE	T3,F.DIR(T1)
	CAMN	T2,F.EXT(P1)
	CAME	T3,F.DIR(P1)
	JRST	NOUSE1
	MOVEI	T3,F.DIR+2(T1)	;NOW FOR SFDS
	MOVEI	T4,F.DIR+2(P1)
	HRLI	T4,-5
NOUSE2:	MOVE	T2,(T3)
	CAME	T2,(T4)
	JRST	NOUSE1		;DIFFERENT
	ADDI	T3,2		;GET NEXT
	ADDI	T4,1
	AOBJN	T4,NOUSE2	;NOT YET DONE
	MOVE	T2,(T1)		;NOW REMOVE IT BUT FIRST
	MOVS	T1,T1		; LINK IN NEXT PTR
	MOVEM	T2,(T1)
	HLRZ	T1,T1
	MOVEI	T2,F.LEN
	PUSHJ	P,DY.RET##
	JRST	ZFPOPJ		;AND DELETE FILE SPEC

NOUSE3:	MOVE	T2,(T1)		;NOW REMOVE IT BUT FIRST
	MOVS	T1,T1		; LINK IN NEXT PTR
	MOVEM	T2,(T1)
	HLRZ	T1,T1
	MOVEI	T2,F.LEN
	PUSHJ	P,DY.RET##
	SKIPE	USEPTR		;ANY MORE?
	JRST	%NOUSERLIB	;YES
	JRST	ZFPOPJ		;NO, DELETE FILE SPEC
SUBTTL	SWITCH ACTION -- /VALUE:sym


;/VALUE:SYMBOL  PRINTS  THE  VALUE OF THE SYMBOL (IF IT HAS ONE YET), ALONG WITH
;SOME STATUS INFORMATION (E.G., COMMON).

%VALUE:
	PUSHJ	P,STRLSW	;WAIT TIL FILE LOADED
.VALUE:
	MOVX	W1,PT.SGN!PT.SYM	;SET FLAGS
	SKIPN	W2,T2		;[1174] SET UP SYMBOL FOR TRYSYM AND CHECK FOR 0
	JRST	E$$ZSV		;[1174] ZERO IS INVALID
	SETZ	W3,		;[605] VALUE 0 UNLESS LONG SYMBOL
E$$VAL::.ERR.	(MS,.EC,V%L,L%F,S%I,VAL,<Symbol >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2) ;[1174]
	.ETC.	(ASC,.EC,,,,.CHTAB) ;[1174]
	.ETC.	(XCT,,,,,<[PUSHJ P,VALOUT]>) ;[1174] THE REST IS COMPLEX
	POPJ	P,		;[1174] DONE
;VALOUT  IS  CALLED  FROM  THE  MIDDLE  OF  THE ABOVE .ERR. MESSAGE TO PRINT THE
;VARIABLE PORTION OF THE MESSAGE.

VALOUT:	PUSHJ	P,.SAVE4##	;[1174] SAVE LNKLOG'S P ACX
	PUSHJ	P,TRYSYM##	;SEE IF IN TABLE
	  JRST	VALOND		;[1174] SYMBOL NEVER DEFINED
	  JRST	VALOUN		;[1174] SYMBOL UNDEFINED
	MOVE	T1,2(P1)	;[1174] PRINT VALUE IN OCTAL
	OUTVIA	.TOCTW##	;[1174]   ..
	MOVE	T1,0(P1)	;[1174] CHECK FOR COMMON BLOCKS
	TXNE	T1,PS.COM	;[1174]   ..
	JRST	VALOCM		;[1174] GO PRINT LENGTH OF COMMON
	MOVEI	T1,[ASCIZ /	defined/] ;[1174] OTHERWISE JUST ORDINARY SYMBOL
VALOST:	OUTVIA	.TSTRG##	;[1174] PRINT STATUS OF SYMBOL
	POPJ	P,		;[1174] DONE

VALOCM:	MOVEI	T1,[ASCIZ /	common, length /] ;[1174] START STATUS OF SYMBOL
	OUTVIA	.TSTRG##	;[1174]   ..
	MOVE	T1,.L+2(P1)	;[1174] PRINT LENGTH IN DECIMAL
	OUTVIA	.TDECW##	;[1174]   ..
	MOVEI	T1,[ASCIZ /./]	;[1174] A DOT TO INDICATE DECIMAL
	PJRST	VALOST		;[1174] GO PRINT STATUS AND RETURN

VALOND:	MOVEI	T1,[ASCIZ /unknown/] ;[1174] HAVEN'T SEEN THE SYMBOL YET
	PJRST	VALOST		;[1174] GO PRINT STATUS AND RETURN

VALOUN:	MOVE	T1,2(P1)	;[1174] PRINT VALUE IN OCTAL
	OUTVIA	.TOCTW##	;[1174]   ..
	MOVEI	T1,[ASCIZ /	undefined/] ;[1174] ONLY SEEN REFERENCES SO FAR

	PJRST	VALOST		;[1174] GO PRINT STATUS AND RETURN
SUBTTL	SWITCH ACTION -- /VERSION:ver


%VERSION:
	PUSHJ	P,STRLSW	;[1122] WAIT TIL FILE INITED
.VERSION:
	MOVE	T2,2(P2)	;[1122] GET VALUE
	SKIPE	T1,IO.CHN	;[1122] GET CURRENT CHAN#
	CAIN	T1,DC		;[1122] IF 0 OR INPUT CHAN
	JRST	[MOVEM	T2,VERNUM	;[1122] STORE VERSION NUMBER
		POPJ	P,]		;[1122] IN CORE
	MOVE	T1,IO.PTR(T1)	;[1122] IF OUTPUT SPEC
	MOVEM	T2,I.VER(T1)	;[1122] SAVE IN DATA BLOCK
	POPJ	P,		;[1122] 
SUBTTL	SWITCH ACTION -- /SSAVE, /SAVE


IFN FTEXE,<
%SSAVE:	SKIPA T1,[0,,SS.SHR]
%SAVE:	SETZ	T1,
	MOVEM	T1,SSEXT
	PUSHJ	P,COPYP1	;MAKE A NEW DATA BLOCK
IFN TOPS20,<
	SKIPN	T1,F.EXT(P1)	;USER SUPPLY EXT?
> ;END IFN TOPS20
	MOVSI	T1,'EXE'	;NO, DEFAULT EXT
	HLLM	T1,SSEXT	;SAVE EXT
	HLLOM	T1,F.EXT(P1)	;UPDATE EXT
	MOVE	T1,F.NAME(P1)	;GET REAL NAME
	MOVEM	T1,SSNAME	;AND SAVE IT
	PUSHJ	P,DVOUT.##	;SET UP DATA BLOCK
	  %VC,,.IODPR		;USE DUMP MODE
	PJRST	RESTP1	;RETURN THIS BLOCK NOW
>;END OF IFN FTEXE

IFE FTEXE,<
%SAVE:
	MOVSI	T1,'HGH'	;STORE NON-SHARABLE EXTENSION
	JRST	SSAVE
%SSAVE:
	MOVSI	T1,'SHR'	;SHARABLE HIGH SEG EXT
SSAVE:	PUSHJ	P,COPYP1	;MAKE A NEW DATA BLOCK
	HLR	T1,F.EXT(P1)	;INCASE USER SUPPLIED LOW EXT
	MOVEM	T1,SSEXT	;SAVE REAL EXT FOR LATER
	HLLOM	T1,F.EXT(P1)	;STORE DEFAULT EXT
	MOVE	T1,F.NAME(P1)	;GET REAL NAME
	MOVEM	T1,SSNAME	;AND SAVE IT
	PUSHJ	P,DVOUT.##	;SETUP DATA BLOCK
	  %VC,,.IODPR		;USE DUMP MODE
	PJRST	RESTP1		;RETURN THIS BLOCK NOW
>;END OF IFE FTEXE
SUBTTL	SWITCH ACTION -- /SYFILE:key


%SYFILE:
	SKIPE	NOSYMS		;IF NOT WANTED
	PJRST	DEFRET		;DON'T DO IT
	PUSHJ	P,COPYP1	;MAKE A NEW DATA BLOCK
	MOVE	T1,SYMTBL-1(T2)	;GET FLAG
	MOVEM	T1,SYMFRM	;SHOW WHICH ONE
	MOVSI	T1,'SYM'	;FILE EXT
	MOVEM	T1,F.EXT(P1)
	PUSHJ	P,DVOUT.##	;SET UP DATA BLOCK
	  %SC,,.IODPR
	PJRST	RESTP1

$SYMRADIX50==-1
$SYMTRIPLET==+1
$SYMALGOL==+2
SUBTTL	SWITCH ACTION -- /XPN, /MAP:key


%XPN:
	PUSHJ	P,COPYP1	;MAKE A NEW DATA BLOCK
	MOVSI	T1,'XPN'	;EXPANDED SAVE FILE
	MOVEM	T1,F.EXT(P1)	;IE CORE IMAGE
	PUSHJ	P,DVOUT.##	;SETUP DATA BLOCK
	  %XC,,.IODPR
	PJRST	RESTP1

%MAP:
	PUSHJ	P,COPYP1	;MAKE A NEW DATA BLOCK
	MOVE	T1,MAPTBL-1(T2)	;GET CODE
	MOVEM	T1,MAPSW	;SAVE IT
	JUMPGE	T1,MAPOK	;-1 NOT YET AVAILABLE
E$$IMA::.ERR.	(MS,0,V%L,L%W,S%W,IMA,<Incremental maps not yet available>) ;[1174]
MAPOK:	MOVSI	T1,'MAP'	;DEFAULT EXT
	SKIPN	F.EXT(P1)	;ALREADY SET
	HLLOM	T1,F.EXT(P1)	;NO
	PUSHJ	P,DVOUT.##	;SET UP DATA BLOCK
	  MC,,.IOASC
	PJRST	RESTP1		;RETURN, BUT DON'T LOAD THIS FILE

;ROUTINE COPYP1 - COPIES THE DATA BLOCK POINTED TO BY P1 TO A NEW BLOCK
;STORES THE OLD P1 IN LH P1 AND NEW BLOCK PTR IN RH P1

COPYP1::PUSH	P,T1		;SAVE EXT
	PUSH	P,T2		;SAVE ARG
	MOVEI	T2,F.LEN	;LENGTH OF A DATA BLOCK
	PUSHJ	P,DY.GET##
	HRL	T1,P1		;FORM BLT PTR
	MOVE	P1,T1		;SETUP P1 TO SAVE OLD AND POINT TO NEW
	ADDI	T2,-1(T1)	;END OF BLT
	BLT	T1,(T2)		;COPY BLOCK
	POP	P,T2		;RESTORE ARG
	POP	P,T1		;...
	POPJ	P,

;ROUTINE RESTP1 - DELETES DATA BLOCK POINTED TO BY P1
;AND RESTORES THE OLD P1

RESTP1::HRRZ	T1,P1		;ADDRESS OF BLOCK
	MOVEI	T2,F.LEN	;LENGTH OF IT
	HLRZ	P1,P1		;RESTORE P1
	SETOM	NULSPC		;FAKE A NULL BLOCK (SAME AS DEFRET)
	PJRST	DY.RET##	;GIVE BACK AND RETURN
SUBTTL	SWITCH ACTION -- /LOG


%LOG:
	PUSHJ	P,.SAVE2##	;GET A SAFE AC BUT NOT P1
	PUSHJ	P,COPYP1	;MAKE A NEW DATA BLOCK
	SETZ	P2,		;ZERO IF NOT ALREADY A LOG FILE
	SKIPN	LOGSUB		;NON-ZERO IF LOG DEVICE OTHER THAN TTY
	SKIPE	LOGTTY		;OR TTY AS LOG
	SETO	P2,		;-1 FOR ALREADY A LOG DEV
	MOVSI	T1,'LOG'	;DEFAULT EXT
	SKIPN	F.EXT(P1)	;UNLESS ALREADY SET
	HLLOM	T1,F.EXT(P1)
	PUSHJ	P,DVOUT.##
	  %RC,,.IOASC
	PUSHJ	P,DVNAM.##	;MAKE SURE NAME IS SETUP
	SKIPL	LOGTTY		;IS CURRENT LOG DEVICE USERS TTY?
	JRST	LOG2		;NO
	MOVE	T1,IO.CHR	;GET DEVCHR WORD
	TXNN	T1,DV.TTA	;IS IT USERS TTY
	JRST	LOG1		;NO, TELL USER WHERE NEW LOG IS AT
LOG0:	MOVEI	T1,%RC		;DON'T NEED THIS BLOCK NOW
	MOVEM	T1,IO.CHN
	PUSHJ	P,DVZAP.##	;SO REMOVE IT
	JRST	RESTP1		;AND RETURN

LOG1:	PUSHJ	P,E$$CLF	;[1174] OUTPUT INFO MESSAGE
	SETZM	LOGTTY		;CLEAR IT
	HLRZ	T1,LOWSUB	;GET LOG SUB ADDRESS
	MOVEM	T1,LOGSUB	;POINT TO IT
	PUSHJ	P,.TYOCH##	;INITIALIZE
	JRST	LOG4		;AND DO REST OF SETUP

LOG2:	MOVE	T1,IO.CHR	;DEVCHR WORD FOR NEW LOG DEV
	TXNN	T1,DV.TTA	;WANTS TTY FOR LOG?
	JRST	LOG3		;NO
	PUSHJ	P,DVCHN.##	;POINT T1 TO DATA BLOCK
	SETZM	I.EXT(T1)	;CLEAR .LOG EXT FOR MESSAGE
	SKIPE	P2		;IF THERE WAS ALREADY A LOG FILE
	PUSHJ	P,LOG5		; GIVE MESSAGE
	SETZM	LOGSUB		;CLEAR OLD LOG OUTPUT ROUTINE
	SETOM	LOGTTY		;SIGNAL TO USE TTY
	HRRZ	T1,LOWSUB	;GET IT
	PUSHJ	P,.TYOCH##	;INITIALIZED
	JUMPL	P2,E$$LFC	;[1174] BEEN INITIALIZED ONCE
E$$LFI::.ERR.	(MS,0,V%L,L%I,S%I,LFI,<Log file initialization>) ;[1174]
	PJRST	LOG0		;AND REMOVE DATA BLOCK

E$$LFC::.ERR.	(MS,0,V%L,L%I,S%I,LFC,<Log file continuation>) ;[1174]
	PJRST	LOG0
LOG3:	SKIPN	IO.PTR+RC	;ALREADY A LOG FILE?
	JRST	LOG4		;NO
	MOVE	T1,IO.PTR+RC	;YES, GET CURRENT PTR
	MOVE	T2,IO.PTR+%RC	;AND NEW PTR
	MOVE	T3,I.DEV(T2)	;GET DEVICE
	CAMN	T3,I.DEV(T1)	;SEE IF SAME
	JRST	RESTP1		;YES, DO RENAME AT END
	MOVE	T4,I.DEV(T1)	;NOW TRY PHYSICAL NAMES
	DEVNAM	T3,		;SINCE LOGICAL = PHYSICAL IS OK
	  JRST	LOG4A		;UUO FAILED
	DEVNAM	T4,
	  JRST	LOG4A
	CAME	T3,T4		;DO WE NOW MATCH?
	JRST	LOG4A		;NO
	MOVE	T3,I.DEV(T1)	;MAKE DEVICES THE SAME
	MOVEM	T3,I.DEV(T2)	;FOR RENAME CODE
	JRST	RESTP1		;AND DO IT LATER

LOG4A:	PUSHJ	P,LOG5		;OUTPUT MESSAGE AND DELETE I/O BLOCK
LOG4:	MOVE	T1,IO.PTR+%RC	;GET NEW PTR
	MOVEM	T1,IO.PTR+RC
	SETZM	IO.PTR+%RC
	MOVSI	T2,(Z RC,)	;GET CHAN#
	MOVEM	T2,I.CHN(T1)
	MOVEI	T1,RC		;SETUP AGAIN
	MOVEM	T1,IO.CHN
	PUSHJ	P,DVCHK.##	;GET DEVCHR WORD
	PUSHJ	P,DVOPN.##	;OPEN
	PUSHJ	P,DVENT.##	;ENTER FILE NAME
	HLRZ	T1,LOWSUB	;GET ADDRESS OF OUTPUT ROUTINE
	MOVEM	T1,LOGSUB	;SAVE IT FOR LOG FILE
	PUSHJ	P,.TYOCH##	;LET SCAN KNOW
	JUMPL	P2,E01LFC	;[1174] BEEN INITIALIZED
E01LFI::.ERR.	(MS,0,V%L,L%I,S%I,LFI) ;[1174]
	JRST	RESTP1		;AND RETURN

E01LFC::.ERR.	(MS,0,V%L,L%I,S%I,LFC) ;[1174]
	PJRST	RESTP1

LOG5:	PUSHJ	P,E$$CLF		;[1174] OUTPUT MESSAGE
	RELEASE	RC,
	MOVEI	T1,RC
	MOVEM	T1,IO.CHN	;FOR I/O ROUTINES
	PJRST	DVZAP.##	;REMOVE ALL TRACES OF IT

E$$CLF::.ERR.	(MS,.EC,V%L,L%I,S%I,CLF,<Closing log file, continuing on file >) ;[1174]
	.ETC.	(FSP,,,,,%RC)
	POPJ	P,
SUBTTL	SWITCH ACTION -- /BACKSPACE, /REWIND


.BACKSPACE:
	PUSHJ	P,STRGSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/BACKSPACE/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,.MTBSF.	;FORM INST
	MOVE	T2,2(P2)	;GET REPEAT COUNT (VALUE)
	PUSHJ	P,CHKLSW	;SEE IF CHAN OPEN
	XCT	T1		;BACKSPACE 1 FILE
	SOJG	T2,.-1
	PJRST	MTAPE0

%BACKSPACE:
	PUSHJ	P,STRLSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/BACKSPACE/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,.MTBSF.	;FORM INST
	MOVE	T2,2(P2)	;GET REPEAT COUNT (VALUE)
	PUSHJ	P,CHKRSW	;SEE IF CHAN OPEN
	XCT	T1		;BACKSPACE 1 FILE
	SOJG	T2,.-1		;LOOP, ALWAYS DO ONCE
	PJRST	MTAPE0		;WAIT FOR POSITIONING TO FINISH

.REWIND:
	PUSHJ	P,STRGSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/REWIND/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,.MTREW.	;FORM INST
	SETZ	T2,
	PUSHJ	P,CHKLSW
	XCT	T1		;REWIND
	JRST	MTAPE0		;WAIT FOR POSITIONING TO FINISH

%REWIND:
	PUSHJ	P,STRLSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/REWIND/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,.MTREW.	;FORM INST
	SETZ	T2,
	PUSHJ	P,CHKRSW
	XCT	T1		;REWIND
	JRST	MTAPE0		;WAIT FOR POSITIONING TO FINISH
SUBTTL	SWITCH ACTION -- /SKIP, /UNLOAD


.SKIP:
	PUSHJ	P,STRGSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/SKIP/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,.MTSKF.	;FORM INST
	MOVE	T2,2(P2)	;GET REPEAT COUNT (VALUE)
	PUSHJ	P,CHKLSW
	XCT	T1		;SKIP 1 FILE
	SOJG	T2,.-1		;LOOP, ALWAYS DO ONCE
	JRST	MTAPE0		;WAIT FOR POSITIONING TO FINISH

%SKIP:
	PUSHJ	P,STRLSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/SKIP/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,.MTSKF.	;FORM INST
	MOVE	T2,2(P2)	;GET REPEAT COUNT (VALUE)
	PUSHJ	P,CHKRSW
	XCT	T1		;SKIP 1 FILE
	SOJG	T2,.-1		;LOOP, ALWAYS DO ONCE
	JRST	MTAPE0		;WAIT FOR POSITIONING TO FINISH

%UNLOAD:
	PUSHJ	P,STRLSW	;WAIT TIL FILE INITED (AFTER FILE ONLY)
	MOVEI	T2,[ASCIZ	/UNLOAD/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,.MTUNL.	;FORM INST
	SETZ	T2,
	PUSHJ	P,CHKRSW
	XCT	T1		;UNLOAD FILE
	POPJ	P,
SUBTTL	SWITCH ACTION -- /MTAPE:key


.MTAPE:
	PUSHJ	P,STRGSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/MTAPE/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	MOVE	T2,2(P2)	;GET KEYWORD VALUE
	IOR	T1,MTPTBL-1(T2)	;GET FUNCTION
	SETZ	T2,
	PUSHJ	P,CHKLSW
	XCT	T1		;MTAPE CH,#
	JRST	MTAPE0

%MTAPE:
	PUSHJ	P,STRLSW	;WAIT TIL FILE INITED
	MOVEI	T2,[ASCIZ	/MTAPE/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	MOVE	T2,2(P2)	;GET KEYWORD VALUE
	IOR	T1,MTPTBL-1(T2)	;GET FUNCTION
	SETZ	T2,
	PUSHJ	P,CHKRSW
	XCT	T1		;MTAPE CH,#
MTAPE0:	HRRI	T1,0		;MTWAT.
	XCT	T1		;WAIT FOR POSITIONING TO FINISH
	POPJ	P,

;TABLE OF MTAPE FUNCTIONS
DEFINE KEYMAC (A,B)<
 IFIDN <A><MTP>,<
  IRP B,<
   .'B:	EXP B
>>>

	XALL
MTPTBL:	KEYWORDS
	SALL
SUBTTL	SWITCH ACTION -- /ZERO


%ZERO:
	PUSHJ	P,STRGSW	;WAIT TIL FILE INITED (BEFORE FILE ONLY)
	MOVEI	T2,[ASCIZ	/ZERO/]
	PUSHJ	P,DNSCHK	;GET CHAN#
	IOR	T1,[UTPCLR]	;FORM INST
	SETZ	T2,
	PUSHJ	P,CHKLSW
	XCT	T1		;ZERO DIRECTORY (DTA ONLY)
	POPJ	P,

DNSCHK:	SKIPN	T1,IO.CHN	;GET LAST CHAN#
	JRST	E$$DNS		;[1174] NO CHAN# NO DEVICE!
	MOVE	T1,IO.PTR(T1)	;POINT TO DATA BLOCK
	MOVE	T1,I.SCN(T1)	;GET SCAN MODIFIER WORD
	TXNE	T1,FX.NDV	;SEE IF DEVICE SPECIFIED
	JRST	E$$DNS		;[1174] NO, DON'T ALLOW DSK BY DEFAULT
	HRLZ	T1,IO.CHN	;GET LAST I/O CHAN INITED
	LSH	T1,5		;INTO AC FIELD
	POPJ	P,		;RETURN WITH CHAN# SETUP IN T1

E$$DNS::.ERR.	(MS,.EC,V%L,L%F,S%F,DNS,<Device not specified for switch />) ;[1174]
	.ETC.	(STR,.EP,,,,T2)
CHKLSW:	MOVE	T3,IO.CHN	;GET CHAN
	SKIPL	IO.PTR(T3)	;NOT INITED YERT
	POPJ	P,		;YES, JUST RET
	PUSH	P,T2		;STACK
	PUSH	P,T1
	MOVEI	T2,3		;NEED 3 WORDS
	PUSHJ	P,DY.GET##
	POP	P,1(T1)		;STACK UUO
	POP	P,2(T2)		;STACK COUNT
	MOVE	T2,IO.CHN	;SEE WHO FOR
	MOVE	T2,IO.PTR(T2)
	MOVE	T3,I.SWT(T2)	;GET SWITCHES TO DO
	TLNN	T3,-1
	JRST	[HRLM	T1,I.SWT(T2)
		JRST	POPJP]
	HLRZ	T2,T3		;ALREADY SWITCHES TO DO
	MOVE	T3,(T2)		;GET END OF LIST
	TLNE	T3,-1
	JRST	.-3		;NOT YET
	MOVEM	T1,(T2)
POPJP:	POP	P,(P)
	POPJ	P,

CHKRSW:	MOVE	T3,IO.CHN	;GET CHAN
	SKIPL	IO.PTR(T3)	;NOT INITED YET
	POPJ	P,
	PUSH	P,T2		;STACK
	PUSH	P,T1
	MOVEI	T2,3		;NEED 3 WORDS
	PUSHJ	P,DY.GET##
	POP	P,1(T1)		;STACK UUO
	POP	P,2(T2)		;STACK COUNT
	MOVE	T2,IO.CHN	;SEE WHO FOR
	MOVE	T2,IO.PTR(T2)
	MOVE	T3,I.SWT(T2)	;GET SWITCHES TO DO
	TRNN	T3,-1
	JRST	[HRRM	T1,I.SWT(T2)
		JRST	POPJP]
	HRRZ	T2,T3		;ALREADY SWITCHES TO DO
	MOVE	T3,(T2)		;GET END OF LIST
	TRNE	T3,-1
	JRST	.-3		;NOT YET
	MOVEM	T1,(T2)
	JRST	POPJP
SUBTTL	DISPATCH TABLE FOR KEY WORDS


DEFINE KEYTBL (K)<
 IRP K,<
  DEFINE KEYMAC (A,B)<
   IFIDN <K><A>,<
    IRP B,<			;GET FIRST AS DEFAULT
     EXP $'A'B			;START TABLE
     STOPI			;RESET
    >
    A'TBL:
    IRP B,<
     EXP $'A'B
  >>>
  KEYWORDS
>>

XALL
KEYTBL	<CPU,DEF,HYL,MAP,MPS,SYM,SYS,VER>
SALL

DEFINE X(A,B,C)<
	EXP	$LIB'B
>
	XALL			;[1203] EXPAND LISTING
	EXP	$LIBDEFAULT	;[1203] -1 ENTRY
LIBTBL:	PROCESSORS		;[1203] GET LIB TABLE
	SALL			;[1203] BACK TO NORMAL

$LIBANY==$LIBDEFAULT
SUBTTL	SWITCH ACTION -- /CONTENTS:key


%CONTENT:
	CAIN	T2,1		;DEFAULT VALUE?
	JRST	[MOVE	T1,CONTAB	;YES, GET IT
		MOVEM	T1,MAPCON	;SET IT
		POPJ	P,]		;AND RETURN
	ROT	T2,-1		;CUT IN HALF
	MOVE	T1,CONTAB(T2)	;GET SWITCH TO CHANGE
	JUMPL	T2,[ANDCAM T1,MAPCON	;UNSET
		POPJ	P,]
	IORM	T1,MAPCON	;SET
	POPJ	P,

DEFINE  KEYMAC (A,B)<
 IFIDN <A><CON>,<
  IRP B,<
   IFN %%&1,<
    C%'B
   >
   %%==%%+1
>>>

	%%==0			;INITIAL VALUE
	XALL
CONTAB:	C%DEFAULT		;DEFAULT VALUE IS FIRST
	KEYWORDS

	SALL
	PURGE	%%
SUBTTL	SWITCH ACTION -- /DEFAULT


;NOTE: THIS SWITCH MUST BE LAST EXECUTED
;IF IT IS NOT, RECHAIN SWITCHES SO THAT IT IS
;DEFERED SWITCHES WILL NOT BE EXECUTED
;THEREFORE /SKIP ETC. WILL HAVE NO EFFECT
;CONTROL FINALLY RETURNS TO LNKFIO TO GET NEXT FILE SPEC.

.DEFAULT:
	POP	P,T1		;REMOVE RETURN ADDRESS
	HRRZ	T2,(P2)		;GET NEXT LINK
	HRLM	T2,F.SWP(P1)	;LINK IN
	EXCH	P2,T2		;SETUP TO XCT NEXT SWITCH
	HLLZS	(T2)		;CLEAR LINK ADDRESS
	MOVEI	T3,F.SWP(P1)	;ADDRESS OF RIGHT HALF CHAIN
	MOVE	T1,T3		;SAVE LAST
	HRRZ	T3,(T1)		;GET NEXT ADDRESS
	JUMPN	T3,.-2		;LOOP TIL END OF CHAIN
	HRRM	T2,(T1)		;LINK IN
	JUMPN	P2,XCTGSW	;XCT NEXT GLOBAL SWITCH IF ANY
	POPJ	P,		;OTHERWISE RETURN

%DEFAULT:
	POP	P,T1		;REMOVE RETURN ADDRESS
	HRRZ	T2,(P2)		;GET NEXT ADDRESS IN CHAIN
	HRRM	T2,F.SWP(P1)	;LINK IN
	JUMPE	T2,DEFAULT	;LAST IF ZERO
	EXCH	P2,T2		;SETUP TO XCT NEXT SWITCH
	HLLZS	(T2)		;CLEAR LINK ADDRESS
	HRRZ	T3,P2		;GET CURRENT LINK ADDRESS
	MOVE	T1,T3		;SAVE LAST
	HRRZ	T3,(T1)		;GET NEXT ADDRESS
	JUMPN	T3,.-2		;LOOP TIL END OF CHAIN
	HRRM	T2,(T1)		;LINK LAST IN
	JRST	XCTLSW		;AND XCT FIRST SWITCH IN CHAIN

DEFAULT:
	MOVE	T2,2(P2)	;LOAD T2 FROM VALUE AGAIN
	JRST	@DEFTBL-1(T2)	;DISPATCH TO RIGHT FUNCTION
;DEFAULT

$DEFINPUT:
	HLLZM	FL,FLAGS	;SAVE AS DEFAULT GLOBAL FLAGS
	MOVE	T2,F.MOD(P1)	;GET MODIFIER WORD
	MOVE	T1,F.DEV(P1)	;GET NEW DEVICE
	TXNN	T2,FX.NDV	;IGNORE NULL DEVICE (DSK BY DEFAULT)
	MOVEM	T1,G.DEV
	SKIPN	T1,F.NAME(P1)	;NEW FILE?
	JRST	.+4		;NO
	MOVEM	T1,G.NAM
	MOVE	T1,F.NAMM(P1)	;AND MASK
	MOVEM	T1,G.NAMM
	MOVE	T1,F.EXT(P1)	;EXT AND MASK
	TXNN	T2,FX.NUL	;IGNORE NULL BUT  SET ZERO IF FILE.
	MOVEM	T1,G.EXT
	SKIPN	T1,F.BFR(P1)	;/BEFORE?
	MOVEM	T1,G.BFR
	SKIPN	T1,F.SNC(P1)	;/SINCE
	MOVEM	T1,G.SNC
	TXNN	T2,FX.DIR	;DIRECTORY
	JRST	[MOVE	T2,F.MODM(P1)	;NO, BUT MIGHT BE [-]
		TXNN	T2,FX.DIR	;IF THIS BIT SET
		JRST	DEFRET		;NO, LEAVE [DIR] AS IT WAS
		SETZM	G.DIR		;CLEAR FIRST WORD
		MOVE	T1,[G.DIR,,G.DIR+1]
		JRST	DFIBLT]		;AND FULL PATH
	MOVE	T1,F.DIR(P1)	;GET PROPOSED PPN
	TLNN	T1,-1		;PROJECT SPECIFIED?
	HLL	T1,MYPPN	;NO, USE DEFAULT
	TRNN	T1,-1		;PROGRAMMER?
	HRR	T1,MYPPN	;NO, DEFAULT IT.
	MOVEM	T1,F.DIR(P1)	;AND RESTORE PROPOSED PPN
	MOVSI	T1,F.DIR(P1)	;FROM ...
	HRRI	T1,G.DIR	;...TO
DFIBLT:	BLT	T1,G.DIR+2*LN.DRB-1	;UNTIL
	JRST	DEFRET		;ALL DONE
$DEFOUTPUT:
	MOVE	T2,F.MOD(P1)	;GET MODIFIER WORD
	MOVE	T1,F.DEV(P1)	;GET NEW DEVICE
	TXNN	T2,FX.NDV	;IGNORE NULL DEVICE (DSK BY DEFAULT)
	MOVEM	T1,O.DEV
	SKIPN	T1,F.NAME(P1)	;NEW FILE?
	JRST	.+4		;NO
	MOVEM	T1,O.NAM
	MOVE	T1,F.NAMM(P1)	;AND MASK
	MOVEM	T1,O.NAMM
	MOVE	T1,F.EXT(P1)	;EXT AND MASK
	TXNN	T2,FX.NUL	;IGNORE NULL BUT  SET ZERO IF FILE.
	MOVEM	T1,O.EXT
	SKIPN	T1,F.BFR(P1)	;/BEFORE?
	MOVEM	T1,G.BFR
	SKIPN	T1,F.SNC(P1)	;/SINCE
	MOVEM	T1,G.SNC
	TXNN	T2,FX.DIR	;DIRECTORY
	JRST	[MOVE	T2,F.MODM(P1)	;NO, BUT MIGHT BE [-]
		TXNN	T2,FX.DIR	;IF THIS BIT SET
		JRST	DEFRET		;NO, LEAVE [DIR] AS IT WAS
		SETZM	O.DIR		;CLEAR FIRST WORD
		MOVE	T1,[O.DIR,,O.DIR+1]
		JRST	DFOBLT]		;AND FULL PATH
	MOVE	T1,F.DIR(P1)	;GET PROPOSED PPN
	TLNN	T1,-1		;PROJECT SPECIFIED?
	HLL	T1,MYPPN	;NO, USE DEFAULT
	TRNN	T1,-1		;PROGRAMMER?
	HRR	T1,MYPPN	;NO, DEFAULT IT.
	MOVEM	T1,F.DIR(P1)	;AND RESTORE PROPOSED PPN
	MOVSI	T1,F.DIR(P1)	;FROM ...
	HRRI	T1,O.DIR	;...TO
DFOBLT:	BLT	T1,O.DIR+2*LN.DRB-1	;UNTIL
;	JRST	DEFRET		;ALL DONE

DEFRET:	SETOM	NULSPC		;FAKE NULL BLOCK
	POPJ	P,		;RETSPC WILL RETURN IT
SUBTTL	MAP SORTING


$MPSALPHABETICAL:
$MPSNUMERICAL:
E$$MSN::.ERR.	(MS,0,V%L,L%W,S%W,MSN,<Map sorting not yet implemented>) ;[1174]
$MPSUNSORTED:
	POPJ	P,

;SYMBOL SORTING
$SYSALPHABETICAL:
$SYSNUMERICAL:
E$$SSN::.ERR.	(MS,0,V%L,L%W,S%W,SSN,<Symbol table sorting not yet implemented>) ;[1174]
$SYSUNSORTED:
	POPJ	P,
SUBTTL	ERROR MESSAGES


E$$ZSV::.ERR.	(MS,0,V%L,L%W,S%W,ZSV,<Zero switch value illegal>) ;[1174]
	POPJ	P,

E$$USI::.ERR.	(MS,.EC,V%L,L%F,S%B,USI,<Undefined symbol >) ;[1174]
	.ETC.	(SBX,.EC!.EP,,,,W2) ;[1174]
	.ETC.	(STR,.EC,,,,,< illegal in switch />) ;[1174]
	.ETC.	(STR,.EP,,,,T1) ;[1174]
	POPJ	P,		;[1174] RETURNS IF NOT BATCH
SUBTTL	THE END


WLDLIT:	END