Google
 

Trailing-Edge - PDP-10 Archives - BB-H138C-BM - language-sources/ovrlay.mac
There are 38 other files named ovrlay.mac in the archive. Click here to see a list.
TITLE	OVRLAY - OVERLAY HANDLER FOR LINK
SUBTTL	D.M.NIXON/DMN/JLd/JNG/MCHC/DZN/PAH	2-Feb-81


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



CUSTVR==0		;CUSTOMER VERSION
DECVER==5		;DEC VERSION
DECMVR==0		;DEC MINOR VERSION
DECEVR==101		;DEC EDIT VERSION



ENTRY	.OVRLA,.OVRLU
INTERN	%OVRLA

%OVRLA==<BYTE(3)CUSTVR(9)DECVER(6)DECMVR(18)DECEVR>

COMMENT	\
THIS ROUTINE PRESERVES ALL ACCS EXCEPT 0 AND 1 WHICH IT DESTROYS FREELY.
\


SEARCH	OVRPAR			;OVERLAY FILE DEFINITIONS
SALL
SUBTTL	TABLE OF CONTENTS


;                    Table of Contents for OVRLAY
;
;
;                             Section                             Page
;
;   1  TABLE OF CONTENTS ........................................   2
;   2  FEATURE TEST SWITCHES ....................................   3
;   3  REVISION HISTORY .........................................   4
;   4  DEFINITIONS
;        4.1  Accumulators ......................................   8
;        4.2  Macros
;             4.2.1  SEGMENT, SPUSH, SPOP, CALL .................   9
;             4.2.2  Type-out ...................................  10
;        4.3  OPDEFs ............................................  11
;   5  PRINCIPLE ENTRY POINT ....................................  12
;   6  RESTART PROCEDURE ........................................  13
;   7  READ PREAMBLE ............................................  16
;   8  CHECK PATH
;        8.1  Determine Links To Delete .........................  17
;        8.2  Delete Old Links ..................................  19
;        8.3  'Other' Relocation And Symbols ....................  20
;        8.4  Move Symbols Down .................................  21
;        8.5  Read In DDT Symbols ...............................  23
;   9  MOVE SYMBOL TABLE UP .....................................  26
;  10  GIVE BACK LINK ...........................................  28
;  11  GIVE BACK SYMBOLS ........................................  31
;  12  GET NEW LINK .............................................  32
;  13  MULTIPLY-DEFINED ENTRY POINTS ............................  35
;  14  RELOCATE LINK ............................................  37
;  15  OTHER RELOCATION .........................................  39
;  16  OVERLAY INITIALIZATION
;       16.1  OVINI - Zero Memory And Get Parameters ............  41
;  17  FILE ROUTINES
;       17.1  TOPS-10
;            17.1.1  Overlay And Temp Files
;                 17.1.1.1  Initialization ......................  48
;                 17.1.1.2  I/O .................................  50
;                 17.1.1.3  Argument Blocks .....................  52
;            17.1.2  Error Messages .............................  54
;            17.1.3  Log File
;                 17.1.3.1  Initialization ......................  56
;                 17.1.3.2  I/O .................................  57
;                 17.1.3.3  Argument Blocks .....................  60
;       17.2  TOPS-20
;            17.2.1  Overlay And Temp Files
;                 17.2.1.1  Initialization ......................  61
;                 17.2.1.2  I/O .................................  62
;                 17.2.1.3  Argument Blocks .....................  64
;                 17.2.1.4  Error Messages ......................  65
;            17.2.2  Log File
;                 17.2.2.1  Initialization ......................  67
;                 17.2.2.2  I/O .................................  68
;                 17.2.2.3  Closing .............................  69
;  18  MANUAL CALL SUBROUTINES
;       18.1  INIOV. - Initialize The Overlay File ..............  70
;       18.2  GETOV. - Get A Link And All Of Its Superiors ......  71
;       18.3  REMOV. - Remove A Link And All Inferiors ..........  72
;       18.4  RUNOV. - Run An Overlay Link ......................  73
;       18.5  SAVOV. - Mark A Link To Be Writable ...............  74
;       18.6  CLROV. - Mark A Link To Not Be Writable ...........  75
;       18.7  LOGOV. - Manipulate The Log File ..................  76
;  19  SUBROUTINES
;       19.1  GETNUM - Get Link Number From Name Or Number ......  78
;       19.2  GETSPC - Convert String Into FILOP. Block .........  81
;       19.3  GETSBX - Convert To SIXBIT, GETOCT - Convert To Octal  83
;       19.4  GETCUR - Get Link Information Of Caller ...........  84
;       19.5  INCORE, WRTPTR ....................................  85
;       19.6  GETJOB - Get Job Number For Temporary File Name ...  86
;       19.7  CHKDDT - Update Symbol Table Pointers On TOPS-20 ..  87
;  20  MESSAGE HANDLING
;       20.1  Miscellaneous Messages ............................  88
;       20.2  FAIL, WARN, INFO ..................................  91
;       20.3  .OVRLU - Undefined Subroutine Entry ...............  92
;       20.4  PRNFSP - Print A File Specification ...............  93
;       20.5  PRNLNK, PRNSBX ....................................  97
;       20.6  PRNDEC, PRNOCT - Print Numbers ....................  98
;       20.7  PRNTXT, PRNFRS ....................................  99
;       20.8  PRNTIM - Print Runtime ............................ 100
;  21  ERROR MESSAGES (TEXT) .................................... 101
;  22  DATA AREAS ............................................... 102
;  23  THE END .................................................. 104
SUBTTL	FEATURE TEST SWITCHES


COMMENT \	STANDARD DEC SETTING

TOPS20==0			;-1 = TOPS-20 VERSION
FT2SEG==-1			;-1 = TWO SEGMENT VERSION
FTRELOC==-1			;-1 = RELOCATABLE OVERLAYS
FTMANUAL==-1			;-1 = MANUAL OVERLAY CALLS
FTLOG==-1			;-1 = LOG FILE CAPABILITY
FTSFD==5			;   = LENGTH OF SFDS ALLOWED
\

IFNDEF	TOPS20,<TOPS20==0>
IFNDEF	FT2SEG,<FT2SEG==-1>
IFNDEF	FTRELOC,<FTRELOC==-1>
IFNDEF	FTLOG,<FTLOG==-1>
IFNDEF	FTMANUAL,<FTMANUAL==-1>
IFNDEF	FTSFD,<FTSFD==5>

IFE TOPS20,<SEARCH MACTEN, UUOSYM>	;GET STANDARD DEFINITIONS
IFN TOPS20,<SEARCH MACSYM, MONSYM>	;GET STANDARD DEFINITIONS
SUBTTL	REVISION HISTORY


;START OF VERSION 1
;1	INITIAL VERSION
;2	ADD FUNCTION CALLS TO RNT, IFS & CBC
;3	FIX VARIOUS BUGS IN MANUAL CALLS
;4	MAKE IT REENTRANT (TWO SEGMENT VERSION)
;5	REDUCE SIZE OF OVERHEAD TABLES
;6	SUPPORT DDT SYMBOLS

;START OF VERSION 1A
;7	JLd	17-Jan-75	SPR 10-14994
;	Fix explicit calls to initialize the overlay list
;	when necessary.

;10	CHANGE GETCUR TO USER PC OF PUSHJ RATHER THAN ADDRESS OF ARGBLOCK
;	THIS IS FOR COBOL WHICH CONSTRUCTS ARG BLOCK IN LIBOL

;11	JLd	26-Mar-75	SPR 10-15706
;	Make relocatable overlays work with all multiple calls:
;	Unrelocate EXTTAB when the overlay is removed.

;12	JLd	27-Mar-75	SPR 10-15706
;	Cause the symbol table to be kept even if core must
;	be expanded.

;13	JNG	26-Jun-75	SPR 10-16380
;	Move symbol table before getting core for an absolute link
;	to avoid problems when trying to move up the symbols.

;14	JNG	27-Jun-75
;	Fix bug introduced by edit 10.  Clean up some code.

;15	JNG	29-Jun-75
;	Edit 11 inserted an instruction into the range of a
;	JUMPN T2,.-3  ... oops!!!

;16	JNG	2-Jul-75	SPR 10-15993
;	Try harder to shrink when we have more core than we need.

;17	JNG	5-Aug-75	SPR 10-15734
;	Reset ADDCOR and SIZCOR after calling MOVSYM,
;	which destroys them.

;START OF VERSION 1B
;20	JNG	8-Oct-75
;	If a manual call comes from the high segment, pretend it is
;	from the ROOT so COBDDT will work properly.

;START OF VERSION 2 (TOPS-20 ONLY)
;21	DMN	13-Nov-75
;	Make overlays work on TENEX
;START OF VERSION 2C -- FROM NOW ON, MAJOR & MINOR VERSIONS SAME AS LINK
;22	JNG	10-Feb-76
;	Make OVRLAY's version correspond to LINK. Clean
;	up the listing. Fix a minor bug in edit 21.

;23	JNG	10-Feb-76	SPR 18030
;	Make sure we have CORE before reading in a relocatable overlay
;	into other than its intended address and symbols are in core.

;24	JNG	10-Feb-76	SPR 18030
;	Try harder to keep symbols in core when debugging, even if
;	this means expanding core.

;25	JNG	22-Feb-76	SPR 18572
;	Fix some minor bugs in non-TTY log file handling, and in the
;	INIOVL manual call subroutine.

;		Edits 26 and 27 were not used

;START OF VERSION 3A
;30	JNG	20-Jun-76
;	Release on both TOPS-10 and TOPS-20 as OVRLAY version 3A(30)

;START OF VERSION 4
;31	JNG	27-Feb-77	SPR 10-21893
;	Allow a call to INIOVL with no args to just read in the
;	symbol table & do other initialization that is not normally
;	done until the first overlay is read in.

;32	JNG	10-Apr-77
;	Keep the symbol table up to date always if symbols are
;	available due to load-time switches.  Never look at the
;	initial .JBSYM or .JBDDT to decide what to do.

;33	JNG	10-Apr-77	SPR 10-22407
;	Make OVRLAY assemble with FTLOG=0.

;34	JNG	10-Apr-77	SPR 10-22436
;	Make OVRLAY work with FTRELOC=0.

;35	JNG	10-Apr-77
;	Set up reference lists correctly when link comes into core.

;36	JNG	10-Apr-77
;	Save the PPN around the LOOKUP in OVRLAY.

;37	MCHC	20-SEP-77
;	Don't output version change message if the change is from zero.
;START OF VERSION 4A
;40	DZN	15-Sep-78
;	On TOPS-20, if DDT exists, set its internal symbol table pointer
;	whenever we change .JBSYM.

;41	DZN	5-Oct-78
;	Use new NAME% form of JSYS names to avoid conflicts with user-defined
;	globals.

;42	DZN	5-Oct-78
;	Change FTENEX conditional to TOPS20 to be consistent with the rest
;	of LINK. Use proper mnemonics for JSYS arguments. Some code cleanup.

;43	DZN	13-Oct-78
;	Fix link deletion problems. Make REMOV. take only a single argument,
;	and delete that link and all of its inferiors (otherwise lost links
;	result). Allow RUNOV. to delete the calling link as documented. Also
;	remove OVLAOC message (use OVLARC instead).

;44	DZN	15-Oct-78
;	Fix argument checking for calls to manual subroutines. This involves
;	allowing all double and single precision argument types to work,
;	making the OVLIAT message fatal and not type junk, and getting
;	the correct user PC (see edit 10).

;45	DZN	15-Oct-78
;	Fix PDL overflow if many calls to RUNOV. RUNOV. now unbinds back
;	through the return PC on the stack, allowing replacement of links
;	at the same level to succeed without the PDL overflow.

;46	JNG	15-Jun-79
;	Use 7.01 GETTABs if available to find overlay file.

;47	DZN	25-Jul-79
;	Clean up the listing for release.

;50	DZN	27-Aug-79
;	Release on both TOPS-10 and TOPS-20 as version 4A(50).
;START OF VERSION 4B
;51	DZN	12-Nov-79	SPR 20-13384
;	Fix forward reference to local label TIME, which subsequently drags
;	in and defines the TIME JSYS.

;52-54	Superceded in Edit 5(100).

;55	PY	5-Jan-81
;	Fix off-by-one bug when relocating overlays which have pointers to
;	other nodes which are not relocated.

;56-100	Reserved for maintenance.

;START OF VERSION 5
;100	DZN	8-Feb-80
;	Implement writable overlays for use by Fortran's SAVE statement.
;	. On initialization, detect a potentially writable overlaid program and
;	  open nnnOVL.TMP.
;	. Move overlay file definitions to OVRPAR.MAC for use by OVRLAY and
;	  LINK.
;	Bugs fixes as a consequence of this edit:
;	. File names, extensions, or SFD names longer than 6 characters in calls
;	  to INIOVL or LOGOVL could result in a badly parsed file specification
;	  or worse.
;	. Closing the log file with CALL LOGOVL() never freed the buffer space
;	  because ROT was used as the FUNCT. function code rather than F.ROT.
;	. [0,0] is not suppressed when a file specification is printed.
;	. On TOPS-20, a CORE UUO is done even if UUO simulation is completely
;	  turned off.

;101	PAH	2-Feb-81
;
;	Save and restore T0 over the I/O call just before RP1.
;
SUBTTL	DEFINITIONS -- Accumulators


;ACCUMULATORS
T0=0				;[42] T0-T5 MUST BE 0-5 FOR JSYS ARGS
T1=1
T2=2
T3=3
T4=4
T5=5

P1=10
P2=11
L=16
P=17
SUBTTL	DEFINITIONS -- Macros -- SEGMENT, SPUSH, SPOP, CALL


DEFINE	SEGMENT (N)<
 IFN FT2SEG,<
  IFNDEF %SEG%,<
   TWOSEG
   RELOC	400000
   RELOC	0
   %SEG%==0
  >
  IFIDN <N><LOW>,<
   IFN %SEG%,<
    RELOC
    %SEG%==0
  >>
  IFIDN <N><HIGH>,<
   IFE %SEG%,<
    RELOC
    %SEG%==-1
>>>>

DEFINE SPUSH (AC) <
 IRP AC,<
	PUSH	P,AC
>>

DEFINE SPOP (AC) <
 IRP AC,<
	POP	P,AC
>>


;CALL MACRO FOR CALLING FUNCT. OR ANY OTHER DPSS CALLABLE ROUTINE. USAGE:
;
;	CALL	FUNCT.##,<<TYPE1,ARG1>,...,<TYPEn,ARGn>>
;
;EACH TYPEi SHOULD BE THE MNEMONIC FOR THE TYPE MINUS THE 'A.', SUCH AS SPI FOR
;SINGLE-PRECISION INTEGER.

DEFINE CALL(ROUT,ARGS)<			;;[100] DPSS CALLING SEQUENCE MACRO
  ..CNT==0				;;[100] COUNT THE ARGS
  IRP ARGS,<..CNT==..CNT+1>		;;[100]   ..
  MOVEI L,1+[				;;[100] BUILD THE ARGUMENT BLOCK
    -..CNT,,0				;;[100] COUNT
    IRP ARGS,<DOARG(ARGS)>]		;;[100] GENERATE EACH ARGUMENT POINTER
  PUSHJ P,ROUT				;;[100] CALL THE ROUTINE
>

DEFINE DOARG(ARG)<DOARG1 ARG>		;[100] DUMMY MACRO TO GET RID OF <>

DEFINE DOARG1(TYPE,ARG)<Z A.'TYPE,ARG>	;[100] GENERATE THE ARGUMENT POINTER
SUBTTL	DEFINITIONS -- Macros -- Type-out


DEFINE TYPE(TEXT)<
  MOVEI T1,[ASCIZ \TEXT\]		;;[100] SET UP THE TEXT
  PUSHJ P,PRNTXT			;;[100] GO PRINT IT
>

DEFINE	TYPEC(CHAR)<
  MOVEI T0,CHAR				;;[100] SET UP THE CHARACTER
  PUSHJ P,@PRNCHR			;;[100] CALL THE PROPER OUTPUT ROUTINE
>


IFE TOPS20,<
  OPDEF STOP [EXIT]
>

IFN TOPS20,<
  DEFINE STOP<
    HALTF%				;;[41]
    JRST .-1				;;[41] HALTF% IS CONTINUABLE
  >
>
SUBTTL	DEFINITIONS -- OPDEFs


;THE FOLLOWING OPDEFS CONTROL THE SELECTION OF THE TEMPORARY FILE WHEN WRITABLE
;OVERLAYS ARE USED. THE INPUT ROUTINES WILL READ FROM EITHER THE OVERLAY OR
;TEMPORARY FILE BASED ON THE SIGN OF THE UBLOCK FLAG. THESE OPDEFS SIMPLIFY THE
;SETTING AND TESTING OF THAT FLAG.

OPDEF	SETTMP	[HRROS UBLOCK]	;[100] USE TEMPORARY FILE IN I/O ROUTINES
OPDEF	CLRTMP	[HRRZS UBLOCK]	;[100] GO BACK TO OVERLAY FILE IN I/O ROUTINES
OPDEF	SKIPT	[SKIPL UBLOCK]	;[100] SKIP IF I/O FROM TEMPORARY FILE
OPDEF	SKIPNT	[SKIPGE UBLOCK]	;[100] SKIP IF I/O NOT FROM TEMPORARY FILE

OPDEF	PJRST	[JUMPA 17,]	;[100] SHOW PJRST'S CORRECTLY IN DDT
SUBTTL	PRINCIPLE ENTRY POINT


;CALLS TO ROUTINES IN INFERIOR LINKS ARE CHANGED BY LINK TO:
;
;	PUSHJ	P,<EXTTAB BLOCK>	;NEED NOT ACTUALLY BE PUSHJ
;
;THE EXTTAB BLOCK FOR A ROUTINE THEN CONTAINS A JSP T1,.OVRLA THAT COMES HERE.
;IF THE LINK BEING CALLED IS ALREADY IN MEMORY AND THE ROUTINE HAS BEEN CALLED
;BEFORE, WE SIMPLY JUMP TO THE ROUTINE. OTHERWISE, THE CORRECT LINK AND ITS PATH
;ARE BROUGHT IN FIRST.
;
;ALL INTER-LINK CALLS EXECUTE THE CODE HERE, SO IT SHOULD BE AS FAST AS
;POSSIBLE. SELF-MODIFYING CODE IS USED FOR THIS.

	SEGMENT	LOW

	'.OVRLA'
.OVRLA:
;************* REPLACE
	JRST	SETINI			;INITIALIZE FIRST TIME
;*************	BY
;	MOVE	T0,JT.FLG(T1)		;GET 1ST WORD OF ARG BLOCK
;*************	AFTER FIRST TIME

	JUMPGE	T0,OVRL1		;NOT KNOWN TO BE IN CORE
	HRRZ	T1,JT.ADR(T1)		;GET ADDRESS
	JRST	@(T1)			;GO TO IT

	SEGMENT	HIGH


SETINI:	PUSH	P,T1			;[100] SAVE CALLER PC
	PUSHJ	P,OVINI			;[100] ZERO MEMORY AND SET UP OVERLAY FILE
	POP	P,T1			;[100] RESTORE PC
	PJRST	.OVRLA			;[100] TRY AGAIN
SUBTTL	RESTART PROCEDURE


RESTART:MOVE	T1,FSTLNK		;[100] GET CONTROL SECTION OF LINK 0
	SETZM	CS.PTR(T1)		;CLEAR FORWARD PTR
	MOVE	T1,CS.EXT(T1)		;POINTER TO EXTTABS
	MOVX	T0,F.LIC		;[100] NO LINKS NOW IN MEMORY
	ANDCAM	T0,ET.FLG(T1)		;[100]   ..
	ADDI	T1,ET.LEN-1
	AOBJN	T1,.-2			;FOR ALL
	MOVE	T1,[JRST SETINI]	;REPLACE INITIALIZING INST
	MOVEM	T1,.OVRLA		;SO WE RE-INIT FILE
	DMOVE	T0,%JBREL		;ORIGINAL .JBREL & .JBSA
	MOVEM	T0,.JBREL##		;[42] RESET .JBREL FOR TOPS20
	MOVEM	T1,.JBSA##		;BACK AS IT WAS
IFN TOPS20,<
	MOVX	T1,.FHSLF		;[42] ONLY DO CORE UUO IF PAT IS AROUND
	GCVEC%				;[41] SO WON'T DRAG IT IN IF NOT
	MOVE	T1,.JBSA##		;RESTORE AC 1 FOR DISPATCH
	SKIPLE	T2			;[100] -1 OR 0 IF NO PA1050
> ;END IFN TOPS20
	CORE	T0,			;RESET OTHERWISE FREE CORE NOT AVAILABLE
	  JFCL
	JRST	(T1)			;GO TO START
;HERE IF THE LINK IS NOT KNOWN TO BE IN MEMORY. EVEN IF A ROUTINE IS IN A LINK
;THAT IS ALREADY IN MEMORY, WE DON'T KNOW IT UNTIL THE ROUTINE IS CALLED THE
;FIRST TIME. SO THERE ARE THREE STEPS:
;
;  1.	RESOLVE MULTIPLY-DEFINED GLOBALS.
;  2.	BRING IN THE REQUESTED LINK AND ITS PATH IF NECESSARY.
;  3.	FINALLY MARK THE ROUTINE AS IN MEMORY SO SUBSEQUENT CALLS ARE FAST, AND
;	JUMP TO THE ROUTINE.


OVRL1:	PUSH	P,T2			;GET A SPARE ACC
	TXNE	T0,F.MDL		;[100] MULTIPLY DEFINED?
	JRST	MDL0			;YES, SEE WHICH WE WANT

;SEE IF IT REALLY IS IN MEMORY.

INC0:	HLRZ	T0,JT.NUM(T1)		;GET NUMBER WE WANT
INC1:	MOVE	T2,FSTLNK		;GET START OF TREE
	CAMN	T0,CS.NUM(T2)		;MATCH?
	JRST	INC2			;YES
	HRRZ	T2,CS.FPT(T2)		;GET FORWARD POINTER
	JUMPN	T2,.-3			;TRY AGAIN
	JRST	NINC			;NOT IN CORE

;HERE WHEN THE LINK IS FINALLY IN MEMORY. MARK THIS ROUTINE AS NOW IN MEMORY,
;AND FIX REFERENCE POINTERS. ENTER WITH:
;
;	T1/	ROUTINE'S EXTTAB ADDRESS + 1 (FROM JSP), SO USE JT.xxx SYMBOLS

INC2:
IFN FTRELOC,<
	MOVE	T0,CS.RLC(T2)		;GET OFFSET
	ADDM	T0,JT.ADR(T1)		;FIXUP INCORE ADDRESS
> ;END IFN FTRELOC
	MOVX	T2,F.LIC		;[100] MARK LINK IN MEMORY
IFN FTRELOC,<
	SKIPE	T0			;NEED TO RELOCATE IT?
	TXO	T2,F.RLC		;[100] YES
> ;END IFN FTRELOC
	IORB	T2,JT.FLG(T1)		;SET FOR NEXT TIME
	HRRZ	T0,IT.REF(T2)		;GET POSSIBLE FORWARD REF
	HRLI	T0,IT.REF(T2)		;POINT TO INTTAB+1
	ADDI	T1,JT.REF		;POINT TO REFERENCE WORD IN EXTTAB
	MOVEM	T0,(T1)			;STORE IN EXTTAB
	HRRM	T1,IT.REF(T2)		;MAKE INTTAB POINT TO THIS EXTTAB
	EXCH	T2,T0			;SO WE CAN INDEX
	TRNE	T2,-1			;IF THERE WAS A FORWARD REF
	HRLM	T1,(T2)			;[35] CHANGE STORED BACK REF

;RESTORE AND EXIT.

INC3:	POP	P,T2			;RESTORE ACC
	HRRZ	T1,T0			;GET ADDRESS
	JRST	@(T1)			;GO TO IT
;HERE IF NOT IN CORE, READ IN PREAMBLE

NINC:	PUSH	P,T1			;SAVE PC
	MOVE	T1,JT.NUM(T1)		;LINK # WE WANT
NINC1:	HRRZM	T1,CURLNK		;SAVE LINK CONTROL SECTION ADDRESS
	HLRZ	T0,T1			;LINK #
	PUSHJ	P,CP0			;CHECK PATH
	POP	P,T1			;RESTORE PC
	MOVE	T0,JT.FLG(T1)		;GET FLAGS
	TXNN	T0,F.MDL		;[100] SPECIAL IF MULTIPLY DEFINED
	JRST	INC0			;NO, TRY AGAIN
MINC:	MOVE	T1,T0			;POINTER TO ACTUAL ENTRY IN MDL TABLE
IFN FTRELOC,<
	HRRZ	T2,MT.ADR(T1)		;GET UNRELOCATED ADDRESS
	HLRZ	T0,MT.NUM(T1)		;GET NUMBER
	MOVE	T1,FSTLNK		;START AT FRONT
	CAME	T0,CS.NUM(T1)		;THIS ONE?
	JRST	[HRRZ	T1,CS.FPT(T1)	;GET NEXT (MUST BE THERE)
		JRST	.-1]		;TRY TEST AGAIN
	MOVE	T0,CS.RLC(T1)		;GET RELOCATION OFFSET
	ADD	T0,T2			;PLUS ORIGINAL ADDRESS
> ;END IFN FTRELOC
IFE FTRELOC,<
	MOVE	T0,MT.ADR(T1)		;GET TRUE ADDRESS
> ;END IFE FTRELOC
	JRST	INC3			;GO TO IT (BUT DON'T MARK INCORE)
SUBTTL	READ PREAMBLE

;RP0 READS IN THE PREAMBLE FOR A SPECIFIED LINK. SINCE THE WINDOW INTO THE LINK
;NUMBER TABLE IS ONLY A DISK BLOCK BIG, WE MAY NEED TO MOVE THE WINDOW BEFORE
;FINDING THE LENGTH AND BLOCK NUMBER OF THE PREAMBLE. THE CALL IS:
;
;	T0/	LINK NUMBER
;
;RETURNS WITH THE PREAMBLE IN PH.

RP0:	MOVE	T1,INCIDX		;GET INCORE LOWEST
	CAIL	T0,(T1)			;SEE IF IN CORE
	CAILE	T0,377(T1)
	SKIPA	T1,T0			;NO
	JUMPN	T0,RP1			;YES, BUT DON'T ALLOW 0
	SKIPLE	T0
	CAMLE	T0,HILINK		;CHECK UPPER RANGE
	JRST	E$$ILN			;[100] ILLEGAL LINK NUMBER
	ANDCMI	T1,377			;WILL BE LOWEST BLOCK IN CORE
	MOVEM	T1,INCIDX		;EVENTUALLY
	LSH	T1,-8			;INTO BLOCK NUMBER
	ADD	T1,DI+DI.LPT		;[100] PLUS BASE
	PUSH	P,T0			;[101] SAVE INDEX NUMBER
	PUSHJ	P,%USETI		;SET ON IT
	MOVE	T0,[IOWD 200,IDXBFR]
	PUSHJ	P,%INZ			;READ IT IN
	POP	P,T0			;[101] RESTORE INDEX

;HERE WHEN THE PROPER WINDOW INTO THE LINK NUMBER TABLE IS IN IDXBFR.

RP1:	MOVE	T1,T0			;GET INDEX # AGAIN
	ANDI	T1,377			;THIS BLOCK ONLY
	ROT	T1,-1			;HALF
	SKIPGE	T1			;EVEN HALF?
	SKIPA	T1,IDXBFR(T1)		;NO
	HLRZ	T1,IDXBFR(T1)		;YES
	PUSHJ	P,%USETU		;SET ON IT
	PUSHJ	P,%INB			;READ PREAMBLE BLOCK
	MOVE	T1,[INBFR,,PH]		;[100] COPY TO PREAMBLE BLOCK
	BLT	T1,PH+PH.LEN-1		;[100]   ..
	POPJ	P,
SUBTTL	CHECK PATH -- Determine Links To Delete


;CP0 READS IN A SPECIFIED LINK AND THOSE LINKS ON ITS PATH. THIS IS DONE IN THE
;FOLLOWING STEPS:
;
;  1.	DETERMINE THE FIRST DIFFERENCE BETWEEN THE PATH CURRENTLY IN MEMORY AND
;	THE PATH REQUIRED FOR THE DESIRED LINK.
;  2.	DELETE ALL LINKS FROM THE FIRST DIFFERENCE DOWN.
;  3.	READ IN THE NEW LINKS REQUERED TO COMPLETE THE SPECIFIED PATH. RELOCATE
;	EACH LINK AS NECESSARY.
;  4.	PERFORM 'OTHER' RELOCATION (EFFECTS ON OTHER LINKS WHEN A LINK IS
;	RELOCATED) ONCE ALL LINKS IN THE PATH ARE ALL IN.
;  5.	READ IN THE SYMBOL TABLE IF NECESSARY, AND RELOCATE IT IF NECESSARY. ON
;	TOPS-10, MOVE THE SYMBOL TABLE TOWARD LOWER ADDRESSES AS FAR AS POSSIBLE
;	TO CONSERVE MEMORY.

CP0:	SPUSH	<P1,P2,L>		;[100] GET MORE ACS
	PUSHJ	P,RP0			;[100] READ THE PREAMBLE
	MOVE	P1,FSTLNK		;GET BASE OF INCORE LINKS
	HLRZ	P2,PH+PH.FPT		;[100] POINTER TO LIST OF WHAT WE NEED
	HRRZ	T1,PH+PH.FPT		;[100] BLOCK # WE NEED
	CAME	T1,UBLOCK		;SAME AS CURRENT?
	PUSHJ	P,[PUSHJ P ,%USETU	;NO, SET ON IT
		PJRST	%INB]		;READ IT
CP1:	HRRZ	T0,CS.FPT(P1)		;GET NEXT LINK CONTROL SEC IN CORE (BYPASS 0)
	JUMPE	T0,CP3			;FIRST TIME ONLY ROOT THERE
	HRLZ	P1,P1			;SAVE LAST GOOD PTR
	HRR	P1,T0			;RESET LINK PTR
	MOVE	T1,INBFR(P2)		;GET LINK # WE WANT
	HRRZ	T0,CS.NUM(P1)		;LINK# WE HAVE
	JRST	CP1B			;BYPASS TEST FOR ROOT
CP1A:	HRRZ	T0,CS.FPT(P1)		;GET NEXT CONTROL SEC.
	JUMPE	T0,CP3			;RAN OUT
	HRLZ	P1,P1			;SAVE LAST GOOD PTR
	HRR	P1,T0			;RESET LINK PTR
	HRRZ	T0,CS.NUM(P1)		;LINK#
	MOVS	T1,INBFR(P2)		;GET NEXT PAIR
	CAIE	T0,(T1)			;MATCH?
	JRST	CP2			;NO, FIRST DIFFERENCE
	MOVS	T1,T1			;TEST FOR SECOND LINK#
	HRRZ	T0,CS.FPT(P1)		;GET NEXT CONTROL SEC.
	JUMPE	T0,CP3			;ALL DONE
	HRLZ	P1,P1			;SAVE LAST GOOD PTR
	HRR	P1,T0			;RESET LINK PTR
	HRRZ	T0,CS.NUM(P1)		;LINK#
CP1B:	CAIE	T0,(T1)			;MATCH?
	JRST	CP2			;NO
	CAIGE	P2,177			;WILL REQUIRED PTR FIT IN 128 WORDS?
	AOJA	P2,CP1A			;YES, LOOP
	AOS	T1,UBLOCK		;GET NEXT BLOCK
	PUSHJ	P,%USETI		;SET ON IT
	PUSHJ	P,%INB			;READ IT IN
	SETZ	P2,			;START AT FRONT
	JRST	CP1A			;AND KEEP TRYING
SUBTTL	CHECK PATH -- Delete Old Links


;HERE TO DELETE ALL NOW-UNNECESSARY LINKS.

CP2:	PUSH	P,P1			;SAVE FIRST DIFF
	HRRZ	P1,P1			;CLEAR PREV
	PUSHJ	P,DELPTH		;[43] DELETE ALL OLD LINKS
	POP	P,P1
	HLRZ	P1,P1			;GET LAST GOOD ONE

;HERE TO READ IN THE REST OF THE DESIRED PATH. THIS IS DONE IN REVERSE ORDER
;SINCE WE ONLY HAVE ONE BUFFER. 'OTHER' RELOCATION MUST WAIT UNTIL ALL LINKS ARE
;IN MEMORY.

CP3:	PUSHJ	P,GTLNK			;GET IT
	MOVE	P1,THSLNK		;GET POINTER TO NEW LINK
	HRRZ	T1,PH+PH.BPT		;[100] GET ADDRESS OF BACK POINTER LIST
	CAME	T1,UBLOCK		;CURRENTLY IN CORE?
	PUSHJ	P,[PUSHJ P ,%USETU	;NO, SET ON IT
		PJRST	%INB]		;READ IT
	HLRZ	P2,PH+PH.BPT		;[100]
	ANDI	T1,177			;OFFSET IN THIS BUFFER
	MOVE	T0,INBFR(P2)		;WHOM IT SHOULD BE LINKED TO
	TRNE	T0,-1			;IF LAST HALF WORD IS NULL
	TLZA	T0,-1			;NO, SO CLEAR LEFT
	HLRZ	T0,T0			;YES, USE LEFT HALF
	HLRZ	T1,CS.BPT(P1)		;GET BACK LINK
	HRRZ	T1,CS.NUM(T1)		;WHOM IT IS LINKED TO
	CAMN	T1,T0			;SAME?
	JRST	CP4			;YES, RETURN
	PUSHJ	P,RP0			;GET THIS PREAMBLE
	HLRZ	P1,CS.BPT(P1)		;RESET P1 TO POINT TO FATHER
	JRST	CP3			;AND READ IN LINK


;ROUTINE TO DELETE A LINK. THIS IMPLIES DELETING ALL OF ITS INFERIORS (THE
;PATH) TOO. IF WE TRY TO DELETE THE CURRENT LINK (THE ONE THAT CALLED US),
;GIVE ?OVLARC.
;
;CALL:
;	P1/	CONTROL BLOCK ADDR OF LINK TO START AT
;DESTROYS P1.

DELPTH:	MOVEM	P1,THSLNK		;[43] SET UP LINK FOR GBLNK
	SKIPN	OKOVLC			;[43] OK TO DELETE THE CALLER'S LINK
	CAME	P1,CURLNK		;[43]   OR NOT THE CALLER'S LINK?
	SKIPA				;[43] YES--DELETE THIS LINK
	JRST	E$$ARC			;[100] NO--ATTEMPT TO REMOVE CALLER
	HRRZ	P1,CS.FPT(P1)		;[43] ADVANCE TO NEXT WHILE WE CAN
	PUSHJ	P,GBLNK			;[43] GIVE BACK THE LINK
	JUMPN	P1,DELPTH		;[43] FREE MORE IF ANY
	POPJ	P,			;[43] ALL DONE
SUBTTL	CHECK PATH -- 'Other' Relocation And Symbols


;HERE TO CHECK FOR AND PERFORM 'OTHER' RELOCATION IF NECESSARY.

CP4:
IFN FTRELOC,<
	MOVE	P1,FSTLNK		;START AT FRONT
CP4A:	MOVE	T1,CS.FLG(P1)		;GET FLAGS
	TXZN	T1,CF.RLO		;[100] OTHER RELOCATION STILL TO DO?
	JRST	CP4C			;NOT FOR THIS ONE
	MOVEM	T1,CS.FLG(P1)		;CLEAR FLAG
	MOVE	T1,FSTLNK		;HOWEVER SEE IF WORTH DOING
CP4B:	HRRZ	T1,CS.FPT(T1)		;GET NEXT
	JUMPE	T1,CP4C			;NOTHING ON PATH WAS RELOCATED
	SKIPN	CS.RLC(T1)		;IS THIS LINK RELOCATED?
	JRST	CP4B			;NO, TRY NEXT
	PUSHJ	P,RLO			;DO RELOCATION
CP4C:	HRRZ	P1,CS.FPT(P1)		;GET NEXT
	JUMPN	P1,CP4A			;AND CHECK IT
> ;END IFN FTRELOC

;HERE TO GET SYMBOLS RIGHT (FOR NOW, WILL FIX LATER).

CP5:	SKIPN	.JBSYM##		;[32] SYMBOLS SET UP AT OVINI4?
	JRST	CP6			;NO
	MOVE	P1,FSTLNK		;GET START OF LIST
CP5A:	SKIPN	CS.SYM(P1)		;ALREADY SETUP?
	PUSHJ	P,GTSYM			;NO
	MOVEI	P2,(P1)			;REMEMBER LAST
	HRRZ	P1,CS.FPT(P1)		;GET NEXT
	JUMPN	P1,CP5A
IFE TOPS20,<
	PUSHJ	P,SYMDWN		;[100] MOVE SYMBOLS DOWN IF POSSIBLE
> ;END IFE TOPS20
CP6:	SPOP	<L,P2,P1>		;[100] RESTORE ACS
	POPJ	P,			;[100] DONE
SUBTTL	CHECK PATH -- Move Symbols Down


;HERE WITH ALL LINKS AND SYMBOLS IN MEMORY. MOVE SYMBOLS DOWN IF POSSIBLE SO
;MEMORY REDUCTION WILL WIN.

IFE TOPS20,<
SYMDWN:	HLRZ	P1,CS.SIZ(P2)		;[100] GET SIZE OF HIGHEST LINK
	ADD	P1,CS.ADR(P2)		;FIND WHAT SHOULD BE FIRST
					;FREE WORD IN CORE.
	MOVEI	P1,200(P1)		;LEAVE SOME ROOM FOR LATER
SYMDW1:	HRRZ	P2,.JBSYM##		;[100] GET CURRENT SYMBOL LOC
	CAMG	P2,P1			;ARE THEY UP TOO HIGH?
	JRST	SYMDW3			;[100] NO, FORGET IT (SNH)
	MOVEM	P1,ADDCOR		;ADDRESS THAT WE WANT
	SUB	P2,P1			;MAX SIZE OF BLOCK WE WANT
	HLRO	P1,.JBSYM##		;GET - S.T. SIZE
	ADD	P2,P1			;FIND SPACE BETWEEN BLOCKS
	SKIPL	P2			;DO THE BLOCKS OVERLAP?
	SETZ	P2,			;NO, NO ADJUSTMENT NEEDED
	MOVN	P1,P1			;LENGTH THAT WE WANT
	ADD	P1,P2			;ADJUST FOR ANY OVERLAP
	MOVEM	P1,SIZCOR		;STORE FOR FUNCT.
	CALL	FUNCT.##,<<SPI,[F.GAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPN	STATUS			;MAKE IT?
	JRST	SYMDW2			;[100] YES, GO MOVE SYMBOLS
	MOVE	P1,ADDCOR		;ADDR OF CORE WE CAN'T GET
	ADD	P1,PAGSIZ		;POINT TO SOME WE CAN
	JRST	SYMDW1			;[100] AND GO TRY AGAIN
;STILL IN IFE TOPS20

;HERE TO COPY THE SYMBOL TABLE DOWN AND DELETE THE OLD COPY.

SYMDW2:	HLRO	P2,.JBSYM##		;[100] GET SYMBOL TABLE SIZE
	MOVN	P2,P2			;...
	ADD	P2,ADDCOR		;POINT TO END OF NEW S.T.
	HRLZ	P1,.JBSYM##		;SOURCE IS OLD S.T.
	HRR	P1,ADDCOR		;DEST IS NEW S.T.
	BLT	P1,-1(P2)		;COPY DOWN S.T.
	HRRZ	T0,.JBSYM##		;ADDR OF OLD S.T.
	SUB	T0,ADDCOR		;FIND HOW FAR THEY MOVED
	MOVN	T0,T0			;FIX SIGN FOR ADJSYM
	HRRZ	P1,.JBSYM##		;GET ADDR OF S.T. TO FREE
	CAMGE	P1,P2			;UNLESS THEY OVERLAP
	MOVE	P1,P2			;THEY DO ... ADJUST POINTER
	MOVEM	P1,ADDCOR		;POINT TO CORE TO FREE
	PUSHJ	P,ADJSYM		;ADJUST ALL S.T. PNTRS
	SKIPE	STATUS			;[100] MAKE SURE ALL IS OK
	JRST	E$$CSM			;[100] MADE IT
SYMDW3:	CALL	FUNCT.##,<<SPI,[F.CBC]>,<AS,OVLNAM>,<SPI,STATUS>>
	POPJ	P,			;[100] DONE


E$$CSM:	PUSHJ	P,FAIL			;[100] THIS SHOULDN'T HAPPEN
	TYPE	<CSM	Cannot shrink memory> ;[100]
	PUSHJ	P,PRNFSP		;[100] SAY FUNCT. COULDN'T DO IT
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP				;SO DIE QUIETLY
> ;END IFE TOPS20
SUBTTL	CHECK PATH -- Read In DDT Symbols


GTSYM:	SKIPN	T1,CS.DDT(P1)		;GET DSK SYMBOL PTR
	POPJ	P,			;NONE, GIVE UP
	PUSHJ	P,%USETI		;SET ON IT
	HLRE	T1,T1			;LENGTH
	HRRZ	T0,.JBSYM##		;TOP OF WHAT WE HAVE
	ADD	T0,T1			;BOTTOM
	MOVEM	T0,ADDCOR
	MOVMM	T1,SIZCOR		;SETUP ARGS
	CALL	FUNCT.##,<<SPI,[F.GAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;DID WE WIN
	JRST	GTSYM1			;NO
	MOVE	T0,ADDCOR		;WHERE TO READ INTO
	HLL	T0,CS.DDT(P1)		;DDT SYMBOL PTR
	MOVEM	T0,CS.SYM(P1)		;INDIVIDUAL LINK SYMBOL PTR
	SUBI	T0,1			;ONE LESS FOR IOWD
	PUSHJ	P,%INZ			;READ IT IN
	MOVN	T1,SIZCOR		;GET LENGTH
	HRLI	T1,-1(T1)		;IN BOTH HALVES, COMPENSATE FOR CARRY
	ADDM	T1,.JBSYM##		;ADJUST SYM PTR
IFN TOPS20,<
	PUSHJ	P,CHKDDT		;[40] STORE S.T. PTR IN DDT IF IT'S THERE
> ;END IFN TOPS20
IFN FTRELOC,<
	SKIPE	CS.RLC(P1)		;[100] WAS LINK RELOCATED
	PUSHJ	P,RLS1			;[100] YES--RELOCATE THE SYMBOLS
> ;END IFN FTRELOC
	POPJ	P,			;NO, RETURN
;RLS1 RELOCATES VALUES IN THE SYMBOL TABLE AS A RESULT OF A LINK BEING
;RELOCATED. USES ACS AS FOLLOWS:
;
;	T0/	TO HOLD TEMP HALF WORD
;	T1/	BYTE WORD (18 BYTES)
;	T2/	TO HOLD BYTE COUNT IN LSH WORD (T1)
;	T3/	OFFSET
;	T4/	AOBJN WORD FOR BYTE WORDS (IN INBFR)
;	T5/	- NO. OF WORDS FOR WHOLE LINK

IFN FTRELOC,<
RLS1:	SPUSH	<T3,T4,T5>		;MORE ACCS
	MOVE	T0,CS.NUM(P1)		;GET LINK#
	PUSHJ	P,RP0			;READ PREAMBLE AGAIN
	MOVE	T3,CS.RLC(P1)		;GET OFFSET
	SKIPN	T1,PH+PH.RDR		;[100] BLOCK WE NEED
	JRST	[MOVEM P1,THSLNK	;[100] MAKE OVLMAN PRINT RIGHT LINK
		 JRST E$$NRS]		;[100] NO RELOCATION TABLE FOR SYMBOLS
	HLRE	T5,T1			;-NO. OF WORDS IN LINK
	HRRZ	T2,CS.SYM(P1)		;FIRST WORD
	HRLI	T2,-^D18		;AOBJN WORD
	PUSHJ	P,RLCRD1		;FIRST TIME
	PUSHJ	P,RLCRW			;GET FIRST WORD

RLS2:	JUMPGE	T1,RLS4			;NO RELOCATION FOR LHS
	HLRZ	T0,(T2)			;GET 1/2 WORD
	ADD	T0,T3			;RELOCATE
	HRLM	T0,(T2)			;PUT BACK
RLS4:	LSH	T1,1			;RIGHT HALF BIT
	JUMPGE	T1,RLS5			;NO RELOCATION
	HRRZ	T0,(T2)			;GET 1/2 WORD
	ADD	T0,T3			;RELOCATE
	HRRM	T0,(T2)			;PUT BACK
RLS5:	LSH	T1,1
	JUMPN	T1,RLS6			;MORE TO DO FOR THIS BYTE WORD?
	AOBJN	T2,.			;USE UP ALL WORDS
	CAIA				; IN THIS 18
RLS6:	AOBJN	T2,RLS2			;LOOP FOR ALL OF LINK
RLS3:	AOJGE	T5,RLS7			;[100] RAN OUT OF WORDS
	PUSHJ	P,RLCRW			;GET NEXT RELOC WORD
	JUMPE	T1,[ADDI T2,^D18	;NONE FOR THIS WORD
		JRST	RLS3]		;IGNORE 0 WORDS
	HRLI	T2,-^D18		;RESET COUNT
	JRST	RLS2			;GET NEXT DATUM

RLS7:	SPOP	<T5,T4,T3>		;[100] RESTORE ACS
	POPJ	P,			;[100] DONE
> ;END OF IFN FTRELOC
GTSYM1:	PUSHJ	P,MOVSYM		;TRY TO MOVE SYMBOL TABLE UP
	SKIPN	STATUS			;DID WE WIN?
	JRST	GTSYM			;YES, TRY AGAIN
E$$NMS:	PUSHJ	P,WARN			;[100] PRINT %OVL PREFIX
	  POPJ	P,			;[100] NO WARNINGS REQUESTED
	TYPE	<NMS	Not enough memory to load symbols> ;[100]
	PUSHJ	P,PRNFRS		;[100] SAY WHY FUNCT. FAILED
	PJRST	CRLF
SUBTTL	MOVE SYMBOL TABLE UP


MOVSYM:	HRRZ	T0,.JBSYM##		;GET BASE OF SYMBOL TABLE
	HLRE	T1,.JBSYM##		;LENGTH
	SUB	T0,T1			;NEXT FREE (WE HOPE)?
	HRRZ	T1,PAGSIZ		;MINIMUM TO EXPAND BY
	DMOVEM	T0,ADDCOR		;STORE ARGS
	CALL	FUNCT.##,<<SPI,[F.GAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPN	T1,STATUS		;WELL?
	JRST	MOVSY3			;GOT IT, NOW MOVE UP SYMBOLS
	CAIE	T1,2			;OTHER ALLOCATED BLOCKS IN THE WAY?
	  POPJ	P,			;NO, GIVE UP
	HLRE	T1,.JBSYM##		;NOW MUST FIND PIECE AS LONG AS ST
	MOVNM	T1,SIZCOR		;SO SET UP FOR NEXT FUNCT. CALL
MOVSY1:	HRRZ	T1,PAGSIZ		;SEE IF CORE A PAGE HIGHER IS FREE
	ADDM	T1,ADDCOR		;SO CAN PUT THE SYMBOL TABLE THERE
	CALL	FUNCT.##,<<SPI,[F.GAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPN	T1,STATUS		;MAKE IT?
	  JRST	MOVSY2			;YES, NOW BLT SYMBOLS
	CAIN	T1,2			;OTHER BLOCKS STILL IN THE WAY?
	JRST	MOVSY1			;YES, TRY HIGHER YET
	POPJ	P,			;NO, GIVE UP ON SYMBOLS

MOVSY2:	HRLZ	T0,.JBSYM##		;OLD LOC OF SYMBOLS
	HRR	T0,ADDCOR		;AND NEW LOC
	HRRZ	T1,T0			;CALC WHERE THEY WILL END
	ADD	T1,SIZCOR		;..
	BLT	T0,-1(T1)		;AND MOVE THE SYMBOLS
	HRRZ	T0,.JBSYM##		;GET ADDRESS TO RETURN
	EXCH	T0,ADDCOR		;STORE IT; GET NEW ADDRESS
	SUB	T0,ADDCOR		;FIND THEIR DIFFERENCE FOR ADJSYM
	JRST	ADJSYM			;GO FIXUP ALL OTHER SYM POINTERS
;MOVE SYMBOL TABLE UP BY REVERSE BLT LOOP

MOVSY3:	HRRZ	T0,.JBSYM##		;BOTTOM OF SYMBOLS
	HLRE	T1,.JBSYM##		;-LENGTH
	MOVM	T1,T1
	HRL	T1,T1			;+LENGTH ,, +LENGTH
	ADD	T1,T0			;+LENGTH ,, TOP + 1
	SUBI	T1,1			;,,TOP
	TLO	T1,(1B0)		;SIGN BIT ON
	MOVEM	T0,ADDCOR		;ADDRESS WE WILL GIVE BACK
IFN FT2SEG,<
	PUSHJ	P,PAGSIZ		;MUST BE IN LOW SEG
> ;END IFN FT2SEG
	SEGMENT	LOW
PAGSIZ:	POP	T1,.-.(T1)		;*** MODIFIED ***
	JUMPL	T1,.-1			;LOOP FOR ALL SYMBOLS
IFN FT2SEG,<
	POPJ	P,			;RETURN
> ;END IFN FT2SEG
	SEGMENT	HIGH
	HRRZ	T0,PAGSIZ		;ADJUST SYMBOL PTR BY HOW MUCH THEY MOVED
ADJSYM:	ADDM	T0,.JBSYM##
IFN TOPS20,<
	PUSHJ	P,CHKDDT		;[40] STORE S.T. PTR IN DDT IF IT'S THERE
> ;END IFN TOPS20
	MOVE	T1,FSTLNK		;MUST DO SAME FOR ALL LINKS IN CORE
	SKIPE	CS.SYM(T1)		;MY NOT BE ANY
	ADDM	T0,CS.SYM(T1)		;ADJUST
	HRRZ	T1,CS.FPT(T1)		;GET NEXT
	JUMPN	T1,.-3			;FOR ALL
	CALL	FUNCT.##,<<SPI,[F.RAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	POPJ	P,			;RETURN
SUBTTL	GIVE BACK LINK


GBLNK:	PUSH	P,P1			;[100] SAVE AN AC FOR ADDRESS OF CONTROL SECTION
	MOVE	P1,THSLNK		;[100]   ..
	SKIPE	.JBSYM##		;[32] KEEPING SYMBOLS UP TO DATE?
	PUSHJ	P,GBSYM			;YES, RETURN SYMBOL SPACE
;CLEAR BI-DIRECTIONAL REFERENCE IN EXTTAB
	MOVX	T0,F.LIC		;[100] TO CLEAR IN-MEMORY FLAG
	MOVE	T1,CS.EXT(P1)		;[100] GET AOBJN POINTER TO TRANS TABLES
	JUMPGE	T1,GBLNK1		;IGNORE IF NONE
GBLNK0:	HLRZ	T2,ET.NUM(T1)		;GET LINK #
	JUMPE	T2,GBLNKU		;MUST BE UNDEFINED IF IN ROOT
	MOVE	T2,ET.REF(T1)		;GET OTHER REF POINTER
	TRNE	T2,-1
	HLLM	T2,(T2)			;BACK LINK IN FORWARD OVERLAY
	MOVS	T2,T2
	TRNE	T2,-1			;SKIP IF NO FORWARD LINK
	HLRM	T2,(T2)			;FORWARD LINK IN BACK OVERLAY
	ANDCAM	T0,ET.FLG(T1)		;CLEAR FLAG FOR COMPLETNESS
GBLNKU:	ADDI	T1,ET.LEN-1		;5 WORD BLOCKS
	AOBJN	T1,GBLNK0		;LOOP FOR ALL OF TABLES

;NOW TO CLEAR ALL DIRECT REFERENCES.

GBLNK1:	PUSH	P,T3			;[100] SAVE UNTIL END OF LOOP
	MOVN	T3,CS.RLC(P1)		;[100] GET RELOC OFFSET
	MOVE	T1,CS.INT(P1)		;[100] AOBJN PTR TO INT TRANS TABLE
	JUMPGE	T1,GBLNK5		;NONE
GBLNK2:	HRRZ	T2,IT.REF(T1)		;GET FORWARD REF
	JUMPE	T2,GBLNK4		;END OF CHAIN
GBLNK3:	HRL	T2,(T2)			;GET ITS REF
GBLNK6:	SETZM	(T2)			;CLEAR THIS
	ANDCAM	T0,ET.ADR-ET.REF(T2)	;AND ITS INCORE FLAG
	ADDM	T3,ET.ADR-ET.REF(T2)	;REMOVE RELOCATION
	HLRZ	T2,T2			;GET NEXT
	JUMPN	T2,GBLNK6		;LOOP IF EXISTS
GBLNK4:	ADDI	T1,IT.LEN-1		;TWO WORD TABLES
	AOBJN	T1,GBLNK2		;LOOP
;NOW TO CLEAR FORWARD AND BACKWARD LINKS.

GBLNK5:	POP	P,T3			;[100] RESTORE AFTER LOOP
	MOVE	T1,CS.PTR(P1)		;[100] GET POINTERS
	TRNE	T1,-1			;SKIP IF NO FORWARD ONE
	HLLM	T1,CS.BPT(T1)		;STORE BACK PTR IN FORWARD LINK
	MOVS	T1,T1
	TRNE	T1,-1			;SKIP IF NO BACK PTR
	HLRM	T1,CS.FPT(T1)		;STORE FORWARD PTR IN BACK LINK
	MOVE	T1,CS.OSY(P1)		;[100] RESTORE SYMBOL TABLE POINTER
	MOVEM	T1,CS.SYM(P1)		;[100]   ..

;HERE TO DELETE THE LINK, WRITING IT OUT FIRST IF NECESSARY.

	MOVE	T1,DI+DI.FLG		;[100] WRITABLE OVERLAYS?
	TXNN	T1,OD.WRT		;[100]   ..
	JRST	GBLNK7			;[100] NO--DON'T BOTHER TESTING THE LINK
	MOVE	T0,CS.NUM(P1)		;[100] YES--IS THIS LINK WRITABLE?
	PUSHJ	P,WRTPTR		;[100]   ..
	LDB	T1,T0			;[100]   ..
	TXNN	T1,OW.WRT		;[100]   ..
	JRST	GBLNK7			;[100] NO--JUST DELETE THE LINK
	TXO	T1,OW.PAG		;[100] YES--MARK IT PAGED
	DPB	T1,T0			;[100]   ..
IFN FTRELOC,<

;**; Unrelocate the link here if necessary.

> ;END IFN FTRELOC

;  ..
;  ..

IFN FTLOG,<
	PUSHJ	P,E$$WLN		;[100] TELL USER WHAT'S GOING ON
> ;END OF IFN FTLOG
	HLLZ	T0,CS.OVL(P1)		;[100] FIND WHERE AND HOW MUCH TO WRITE
	HRR	T0,CS.COR(P1)		;[100]   ..
	SUBI	T0,1			;[100]   ..
	HRRZ	T1,CS.OVL(P1)		;[100]   ..
	PUSHJ	P,%USETO		;[100] WRITE OUT THE LINK
	PUSHJ	P,%OUTZ			;[100]   ..

;FINALLY, FREE THE MEMORY ASSIGNED TO THE LINK.

GBLNK7:
IFN FTLOG,<
	PUSHJ	P,E$$DLN		;[100] TELL USER THE LINK'S GOING
> ;END OF IFN FTLOG
	MOVE	T1,THSLNK		;GET CONTROL SECTION OF THIS LINK
	MOVE	T1,CS.COR(T1)		;GET CORE SIZE AND ORIGIN
	HRRZM	T1,ADDCOR		;ORIGIN
	HLRZM	T1,SIZCOR		;LENGTH
	CALL	FUNCT.##,<<SPI,[F.RAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;[100] IF THE MEMORY COULDN'T BE FREED
	JRST	E$$CDL			;[100] THEN TELL THE USER AND DIE
	POP	P,P1			;[100] RESTORE THE AC
	POPJ	P,			;[100] DONE
SUBTTL	GIVE BACK SYMBOLS


GBSYM:	MOVE	T1,THSLNK		;GET START OF CONTROL SECTION
	MOVE	T0,CS.SYM(T1)		;GET SYMBOL TABLE PTR
	JUMPE	T0,CPOPJ		;NONE
	HRRZM	T0,ADDCOR		;GIVE BACK AT THIS ADDRESS
	HLRE	T0,T0
	MOVM	T0,T0
	MOVEM	T0,SIZCOR		;THIS MUCH
	HRL	T0,T0
	ADDM	T0,.JBSYM##		;REDUCE SYMBOL TABLE
IFN TOPS20,<
	PUSHJ	P,CHKDDT		;[40] STORE S.T. PTR IN DDT IF IT'S THERE
> ;END IFN TOPS20
	CALL	FUNCT.##,<<SPI,[F.RAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;MAKE SURE OK
	JRST	E$$CDL			;[100] NO
	POPJ	P,			;YES, RETURN
SUBTTL	GET NEW LINK


GTLNK:	SKIPN	T1,.JBSYM##		;SYMBOLS MAY BE IN THE WAY
	JRST	GTLNK4			;NO SUCH LUCK
	MOVE	T0,PH+PH.ADD		;[100] SEE IF THEY ARE IN THE WAY
	ADD	T0,PH+PH.LLN		;[100]   ..
	CAIGE	T0,(T1)			;ARE THEY?
	JRST	GTLNK4			;NO, GO LOAD THE LINK
	PUSHJ	P,MOVSYM		;YES, TRY TO MOVE THEM
	SKIPN	STATUS			;DID WE
	JRST	GTLNK			;YES, TRY AGAIN
	JRST	GTLNK0			;NO - MUST RELOCATE LINK
GTLNK4:	DMOVE	T0,PH+PH.ADD		;[100] WHERE WE WANT LINK TO GO & LENGTH OF IT
	DMOVEM	T0,ADDCOR		;STORE FOR FUNCT. CALL
	CALL	FUNCT.##,<<SPI,[F.GAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPN	STATUS			;CHECK FOR FAILURE
	JRST	GTLNK2			;GOT WHAT WE NEED

;  ..
;  ..

;HERE IF WE COULDN'T GET THE MEMORY FOR THE LINK WHERE WE WANTED TO. TRY TO GET
;THE MEMORY WHEREEVER WE CAN. IF THAT FAILS, DELETE THE SYMBOL TABLE (IF ANY)
;AND TRY ONE LAST TIME.

GTLNK0:
IFN FTRELOC,<
	MOVE	T1,DI+DI.FLG		;[100] SEE IF RELOCATABLE OVERLAYS
	TXNN	T1,OD.RLC		;[100]   ..
> ;END IFN FTRELOC
	JRST	[MOVEI T1,PH+PH.NUM-CS.NUM ;[100] NO--DON'T BOTHER WITH TRICKS
		 MOVEM T1,THSLNK	;[100] FAKE UP POINTER FOR LINK NAME
		 JRST E$$MAN]		;[100] MEMORY FOR ABSOLUTE LINK NOT AV.
IFN FTRELOC,<
	DMOVE	T0,PH+PH.ADD		;[100] GET ADDR AND SIZE OF LINK
	DMOVEM	T0,ADDCOR		;STORE FOR FUNCT. CALL
	CALL	FUNCT.##,<<SPI,[F.COR]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;CHECK FOR FAILURE
	JRST	E$$CGM			;[100] FAILED
	HRRZ	T1,.JBSYM##		;IF LOADING SYMBOLS
	JUMPE	T1,GTLNK2		;[100] NO
	CAMLE	T1,ADDCOR		;SEE IF ABOVE SYMBOLS
	JRST	GTLNK2			;[100] NO, ALL IS WELL

;GIVE BACK SPACE, MOVE SYMBOLS AND TRY AGAIN

	CALL	FUNCT.##,<<SPI,[F.RAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SPUSH	<ADDCOR,SIZCOR>		;PRESERVE THESE ACROSS MOVSYM
	PUSHJ	P,MOVSYM		;MOVE SYMBOLS
	SPOP	<SIZCOR,ADDCOR>		;RESTORE FROM MOVSYM
	SKIPN	STATUS			;DID THAT WIN?
	JRST	GTLNK			;YES, TRY WHOLE CYCLE AGAIN
	CALL	FUNCT.##,<<SPI,[F.COR]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;STILL THERE?
	JRST	E$$CGM			;[100] NO???????????? BUG IN OTS
> ;END IFN FTRELOC

;  ..
	;  ..

GTLNK2:	HRRZ	T0,PH+PH.NUM		;[100] GET LINK NUMBER WE'RE READING
	PUSHJ	P,WRTPTR		;[100] GET WRITABLE LINK FLAGS
	LDB	T1,T0			;[100]   ..
	TXNE	T1,OW.PAG		;[100] IS THIS LINK IN TEMPORARY FILE?
	SETTMP				;[100] YES--TELL INPUT ROUTINES
	MOVE	T1,PH+PH.OVL		;[100] BLOCK# LINK STARTS AT
	PUSHJ	P,%USETI		;SET ON IT
	MOVN	T1,PH+PH.LLN		;[100] -LENGTH
	HRLZ	T0,T1			;LEFT HALF OF IOWD
	HRR	T1,ADDCOR		;START OF BLOCK
	HRRI	T0,-1(T1)		;-LENGTH,,ADDRESS-1
	PUSHJ	P,%INZ			;READ IT
	CLRTMP				;[100] DONE WITH TEMPORARY FILE
;*** NOW CHECK RELOCATION ***
IFN FTRELOC,<
	MOVE	T0,ADDCOR		;ADDRESS WE GOT
	SUB	T0,PH+PH.ADD		;[100] ADDRESS WE WANTED
	MOVE	T1,PH+PH.CST		;[100] WHERE CONTROL SECT SHOULD BE
	ADD	T1,T0			;WHERE IT IS
	MOVEM	T1,THSLNK		;POINT TO IT
	PUSHJ	P,RLC0			;SEE IF RELOCATION REQUIRED
> ;END IFN FTRELOC
IFE FTRELOC,<
	MOVE	T1,PH+PH.CST		;[100] LINK IS ALWAYS WHERE EXPECTED
	MOVEM	T1,THSLNK		;[34] POINT THSLNK TO IT
> ;END IFE FTRELOC
IFN FTLOG,<
	PUSHJ	P,E$$RLN		;[100] NOTIFY LOG FILE OF LINK
  IFN FTRELOC,<
	MOVE	T1,THSLNK
	SKIPE	CS.RLC(T1)		;DID IT NEED RELOCATION?
	PUSHJ	P,E$$RLL		;[100] YES--SAY SO
  > ;END IFN FTRELOC
> ;END OF IFN FTLOG
	MOVE	T1,THSLNK		;ADDRESS OF LINK WE JUST READ IN
	MOVE	T0,CS.SYM(T1)		;[100] SAVE ORIGINAL SYMBOL TABLE PTR
	MOVEM	T0,CS.OSY(T1)		;[100]   ..
	MOVE	T0,CS.FPT(P1)		;GET FORWARD POINTER
	HRLZM	P1,CS.BPT(T1)		;LINK TOWARDS ROOT
	HRRM	T0,CS.FPT(T1)		;POSSIBLE FORWARD LINK
	HRRM	T1,CS.FPT(P1)		;PUTIN NEW FORWARD LINK
	EXCH	T1,T0			;SO WE CAN INDEX TO FORWARD PTR
	TRNE	T1,-1			;BUT NOT IF 0
	HRLM	T0,CS.BPT(T1)		;LINK FORWARD LINK TO THIS ONE
	POPJ	P,
SUBTTL	MULTIPLY-DEFINED ENTRY POINTS


;HERE TO RESOLVE A CALL TO A MULTIPLY-DEFINED ROUTINE. WE HAVE SEVERAL POSSIBLE
;CHOICES, SO ARBITRARILY CHOOSE THE ONE THAT MINIMIZES DISK I/O. ATTEMPT TO
;CHOOSE THE CLOSEST ONE TO THE ROOT IF SEVERAL ARE ALREADY IN MEMORY. OTHERWISE,
;READ ALL THE PREAMBLES AND PICK THE ONE WITH THE LARGEST PATH IN MEMORY, AND
;IF POSSIBLE ONE THAT DOES NOT OVERLAY EXISTING LINKS.

MDL0:	PUSH	P,T3			;ACC FOR AOBJN WORD
	MOVE	T3,JT.MDL(T1)		;GET AOBJN PTR TO MDL TABLE
	ADDI	T3,1			;BYPASS NAME
MDL1:	HLRZ	T0,MT.NUM(T3)		;GET LINK# WE WANT
	MOVE	T2,FSTLNK		;START OF INCORE LIST
	CAMN	T0,CS.NUM(T2)		;MATCH?
	JRST	MDLIC			;YES
	HRRZ	T2,CS.FPT(T2)		;GET NEXT
	JUMPN	T2,.-3			;TRY AGAIN
	ADDI	T3,1			;WORDS ARE PAIRS
	AOBJN	T3,MDL1			;TRY NEXT POSSIBLE ENTRY
	PUSH	P,T1			;SAVE PTR
	MOVE	T3,JT.MDL(T1)		;GET AOBJN PTR BACK
	ADDI	T3,1			;BYPASS NAME
	SPUSH	<T4,T5>			;USED AS COUNTERS
	SETZB	T4,T5			;INITIALIZE
MDL3:	HLRZ	T0,MT.NUM(T3)		;GET POSSIBLE LINK
	PUSHJ	P,RP0			;READ PREAMBLE IN
	HRRZ	T1,PH+PH.FPT		;[100] BLOCK# WE NEED
	CAME	T1,UBLOCK		;SAME AS CURRENT?
	PUSHJ	P,[PUSHJ P,%USETU	;NO SET ON IT
		PJRST	P,%INB]		;AND READ IT IN
	HLRZ	T1,PH+PH.FPT		;[100] REL WORD IN BLOCK
	ADDI	T1,INBFR		;FIX IN CORE
	HRLI	T1,(POINT 18,0,17)	;BYPASS FIRST BYTE SINCE ITS 0
	MOVE	T2,FSTLNK		;GET START
	JFFO	T3,MDL5			;BYPASS ROOT AND CLEAR T4 ON THE FLY
MDL4:	ILDB	T0,T1			;GET NEXT ONE WE WANT
	CAME	T0,CS.NUM(T2)		;MATCH?
	JRST	MDL6			;NO, END OF THIS TRY
	ADDI	T4,1			;ONE MORE MATCH
MDL5:	HRRZ	T2,CS.FPT(T2)		;GET NEXT
	JUMPN	T2,MDL4			;AS LONG AS THERE IS ONE
MDL6:	CAIG	T4,(T5)			;LONGEST PATH YET?
	JRST	.+3			;NO
	HRRZ	T5,T4			;LENGTH
	HRL	T5,T3			;PTR TO IT
	ADDI	T3,1			;WORDS ARE IN PAIRS
	AOBJN	T3,MDL3			;MORE TO TRY?
	HLRZ	T3,T5			;NO PICK LONGEST
	SPOP	<T5,T4>

;  ..
;  ..

	JUMPN	T3,E$$ARL		;[100] HOWEVER IF NONE WERE ANY GOOD
	MOVE	T1,0(P)			; RESTORE ORIGINAL PTR
	MOVE	T3,JT.MDL(T1)		; AND USE FIRST!
	ADDI	T3,1			;BYPASS NAME
E$$ARL:	PUSHJ	P,WARN			;[100] PRINT %OVL PREFIX
	  JRST	MDL2			;NOT WANTED, RESTORE T1
	TYPE	<ARL	Ambiguous request in>
	HRRZ	T1,MT.CST(T3)		;GET CONTROL SEC ADDRESS
	MOVEM	T1,THSLNK		;FOR ERROR MESSAGE
	PUSHJ	P,PRNLNK		;LINK #
	TYPE	< for >			;[100]
	MOVE	T1,0(P)			;GET EXTTAB PTR
	MOVE	T1,JT.MDL(T1)		;GET MULTIPLE-DEFINED PTR
	MOVE	T1,0(T1)		;GET NAME
	PUSHJ	P,PRNSBX
	TYPE	<, using link number > 	;[100]
	HLRZ	T0,MT.NUM(T3)		;GET ONE WE PICKED OUT
	PUSHJ	P,PRNDEC
	PUSHJ	P,CRLF
MDL2:	POP	P,T1
	HRRM	T3,JT.ADR(T1)		;STORE POINTER INCASE RELOCATED
	EXCH	T1,0(P)			;GET OLD T3, PUT T1 ON STACK
	MOVE	T3,MT.CST(T3)		;GET LINK #
	EXCH	T1,T3			;PUT IN T1, RESTORE T3
	JRST	NINC1			;NOT INCORE

MDLIC:	HRRZ	T0,T3			;POINTER TO INTTAB
	POP	P,T3			;RESTORE ACC
	JRST	MINC			;AND SEE IF RELOCATED
SUBTTL	RELOCATE LINK


IFN FTRELOC,<
COMMENT \
USES AC T0 - T5 AS FOLLOWS
T0	TO HOLD TEMP HALF WORD
T1	BYTE WORD (18 BYTES)
T2	TO HOLD BYTE COUNT IN LSH WORD (T1)
T3	OFFSET
T4	AOBJN WORD FOR BYTE WORDS (IN INBFR)
T5	- NO. OF WORDS FOR WHOLE LINK
\

RLC0:	SKIPE	T0			;NONE FOR THIS LINK
	PUSHJ	P,RLC1			;RELOCATE THIS LINK
	MOVX	T0,CF.RLO		;[100] GET READY TO MARK LINK RELOCATED
	MOVE	T1,THSLNK		;GET POINTER
	SKIPE	PH+PH.ORL		;[100] ANY OTHER RELOCATION?
	IORM	T0,CS.FLG(T1)		;YES, DO IT LATER
	POPJ	P,

RLC1:	SPUSH	<T3,T4,T5>		;MORE ACCS
	MOVE	T3,T0			;SAFER PLACE
	MOVE	T1,PH+PH.CST		;[100] WHERE CS SHOULD HAVE BEEN
	ADD	T1,T3			;WHERE IT IS
	MOVEM	T3,CS.RLC(T1)		;STORE DIFF
	SKIPN	T1,PH+PH.REL		;[100] BLOCK WE NEED
	JRST	E$$MAN			;[100] NOT RELOCATABLE
	HLRE	T5,T1			;-NO. OF WORDS IN LINK
	HRRZ	T2,ADDCOR		;FIRST WORD
	HRLI	T2,-^D18		;AOBJN WORD
	PUSHJ	P,RLCRD1		;FIRST TIME
	PUSHJ	P,RLCRW			;GET FIRST WORD
RLC2:	JUMPGE	T1,RLC4			;NO RELOCATION FOR LHS
	HLRZ	T0,(T2)			;GET 1/2 WORD
	ADD	T0,T3			;RELOCATE
	HRLM	T0,(T2)			;PUT BACK
RLC4:	LSH	T1,1			;RIGHT HALF BIT
	JUMPGE	T1,RLC5			;NO RELOCATION
	HRRZ	T0,(T2)			;GET 1/2 WORD
	ADD	T0,T3			;RELOCATE
	HRRM	T0,(T2)			;PUT BACK
RLC5:	LSH	T1,1
	JUMPN	T1,RLC6			;MORE TO DO FOR THIS BYTE WORD?
	AOBJN	T2,.			;USE UP ALL WORDS
	CAIA				; IN THIS 18
RLC6:	AOBJN	T2,RLC2			;LOOP FOR ALL OF LINK
RLC3:	AOJGE	T5,RLCZ			;RAN OUT OF WORDS
	PUSHJ	P,RLCRW			;GET NEXT RELOC WORD
	JUMPE	T1,[ADDI T2,^D18	;NONE FOR THIS WORD
		JRST	RLC3]		;IGNORE 0 WORDS
	HRLI	T2,-^D18		;RESET COUNT
	JRST	RLC2			;GET NEXT DATUM

RLCZ:	SPOP	<T5,T4,T3>		;RESTORE ACCS
	POPJ	P,			;RETURN

RLCRW0:	JUMPE	T5,RLCZ			;SEE IF ALL DONE
	PUSHJ	P,RLCRD			;NO, FILL BUFFER
RLCRW:	AOBJP	T4,RLCRW0		;JUMP IF BUFFER IS EMPTY
	MOVE	T1,(T4)			;GET NEXT WORD
	POPJ	P,

RLCRD:	AOS	T1,UBLOCK		;READ NEXT BLOCK
RLCRD1:	PUSHJ	P,%USETU		;SET ON IT
	PUSHJ	P,%INB			;READ IT IN
	MOVE	T4,[-201,,INBFR-1]	;ACCOUNT FOR INITIAL AOBJX
	POPJ	P,
SUBTTL	OTHER RELOCATION


COMMENT	\
USES AC T0 - T5 AS FOLLOWS
T0	TEMP 1/2 WORD
T1	WORD TO RELOC
T2	RELOC BYTES
T3	OFFSET
T4	AOBJN COUNTER FOR NO. OF WORDS IN BUFFER
T5	-NO. OF WORDS IN THIS LINK,, -NO. OF WORDS IN PH.ORL
\

RLO:	MOVE	T0,CS.NUM(P1)		;GET LINK#
	PUSHJ	P,RP0			;READ IN PREAMBLE AGAIN
	SPUSH	<T3,T4,T5>		;NEED ACCS AGAIN
	MOVE	T1,PH+PH.ORL		;[100] GET POINTER
	HLRZ	T5,T1			;-NO. OF WORDS IN PH.ORL
	PUSHJ	P,RLCRD1		;SETUP FIRST TIME
RLO1:	JUMPE	T5,RLCZ			;ALL DONE
	PUSHJ	P,RLCRW			;READ A WORD
	JUMPE	T1,RLCZ			;ALL DONE
	MOVN	T1,T1			;NO. OF WORDS
	HRL	T5,T1			;FORM AOBJN COUNTER
	PUSHJ	P,RLCRW			;GET LINK#,,ADDRESS
	HLRZ	T2,T1			;LINK#
	HRRZ	T3,T1			;ADDRESS WE WOULD LIKE IT AT
	MOVE	T1,FSTLNK		;START OF CHAIN
RLO2:	CAMN	T2,CS.NUM(T1)		;ONE WE WANT?
	JRST	RLO3			;YES
	HRRZ	T1,CS.FPT(T1)		;GET NEXT
	JUMPN	T1,RLO2			;TRY IT
E$$LNM:	PUSHJ	P,FAIL			;[100] NOT IN CORE!
	TYPE	<LNM	Link number >
	MOVE	T0,T2			;NUMBER WE WANTED
	PUSHJ	P,PRNDEC		;BUT FAILED TO FIND
	TYPE	< not in memory>	;[100]
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP
RLO3:	HRRZ	T1,CS.ADR(T1)		;WHERE IT REALLY IS
	SUBM	T1,T3			;DIFFERENCE
	JUMPE	T3,RLO8			;OK, ITS THERE
RLO4:	AOBJP	T5,RLO1			;GET NEXT LINK 
	PUSHJ	P,RLCRW			;GET A RELOC WORD
	HLLZ	T2,T1			;RELOC BITS
	HRRZ	T1,T1			;ADDRESS
	ADD	T1,CS.RLC(P1)		;PUT IN RIGHT PLACE
RLO5:	JUMPGE	T2,RLO6			;NO RELOC FOR LHS
	HLRZ	T0,(T1)			;GET 1/2 WORD
	ADD	T0,T3			;ADDRESS IT SHOULD BE AT
	HRLM	T0,(T1)
RLO6:	LSH	T2,1			;GET RHS RELOC
	JUMPGE	T2,RLO7			;NONE
	HRRZ	T0,(T1)
	ADD	T0,T3
	HRRM	T0,(T1)
RLO7:	LSH	T2,1
	JUMPE	T2,RLO4			;GET NEXT
	AOJA	T1,RLO5


RLO8:	HLRE	T1,T5			;NO. OF WORDS LEFT IN THIS AREA
	MOVM	T1,T1
;[55]	Insert 1 Line after RLO8+1 Line		PY	5-Jan-81
	SOS	T1		;[55] DECREMENT T1 TO CORRECT FOR RLCRD
	HRL	T1,T1
	ADD	T5,T1			;BYPASS THEM
RLO9:	ADD	T4,T1			;AND IN BUFFER
	JUMPL	T4,RLO1			;TRY NEXT AREA
	HLRZ	T2,T4			;STORE EXCESS
	PUSHJ	P,RLCRD			;GET NEXT BLOCK
	MOVE	T1,T2
;[55]	Insert 1 Line after RLO9+4 Lines	PY	5-Jan-81
	AOS	T1		;[55] DO PART OF FAKED AOBJN
	HRL	T1,T1			;AOBJN TO ADD TO BUFFER PTR
	JRST	RLO9

> ;END OF IFN FTRELOC
SUBTTL	OVERLAY INITIALIZATION -- OVINI - Zero Memory And Get Parameters


OVINI:	SPUSH	<T2,T3,L>		;[100] SAVE ACS FOR INITIALIZATION
	MOVE	T0,[I.ZZ,,I.ZZ+1]
	SETZB	T1,I.ZZ
	BLT	T0,I.END		;ZERO DATA
	MOVEI	T0,1000			;[100] GET MONITOR'S PAGE SIZE
	HRRM	T0,PAGSIZ		;ONLY USED IF SYMBOLS LOADED
IFE TOPS20,<
	PUSHJ	P,GETJOB		;[100] GET JOB NUMBER FOR TEMP FILE NAME
> ;END IFE TOPS20
IFN FTLOG,<
	CALL	FUNCT.##,<<SPI,[F.RNT]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ITIME>>
> ;END IFN FTLOG

;  ..
;  ..

;HERE TO GET THE OVERLAY FILE SPECIFICATION IF WE'RE RUNNING ON TOPS-10. IF THE
;USER CALLED INIOVL, WE'VE ALREADY DONE THIS. OTHERWISE, LOOK FOR THE OVERLAY
;FILE IN THE SAME PLACE THE .EXE FILE CAME FROM. THIS IS DONE WITH 7.01 GETTAB'S
;IF THEY EXIST, OR THE FUNCT. F.IFS FUNCTION IF THEY DON'T.


IFE TOPS20,<
	SKIPE	OVLSPC			;[100] ALREADY HAVE A FILE SPEC?
	JRST	OVINI1			;[100] YES--DON'T NEED TO FIND ONE
	MOVX	T1,'OVL   '		;[100] NO--START WITH .OVL
	MOVEM	T1,OFOLKP+.RBEXT	;[100]   ..


;NOW TRY TO GET WHERE WE CAME FROM (INCLUDING SFD'S) VIA GETTAB.
;IF UNAVAILABLE (OLD MONITOR), USE INFO FROM FUNCT.

	MOVSI	T1,-<.PTMAX-.PTSFD-1>	;[46] NUMBER OF SFD'S
	HRROI	T0,.GTRS0		;[46] GETTAB FOR RUN FROM SFD, THIS JOB
SFDLUP:	PUSH	P,T0			;[46] SAVE OVER GETTAB
	GETTAB	T0,			;[46] GET IT
	  JRST	NOSFD			;[46] GETTAB FAILED, SEE WHY
	MOVEM	T0,OFOPTH+.PTSFD(T1)	;[100] STORE THIS SFD
	POP	P,T0			;[46] RESTORE
	ADDI	T0,1			;[46] INCREMENT GETTAB ARG
	AOBJN	T1,SFDLUP		;[46] LOOP FOR ALL SFD'S
	JRST	GETUFD			;[46] GOT ALL SFDS, NOW FOR UFD


;HERE WHEN A GETTAB TO GET AN SFD FAILED.  SEE IF THE MONITOR IS TOO OLD.

NOSFD:	POP	P,T0			;[46] KEEP STACK IN PHASE
	TRNE	T1,-1			;[46] FAIL FIRST TIME?
	JRST	GETUFD			;[46] NO, GOT SOME SFDS, USE NEW DATA
	JRST	NOT701			;[46] GO USE FUNCT.
;HERE IF THE 7.01 GETTABS WORK.  FILL IN THE REST OF THE DATA.

GETUFD:	SETZM	OFOPTH+.PTSFD(T1)	;[100] FORCE A ZERO AFTER THE LAST SFD
	HRROI	T1,.GTRDI		;[46] UFD OF PATH WE WERE RUN FROM
	GETTAB	T1,			;[46] GET IT
	  JRST	NOT701			;[46] CAN'T
	SKIPN	T1			;[46] THERE?
	JRST	NOT701			;[46] NO, GIVE UP
	MOVEM	T1,OFOPTH+.PTPPN	;[100] STORE UFD TO FINISH PATH BLOCK
	HRROI	T1,.GTRDV		;[46] GET DEVICE WE WERE RUN FROM
	GETTAB	T1,			;[46]  . . .
	  JRST	NOT701			;[46] NOT THERE FORGET IT
	SKIPN	T1			;[46] AVAILABLE?
	JRST	NOT701			;[46] NOPE, DON'T USE THIS INFO
	MOVEM	T1,OFORED+.FODEV	;[100] YES, STORE DEVICE
	HRROI	T1,.GTRFN		;[46] THE FILE NAME WE CAME FROM
	GETTAB	T1,			;[46] GET IT
	  JRST	NOT701			;[46] CAN'T, LEAVE WELL ENOUGH ALONE
	SKIPN	T1			;[46] RETURN ANYTHING?
	  JRST	NOT701			;[46] NO, IGNORE IT
	MOVEM	T1,OFOLKP+.RBNAM	;[100] OK, STORE IT
	MOVEI	T1,OFOPTH		;[100] POINT LOOKUP BLOCK TO PATH BLOCK
	MOVEM	T1,OFOLKP+.RBPPN	;[100] STORE IN .RBPPN
	JRST	OVINI1			;[46] DONE, PROCEED


;HERE IF THE GETTABS DON'T WORK.  USE FUNCT. TO ASK THE OTS THE
;CONTENTS OF THE ACS AT STARTUP.

NOT701:	CALL	FUNCT.##,<<SPI,[F.IFS]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,OFORED+.FODEV>,
<SPI,OFOLKP+.RBNAM>,<SPI,OFOLKP+.RBPPN>>
> ;END IFE TOPS20

;  ..
;  ..

;HERE TO SET UP THE OVERLAY FILE SPECIFICATION IF WE'RE RUNNING ON TOPS-20.
;AGAIN, IF THE USER CALLED INIOVL, WE'RE DONE. OTHERWISE, LOOK FOR THE OVERLAY
;FILE IN THE SAME PLACE AS THE .EXE FILE WE'RE MAPPED FROM. THIS NON-OBVIOUS
;RESTRICTION IS REQUIRED BECAUSE THERE IS NO OTHER WAY TO FIND THE .EXE FILE. A
;SIDE EFFECT IS THAT BREAKPOINTS CANNOT BE SET IN THE OVERLAY HANDLER IN THE
;PAGE THAT IS CHECKED, UNTIL WE GET PAST THE RPACS% JSYS.

IFN TOPS20,<
	SKIPE	STRPTR			;STRING SETUP?
	JRST	OVINI1			;YES
	MOVEI	T1,OVRL1+1000		;[42] SEE IF A PURE PAGE IN THE
	LSH	T1,-9			;[42]   MIDDLE OF OVRLAY IS
	HRLI	T1,.FHSLF		;[42]   SHARABLE
	RPACS%				;[41] READ ACCESSABILITY
	  ERJMP	E$$RPA			;[100] RPACS% JSYS FAILED
	TXNE	T2,PA%PRV		;[42] PRIVATE?
	JRST	E$$OPP			;[100] OVERLAY HANDLER IN PRIVATE PAGE
	RMAP%				;[41] JFN FROM WHENCE WE CAME
	  ERJMP	E$$RMP			;[100] RMAP% JSYS FAILED
	HLRZ	T2,T1			;[42] JFN
	HRROI	T1,INBFR		;[42] WHERE TO STORE IT
	MOVEM	T1,STRPTR		;[42] FOR GTJFN%
	MOVX	T3,<<FLD .JSAOF,JS%DEV>!<FLD .JSAOF,JS%DIR>!
		    <FLD .JSAOF,JS%NAM>!JS%PAF> ;[42] DEV:<DIR>NAME
	JFNS%				;[41]
> ;END IFN TOPS20

;  ..
;  ..

OVINI1:	MOVX	T1,<MOVE T0,JT.FLG(T1)> ;[42]
	MOVEM	T1,.OVRLA		;REPLACE INST
	MOVE	T1,.JBSA##		;GET START ADDRESS
	MOVE	T0,.JBREL##		;AND INITIAL CORE SIZE
	DMOVEM	T0,%JBREL		;STORE
	MOVEI	T1,RESTART		;SO WE CAN RE-INIT THE OVERLAY FILE
	HRRM	T1,.JBSA##		;AFTER ^C START
	PUSHJ	P,OVLINI		;[100] INITIALIZE THE OVERLAY FILE
	DMOVE	T0,[EXP <IOWD DI.LEN,DI>,1] ;[100] READ IN THE DIRECTORY BLOCK
	PUSHJ	P,%USETI		;[100]   ..
	PUSHJ	P,%INZ			;[100]   ..
	HLRE	T1,DI+DI.LPT		;[100] GET NUMBER OF LINKS
	MOVMM	T1,HILINK		;STORE FOR RANGE CHECK
	MOVE	T1,.JBVER##		;GET VERSION NUMBER
	CAME	T1,DI+DI.VER		;[100] SEE IF SAME
	PUSHJ	P,E$$IVN		;[100] WARN USER
	MOVE	T1,DI+DI.LPT		;[100] GET BLOCK # OF NUMBERS
	PUSHJ	P,%USETI
	MOVE	T0,[IOWD 200,IDXBFR]
	PUSHJ	P,%INZ
	SKIPN	T1,DI+DI.WPT		;[100] WRITABLE LINK TABLE TO READ?
	JRST	OVINI6			;[100] NO--DON'T BOTHER
	HLLZ	T0,T1			;[100] YES--READ IT ALL IN
	HRRI	T0,OW-1			;[100]   ..
	PUSHJ	P,%USETI		;[100]   ..
	PUSHJ	P,%INZ			;[100]   ..
	MOVE	T1,DI+DI.FLG		;[100] DOES THIS PROGRAM CONTAIN WRITABLE
	TXNE	T1,OD.WRT		;[100]   OVERLAY LINKS?
	PUSHJ	P,TMPINI		;[100] YES--INITIALIZE THE TEMP FILE
OVINI6:	SETZ	T0,			;[100] READ IN PREAMBLE FOR LINK 0 (ROOT)
	PUSHJ	P,RP1			;[100]   ..
	MOVE	T1,PH+PH.CST		;[100] CONTROL SECTION FOR LINK 0
	MOVEM	T1,FSTLNK

;  ..
;  ..

;TRY TO ALLOCATE MEMORY WHERE THE FIRST LINKS PAST THE ROOT WILL COME IN. IF
;THIS FAILS, TRY GETTING MEMORY AT ADDRESSES IN 1000 WORD INCREMENTS UNTIL WE
;SUCCEED. COBOL USES THE -1 SET IN SIZCOR TO MARK THE END OF THE OTS AREA
;SPECIFIED BY /SPACE IN LINK.

	MOVE	T0,PH+PH.NFL		;[100] NEXT FREE LOC
	MOVEM	T0,ADDCOR		;STORE FOR FUNCT. CALL
OVINI2:	SETOM	SIZCOR			;-1 MEANS GET WHATS FREE
	CALL	FUNCT.##,<<SPI,[F.GAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPN	STATUS			;DID WE WIN?
	JRST	OVINI3			;YES
OVINI5:	MOVEI	T0,1000			;NO, WILL HAVE TO GO RELOCATABLE
	ADDM	T0,ADDCOR		;LEAVE SOME SPACE
	JRST	OVINI2			;AND TRY AGAIN

OVINI3:	CALL	FUNCT.##,<<SPI,[F.RAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	MOVE	T1,ADDCOR		;[100] DID WE GET IT WHERE WE WANTED TO?
	CAME	T1,PH+PH.NFL		;[100]   ..
	PUSHJ	P,E$$STS		;[100] NO--OTS RESERVED SPACE TOO SMALL

;  ..
;  ..

;NOW FOR DDT SYMBOLS FOR ROOT
	SETZM	.JBSYM##		;[32] ASSUME NOT KEEPING SYMBOLS IN CORE
IFN TOPS20,<
	PUSHJ	P,CHKDDT		;[40] STORE S.T. PTR IN DDT IF IT'S THERE
> ;END IFN TOPS20
	SKIPN	T1,PH+PH.RDX		;[100] GET POINTER
	JRST	OVXIT			;[100] NOT WANTED, OR AVAILABLE
	PUSHJ	P,%USETI		;SET ON BLOCK
	HLRE	T1,T1			;-LENGTH
	MOVMM	T1,SIZCOR		;WHAT WE NEED
	ADD	T1,.JBREL##		;FROM TOP OF CORE
	ADDI	T1,1			;SYMBOL TABLE POINTS BEYOND TOP
	CAML	T1,ADDCOR		;LESS THAN END OF ROOT?
	JRST	OVINI4			;NO, USE THE ADDRESS
	MOVE	T0,T1			;YES, SAVE ADDR WANTED
	SUB	T1,ADDCOR		;GET THE OVERLAP
	MOVN	T1,T1			;  OF SYMBOLS OVER ROOT
	ADDI	T1,1777			;ROUND UP, TO THE NEAREST
	ANDI	T1,776000		;  1K BOUNDRY.
	ADD	T1,T0			;ADD TO FIRST TRY
OVINI4:	MOVEM	T1,ADDCOR		;SET START OF SYMBOLS ADDR
	CALL	FUNCT.##,<<SPI,[F.GAD]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;DID WE GET IT?
	JRST	[PUSHJ P,E$$NMS		;[100] NO MEMORY FOR SYMBOLS
		 JRST OVXIT]		;[100] DON'T BOTHER
	MOVE	T0,ADDCOR		;GET ADDRESS
	HLL	T0,PH+PH.RDX		;[100] -LENGTH
	MOVE	T1,PH+PH.CST		;[100] ADDRESS OF HEADER
	MOVEM	T0,CS.SYM(T1)		;SET SYMBOL PTR
	MOVEM	T0,.JBSYM##		;AND FOR DDT
IFN TOPS20,<
	PUSHJ	P,CHKDDT		;[40] STORE S.T. PTR IN DDT IF IT'S THERE
> ;END IFN TOPS20
	SUBI	T0,1			;IOWD IS 1 LESS
	PUSHJ	P,%INZ			;READ IT IN
OVXIT:	SPOP	<L,T3,T2>		;[100] RESTORE ACS
	POPJ	P,			;[100] DONE

POPL:	POP	P,L			;[100] FOR NOW
	POPJ	P,
SUBTTL	FILE ROUTINES -- TOPS-10 -- Overlay And Temp Files -- Initialization


IFE TOPS20,<
OVLINI:	MOVX	T1,FO.ASC		;[100] ALLOCATE A NEW CHANNEL
	HLLM	T1,OFORED+.FOFNC	;[100]   ..
	MOVE	T1,[.FOLEB+1,,OFORED]	;[100] LOOK UP THE OVERLAY FILE
	MOVE	T0,OFOLKP+.RBPPN	;[100] SAVE PPN WORD FROM MAD MONITOR
	FILOP.	T1,			;[100]
	  JRST	[MOVEM T0,OFOLKP+.RBPPN	;[100] RESTORE PPN FOR CORRECT ERR MSG
		 HRLI T1,OFORED		;[100] TELL ERROR ROUTINE WHICH SPEC
		 JRST	E$$CFF]		;[100] CANNOT FIND FILE
	MOVEM	T0,OFOLKP+.RBPPN	;[100] RESTORE PPN FOR CORRECT MSGS
	LDB	T1,[POINTR (OFORED+.FOFNC,FO.CHN)] ;[100] GET ASSIGNED CHANNEL
	DPB	T1,[POINTR (OFOUSI,FO.CHN)] ;[100] STORE WHERE NEEDED
	DPB	T1,[POINTR (OFOINP,FO.CHN)] ;[100]   ..
	POPJ	P,			;[100] DONE
;STILL IN IFE TOPS20

;HERE TO INITIALIZE THE OVERLAY TEMPORARY FILE ON TOPS-10 IF WRITABLE OVERLAYS
;ARE REQUIRED. WE MUST OPEN A NEW FILE CALLED nnnOVL.TMP IN THE USER'S DEFAULT
;PATH. SINCE THE .FOSAU FUNCTION OF FILOP. WILL USE AN EXISTING FILE, IF ANY, WE
;MUST CREATE THE FILE WITH THE .FOWRT FUNCTION FIRST, THEN USE .FOSAU.

TMPINI:	MOVX	T1,FO.ASC+.FOWRT	;[100] ASK FOR CHAN AND SUPERSEDE
	MOVEM	T1,TFOWRT+.FOFNC	;[100]   ..
	MOVE	T1,JOBNUM		;[100] BUILD nnnOVL FILE NAME
	HLLM	T1,TFOENT+.RBNAM	;[100]   ..
	HLLZS	TFOENT+.RBEXT		;[100] FIX ANY DATE-75 BUGS
	MOVE	T1,[.FOLEB+1,,TFOWRT]	;[100] PREPARE TO CREATE THE FILE
	MOVE	T0,TFOENT+.RBPPN	;[100] SAVE PPN WORD FROM MAD MONITOR
	FILOP.	T1,			;[100] CREATE THE FILE
	  JRST	[MOVEM T0,TFOENT+.RBPPN	;[100] RESTORE PPN WORD FOR ERR MSG
		 HRLI T1,TFOWRT		;[100] TELL ERROR ROUTINE WHICH SPEC
		 JRST E$$CWF]		;[100] CANNOT WRITE FILE
	MOVEM	T0,TFOENT+.RBPPN	;[100] RESTORE PPN WORD
	LDB	T1,[POINTR (TFOWRT+.FOFNC,FO.CHN)] ;[100] GET ASSIGNED CHANNEL
	DPB	T1,[POINTR (TFOREL+.FOFNC,FO.CHN)] ;[100] STORE WHERE WE NEED IT
	MOVE	T1,[.FOFNC+1,,TFOREL]	;[100] CLOSE TEMP FILE TO CREATE IT
	FILOP.	T1,			;[100]   ..
	  JRST	[HRLI T1,TFOWRT		;[100] SELECT PROPER FILE SPEC
		 JRST E$$CCF]		;[100] CANNOT CLOSE FILE
	MOVX	T1,FO.ASC+.FOSAU	;[100] FIX FILOP. BLOCK FOR UPDATE
	MOVEM	T1,TFOWRT+.FOFNC	;[100]   MODE
	HLLZS	TFOENT+.RBEXT		;[100] FIX ANY DATE-75 BUGS
	MOVE	T1,[.FOLEB+1,,TFOWRT]	;[100] OPEN FILE IN UPDATE MODE
	MOVE	T0,TFOENT+.RBPPN	;[100] SAVE PPN WORD FROM MAD MONITOR
	FILOP.	T1,			;[100] OPEN THE TEMP FILE
	  JRST	[MOVEM T0,TFOENT+.RBPPN	;[100] RESTORE PPN WORD FOR ERR MSG
		 HRLI T1,TFOWRT		;[100] TELL ERROR ROUTINE WHICH SPEC
		 JRST E$$CUF]		;[100] CANNOT UPDATE FILE
	MOVEM	T0,TFOENT+.RBPPN	;[100] RESTORE PPN WORD
	LDB	T1,[POINTR (TFOWRT+.FOFNC,FO.CHN)] ;[100] GET ASSIGNED CHANNEL
	DPB	T1,[POINTR (TFOUSI,FO.CHN)] ;[100] STORE WHERE NEEDED
	DPB	T1,[POINTR (TFOINP,FO.CHN)] ;[100]   ..
	DPB	T1,[POINTR (TFOUSO,FO.CHN)] ;[100]   ..
	DPB	T1,[POINTR (TFOOUT,FO.CHN)] ;[100]   ..
	POPJ	P,			;[100] DONE
SUBTTL	FILE ROUTINES -- TOPS-10 -- Overlay And Temp Files -- I/O


;STILL IN IFE TOPS20

;%USETU POSITIONS THE OVERLAY OR TEMPORARY FILE ON A SPECIFIED BLOCK NUMBER, AND
;REMEMBERS THAT BLOCK NUMBER IN UBLOCK. %USETI DOES THE SAME THING, BUT DOES NOT
;REMEMBER THE BLOCK NUMBER. THE CALL IS:
;
;	T1/	<ANYTHING>,,<BLOCK NUMBER>
;
;ALL ACS ARE SAVED.

%USETU:	HRRM	T1,UBLOCK		;[100] REMEMBER BLOCK # INBFR WILL HAVE
%USETI:	PUSH	P,T1			;[100] SAVE T1 OVER FILOP.
	HRRZM	T1,FILBLK+.FOIOS	;[100] POSITION FILE ON PROPER BLOCK
	MOVE	T1,OFOUSI		;[100] ASSUME OVERLAY FILE
	SKIPNT				;[100] IS IT THE TEMPORARY FILE INSTEAD?
	MOVE	T1,TFOUSI		;[100] YES--USE THAT FILE
	MOVEM	T1,FILBLK+.FOFNC	;[100]   ..
	MOVE	T1,[.FOIOS+1,,FILBLK]	;[100]   ..
	FILOP.	T1,			;[100]   ..
	  JRST	[HRLI T1,OFORED		;[100] ASSUME WE USED OVERLAY FILE
		 SKIPNT			;[100] DID WE?
		 HRLI T1,TFOWRT		;[100] NO--IT WAS THE TEMPORARY FILE
		 JRST E$$IPE]		;[100] INPUT POSITIONING ERROR
	POP	P,T1			;[100] RESTORE T1
	POPJ	P,			;[100] DONE


;THE THREE ROUTINES HERE ALL READ DATA FROM THE OVERLAY OR TEMPORARY FILE,
;PRESERVING ALL ACCUMULATORS. %INB SETS UP A COMPLETE COMMAND LIST ASSUMING 200
;WORDS AT INBFR, %INZ ASSUMES THAT THE COMMAND WORD IS ALREADY IN T0 AND NEEDS
;ONLY THE ENDING 0 IN T1, AND %IN ASSUMES THAT THE ENTIRE LIST IS ALREADY SET
;UP, BEGINNING IN T0.

%INB:	MOVE	T0,[IOWD 200,INBFR]	;[100] SET UP DEFAULT COMMAND LIST
%INZ:	SETZ	T1,			;[100] FINISH PRE-SPECIFIED LIST
%IN:	PUSH	P,T2			;[100] SAVE AN AC FOR FILOP.
	MOVE	T2,OFOINP		;[100] ASSUME OVERLAY FILE
	SKIPNT				;[100] IS IT?
	MOVE	T2,TFOINP		;[100] NO--USE TEMPORARY FILE FOR READ
	MOVEM	T2,FILBLK+.FOFNC	;[100] STORE FILOP. CHANNEL AND FUNCTION
	SETZM	FILBLK+.FOIOS		;[100] POINTER TO CMD LIST IS IN T0
	MOVE	T2,[.FOIOS+1,,FILBLK]	;[100] READ IN THE DATA
	FILOP.	T2,			;[100]   ..
	  JRST	[HRLI T1,OFORED		;[100] ASSUME IT WAS OVERLAY FILE
		 SKIPNT			;[100] WAS IT?
		 HRLI T1,TFOWRT		;[100] NO--USE THE TEMPORARY FILE
		 JRST E$$IEF]		;[100] INPUT ERROR FOR FILE
	POP	P,T2			;[100] RESTORE T2
	POPJ	P,			;[100] DONE
;STILL IN IFE TOPS20

;%USETO POSITIONS THE TEMPORARY FILE ON A SPECIFIED BLOCK NUMBER FOR WRITING.
;THE CALL IS:
;
;	T1/	<ANYTHING>,,<BLOCK NUMBER>
;
;ALL ACS ARE SAVED.

%USETO:	PUSH	P,T1			;[100] SAVE T1 OVER FILOP.
	HRRZM	T1,FILBLK+.FOIOS	;[100] POSITION FILE ON PROPER BLOCK
	MOVE	T1,TFOUSO		;[100]   ..
	MOVEM	T1,FILBLK+.FOFNC	;[100]   ..
	MOVE	T1,[.FOIOS+1,,FILBLK]	;[100]   ..
	FILOP.	T1,			;[100]   ..
	  JRST	[HRLI T1,TFOWRT		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$OPE]		;[100] OUTPUT POSITIONING ERROR
	POP	P,T1			;[100] RESTORE T1
	POPJ	P,			;[100] DONE


;%OUTZ WRITES DATA TO THE TEMPORARY FILE, PRESERVING ALL ACCUMULATORS. %OUTZ
;ASSUMES THAT THE COMMAND WORD IS ALREADY IN T0 AND NEEDS ONLY THE ENDING 0 IN
;T1.

%OUTZ:	SETZ	T1,			;[100] FINISH PRE-SPECIFIED LIST
	PUSH	P,T2			;[100] SAVE AN AC FOR FILOP.
	MOVE	T2,TFOOUT		;[100] USE TEMPORARY FILE FOR WRITE
	MOVEM	T2,FILBLK+.FOFNC	;[100] STORE FILOP. CHANNEL AND FUNCTION
	SETZM	FILBLK+.FOIOS		;[100] POINTER TO CMD LIST IS IN T0
	MOVE	T2,[.FOIOS+1,,FILBLK]	;[100] READ IN THE DATA
	FILOP.	T2,			;[100]   ..
	  JRST	[HRLI T1,TFOWRT		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$OEF]		;[100] OUTPUT ERROR FOR FILE
	POP	P,T2			;[100] RESTORE T2
	POPJ	P,			;[100] DONE
SUBTTL	FILE ROUTINES -- TOPS-10 -- Overlay And Temp Files -- Argument Blocks


;STILL IN IFE TOPS20

;FILE SPECIFICATION BLOCK DEFINITIONS FOR GETSPC AND PRNFSP.

	LOC	0			;[100]
$FOFIL:!BLOCK	.FOLEB+1		;[100] FILOP. BLOCK
$FORIB:!BLOCK	.RBEXT+1		;[100] LOOKUP/ENTER BLOCK
$FOPTH:!BLOCK	FTSFD+4			;[100] PATH. BLOCK
	RELOC				;[100]


	SEGMENT	LOW

;FILOP. ARGUMENT BLOCKS FOR INITIALIZING THE OVERLAY OR TEMPORARY FILE. THESE
;MUST BE LEFT INTACT FOR USE IN ERROR MESSAGES LATER. NOTE THAT THE FILOP.,
;LOOKUP, AND PATH. BLOCKS **MUST** BE CONSECUTIVE FOR GETSPC.

OFORED:	.-.,,.FORED			;[100] FUNCTION AND FLAGS
	.IODMP				;[100] ALL I/O IN DUMP MODE
	.-.				;[100] DEVICE IS FILLED IN
	0,,0				;[100] DUMP MODE SO NO BUFFERS
	0,,0				;[100]   ..
	0,,OFOLKP			;[100] ADDRESS OF LOOKUP BLOCK

OFOLKP:	3				;[100] LOOKUP BLOCK--COUNT OF ARGS
	.-.				;[100] CHANGED TO PATH
	.-.				;[100] CHANGED TO FILE NAME
	.-.				;[100] CHANGED TO FILE EXTENSION

OFOPTH:	BLOCK	FTSFD+4			;[100] CHANGED TO PATH


;ARGUMENT BLOCKS FOR THE TEMPORARY FILE INITIALIZATION.

TFOWRT:	.-.				;[100] FUNCTION AND FLAGS
	.IODMP				;[100] ALL I/O IN DUMP MODE
	'DSK   '			;[100] DEFAULT DEVICE
	0,,0				;[100] DUMP MODE SO NO BUFFERS
	0,,0				;[100]   ..
	0,,TFOENT			;[100] ADDRESS OF ENTER BLOCK

TFOENT:	3				;[100] BLOCK LENGTH
	0				;[100] DEFAULT PATH
	.-.,,'OVL'			;[100] nnnOVL.TMP FILE NAME
	'TMP',,.-.			;[100]   ..

TFOREL:	.-.,,.FOREL			;[100] CLOSE THE FILE
;STILL IN IFE TOPS20

;THESE ARGUMENT BLOCKS CONTAIN THE .FOFNC WORD FOR THE OVERLAY AND TEMPORARY
;FILE POSITIONING AND INPUT OPERATIONS. THE ASSIGNED CHANNEL NUMBER IS STORED IN
;THEM FOLLOWING INITIALIZATION. EACH IS COPIED TO FILBLK ALONG WITH THE
;APPROPRIATE ARGUMENT TO PERFORM A PARTICULAR OPERATION.

OFOUSI:	.-.,,.FOUSI			;[100] POSITION FILE FOR INPUT
OFOINP:	.-.,,.FOINP			;[100] READ DATA
TFOUSI:	.-.,,.FOUSI			;[100] POSITION FILE FOR INPUT
TFOINP:	.-.,,.FOINP			;[100] READ DATA
TFOUSO:	.-.,,.FOUSO			;[100] POSITION FILE FOR OUTPUT
TFOOUT:	.-.,,.FOOUT			;[100] WRITE DATA

FILBLK:	BLOCK	2			;[100] FILOP. ARG BLOCK FOR ABOVE

	SEGMENT	HIGH			;[100] BACK TO CODE
SUBTTL	FILE ROUTINES -- TOPS-10 -- Error Messages


;STILL IN IFE TOPS20

;ALL TOPS-10 ERROR MESSAGE ROUTINES THAT PRINT THE FILE SPECIFICATION EXPECT:
;
;	T1/	<ADDRESS OF I/O DATA BLOCK>,,<FILOP. ERROR CODE OR STATUS>

E$$NSD:	PUSH	P,T1			;[100] SAVE FILE SPEC BLOCK ADDRESS
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<NSD	No such device for >
	POP	P,T1			;[100] GET BACK FILE SPEC ADDRESS
	PUSHJ	P,PRNFSP		;[100] PRINT THE AILING FILE SPEC
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

E$$CWF:	PUSH	P,T1			;[100] SAVE FILE SPEC BLOCK ADDR
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<CWF	Cannot write file >
.ERFS1:	MOVE	T1,(P)			;[100] GET BACK FILE SPEC ADDRESS
	PUSHJ	P,PRNFSP		;[100] PRINT AILING FILE SPEC
	POP	P,T1			;[100] GET BACK FILE SPEC ADDRESS
	PUSHJ	P,PRNLEE		;[100] PRINT LOOKUP/ENTER ERROR
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP				;[100] DIE NOW

E$$CFF:	PUSH	P,T1			;[100] SAVE FILE SPEC BLOCK ADDR
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<CFF	Cannot find file >
	PJRST	.ERFS1			;[100] GO PRINT FILE SPEC AND REASON

E$$CUF:	PUSH	P,T1			;[100] SAVE FILE SPEC BLOCK ADDRESS
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<CUF	Cannot update file >
	PJRST	.ERFS1			;[100] GO PRINT FILE SPEC AND REASON
;STILL IN IFE TOPS20

E$$CCF:	PUSH	P,T1			;[100] SAVE FILE SPEC BLOCK ADDRESS
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<CCF	Cannot close file >
.ERFS2:	HRRZ	T1,(P)			;[100] GET BACK FILE SPEC ADDRESS
	PUSHJ	P,PRNFSP		;[100] PRINT THE AILING FILE SPEC
	TYPE	<, status >		;[100] TYPE THE STATUS
	POP	P,T0			;[100] GET BACK THE FILE STATUS
	HRRZS	T0			;[100]   ..
	PUSHJ	P,PRNOCT		;[100] PRINT THE FILE STATUS
	PUSHJ	P,CRLF			;[100] FINISH THE LINE
	STOP				;[100] DIE NOW

E$$IPE:	PUSH	P,T1			;[100] SAVE STATUS AND FILE SPEC BLOCK
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<IPE	Input positioning error for file >
	PJRST	.ERFS2			;[100] GO PRINT FILE SPEC AND STATUS

E$$IEF:	PUSH	P,T1			;[100] SAVE STATUS AND FILE SPEC BLOCK
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<IEF	Input error for file >
	PJRST	.ERFS2			;[100] GO PRINT FILE SPEC AND STATUS

E$$OPE:	PUSH	P,T1			;[100] SAVE STATUS AND FILE SPEC BLOCK
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<OPE	Output positioning error for file >
	PJRST	.ERFS2			;[100] GO PRINT FILE SPEC AND STATUS

E$$OEF:	PUSH	P,T1			;[100] SAVE STATUS AND FILE SPEC BLOCK
	PUSHJ	P,FAIL			;[100] PRINT ?OVL
	TYPE	<OEF	Output error for file >
	PJRST	.ERFS2			;[100] GO PRINT FILE SPEC AND STATUS
SUBTTL	FILE ROUTINES -- TOPS-10 -- Log File -- Initialization


;STILL IN IFE TOPS20
  IFN FTLOG,<

LOGINI:	SPUSH	<T2,L>			;[100] SAVE SOME ACS
	MOVE	T1,LFOWRT+.FODEV	;[100] SEE IF DEVICE IS USER'S TERMINAL
	DEVCHR	T1,			;[100]   ..
	JUMPE	T1,[HRLZI T1,LFOWRT	;[100] SELECT FILE SPEC FOR MESSAGE
		 JRST E$$NSD]		;[100] NO SUCH DEVICE
	TXC	T1,DV.TTA!DV.AVL	;[100] IF CONTROLLING TERMINAL AND
	TXCN	T1,DV.TTA!DV.AVL	;[100]   AVAILABLE TO US
	JRST	[SETOM .OVRLO		;[100] THEN USE SIMPLER CALLS FOR OUTPUT
		 JRST LOGINX]		;[100]   ..
	MOVEI	T1,LFOWRT+.FOIOS	;[100] GET BUFFER SIZES FOR FILOP.
	DEVSIZ	T1,			;[100]   ..
	  PUSHJ	P,E$$IMP		;[100] ?? DEVCHR SAID DEVICE EXISTS
	HLRZ	T2,T1			;[100] COMPUTE TOTAL # WORDS
	IMULI	T2,(T1)			;[100]   ..
	MOVEM	T2,SIZCOR		;[100] GET THAT MUCH FROM FUNCT.
	CALL	FUNCT.##,<<SPI,[F.GOT]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;[100] DID WE GET IT?
	PUSHJ	P,E$$MEF		;[100] NO--MEMORY EXPANSION FAILED
	MOVE	T1,ADDCOR		;[100] REMEMBER ARGS FOR LATER CLOSE
	HRL	T1,SIZCOR		;[100]   ..
	MOVEM	T1,.OVRLO		;[100]   ..
	PUSH	P,.JBFF##		;[100] MAKE BUFFERS GO IN NEW MEMORY
	HRRZM	T1,.JBFF##		;[100]   ..
	MOVX	T1,FO.ASC		;[100] ALLOCATE AN EXTENDED CHANNEL
	HLLM	T1,LFOWRT+.FOFNC	;[100]   ..
	MOVE	T1,[.FOLEB+1,,LFOWRT]	;[100] OPEN THE LOG FILE
	MOVE	T0,LFOENT+.RBPPN	;[100] SAVE PPN FROM MAD MONITOR
	FILOP.	T1,			;[100]
	  JRST	[MOVEM T0,LFOENT+.RBPPN	;[100] RESTORE PPN FOR ERROR MESSAGE
		 HRLI T1,LFOWRT		;[100] TELL ERROR ROUTINE WHICH SPEC
		 JRST E$$CWF]		;[100] CANNOT WRITE FILE
	MOVEM	T0,LFOENT+.RBPPN	;[100] RESTORE PPN FOR MESSAGES
	POP	P,.JBFF##		;[100] RESTORE .JBFF
	LDB	T1,[POINTR (LFOWRT+.FOFNC,FO.CHN)] ;[100] GET ALLOCATED CHANNEL
	DPB	T1,[POINTR (LFOOUT,FO.CHN)] ;[100] STORE WHERE NEEDED
	DPB	T1,[POINTR (LFOREL,FO.CHN)] ;[100]   ..
LOGINX:	SPOP	<L,T2>			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE
  > ;END IFN FTLOG
SUBTTL	FILE ROUTINES -- TOPS-10 -- Log File -- I/O


;STILL IN IFE TOPS20

;OUTTTY EXPECTS A CHARACTER IN T0, AND UNCONDITIONALLY SENDS IT TO THE USER'S
;TERMINAL. TTYOUT IS CALLED INDIRECTLY VIA PRNCHR.

OUTTTY:	OUTCHR	T0,			;[100] PRINT THE CHARACTER
	POPJ	P,			;[100] DONE


;POSCHK GIVES A SKIP RETURN IF THE OUTPUT FILE IS CURRENTLY POSITIONED AT THE
;LEFT MARGIN, AND A NON-SKIP RETURN IF NOT (OR IF WE CAN'T TELL). THE LOG FILE
;IS ALWAYS CONSIDERED TO BE AT THE LEFT MARGIN. FOR THE USER'S TERMINAL, TOPS-10
;PROVIDES NO EASY FACILITY FOR CHECKING THIS THAT IS SYNCHRONIZED WITH
;CHARACTERS WE HAVE SENT TO THE TERMINAL. THEREFORE, WE WAIT UNTIL ALL OUTPUT TO
;THE TERMINAL HAS STOPPED (CHECKING LESS OFTEN IF THE TERMINAL IS PAGED), AND
;THEN READ THE TERMINAL'S HORIZONTAL POSITION.

POSCHK:	MOVEI	T1,OUTTTY		;[100] IS THE TERMINAL SELECTED?
	CAME	T1,PRNCHR		;[100]   ..
	JRST	POSCX1			;[100] NO--LOG FILE ALWAYS AT LEFT MARGIN
	SETZB	T0,T4			;[100] SET SLEEP CTRS FOR SPEED FIRST TIME
	SETO	T3,			;[100] READ CONTROLLING TERMINAL'S PARMS
POSCH1:	MOVE	T1,[2,,2]		;[100] SET UP PERMANENT TRMOP. ARG
	MOVEI	T2,.TOSOP		;[100] IF TERMINAL'S BUFFER IS EMPTY
	TRMOP.	T1,			;[100]   ..
	  JRST	POSCH3			;[100] THEN WE CAN READ POSITION
	SOJGE	T0,POSCH2		;[100] ELSE TIME TO RECHECK PAGING
	MOVEI	T2,.TOSTP		;[100] TERMINAL PAGED?
	TRMOP.	T1,			;[100]   ..
	  JRST	POSCX			;[100] NO TRMOP.'S--ASSUME NOT AT LEFT
	SKIPN	T4,T1			;[100] SLEEP 1 SEC OR 1 TICK
	MOVEI	T1,^D60			;[100] WAIT AWHILE BEFORE CHECKING AGAIN
POSCH2:	SLEEP	T4,			;[100] WAIT  FOR A WHILE
	JRST	POSCH1			;[100]   ..

POSCH3:	MOVEI	T2,.TOHPS		;[100] OUTPUT STOPPED--READ TERM'S POS
	TRMOP.	T1,			;[100]   ..
	  JRST	POSCX			;[100] NO TRMOP.'S, ASSUME NOT AT LEFT
	SKIPN	T1			;[100] TERMINAL AT LEFT MARGIN?
POSCX1:	AOS	(P)			;[100] YES--GIVE SKIP RETURN
POSCX:	POPJ	P,			;[100] NO--GIVE NON-SKIP RETURN
;STILL IN IFE TOPS20

;OUTLOG EXPECTS A CHARACTER IN T0, AND UNCONDITIONALLY SENDS IT TO THE LOG FILE.
;OUTLOG IS CALLED INDIRECTLY VIA PRNCHR.

  IFN FTLOG,<

OUTLOG:	SOSGE	LFOBUF+.BFCTR		;[100] ROOM FOR MORE CHARACTERS?
	PJRST	OUTLO1			;[100] NO--TIME FOR OUTPUT
	IDPB	T0,LFOBUF+.BFPTR	;[100] YES--SIMPLY SEND THE CHARACTER
	POPJ	P,			;[100] DONE

OUTLO1:	PUSH	P,T1			;[100] SAVE AN AC
	MOVE	T1,LFOOUT		;[100] BUILD FILOP. OUTPUT BLOCK FOR
	MOVEM	T1,FILBLK+.FOFNC	;[100]   THE OUTPUT
	SETZM	FILBLK+.FOIOS		;[100]   ..
	MOVE	T1,[.FOIOS+1,,FILBLK]	;[100] WRITE A BUFFER-FULL
	FILOP.	T1,			;[100]   ..
	  JRST	[HRLI T1,LFOWRT		;[100] SELECT PROPER FILE SPEC
		 JRST E$$OEF]		;[100] OUTPUT ERROR FOR FILE
	POP	P,T1			;[100] RESTORE ACS
	PJRST	OUTLOG			;[100] TRY NOW
;STILL IN IFE TOPS20, IFN FTLOG

;LOGCLS CLOSES THE LOG FILE. IF THE TERMINAL IS THE LOG FILE, THEN WE SIMPLY
;STOP LOGGING. OTHERWISE, IF THE LOG FILE IS 'REAL', WE CLOSE IT AND RETURN THE
;MEMORY ASSIGNED FOR BUFFERS.

LOGCLS:	PUSH	P,L			;[100] SAVE ACS
	SKIPG	.OVRLO			;[100] IF IT'S JUST THE USER'S TERMINAL
	JRST	LOGCLX			;[100] THEN JUST STOP LOGGING
	MOVE	T1,[.FOFNC+1,,LFOREL]	;[100]   ..
	FILOP.	T1,			;[100]   ..
	  JRST	[HRLI T1,LFOWRT		;[100] SELECT PROPER FILE SPEC
		 JRST E$$CCF]		;[100] CANNOT CLOSE FILE
	MOVE	T1,.OVRLO		;[100] FREE UP ASSIGNED BUFFER SPACE
	HRRZM	T1,ADDCOR		;[100]   ..
	HLRZM	T1,SIZCOR		;[100]   ..
	CALL	FUNCT.##,<<SPI,[F.ROT]>,<AS,OVLNAM>,<SPI,STATUS>,<SPI,ADDCOR>,<SPI,SIZCOR>>
	SKIPE	STATUS			;[100] WERE BUFFERS RETURNED OK?
	JRST	E$$CSM			;[100] NO--CANNOT SHRINK MEMORY
LOGCLX:	SETZM	.OVRLO			;[100] NO LOG FILE ANYMORE
	POP	P,L			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE

  > ;END IFN FTLOG
SUBTTL	FILE ROUTINES -- TOPS-10 -- Log File -- Argument Blocks


;STILL IN IFE TOPS20, IFN FTLOG

;ARGUMENT BLOCKS FOR THE LOG FILE INITIALIZATION. NOTE THAT THE FILOP., LOOKUP,
;PATH., AND FILOP. GETSTS BLOCKS **MUST** BE CONSECUTIVE (SEE $FOFIL
;DEFINITIONS).

  IFN FTLOG,<
LFOWRT:	.-.,,.FOWRT			;[100] FUNCTION AND FLAGS
	.IOASL				;[100] ASCII LINE MODE FOR I/O
	.-.				;[100] DEVICE IS FILLED IN
	LFOBUF,,0			;[100] OUTPUT BUFFER HEADER
	0,,0				;[100] DEFAULT NUMBER OF BUFFERS
	0,,LFOENT			;[100] ADDRESS OF ENTER BLOCK

LFOENT:	3				;[100] BLOCK LENGTH
	.-.				;[100] DEFAULT PATH
	.-.				;[100] CHANGED TO FILE NAME
	.-.				;[100] CHANGED TO FILE EXTENSION

LFOPTH:	BLOCK	FTSFD+4			;[100] CHANGED TO PATH

LFOBUF:	BLOCK	3			;[100] BUFFER HEADER

;THESE ARGUMENT BLOCKS CONTAIN THE .FOFNC WORD FOR THE LOG FILE I/O OPERATIONS.
;THE ASSIGNED CHANNEL NUMBER IS STORED IN THEM FOLLOWING LOG FILE
;INITIALIZATION. EACH IS COPIED TO FILBLK ALONG WITH THE APPROPRIATE ARGUMENT TO
;PERFORM A PARTICULAR OPERATION.

LFOOUT:	.-.,,.FOOUT			;[100] WRITE DATA
LFOREL:	.-.,,.FOREL			;[100] CLOSE THE LOG FILE

  > ;END IFN FTLOG
> ;END IFE TOPS20
SUBTTL	FILE ROUTINES -- TOPS-20 -- Overlay And Temp Files -- Initialization


;HERE TO INITIALIZE THE OVERLAY FILE ON TOPS-20. SIMPLY GET A JFN ON IT, AND
;OPEN IT. THE CALL IS:
;
;	STRPTR/	BYTE POINTER TO ASCIZ OVERLAY FILE SPECIFICATION, AS SUPPLIED BY
;		THE USER IN INIOVL, OR DEFAULTED IN OVINI

IFN TOPS20,<
OVLINI:	MOVX	T1,GJ%OLD		;[100] FILE MUST EXIST
	MOVEM	T1,DEFTBL+.GJGEN	;[100]   ..
	HRROI	T1,[ASCIZ /OVL/]	;[100] SET DEFAULT FILE TYPE TO .OVL
	MOVEM	T1,DEFTBL+.GJEXT	;[100]   ..
	MOVEI	T1,DEFTBL		;[100] GET JFN FOR OVERLAY FILE
	MOVE	T2,STRPTR		;[42]
	GTJFN%				;[41]
	  ERJMP	[MOVE T1,STRPTR		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$CFF]		;[100] CANNOT FIND FILE
	HRRZM	T1,OVRJFN		;[100] SAVE THE JFN
	MOVX	T2,<<FLD ^D36,OF%BSZ>!OF%RD> ;[100] OPEN FOR INPUT, 36 BITS
	OPENF%				;[100]   ..
	  ERJMP	[MOVE T1,OVRJFN		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$CRF]		;[100] CANNOT FIND FILE
	POPJ	P,			;[100] DONE


;TMPINI INITIALIZES THE TEMPORARY FILE ON TOPS-20. SIMPLY GET A JFN ON IT, AND
;OPEN IT.

TMPINI:	MOVX	T1,GJ%FOU!GJ%TMP	;[100] NEW TEMPORARY FILE
	HRROI	T1,TMPNAM		;[100]   ..
	GTJFN%				;[100]   ..
	  ERJMP	[MOVEI T1,TMPNAM	;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$CFF]		;[100] CANNOT WRITE FILE
	HRRZM	T1,TMPJFN		;[100] SAVE JFN FOR LATER USE
	MOVX	T2,<<FLD ^D36,OF%BSZ>!OF%RD!OF%WR> ;[100] OPEN FOR READ AND WRITE
	OPENF%				;[100]   ..
	  ERJMP	[MOVE T1,TMPJFN		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$CWF]		;[100] CANNOT WRITE FILE
	POPJ	P,			;[100] DONE
SUBTTL	FILE ROUTINES -- TOPS-20 -- Overlay And Temp Files -- I/O


;STILL IN IFN TOPS20

;%USETU POSITIONS THE OVERLAY OR TEMPORARY FILE ON A SPECIFIED BLOCK NUMBER, AND
;REMEMBERS THAT BLOCK NUMBER IN UBLOCK. %USETI DOES THE SAME THING, BUT DOES NOT
;REMEMBER THE BLOCK NUMBER. THE CALL IS:
;
;	T1/	<ANYTHING>,,<BLOCK NUMBER>
;
;ALL ACS ARE SAVED.

%USETU:	HRRM	T1,UBLOCK		;[100] STORE INCORE BLOCK TO BE
%USETI:	SPUSH	<T1,T2>			;[100] SAVE JSYS ACS
	MOVEI	T2,-1(T1)		;[42] GET BLOCK -1
	LSH	T2,7			;[42] WORDS
	MOVE	T1,OVRJFN		;[100]  ASSUME WE POSITION OVERLAY FILE
	SKIPNT				;[100] TEMPORARY FILE INSTEAD?
	MOVE	T1,TMPJFN		;[100] YES--USE IT THEN
	SFPTR%				;[100] POSITION THE FILE
	  ERJMP	[MOVE T1,OVRJFN		;[100] SELECT PROPER FILE SPECIFICATION
		 SKIPNT			;[100]   ..
		 MOVE T1,TMPJFN		;[100]   ..
		 JRST E$$IPE]		;[100] INPUT POSITIONING ERROR
	SPOP	<T2,T1>			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE


;THE THREE ROUTINES HERE ALL READ DATA FROM THE OVERLAY OR TEMPORARY FILE,
;PRESERVING ALL ACCUMULATORS. %INB SETS UP A COMPLETE COMMAND LIST ASSUMING 200
;WORDS AT INBFR, %INZ ASSUMES THAT THE COMMAND WORD IS ALREADY IN T0 AND NEEDS
;ONLY THE ENDING 0 IN T1, AND %IN ASSUMES THAT THE ENTIRE LIST IS ALREADY SET
;UP, BEGINNING IN T0.

%INB:	MOVE	T0,[IOWD 200,INBFR]
%INZ:					;[100]
%IN:	SPUSH	<T2,T3>			;[100] SAVE JSYS ACS
	MOVE	T1,OVRJFN		;[100] ASSUME OVERLAY FILE
	SKIPNT				;[100] IS IT THE TEMPORARY FILE INSTEAD?
	MOVE	T1,TMPJFN		;[100] YES--USE IT THEN
	HRRZ	T2,T0			;[100] BUILD BYTE POINTER TO BUFFER
	HRLI	T2,(POINT 36,0,35)	;[100]   ..
	HLRO	T3,T0			;[42] - WORD COUNT
	SIN%				;[100] READ IN THE DATA
	  ERJMP	[MOVE T1,OVRJFN		;[100] SELECT PROPER FILE SPECIFICATION
		 SKIPNT			;[100]   ..
		 MOVE T1,TMPJFN		;[100]   ..
		 JRST E$$IEF]		;[100] INPUT ERROR FOR FILE
	SPOP	<T3,T2>			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE
;STILL IN IFN TOPS20


;%USETO POSITIONS THE TEMPORARY FILE ON A SPECIFIED BLOCK NUMBER FOR WRITING.
;THE CALL IS:
;
;	T1/	<ANYTHING>,,<BLOCK NUMBER>
;
;ALL ACS ARE SAVED.

%USETO:	SPUSH	<T1,T2>			;[100] SAVE JSYS ACS
	MOVEI	T2,-1(T1)		;[100] GET BLOCK -1
	LSH	T2,7			;[100] WORDS
	MOVE	T1,TMPJFN		;[100] SELECT THE TEMP FILE
	SFPTR%				;[100] POSITION THE FILE
	  ERJMP	[MOVE T1,TMPJFN		;[100] SELECT PROPER FILE SPEC
		 JRST E$$OPE]		;[100] OUTPUT POSITIONING ERROR
	SPOP	<T2,T1>			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE


;%OUTZ WRITES DATA TO THE TEMPORARY FILE, PRESERVING ALL ACCUMULATORS. %OUTZ
;ASSUMES THAT THE COMMAND WORD IS ALREADY IN T0.

%OUTZ:	SPUSH	<T2,T3>			;[100] SAVE JSYS ACS
	MOVE	T1,TMPJFN		;[100] SELECT THE TEMP FILE
	HRRZ	T2,T0			;[100] BUILD BYTE POINTER TO BUFFER
	HRLI	T2,(POINT 36,0,35)	;[100]   ..
	HLRO	T3,T0			;[100] - WORD COUNT
	SIN%				;[100] READ IN THE DATA
	  ERJMP	[MOVE T1,TMPJFN		;[100] SELECT PROPER FILE SPEC
		 JRST E$$OEF]		;[100] INPUT ERROR FOR FILE
	SPOP	<T3,T2>			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE
SUBTTL	FILE ROUTINES -- TOPS-20 -- Overlay And Temp Files -- Argument Blocks


;STILL IN IFN TOPS20

	SEGMENT	LOW

DEFTBL:	.-.				;[100] GTJFN% FLAGS
	.NULIO,,.NULIO			;[42] DON'T READ FROM ANYWHERE
	0				;[100]
	0
	0
	.-.				;[100] DEFAULT TYPE
	0
	0
	0

	SEGMENT	HIGH
SUBTTL	FILE ROUTINES -- TOPS-20 -- Overlay And Temp Files -- Error Messages


;STILL IN IFN TOPS20

;GTJFN% FAILURE MESSAGES CANNOT BE PROVIDED THE JFN, SINCE ONE WAS NOT ASSIGNED.
;THUS, THESE EXPECT:
;
;	T1/	ADDRESS OF FILE SPEC USED FOR THE GTJFN%

E$$CFF:	PUSH	P,T1			;[100] SAVE THE FILE SPEC ADDRESS
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<CFF	Cannot find file > ;[100]
.ERCF1:	POP	P,T1			;[100] GET BACK THE FILE SPEC
	PUSHJ	P,PRNTXT		;[100] PRINT THE FILE SPECIFICATION
	PUSHJ	P,PRNJSE		;[100] GIVE SYSTEM'S REASON FOR FAILURE
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP				;[100] DIE

;ALL OTHER FILE ERROR MESSAGE ROUTINES EXPECT:
;
;	T1/	JFN OF THE FILE

E$$CWF:	PUSH	P,T1			;[100] SAVE THE JFN
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<CWF	Cannot write file > ;[100]
.ERCW1:	POP	P,T1			;[100] GET BACK THE JFN
	PUSHJ	P,PRNFSP		;[100] PRINT THE FILE SPECIFICATION
	PUSHJ	P,PRNJSE		;[100] PRINT THE SYSTEM'S REASON
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP				;[100] DIE

E$$CRF:	PUSH	P,T1			;[100] SAVE THE JFN
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<CRF	Cannot read file > ;[100]
	PJRST	.ERCW1			;[100] PRINT FILE SPEC, REASON, AND DIE

E$$IPE:	PUSH	P,T1			;[100] SAVE THE JFN
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<IPE	Input positioning error for file > ;[100]
	PJRST	.ERCW1			;[100] PRINT FILE SPEC, REASON, AND DIE

E$$IEF:	PUSH	P,T1			;[100] SAVE THE JFN
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<IEF	Input error for file > ;[100]
	PJRST	.ERCW1			;[100] PRINT FILE SPEC, REASON, AND DIE
;STILL IN IFN TOPS20

E$$OPE:	PUSH	P,T1			;[100] SAVE THE JFN
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<OPE	Output positioning error for file > ;[100]
	PJRST	.ERCW1			;[100] PRINT FILE SPEC, REASON, AND DIE

E$$OEF:	PUSH	P,T1			;[100] SAVE THE JFN
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<OEF	Output error for file > ;[100]
	PJRST	.ERCW1			;[100] PRINT FILE SPEC, REASON, AND DIE

E$$CCF:	PUSH	P,T1			;[100] SAVE THE JFN
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<CCF	Cannot close file > ;[100]
	PJRST	.ERCW1			;[100] PRINT FILE SPEC, REASON, AND DIE

E$$OPP:	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<OPP	Overlay handler in private page> ;[100]
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

E$$RPA:	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<RPA	RPACS% JSYS failed> ;[100]
	PUSHJ	P,PRNJSE
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

E$$RMP:	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<RMP	RMAP% JSYS failed> ;[100]
	PUSHJ	P,PRNJSE
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP
SUBTTL	FILE ROUTINES -- TOPS-20 -- Log File -- Initialization


;STILL IN IFN TOPS20

;HERE TO INITIALIZE THE LOG FILE ON TOPS-20. SIMPLY GET A JFN ON IT, AND OPEN
;IT. THE CALL IS:
;
;	@(L)/	ADDRESS OF ASCIZ LOG FILE SPECIFICATION, AS SUPPLIED BY THE USER

LOGINI:	PUSH	P,T2			;[100] SAVE AN AC FOR JSYSES
	MOVX	T1,GJ%FOU		;[100] NEW FILE
	MOVEM	T1,DEFTBL+.GJGEN	;[100]   ..
	MOVEI	T1,DEFTBL		;[100] GET JFN FOR LOG FILE
	HRROI	T2,@(L)			;[100]   ..
	GTJFN%				;[100]   ..
	  ERJMP	[HRRZ T1,.OVRLO		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$CFF]		;[100] CANNOT FIND FILE
	HRRZM	T1,.OVRLO		;[100] SAVE THE JFN

;**; Find out if spec is user's terminal, and set .OVRLO to -1,,.PRIOU if so.
;**; If so, release the JFN too.

	MOVX	T2,<<FLD ^D36,OF%BSZ>!OF%RD> ;[100] OPEN FOR INPUT, 36 BITS
	OPENF%				;[100]   ..
	  ERJMP	[HRRZ T1,.OVRLO		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$CFF]		;[100] CANNOT FIND FILE
LOGINX:	POP	P,T2			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE
SUBTTL	FILE ROUTINES -- TOPS-20 -- Log File -- I/O


;OUTTTY EXPECTS A CHARACTER IN T0, AND UNCONDITIONALLY SENDS IT TO THE USER'S
;TERMINAL. OUTTTY IS CALLED INDIRECTLY VIA PRNCHR. NO ACS ARE DESTROYED.

OUTTTY:	PUSH	P,T1			;[100] SAVE AN AC
	MOVE	T1,T0			;[100] SEND THE CHARACTER
	PBOUT%				;[100]   ..
	POP	P,T1			;[100] RESTORE THE CHARACTER
	POPJ	P,			;[100] DONE


;POSCHK GIVES A SKIP RETURN IF THE TERMINAL'S PRINT POSITION IS IN COLUMN 1
;(BEGINNING OF THE LINE), AND A NON-SKIP RETURN OTHERWISE. THIS IS USED TO
;ASSURE THAT MESSAGES BEGIN IN COLUMN 1 FOR BATCH.

POSCHK:	JRST	CPOPJ1			;[100] FOR NOW--USE RFPTR% LATER


;OUTLOG EXPECTS A CHARACTER IN T0, AND UNCONDITIONALLY SENDS IT TO THE LOG FILE.
;OUTLOG IS CALLED INDIRECTLY VIA PRNCHR. NO ACS ARE DESTROYED.

  IFN FTLOG,<
OUTLOG:	SPUSH	<T1,T2>			;[100] SAVE SOME ACS
	MOVE	T2,T0			;[100] SEND THE CHARACTER
	HRRZ	T1,.OVRLO		;[100]   ..
	BOUT%				;[100]   ..
	  ERJMP	[HRRZ T1,.OVRLO		;[100] SELECT PROPER FILE SPECIFICATION
		 JRST E$$OEF]		;[100] OUTPUT ERROR FOR FILE
	SPOP	<T2,T1>			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE
SUBTTL	FILE ROUTINES -- TOPS-20 -- Log File -- Closing


;STILL IN IFN TOPS20, IFE FTLOG

;LOGCLS CLOSES THE LOG FILE. IF THE TERMINAL IS THE LOG FILE, THEN WE SIMPLY
;STOP LOGGING. OTHERWISE, IF THE LOG FILE IS 'REAL', WE CLOSE IT.

LOGCLS:	SKIPG	.OVRLO			;[100] IF IT'S JUST THE USER'S TERMINAL
	JRST	LOGCLX			;[100] THEN JUST STOP LOGGING
	HRRZ	T1,.OVRLO		;[100] ELSE CLOSE THE LOG FILE
	CLOSF%				;[100]   ..
	  ERJMP	[HRRZ T1,.OVRLO		;[100] SELECT PROPER FILE SPEC
		 JRST E$$CCF]		;[100] CANNOT CLOSE FILE
LOGCLX:	SETZM	.OVRLO			;[100] NO LOG FILE ANYMORE
	POPJ	P,			;[100] DONE

  > ;END IFN FTLOG
> ;END IFN TOPS20
SUBTTL	MANUAL CALL SUBROUTINES -- INIOV. - Initialize The Overlay File


IFN FTMANUAL,<

;INIOV. (AND ITS FORTRAN ALIAS INIOVL) ALLOWS THE USER TO EXPLICITLY INITIALIZE
;THE OVERLAY HANDLER BEFORE THE FIRST OVERLAY LINK IS IMPLICITLY REQUESTED. THIS
;ALLOWS THE USER TO SPECIFY THE FILE SPECIFICATION OF THE OVERLAY FILE IF IT IS
;NOT WHAT LINK THOUGHT IT WAS AT LOAD TIME. NOTE, HOWEVER, THAT THE OVERLAY FILE
;SPECIFIED MUST BE THE ACTUAL ONE THAT WAS CREATED WITH THE PROGRAM BEING RUN,
;AND NOT A DIFFERENT ONE. THE CALL IS:
;
;	MOVEI	16,1+[-1,,0
;		      Z TYPE,[ASCIZ /file specification/]]
;	PUSHJ	17,INIOV.	;OR INIOVL IN FORTRAN

	ENTRY	INIOV.

	'INIOVL'
INIOV.:	HRRZ	T1,(P)			;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC		;[44]   ..
	SETZM	OVLSPC			;[100] ASSUME USER SPECIFIED A SPEC
	SKIPN	-1(L)			;[100] ANY ARGUMENTS?
	PJRST	OVINI			;[100] NO, JUST NORMAL INITIALIZATION
	SETOM	OVLSPC			;[100] REMEMBER USER SUPPLIED A SPEC
  IFE TOPS20,<
	MOVX	T1,'DSK   '		;[100] DEFAULT TO DSK:.OVL[-]
	MOVEM	T1,OFORED+.FODEV	;[100]   ..
	SETZM	OFOLKP+.RBPPN		;[100]   ..
	MOVX	T1,'OVL   '		;[100]   ..
	MOVEM	T1,OFOLKP+.RBEXT	;[100]   ..
	MOVEI	T1,OFORED		;[100] READ FILE SPEC INTO OFORED BLOCK
	PUSHJ	P,GETSPC		;[100]   ..
  > ;END IFE TOPS20
  IFN TOPS20,<
	HRROI	T1,@(L)			;[42] GET POINTER TO ARG STRING
	MOVEM	T1,STRPTR		;SETUP PTR
  > ;END IFN TOPS20
	PUSHJ	P,OVINI			;OPEN OVERLAY FILE
	POPJ	P,			;RETURN
SUBTTL	MANUAL CALL SUBROUTINES -- GETOV. - Get A Link And All Of Its Superiors


;STILL IN IFN FTMANUAL

;GETOV. (AND ITS FORTRAN ALIAS GETOVL) ALLOW THE USER TO SPECIFICALLY REQUEST
;THAT A PARTICULAR LINK AND ITS SUPERIORS BE BROUGHT IN. THE CALL IS:
;
;	MOVEI	16,1+[-1,,0	;ONE ARG--ALL LINKS IN PATH BROUGHT IN
;		      Z TYPE,[LINK NAME]]
;	PUSHJ	P,GETOV.	;OR GETOVL IN FORTRAN
;
;LINK CAN BE A LINK NUMBER OR ASCII NAME, DEPENDING ON THE ARGUMENT TYPE (SEE
;GETNUM).

	ENTRY	GETOV.

	'GETOVL'
GETOV.:	HRRZ	T1,(P)			;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC		;[44]   ..
	PUSH	P,L			;SAVE L
	PUSHJ	P,GETCUR		;SEE WHO CALLED
	PUSHJ	P,GETNUM		;[100] CONVERT ARG IT TO A LINK NUMBER
	JFCL	GETOV.-1		;INCASE OF ILL ARG TYPE
	PUSHJ	P,INCORE		;SEE IF ALREADY INCORE
	  JRST	GTOVL1			;[100] NO
	PJRST	POPL			;RESTORE AND RETURN

GTOVL1:	PUSHJ	P,CP0			;[100] CHECK PATH
	PJRST	POPL			;[100] DONE
SUBTTL	MANUAL CALL SUBROUTINES -- REMOV. - Remove A Link And All Inferiors


;STILL IN IFN FTMANUAL

;REMOV. DELETES THE REQUESTED LINK AND ALL OF ITS INFERIORS, THEN ATTEMPTS
;TO SHRINK MEMORY.
;
;CALL:
;	MOVEI	16,1+[1,,0
;		      Z TYPE,[LINK]
;	PUSHJ	17,REMOV.
;
;DEPENDING ON TYPE (SEE GETNUM) LINK CAN BE A LINK NUMBER OR ASCII NAME.

	ENTRY	REMOV.

	'REMOVL'
REMOV.:	HRRZ	T1,(P)			;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC		;[44]   ..
	PUSH	P,L			;[44] SAVE L
	PUSHJ	P,GETCUR		;[43] GET CURRENT LINK SETUP
	PUSHJ	P,GETNUM		;GET LINK # TO REMOVE
	JFCL	REMOV.-1		;IN CASE OF ILL ARG TYPE
	PUSHJ	P,INCORE		;GET ADDRESS
	  JRST	REMOV1			;[43] NOT IN CORE--NOTHING TO DO
	MOVEI	P1,(T1)			;[43] GO DO THE WORK
	PUSHJ	P,DELPTH		;[43]   ..
	CALL	FUNCT.##,<<SPI,[F.CBC]>,<AS,OVLNAM>,<SPI,STATUS>>
REMOV1:	PJRST	POPL			;[43] RESTORE AND RETURN
SUBTTL	MANUAL CALL SUBROUTINES -- RUNOV. - Run An Overlay Link


;STILL IN IFN FTMANUAL

;RUNOV. (AND ITS FORTRAN ALIAS RUNOVL) ALLOW THE USER TO REPLACE A LINK WITH
;ANOTHER, AND START IT AT ITS START ADDRESS. THIS FACILITY WAS ORIGINALLY
;DESIGNED TO REPLACE LOADER'S OLD CHAIN FACILITY, AND IS NOT AS USEFUL OR
;GENERAL AS GETOVL. NOTE THAT A LINK THAT HAS BEEN RUN BY RUNOV. MAY NEVER
;RETURN. THE CALL IS:
;
;	MOVEI	16,1+[-1,,0
;		      Z TYPE,[LINK NAME OR NUMBER]]
;	PUSHJ	P,RUNOV.	;OR RUNOVL IN FORTRAN

	ENTRY	RUNOV.

	'RUNOVL'
RUNOV.:	HRRZ	T1,(P)			;[44] SAVE USER'S RETURN PC
	MOVEM	T1,USERPC		;[44]   ..
	PUSHJ	P,GETCUR		;POINT TO CALLER
	PUSHJ	P,GETNUM		;CONVERT ARG TO A LINK NUMBER
	JFCL	RUNOV.-1		;INCASE OF ILL ARG TYPE
	PUSHJ	P,INCORE		;SEE IF ALREADY INCORE
	  JRST	[PUSH	P,T0		;SAVE LINK# INCASE WAS A NAME
		SETOM	OKOVLC		;[100] ALLOW OVERLAY OF CALLER
		PUSHJ	P,CP0		;CHECK PATH
		SETZM	OKOVLC		;[43] DISALLOW OVERLAY OF CALLER
		POP	P,T0		;RESTORE LINK #
		JRST	.-1]		;TRY AGAIN
	HRRZ	T0,CS.STA(T1)		;GET START ADDRESS
	JUMPE	T0,E$$NSA		;[100] SEE IF THERE'S A START ADDRESS
	POP	P,(P)			;[45] LOSE USER'S RETURN PC
	JRST	@T0			;[45]   SINCE LINK WILL NEVER RETURN

E$$NSA:	MOVEM	T1,THSLNK		;[45] SO WE CAN ADDRESS LINK
	PUSHJ	P,FAIL			;[100] PRINT ?OVL PREFIX
	TYPE	<NSA	No start address for> ;[100]
	PUSHJ	P,PRNLNK		;PRINT NUMBER
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP
SUBTTL	MANUAL CALL SUBROUTINES -- SAVOV. - Mark A Link To Be Writable


;STILL IN IFN FTMANUAL

;SAVOV. (OR ITS FORTRAN ALIAS SAVOVL) ALLOWS THE USER TO DECLARE AN OVERLAY LINK
;TO BE WRITABLE. THIS DOES NOT AFFECT THE CURRENT STATE OF THE CODE IMMEDIATELY,
;BUT WAITS UNTIL THE LINK IS ABOUT TO BE OVERLAID. IF A LINK IS ALREADY
;WRITABLE, NOTHING NEW HAPPENS.
;
;	MOVEI	16,1+[-n,,0	;COUNT OF LINKS TO MAKE WRITABLE
;		      Z TYPE,[LINK]
;		      ...
;		      Z TYPE,[LINK]]
;	PUSHJ	17,SAVOV.	;OR SAVOVL IN FORTRAN
;
;IF CALLED WITH NO ARGUMENTS, JUST INITIALIZE THE TEMPORARY FILE.

	ENTRY	SAVOV.			;[100]

	'SAVOVL'			;[100] NAME FOR FORTRAN TRACE-BACK
SAVOV.:	HRRZ	T1,(P)			;[100] SAVE RETURN PC FOR ERRORS
	MOVEM	T1,USERPC		;[100]   ..
	SKIPN	-1(L)			;[100] ANY ARGS?
	JRST	SAVOV2			;[100] NO--JUST SET UP TEMP FILE
	PUSH	P,L			;[100] SAVE L FOR AOBJN POINTER
	HLL	L,-1(L)			;[100] MAKE AOBJN POINTER FOR ARGS
	PUSHJ	P,GETCUR		;[100] GET DATA ABOUT CALLER'S LINK
SAVOV1:	PUSHJ	P,GETNUM		;[100] GET NEXT LINK NUMBER IN T0
	JFCL	SAVOV.-1		;[100] IN CASE OF ILLEGAL ARG TYPE
	PUSHJ	P,WRTPTR		;[100] GET BYTE POINTER TO OW TABLE
	LDB	T1,T0			;[100] GET CURRENT VALUE IN CASE PAGED
	TXO	T1,OW.WRT		;[100] MAKE LINK WRITABLE
	DPB	T1,T0			;[100] STORE FLAGS BACK
	AOBJN	L,SAVOV1		;[100] LOOP FOR MORE LINKS
SAVOV2:	MOVE	T1,DI+DI.FLG		;[100] INITIALIZE TEMPORARY FILE
	TXNN	T1,OD.WRT		;[100]   IF IT HASN'T BEEN YET
	PUSHJ	P,TMPINI		;[100]   ..
	MOVX	T1,OD.WRT		;[100] MARK THAT IT'S NOW WRITABLE
	ORM	T1,DI+DI.FLG		;[100]   ..
	PJRST	POPL			;[100] DONE
SUBTTL	MANUAL CALL SUBROUTINES -- CLROV. - Mark A Link To Not Be Writable


;STILL IN IFN FTMANUAL

;CLROV. (OR ITS FORTRAN ALIAS CLROVL) ALLOWS THE USER TO DECLARE AN OVERLAY LINK
;TO NOT BE WRITABLE. THIS DOES NOT AFFECT THE CURRENT STATE OF THE CODE
;IMMEDIATELY, BUT WAITS UNTIL THE LINK IS ABOUT TO BE OVERLAID OR READ IN. IF A
;LINK IS ALREADY NOT WRITABLE, NOTHING NEW HAPPENS.
;
;	MOVEI	16,1+[-n,,0	;COUNT OF LINKS TO MAKE NOT WRITABLE
;		      Z TYPE,[LINK]
;		      ...
;		      Z TYPE,[LINK]]
;	PUSHJ	17,CLROV.	;OR CLROVL IN FORTRAN

	ENTRY	CLROV.			;[100]

	'CLROVL'			;[100] NAME FOR FORTRAN TRACE-BACK
CLROV.:	HRRZ	T1,(P)			;[100] SAVE RETURN PC FOR ERRORS
	MOVEM	T1,USERPC		;[100]   ..
	SKIPN	-1(L)			;[100] ANY ARGS?
	POPJ	P,			;[100] NO--ALL DONE THEN
	PUSH	P,L			;[100] SAVE L FOR AOBJN POINTER
	HLL	L,-1(L)			;[100] MAKE AOBJN POINTER FOR ARGS
	PUSHJ	P,GETCUR		;[100] GET DATA ABOUT CALLER'S LINK
CLROV1:	PUSHJ	P,GETNUM		;[100] GET NEXT LINK NUMBER IN T0
	JFCL	CLROV.-1		;[100] IN CASE OF ILLEGAL ARG TYPE
	PUSHJ	P,WRTPTR		;[100] GET BYTE POINTER TO OW TABLE
	SETZ	T1,			;[100] NOT WRITABLE, NOT PAGED
	DPB	T1,T0			;[100] STORE FLAGS BACK
	AOBJN	L,CLROV1		;[100] LOOP FOR MORE LINKS
	PJRST	POPL			;[100] DONE
SUBTTL	MANUAL CALL SUBROUTINES -- LOGOV. - Manipulate The Log File


;STILL IN IFN FTMANUAL

;LOGOV. (OR ITS FORTRAN ALIAS LOGOVL) CONTROLS THE RUN-TIME OVERLAY LOG FILE.
;THERE ARE THREE POSSIBLE CALLS:
;
;	MOVEI	16,1+[0,,0]		;NO ARGUMENTS
;	PUSHJ	17,LOGOV.
;
;THE ABOVE CALL CLOSES ANY CURRENTLY OPEN LOG FILE.
;
;	MOVEI	16,1+[-1,,0		;1 ARGUMENT
;		      Z TYPE,[ASCIZ /file specification/]]
;	PUSHJ	17,LOGOV.
;
;THE ABOVE CALL CAN BE IN TWO CASES. IF THE FILE SPECIFICATION REFERS TO THE
;USER'S CONTROLLING TERMINAL, SIMPLE TERMINAL OUTPUT CALLS ARE USED TO WRITE THE
;LOG FILE. IF THE FILE SPECIFICATION REFERS TO ANYTHING ELSE, GENERAL I/O IS
;DONE.


  IFN FTLOG,<

	ENTRY	LOGOV.

	'LOGOVL'
LOGOV.:	HRRZ	T1,(P)			;[100] SAVE USER'S PC FOR ERROR MESSAGES
	MOVEM	T1,USERPC		;[100]   ..
	SPUSH	<T2,L>			;[100] SAVE SOME ACS
	SKIPE	.OVRLO			;[100] CLOSE LOG FILE IF OPEN
	PUSHJ	P,LOGCLS		;[100]   ..
	SKIPN	-1(L)			;[100] LOG FILE SPECIFIED?
	JRST	LOGOVX			;[100] NO--NOTHING MORE TO DO
    IFE TOPS20,<
	MOVX	T1,'DSK   '		;[100] DEFAULT TO DSK:.LOG[-]
	MOVEM	T1,LFOWRT+.FODEV	;[100]   ..
	MOVX	T1,'LOG   '		;[100]   ..
	MOVEM	T1,LFOENT+.RBEXT	;[100]   ..
	SETZM	LFOENT+.RBPPN		;[100]   ..
	MOVEI	T1,LFOWRT		;[100] READ THE LOG FILE SPECIFICATION
	PUSHJ	P,GETSPC		;[100]   ..
    > ;END IFE TOPS20

;  ..
;  ..

;STILL IN IFN FTMANUAL

    IFN TOPS20,<
	HRROI	T1,[ASCIZ /LOG/]	;[100] DEFAULT TO .LOG
	MOVEM	T1,DEFTBL+.GJEXT	;[100]   ..
    > ;END IFN TOPS20

	PUSHJ	P,LOGINI		;[100] INITIALIZE THE LOG FILE
LOGOVX:	SPOP	<T2,L>			;[100] RESTORE ACS
	POPJ	P,			;[100] DONE

  > ;END IFN FTLOG
> ;END OF IFN FTMANUAL
SUBTTL	SUBROUTINES -- GETNUM - Get Link Number From Name Or Number


;GETNUM CONVERTS AN ARGUMENT FROM A SUBROUTINE CALL TO A LINK NUMBER. DEPENDING
;ON THE ARGUMENT TYPE, THE LINK CAN BE SPECIFIED AS A NUMBER, 5 OR 10
;CHARACTERS, OR AN ASCIZ STRING. THE CALL IS:
;
;	L/	ADDRESS OF CURRENT ARGUMENT POINTER

GETNUM:	LDB	T1,[POINT 4,0(L),12]	;GET TYPE
	JRST	@TYPTBL(T1)	;DO CONVERSION

TYPTBL:	A.UND,TY.SP		;[100] UNDEFINED, ASSUME ASCII OR INTEGER #
	A.LOG,TY.SP		;[100] LOGICAL, ASSUME ASCII OR INTEGER #
	A.SPI,TY.SP		;[100] INTEGER, ASSUME ASCII OR INTEGER #
	    3,E$$IAT		;[100] RESERVED
	A.SPR,TY.SP		;[100] REAL, ASSUME ASCII OR INTEGER #
	    5,E$$IAT		;[100] RESERVED
	A.OCT,TY.SP		;[100] OCTAL, ASSUME ASCII OR INTEGER #
	A.LBL,E$$IAT		;[100] LABEL
	A.DPR,TY.DP		;[100] DOUBLE REAL, ASSUME ASCII OR INTEGER #
	A.DPI,TY.DP		;[100] DOUBLE INTEGER, ASSUME ASCII OR INTEGER #
	A.DO ,TY.DP		;[100] DOUBLE OCTAL, ASSUME ASCII OR INTEGER #
	   13,E$$IAT		;[100] RESERVED
	A.CMP,TY.DP		;[100] COMPLEX, ASSUME ASCII OR INTEGER #
	   15,E$$IAT		;[100] BYTE STRING
	   16,E$$IAT		;[100] RESERVED
	A.AS ,TY.STR		;[100] ASCIZ STRING

E$$IAT:	PUSHJ	P,FAIL			;[100]
	TYPE	<IAT	Illegal argument type on call to > ;[100]
	MOVE	T1,(P)			;[44] GET ROUTINE NAME POINTED TO
	MOVE	T1,@(T1)		;[44]   BY THE JFCL
	PUSHJ	P,PRNSBX		;PRINT IT
	TYPE	< from PC = >		;[100]
	MOVE	T0,USERPC		;[44] GET USER'S PC FOR MESSAGE
	SUBI	T0,1			;[44] MAKE IT PC OF CALL
	PUSHJ	P,PRNOCT
	PUSHJ	P,CRLF			;[44] END THE LINE
	STOP				;[44] DIE
TY.DP0:	MOVE	T0,T1			;PUT LOW ORDER WORD INTO HIGH
	CAIA				;CANNOT SKIPA OVER 0

TY.SP:	MOVE	T0,@(L)			;GET ARG
	TLNN	T0,-1			;18 BITS?
	POPJ	P,			;YES, MUST BE NUMBER
	PUSHJ	P,TY.PTR		;SAVE ACC AND SETUP PTRS
TY.SP1:	ILDB	T1,T2			;GET CHAR
	SKIPE	T1			;LEAVE NULL ALONE
	SUBI	T1," "			;SIXBITIZE
	IDPB	T1,T3			;STORE 
	TLNE	T2,(77B5)		;MORE TO READ?
	JRST	TY.SP1			;YES
	ANDCMI	T0,77			;CLEAR 6TH CHAR

;NOW TO CONVERT NAME TO A LINK NUMBER
TY.NO:	MOVE	T3,T0			;PUT IN SAFE PLACE
	MOVE	T1,DI+DI.NPT		;[100] GET BLOCK
	HLRE	T2,T1			;TOTAL WORD LENGTH
	PUSHJ	P,%USETU		;SET ON BLOCK
TY.NO1:	PUSHJ	P,%INB			;READ A BLOCK
	MOVE	T1,[-100,,INBFR]	;FORM AOBJN WORD
TY.NO2:	CAMN	T3,1(T1)		;MATCH?
	JRST	TY.NO3			;YES
	ADDI	T1,1
	AOBJN	T1,TY.NO2		;LOOP IN THIS BLOCK
	ADDI	T2,200			;SEE IF MORE BLOCKS
	JUMPL	T2,TY.NO1		;YES
E$$ULN:	PUSHJ	P,FAIL			;[100] PRINT ?OVL PREFIX
	TYPE	<ULN	Unknown link name > ;[100]
	MOVE	T1,T3			;[100] PRINT THE BAD LINK NAME
	PUSHJ	P,PRNSBX		;[100]   ..
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

TY.NO3:	HRRZ	T0,0(T1)		;GET NUMBER
	JRST	T3POPJ			;RESTORE
TY.DP:	JUMPE	T0,TY.DP0		;LOW ORDER ONLY?
	JUMPE	T1,TY.SP		;HIGH ORDER ONLY?
	PUSHJ	P,TY.PTR		;SAVE ACCS AND SETUP PTRS
	PUSH	P,T4			;NEED ANOTHER ACC
TY.DP1:	ILDB	T4,T2			;GET CHAR
	SKIPE	T4			;LEAVE NULL ALONE
	SUBI	T4," "			;SIXBITIZE
	IDPB	T4,T3			;STORE 
	TLNE	T3,(77B5)		;MORE TO STORE?
	JRST	TY.DP1			;YES
	POP	P,T4			;RESTORE LAST ACC
	JRST	TY.NO			;AND CONVERT TO NUMBER

TY.STR:	PUSHJ	P,TY.PTR		;SAVE ACCS AND SETUP PTRS
	HRRI	T2,@(L)			;FILL IN INPUT ADDRESS
	SETZ	T0,			;START WITH 0
TYSTR1:	ILDB	T1,T2			;GET CHAR
	JUMPE	T1,TY.NO		;DONE, NOW CONVERT TO LINK #
	SUBI	T1," "			;SIXBITIZE
	TLNE	T3,(77B5)		;RAN OUT OF SPACE?
	IDPB	T1,T3			;NO
	JRST	TYSTR1			;LOOP

TY.PTR:	EXCH	T2,(P)			;PUT T2 ON STACK
	SPUSH	<T3,T2>			;SAVE TWO ACCS
	MOVSI	T2,(POINT 7,T0)		;READ PTR
	MOVSI	T3,(POINT 6,T0)		;WRITE PTR
	POPJ	P,
SUBTTL	SUBROUTINES -- GETSPC - Convert String Into FILOP. Block


;GETSPC CONVERTS AN ASCIZ FILE SPECIFICATION TO INFORMATION SUITABLE FOR A
;FILOP. UUO. THE CALL IS:
;
;	T1/	ADDRESS OF FILOP., FOLLOWED BY LOOKUP/ENTER, FOLLOWED BY PATH.
;		BLOCK
;	L/	ADDRESS OF ARGUMENT BLOCK
;
;ON RETURN, THE FILE INFORMATION HAS BEEN FILLED IN TO THE VARIOUS BLOCKS.

IFE TOPS20,<
GETSPC:	SPUSH	<T2,T3,T4,L>		;[100] SAVE SOME ACS
	MOVE	T3,T1			;[100] SAVE ADDRESS OF FILOP. INFO
	MOVEI	L,@(L)			;[100] BUILD BYTE POINTER TO STRING
	HRLI	L,(POINT 7,)		;FORM INPUT BYTE PTR
	PUSHJ	P,GETSBX		;GET DEVICE
	CAIE	T1,":"			;WAS IT?
	JRST	GETNAM			;NO, TRY FILE NAME
	MOVEM	T0,$FOFIL+.FODEV(T3)	;[100] YES--STORE DEVICE
	PUSHJ	P,GETSBX		;GET FILE NAME
GETNAM:	MOVEM	T0,$FORIB+.RBNAM(T3)	;[100] STORE FILE NAME
	CAIE	T1,"."			;EXT TO FOLLOW?
	JRST	GETPRJ			;NO, TRY PPN
	PUSHJ	P,GETSBX		;GET EXT
	HLLZM	T0,$FORIB+.RBEXT(T3)	;[100] STORE EXTENSION
GETPRJ:	SETZM	$FORIB+.RBPPN(T3)	;[100] ASSUME DEFAULT PATH
	CAIE	T1,"["			;PPN TO FOLLOW?
	PJRST	GETSPX			;[100] NO--DONE
	PUSHJ	P,GETOCT		;GET PRJ
	TRNN	T0,-1			;IS IT [,XXX]?
	HLRZ	T0,MYPPN		;[100] YES--FILL IN FROM LOGGED IN PPN
	HRLZM	T0,$FORIB+.RBPPN(T3)	;[100] SAVE FIRST HALF OF PPN
	PUSHJ	P,GETOCT		;GET PRG
	TRNN	T0,-1			;IS IT [XXX,] ?
	HRRZ	T0,MYPPN		;[100] YES--FILL IN FROM LOGGED IN PPN
	HRRM	T0,$FORIB+.RBPPN(T3)	;[100] STORE REST OF PPN

;  ..
;  ..

;STILL IN IFE TOPS20

  IFN FTSFD,<
	CAIN	T1,"]"			;CLOSED CORRECTLY?
	JRST	GETSPX			;[100] YES--NO SFD'S
	MOVE	T1,$FORIB+.RBPPN(T3)	;[100] SFD'S--MOVE PPN TO PATH. BLOCK
	MOVEM	T1,$FOPTH+.PTPPN(T3)	;[100]   ..
	MOVEI	T1,$FOPTH(T3)		;[100]   AND POINT LOOKUP/ENTER BLOCK
	MOVEM	T1,$FORIB+.RBPPN(T3)	;[100]   TO IT
	MOVSI	T4,-FTSFD		;[100] READ AND STORE ALL SFD'S
	HRRI	T4,$FOPTH+.PTSFD(T3)	;[100]   ..
GETSP3:	PUSHJ	P,GETSBX		;[100]   ..
	MOVEM	T0,(T4)			;[100]   ..
	CAIN	T1,","			;MORE?
	AOBJN	T4,GETSP3		;[100] YES--CAN WE TAKE MORE?
  > ;END OF IFN FTSFD

GETSPX:	SPOP	<L,T4,T3,T2>		;[100] RESTORE ACS
	POPJ	P,			;[100] DONE

> ;END IFE TOPS20
SUBTTL	SUBROUTINES -- GETSBX - Convert To SIXBIT, GETOCT - Convert To Octal


;GETSBX CONVERTS ALPHANUMERIC CHARACTERS IN AN ASCIZ STRING TO SIXBIT. THE CALL IS:
;
;	L/	BYTE POINTER TO ASCIZ STRING
;
;RETURNS:
;
;	T0/	SIXBIT WORD
;	T1/	BREAK CHARACTER
;
;DESTROYS T2.

GETSBX:	MOVX	T2,<POINT 6,T0>		;[100] SET UP BYTE POINTER TO RESULT
	SETZ	T0,
GTSBX1:	ILDB	T1,L			;GET NEXT CHAR
	CAIL	T1,"a"			;TEST FOR LOWER CASE
	CAILE	T1,"z"			;...
	CAIA				;NO
	SUBI	T1,"a"-"A"		;MAKE UPPER CASE
	CAIL	T1,"0"			;TEST FOR VALID ALPHANUMERICS
	CAILE	T1,"Z"			;...
	POPJ	P,			;END TEST FAILED
	CAILE	T1,"9"			;SEE IF 0-9
	CAIL	T1,"A"			;OR A-Z
	CAIA				;YES
	POPJ	P,			;NO
	SUBI	T1," "-' '		;[100] SIXBITIZE
	CAME	T1,[POINT 6,T0,35]	;[100] HAVE WE STORED 6 CHARS ALREADY?
	IDPB	T1,T2			;[100] NO--STORE ANOTHER
	JRST	GTSBX1			;LOOP


;GETOCT RETURNS THE OCTAL REPRESENTATION OF A NUMBER IN AN ASCIZ STRING. THE
;CALL IS:
;
;	L/	BYTE POINTER TO THE ASCIZ STRING
;
;RETURNS:
;
;	T0/	OCTAL NUMBER
;	T1/	BREAK CHARACTER

GETOCT:	SETZ	T0,			;CLEAR STORE AC
GTOCT1:	ILDB	T1,L			;GET NEXT CHAR
	CAIL	T1,"0"			;TEST FOR VALID OCTAL
	CAILE	T1,"7"			;ONLY
	POPJ	P,			;BREAK
	LSH	T0,3			;MAKE SPACE
	ADDI	T0,-"0"(T1)		;[100] STORE NEW DIGIT
	JRST	GTOCT1			;LOOP
SUBTTL	SUBROUTINES -- GETCUR - Get Link Information Of Caller


GETCUR:	SPUSH	<T2,T3,T4>		;NEED SOME ACCS
	MOVE	T4,USERPC		;[44] GET USER'S RETURN PC
	SKIPN	T1,FSTLNK		;GET START OF OVERLAY LIST
	PUSHJ	P,OVINI			;NOT YET SETUP
	MOVE	T1,FSTLNK		;IT IS NOW
GTCUR1:	HLRZ	T3,CS.SIZ(T1)		;GET LENGTH OF LINK
	HRRZ	T2,CS.ADR(T1)		;AND LOWER BOUND
	ADD	T3,T2			;UPPER BOUND
	CAML	T4,T2			;SEE IF ENCLOSED
	CAML	T4,T3			;BETWEEN T2 .LT. L .LT. T3
	JRST	GTCUR2			;NO
GTCUR4:	MOVEM	T1,CURLNK		;SAVE PTR TO LINK
	MOVE	T2,CS.NUM(T1)		;GET LINK NUMBER
	MOVEM	T2,CURNUM		;SAVE IT
	POP	P,T4			;LEAVE THIS POP OUT OF T3POPJ!!
T3POPJ:	SPOP	<T3,T2>
	POPJ	P,

GTCUR2:	HRRZ	T1,CS.FPT(T1)		;GET NEXT
	JUMPN	T1,GTCUR1		;VALID?
	HRRZ	T3,.JBHRL##		;GET END OF HIGH SEG, IF ANY
	JUMPE	T3,GTCUR3		;NO HIGH SEG, NOT POSSIBLE!
	HRRZ	T3,.JBREL##		;HIGHEST ADDRESS IN LOW SEG
	CAIGE	T3,400000		;LOW SEG OVER 128K?
	MOVEI	T3,377777		;NO, ASSUME HI SEG STARTS AT 128K
IFE TOPS20,<
	MOVE	T2,[-2,,.GTUPM]		;NEED TO FIND HI-SEG ORIGIN
	GETTAB	T2,			;CURRENTLY AVAIL ONLY BY GETTAB
	  SKIPA				;NOT THERE, ASSUME 400000
	SKIPN	T2			;GETTAB IMPLIMENTED?
> ;END IFE TOPS20
	MOVSI	T2,1(T3)		;NO, ASSUME DEFAULT
	HLRZ	T2,T2			;PUT IN CORRECT PLACE
	ANDCMI	T2,777			;ZAP BITS RESERVED FOR FUTURE
	HRRZ	T3,.JBHRL##		;GET HIGHEST LEGAL ADDR IN HI SEG
	CAML	T4,T2			;IS THIS FROM THE HIGH SEG?
	CAMLE	T4,T3			;MAYBE. IS IT?
GTCUR3:	PUSHJ	P,E$$IMP		;[100] NO, NOT POSSIBLE!
	MOVE	T1,FSTLNK		;YES, PRETEND FROM THE ROOT
	JRST	GTCUR4			;AND GO FILL THINGS IN
SUBTTL	SUBROUTINES -- INCORE, WRTPTR


;INCORE CHECKS TO SEE IF A LINK IS IN MEMORY. THE CALL IS:
;
;	T0/	LINK NUMBER
;
;INCORE GIVES A SKIP RETURN WITH THE LINK'S ADDRESS IF THE LINK IS IN MEMORY,
;AND A NON-SKIP RETURN OTHERWISE.

INCORE:	MOVE	T1,FSTLNK		;GET START
	CAMN	T0,CS.NUM(T1)		;ONE WE WANT?
	JRST	CPOPJ1			;YES
	HRRZ	T1,CS.FPT(T1)		;NO, GET NEXT
	JUMPN	T1,.-3
	POPJ	P,


;WRTPTR RETURNS A BYTE POINTER TO THE WRITABLE LINK FLAGS FOR A SPECIFIED LINK.
;THIS IS USED TO TEST AND SET THE WRITABLE STATUS OF A LINK. THE CALL IS:
;
;	T0/	LINK NUMBER
;
;ON RETURN, T0 CONTAINS THE BYTE POINTER. T1 IS USED.

WRTPTR:	IDIVI	T0,^D18			;[100] FLAGS ARE 2 BITS PER LINK
	ADD	T0,[POINT 2,OW,35]	;[100] ADD TEMPLATE BYTE POINTER TO ADDR
	IMULI	T1,-2			;[100] COMPUTE P FIELD OF BYTE POINTER
	ADDI	T1,^D36			;[100]   ..
	DPB	T1,[POINT 6,T0,5]	;[100] STORE IN P FIELD
	POPJ	P,			;[100] DONE
SUBTTL	SUBROUTINES -- GETJOB - Get Job Number For Temporary File Name


;ON TOPS-10, GETJOB SETS JOBNUM TO CONTAIN <SIXBIT JOB #>,,<BINARY JOB #>. THIS
;IS USED IN THE CREATION OF THE TEMPORARY FILE NAME.

IFE TOPS20,<
GETJOB:	PJOB	T0,			;[100] GET JOB NUMBER
	HRRZM	T0,JOBNUM		;[100] SAVE IN RIGHT HALF
	MOVEI	T3,3			;[100] PICK UP 3 CHARS
PJLOOP:	IDIVI	T0,^D10			;[100] ONE AT A TIME
	ADDI	T1,'0'			;[100] MAKE SIXBIT
	LSHC	T1,-6			;[100] SAVE CHAR
	SOJG	T3,PJLOOP
	HLLM	T2,JOBNUM		;[100] SAVE SIXBIT FOR TMP FILES
	GETPPN	T1,			;[100] GET LOGGED IN PPN
	  JFCL				;[100] OVRLAY WITH JACCT?
	MOVEM	T1,MYPPN		;[100] SAVE FOR LATER
	POPJ	P,			;[100] DONE
> ;END IFE TOPS20
SUBTTL	SUBROUTINES -- CHKDDT - Update Symbol Table Pointers On TOPS-20


;ROUTINE TO STUFF C(.JBSYM) INTO DDT IF DDT IS IN MEMORY (TOPS-20 ONLY).
;THIS IS BECAUSE DDT DOESN'T LOOK FOR SYMBOL TABLES IN JOBDAT, BUT MUST
;BE FORCE-FED. SAVES ALL ACS.

IFN TOPS20,<
CHKDDT:	PUSH	P,T1			;[40] SAVE SOME TEMPS
	PUSH	P,T2			;[40]   ..
	MOVX	T1,<.FHSLF,,770>	;[40] SEE IF PAGE 770 EXISTS
	RPACS%				;[41]   ..
	TXNN	T2,PA%EX		;[40]   ..
	JRST	CHKEND			;[40] NO--CAN'T BE STANDARD DDT
	MOVE	T1,770000		;[40] SEE IF IT'S DDT THAT'S THERE
	CAME	T1,[JRST 770002]	;[40] CROCK, BUT THIS IS WHAT EXEC DOES
	JRST	CHKEND			;[40] NOT DDT
	MOVE	T1,.JBSYM##		;[40] IT'S DDT--STORE S.T. POINTER
	MOVEM	T1,@770001		;[40]   IN STANDARD PLACE
CHKEND:	POP	P,T2			;[40] RESTORE TEMPS
	POP	P,T1			;[40]   ..
	POPJ	P,			;[40] DONE
> ;END IFN TOPS20
SUBTTL	MESSAGE HANDLING -- Miscellaneous Messages


;THESE INFORMATIONAL MESSAGES REPORT THE PAGING ACTION OF THE OVERLAY HANDLER,
;AND GIVE THE USER SOME IDEA OF THE PERFORMANCE OF THE OVERLAYS. IN PARTICULAR,
;THE OVLRLL MESSAGE ALERTS THE USER TO THE POSSIBILITY THAT PLAYING WITH THE
;PROGRAM'S MEMORY MANAGEMENT OR WITH /SPACE IN LINK MIGHT PREVENT THE EXPENSIVE
;RELOCATION. ALL OF THESE MESSAGES (AND ONLY THESE) ARE UNDER CONTROL OF THE
;LOGOV. SUBROUTINE AND LINK'S /OVERLAY:LOG SWITCH.

IFN FTLOG,<
E$$RLN:	PUSHJ	P,INFO			;[100] PRINT [OVL PREFIX
	  POPJ	P,			;[100] NO LOG FILE REQUESTED
	TYPE	<RLN	Reading>	;[100]
LNKNO:	PUSHJ	P,PRNLNK		;PRINT NAME OR NUMBER
	TYPE	< after >		;[100]
	PUSHJ	P,PRNTIM		;[100] RUNTIME
	PJRST	INFOX			;[100] END THE LINE

E$$WLN:	PUSHJ	P,INFO			;[100] PRINT [OVL PREFIX
	  POPJ	P,			;[100] NO LOG FILE REQUESTED
	TYPE	<WLN	Writing>	;[100]
	PJRST	LNKNO			;[100] PRINT THE LINK NAME, ETC.

E$$DLN:	PUSHJ	P,INFO			;[100] PRINT [OVL PREFIX
	  POPJ	P,			;[100] NO LOG FILE REQUESTED
	TYPE	<DLN	Deleting>
	PJRST	LNKNO			;[100] PRINT THE LINK NAME, ETC.

  IFN FTRELOC,<
E$$RLL:	PUSHJ	P,INFO			;[100] PRINT [OVL PREFIX
	  POPJ	P,			;[100] NO LOG FILE REQUESTED
	TYPE	<RLL	Relocating>	;[100]
	PUSHJ	P,PRNLNK
	TYPE	< at >			;[100]
	MOVE	T1,THSLNK
	HRRZ	T0,CS.ADR(T1)		;[100] PRINT ADDRESS IT'S RELOCATED TO
	PUSHJ	P,PRNOCT
	PJRST	INFOX			;[100] FINISH THE LINE AND RETURN
  > ;END IFN FTRELOC
> ;END IFN FTLOG
E$$ARC:	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<ARC	Attempt to remove caller from> ;[100]
	PUSHJ	P,PRNLNK		;[100] PRINT THE OFFENDING LINK NAME
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

;E$$IMP IS USED FOR CASES THAT SHOULD NEVER (!) HAPPEN. IT SHOULD BE CALLED WITH
;A PUSHJ P,E$$IMP SO THE PC CAN BE PRINTED.

E$$IMP:	PUSHJ	P,FAIL			;[100]
	TYPE	<IMP	'Impossible' error condition at PC = >
	MOVE	T0,(P)			;[100] PRINT THE PC OF THE PUSHJ
	SUBI	T0,1			;[100]   ..
	PUSHJ	P,PRNOCT		;[100]   ..
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

E$$ILN:	PUSH	P,T0			;[100] SAVE THE BAD LINK NUMBER
	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<ILN	Illegal link number > ;[100]
	POP	P,T0			;[100] PRINT THE BAD LINK NUMBER
	PUSHJ	P,PRNDEC		;[100]   ..
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

E$$IVN:	SKIPE	DI+DI.VER		;[100] IGNORE IF VERSION NUMBER WAS 0
	PUSHJ	P,WARN			;[100] PRINT %OVR PREFIX
	  POPJ	P,			;[100] NO WARNINGS REQUESTED
	TYPE	<IVN	Inconsistent version numbers> ;[100]
	PJRST	CRLF

E$$MEF:	PUSHJ	P,FAIL			;[100] PRINT ?OVL PREFIX
	TYPE	<MEF	Memory expansion failed> ;[100]
	PUSHJ	P,PRNFRS		;[100] PRINT FUNCT. REASON FOR FAILURE
	PUSHJ	P,CRLF			;[100] FINISH THE LINE
	STOP				;[100] DIE NOW

IFN FTRELOC!FTLOG<
E$$CGM:	PUSHJ	P,FAIL			;[100] PRINT ?OVL PREFIX
	TYPE	<CGM	Cannot get memory from OTS>
	PUSHJ	P,PRNFRS		;INDICATE WHY
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP
> ;END IFN FTRELOC!FTLOG

E$$STS:	PUSHJ	P,WARN			;[100] NO--PRINT %OVL PREFIX
	  JRST	OVINI5			;[100] NO WARNINGS REQUESTED
	TYPE	<STS	OTS reserved space too small>
	PUSHJ	P,CRLF			;[100] FINISH THE LINE

E$$CDL:	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<CDL	Cannot delete>	;[100]
	PUSHJ	P,PRNLNK		;[100] PRINT LINK#
	PUSHJ	P,PRNFRS		;[100] INDICATE WHY
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP				;[100] DIE NOW
E$$MAN:	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<MAN	Memory for absolute> ;[100]
	PUSHJ	P,PRNLNK
	TYPE	< not available>	;[100]
	PUSHJ	P,PRNFRS		;[100] SAY WHY
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP

IFN FTRELOC,<
E$$NRS:	PUSHJ	P,FAIL			;[100] PRINT THE ?OVL PREFIX
	TYPE	<NRS	No relocation table for symbols>
	PUSHJ	P,CRLF			;[100] END THE LINE
	STOP				;[100] DIE NOW
> ;END IFN FTRELOC
SUBTTL	MESSAGE HANDLING -- FAIL, WARN, INFO


;FAIL IS CALLED TO SET UP A FATAL MESSAGE. IT FORCES ALL OUTPUT TO THE USER'S
;TERMINAL, AND VERIFIES THAT THE LINE POSITION IS COLUMN 1.

FAIL:	MOVEI	T1,OUTTTY		;[100] FORCE TERMINAL OUTPUT
	MOVEM	T1,PRNCHR		;[100]   ..
	PUSHJ	P,POSCHK		;[100] ARE WE IN COLUMN 1?
	  PUSHJ	P,CRLF			;[100] NO--GET US THERE
	TYPE	<?OVL>			;[100] TYPE THE PREFIX
	POPJ	P,			;[100] DONE


;WARN IS CALLED TO SET UP A WARNING MESSAGE. IF THE USER REQUESTED WARNINGS, WE
;GIVE A SKIP RETURN WITH ALL OUTPUT FORCED TO THE TERMINAL AND THE LINE
;POSITIONED AT COLUMN 1.

WARN:	SKIPE	.OVRWA			;[100] USER REQUESTED WARNINGS?
	POPJ	P,			;[100] NO--GIVE NON-SKIP FOR NO WARNINGS
	MOVEI	T1,OUTTTY		;[100] YES--FORCE OUTPUT TO TERMINAL
	MOVEM	T1,PRNCHR		;[100]   ..
	PUSHJ	P,POSCHK		;[100] ARE WE IN COLUMN 1?
	  PUSHJ	P,CRLF			;[100] NO--GET US THERE
	TYPE	<%OVL>			;[100] TYPE THE PREFIX
CPOPJ1:	AOS	(P)			;[100] ALLOW WARNING TO PRINT
CPOPJ:	POPJ	P,			;[100] DONE


;INFO IS CALLED TO SET UP A WARNING MESSAGE. IF THE USER REQUESTED A LOG FILE,
;WE GIVE A SKIP RETURN INDICATING INFORMATIONAL MESSAGES, AND PRINT THE PREFIX
;BEGINNING IN COLUMN 1.

IFN FTLOG,<
INFO:	SKIPN	.OVRLO			;[100] ANY LOG FILE?
	POPJ	P,			;[100] NO--INDICATE NO MESSAGE THEN
	MOVEI	T1,OUTTTY		;[100] ASSUME LOG FILE IS TERMINAL
	SKIPL	.OVRLO			;[100] IS IT?
	MOVEI	T1,OUTLOG		;[100] NO--SET TO REAL LOG FILE OUTPUT
	MOVEM	T1,PRNCHR		;[100]   ..
	PUSHJ	P,POSCHK		;[100] ARE WE IN COLUMN 1?
	  PUSHJ	P,CRLF			;[100] NO--GET US THERE
	TYPE	<[OVL>			;[100] TYPE THE PREFIX
	JRST	CPOPJ1			;[100] INDICATE LOG FILE TO BE USED

;INFOX COMPLETES THE INFORMATIONAL LINE BY TYPING THE CLOSING BRACKET AND CRLF.

INFOX:	TYPE	<]
>					;[100]
	POPJ	P,			;[100] DONE
> ;END IFN FTLOG
SUBTTL	MESSAGE HANDLING -- .OVRLU - Undefined Subroutine Entry


	'.OVRLU'
.OVRLU:	EXP	.+1			;FOR @ IN JRST @(T1)
E$$USC:	PUSHJ	P,WARN			;[100] PRINT %OVL PREFIX
	  JRST	OVRLUX			;[100] NO WARNINGS REQUESTED
	TYPE	<USC	Undefined subroutine >
	MOVE	T1,(P)			;GET PC+1 OF CALLER
	MOVEI	T1,@-1(T1)		;ADDRESS OF EXTTAB
	MOVE	T1,ET.NAM(T1)		;GET SIXBIT NAME OF CALLED ROUTINE
	PUSHJ	P,PRNSBX
	TYPE	< called from PC = >
	MOVE	T1,(P)			;GET PC+1 BACK
	MOVEI	T0,-1(T1)		;BACKUP
	PUSHJ	P,PRNOCT
	PUSHJ	P,CRLF			;[100] FINISH THE LINE
OVRLUX:	SETZB	0,1			;RETURN 0
	POPJ	P,			;[100] DONE

CRLF:	TYPE	<
>
	POPJ	P,			;END LINE AND RETURN TO USER
SUBTTL	MESSAGE HANDLING -- PRNFSP - Print A File Specification


;PRNFSP PRINTS A FILE SPECIFICATION ON TOPS-10. THE FILE SPECIFICATION IS
;CONTAINED IN THE FILOP. AND RELATED BLOCKS POINTED TO BY T1. SEE $FOFIL.

IFE TOPS20,<
PRNFSP:	SPUSH	<T2,T3>			;[100] SAVE SOME ACS
	MOVS	T2,T1			;[100] PUT ADDRESS IN SAFE PLACE
	MOVE	T1,$FOFIL+.FODEV(T2)	;[100] PRINT THE DEVICE
	PUSHJ	P,PRNSBX		;[100]   ..
	TYPEC	":"			;[100]   ..
	MOVE	T1,$FORIB+.RBNAM(T2)	;[100] PRINT THE FILE NAME
	PUSHJ	P,PRNSBX		;[100]   ..
	TYPEC	"."			;[100] PRINT THE EXTENSION
	HLLZ	T1,$FORIB+.RBEXT(T2)	;[100]   ..
	PUSHJ	P,PRNSBX		;[100]   ..
	SKIPN	$FORIB+.RBPPN(T2)	;[100] ANY PATH TO PRINT?
	JRST	PRNFSX			;[100] NO--DONE
	TYPEC	"["			;[100] START THE PATH SPECIFICATION
	MOVE	T1,$FORIB+.RBPPN(T2)	;[100] GET PPN BACK
	TLNN	T1,-1			;[100] PATH BLOCK INSTEAD OF PPN?
	JRST	PRNFS1			;[100] YES--GO PRINT IT

	HLRZ	T0,$FORIB+.RBPPN(T2)	;[100] NO--IT'S JUST THE PPN
	PUSHJ	P,PRNOCT		;[100] PRINT THE PPN
	TYPEC	","			;[100]   ..
	HRRZ	T0,$FORIB+.RBPPN(T2)	;[100]   ..
	PUSHJ	P,PRNOCT		;[100]   ..
	JRST	PRNFS3			;[100] GO FINISH UP
;STILL IN IFE TOPS20

PRNFS1:	HLRZ	T0,$FOPTH+.PTPPN(T2)	;[100] PRINT THE PPN
	PUSHJ	P,PRNOCT		;[100]   ..
	TYPEC	","			;[100]   ..
	HRRZ	T0,$FOPTH+.PTPPN(T2)	;[100]   ..
	PUSHJ	P,PRNOCT		;[100]   ..
	MOVSI	T3,-FTSFD		;[100] SET UP TO LOOP OVER SFD'S
PRNFS2:	SKIPN	$FOPTH+.PTSFD(T2)	;[100] ANY MORE SFD'S?
	JRST	PRNFS3			;[100] NO--DONE
	TYPEC	","			;[100] LEADING COMMA
	MOVE	T1,$FOPTH+.PTSFD(T2)	;[100] PRINT THE SFD NAME
	PUSHJ	P,PRNSBX		;[100]   ..
	AOBJN	T3,PRNFS2		;[100] LOOP OVER ENTIRE PATH

PRNFS3:	TYPEC	"]"			;[100] END THE PATH
PRNFSX:	SPOP	<T3,T2>			;[100] RESTORE THE ACS
	POPJ	P,			;[100] DONE
;STILL IN IFE TOPS20

;PRNLEE PRINTS THE LOOKUP/ENTER MESSAGE ASSOCIATED WITH AN ERROR CODE.

PRNLEE:	TYPEC	" "			;[100] PROVIDE SPACING FOR MESSAGE
	HRRZS	T1			;[100] GET THE ERROR CODE
	CAILE	T1,LEELEN-1		;[100] IF WE DON'T KNOW ABOUT IT
	JRST	PRNLE1			;[100] THEN PRINT THE UNKNOWN MESSAGE
	MOVE	T1,LEETBL(T1)		;[100] ELSE PRINT THE KNOWN MESSAGE
	PJRST	PRNTXT			;[100]   ..

PRNLE1:	PUSH	P,T1			;[100] SAVE THE CODE
	TYPEC	"("			;[100] PRINT THE CODE FOR REFERENCE
	POP	P,T0			;[100]   ..
	PUSHJ	P,PRNOCT		;[100]   ..
	TYPE	<) Unknown error>	;[100]
	POPJ	P,			;[100] DONE

LEETBL:	[ASCIZ \(0) File not found\]
	[ASCIZ \(1) No such directory\]
	[ASCIZ \(2) Protection failure or DECtape directory full\]
	[ASCIZ \(3) File being modified\]
	[ASCIZ \(4) File already exists\]
	[ASCIZ \(5) Illegal sequence of monitor calls\]
	[ASCIZ \(6) Directory data error\]
	[ASCIZ \(7)\]; Not a saved file\]
	[ASCIZ \(10)\]; Not enough memory\]
	[ASCIZ \(11) Device not available\]
	[ASCIZ \(12) No such device\]
	[ASCIZ \(13) Illegal monitor call\]
	[ASCIZ \(14) Quota exceeded or disk full\]
	[ASCIZ \(15) Device is write-locked\]
	[ASCIZ \(16) No monitor free memory\]
	[ASCIZ \(17)\]; Partial allocation only\]
	[ASCIZ \(20)\]; Block not free\]
	[ASCIZ \(21) Cannot supersede existing directory\]
	[ASCIZ \(22) Cannot delete existing directory\]
	[ASCIZ \(23) Sub-directory not found\]
	[ASCIZ \(24) Search list empty\]
	[ASCIZ \(25) Sub-directory nesting exceeded\]
	[ASCIZ \(26) No structure is writable\]
	[ASCIZ \(27)\]; High segment not on swapping space\]
	[ASCIZ \(30) File cannot be updated\]
	[ASCIZ \(31)\]; Low segment overlaps high segment\]
	[ASCIZ \(32)\]; Not logged in\]
	[ASCIZ \(33)\]; Outstanding locks still set\]
	[ASCIZ \(34)\]; Bad EXE file directory\]
	[ASCIZ \(35)\]; Must have .EXE extension\]
	[ASCIZ \(36)\]; EXE file directory too big\]
	[ASCIZ \(37) Network capacity exceeded\]
	[ASCIZ \(40) Task not available\]
	[ASCIZ \(41) Unknown network node\]
	[ASCIZ \(42) Sub-directory is in use\]
	[ASCIZ \(43)\]; File has an NDR lock\]
	[ASCIZ \(44) Job count too high\]
	[ASCIZ \(45) Cannot rename sub-directory to a lower level\]
LEELEN==.-LEETBL			;[100]
> ;END IFE TOPS10
IFN TOPS20,<

;PRNFSP PRINTS THE FILE SPECIFICATION ASSOCIATED WITH A JFN. THE CALL IS:
;
;	T1/	JFN OF THE FILE

PRNFSP:	MOVE	T2,T1			;[100] PUT JFN IN CORRECT AC
	HRROI	T1,INBFR		;[100] NO LONGER NEED THAT BUFFER
	SETZ	T3,			;[100] PRINT DEFAULT FIELDS
	JFNS%				;[100]   ..
	  ERJMP	CPOPJ			;[100] FORGET IT IF ERRORS HERE
	MOVEI	T1,INBFR		;[100] NOW PRINT THE STRING
	PJRST	PRNTXT			;[100]   ..


;PRNJSE PRINTS THE MESSAGE ASSOCIATED WITH THE LAST PROCESS ERROR.

PRNJSE:	TYPEC	" "			;[100] SEPARATE THE TEXT
	HRROI	T1,INBFR		;[42] WHERE TO STORE STRING
	HRLOI	T2,.FHSLF		;[42] THIS FORK, LAST ERROR
	SETZ	T3,			;[42] ANY LENGTH
	ERSTR%				;[41]
	  POPJ	P,			;TOO BAD
	  POPJ	P,			;...
	MOVEI	T1,INBFR		;[100] NOW PRINT THE STRING
	PJRST	PRNTXT			;[100]   ..
> ;END IFN TOPS20
SUBTTL	MESSAGE HANDLING -- PRNLNK, PRNSBX


;PRNLNK PRINTS THE CURRENT LINK'S NAME, OR ITS NUMBER IF IT DOES NOT HAVE A
;NAME. THE TEXT IS PRINTED ON THE USER'S TERMINAL OR THE LOG FILE. THE CALL IS:
;
;	THSLNK/	CONTROL SECTION ADDRESS OF LINK TO PRINT
;	PRNCHR/	ADDRESS OF CHARACTER OUTPUT ROUTINE
;
;USES T0 AND T1.

PRNLNK:	TYPE	< link >		;[100]
	MOVE	T1,THSLNK		;GET CONTROL SECTION ADDRESS
	SKIPE	CS.LNM(T1)		;DOES IT HAVE A NAME?
	JRST	PRNLNM			;YES
	TYPE	<number >		;[100]
	MOVE	T1,THSLNK		;GET CONTROL SECTION ADDRESS AGAIN
	MOVE	T0,CS.NUM(T1)		;LINK#
	PJRST	PRNDEC			;[100] GO PRINT THE LINK NUMBER

PRNLNM:	TYPE	<name >			;[100]
	MOVE	T1,THSLNK		;GET CONTROL SECTION ADDRESS AGAIN
	MOVE	T1,CS.LNM(T1)		;GET IT
;	PJRST	PRNSBX			;[100] PRINT THE NAME AND RETURN


;PRNSBX PRINTS A SIXBIT ITEM TO EITHER THE USER'S TERMINAL OR THE LOG FILE. THE
;CALL IS:
;
;	T1/	SIXBIT WORD TO PRINT
;	PRNCHR/	ADDRESS OF CHARACTER OUTPUT ROUTINE
;
;USES BOTH T0 AND T1

PRNSBX:	JUMPE	T1,CPOPJ		;[100] DONE IF NOTHING TO DO
PRNSB1:	SETZ	T0,			;[100] GET NEXT CHARACTER IN T0
	LSHC	T0,6			;[100]   ..
	ADDI	T0," "-' '		;[100] CONVERT TO ASCII
	PUSHJ	P,@PRNCHR		;[100] AND OUTPUT IT
	JUMPN	T1,PRNSB1		;IF MORE TO DO
	POPJ	P,
SUBTTL	MESSAGE HANDLING -- PRNDEC, PRNOCT - Print Numbers


;PRNDEC PRINTS A DECIMAL NUMBER ON THE USER'S TERMINAL OR THE LOG FILE. THE CALL
;IS:
;
;	T0/	NUMBER TO PRINT IN DECIMAL
;	PRNCHR/	ADDRESS OF CHARACTER OUTPUT ROUTINE
;
;USES T0 AND T1.

PRNDEC:	IDIVI	T0,^D10
	HRLM	T1,(P)			;STORE ON STACK
	SKIPE	T0			;DONE?
	PUSHJ	P,PRNDEC		;NOT YET
PRNDE1:	HLRZ	T0,(P)			;RECOVER
	ADDI	T0,"0"
	PJRST	@PRNCHR			;[100] PRINT THE CHARACTER


;PRNOCT PRINTS A OCTAL NUMBER ON THE USER'S TERMINAL OR THE LOG FILE. THE CALL
;IS:
;
;	T0/	NUMBER TO PRINT IN OCTAL
;	PRNCHR/	ADDRESS OF CHARACTER OUTPUT ROUTINE
;
;USES T0 AND T1.

PRNOCT:	IDIVI	T0,8
	HRLM	T1,(P)			;STORE ON STACK
	SKIPE	T0			;DONE?
	PUSHJ	P,PRNOCT		;NOT YET
	PJRST	PRNDE1
SUBTTL	MESSAGE HANDLING -- PRNTXT, PRNFRS


;PRNTXT PRINTS A TEXT STRING TO EITHER THE USER'S TERMINAL OR THE LOG FILE. THE
;CALL IS:
;
;	T1/	ADDRESS OF ASCIZ STRING
;	PRNCHR/	ADDRESS OF CHARACTER OUTPUT ROUTINE
;
;USES BOTH T0 AND T1.

PRNTXT:	HRLI	T1,(POINT 7,0)		;[100] BUILD THE BYTE POINTER
PRNTX1:	ILDB	T0,T1			;[100] GET NEXT CHARACTER
	JUMPE	T0,CPOPJ		;[100] DONE WHEN WE GET A NULL
	PUSHJ	P,@PRNCHR		;[100] PRINT THE CHARACTER
	JRST	PRNTX1			;[100] LOOP FOR ALL CHARACTERS


;PRNFRS PRINTS THE FUNCT. RETURN STATUS FOLLOWING A FAILING CALL TO FUNCT.. THE
;TEXT IS PRINTED ON THE USER'S TERMINAL OR THE LOG FILE. THE CALL IS:
;
;	STATUS/	FUNCT. RETURN STATUS
;	PRNCHR/	ADDRESS OF CHARACTER OUTPUT ROUTINE
;
;USES T0 AND T1.

PRNFRS:	TYPE	<, FUNCT. return status > ;[100] PRINT FUNCT.'S STATUS
	MOVE	T0,STATUS		;[100]   ..
	PJRST	PRNOCT			;[100]   ..
SUBTTL	MESSAGE HANDLING -- PRNTIM - Print Runtime


IFN FTLOG,<
PRNTIM:	SPUSH	<T2,T3>			;[100] SAVE SOME ACCUMULATORS
  IFE TOPS20,<
	SETZ	T0,			;THIS JOB
	RUNTIM	T0,			;RUNNING TIME IN MILLISECS
  > ;END IFE TOPS20
  IFN TOPS20,<
	MOVX	T1,.FHJOB		;[42] WHOLE JOB
	RUNTM%				;[41]
	MOVE	T0,T1			;[42]
	IMULI	T0,^D1000		;* MILISECS
	IDIVI	T0,(T2)			;[42] AFTER SECONDS DIVIDER IS APPLIED
  > ;END IFN TOPS20
	SUB	T0,ITIME
	IDIV	T0,[^D3600000]		;GET HOURS
	MOVE	T3,T1			;SAVE REST
	MOVEI	T2," "			;FILL WITH SPACE
	JUMPE	T0,.+3			;NO HOURS
	PUSHJ	P,PRNDC2		;TYPE TWO DIGITS
	PUSHJ	P,PRNCLN		;TYPE COLON
	MOVE	T0,T3			;RESTORE REST
	IDIVI	T0,^D60000		;GET MINS
	MOVE	T3,T1			;SAVE REST
	JUMPE	T0,.+3			;NO MINS
	PUSHJ	P,PRNDC2		;TYPE TWO DIGITS
	PUSHJ	P,PRNCLN		;TYPE COLON
	MOVE	T0,T3			;RESTORE THE REST
	IDIVI	T0,^D1000		;GET SECONDS
	MOVE	T3,T1			;SAVE REM
	PUSHJ	P,PRNDC2		;PRINT TWO DIGITS
	MOVEI	T0,"."
	PUSHJ	P,PRNCL0		;SET NEW FILLER
	MOVE	T0,T3			;GET MILLISECS
	IDIVI	T0,^D10
	PUSHJ	P,PRNDC2		;TWO DIGITS IS ENOUGH
	PJRST	T3POPJ

PRNDC2:	CAILE	T0,^D9			;SEE IF ONE DIGIT
	PJRST	PRNDEC			;NO--JUST OUTPUT
	EXCH	T0,T2			;[100] SWAP DIGITS
	PUSHJ	P,@PRNCHR		;[100] PRINT FILL CHARACTER
	EXCH	T2,T0			;[100] GET DIGIT BACK
	ADDI	T0,"0"			;[100] CONVERT TO A CHARACTER
	PJRST	@PRNCHR			;[100] PRINT IT

PRNCLN:	MOVEI	T0,":"
PRNCL0:	MOVEI	T2,"0"			;NEW FILLER
	PJRST	@PRNCHR			;[100] PRINT THE CHARACTER
> ;END IFN FTLOG
SUBTTL	ERROR MESSAGES (TEXT)


COMMENT	\
ARC	Attempt to remove caller from [link]
ARL	Ambiguous request in [link], using link number [decimal]
CCF	Cannot close file [file], status [octal]
CDL	Cannot delete [link], FUNCT. return status [octal]
CFF	Cannot find file [file] [jserr]
CFF	Cannot find file [file] [reason]
CGM	Cannot get memory from OTS, FUNCT. return status [octal]
CRF	Cannot read file [file] [jserr]
CSM	Cannot shrink memory, FUNCT. return status [octal]
CUF	Cannot update file [file] [reason]
CWF	Cannot write file [file] [jserr]
CWF	Cannot write file [file] [reason]
DLN	Deleting [link] after [time]
IAT	Illegal argument type on call to [symbol] from PC = [octal]
IEF	Input error for file [file] [jserr]
IEF	Input error for file [file], status [octal]
ILN	Illegal link number [decimal]
IMP	'Impossible' error condition at PC = [octal]
IPE	Input positioning error for file [file] [jserr]
IPE	Input positioning error for file [file], status [octal]
IVN	Inconsistent version numbers
LNM	Link number [decimal] not in memory
MAN	Memory not available for absolute [link], FUNCT. return status [octal]
MEF	Memory expansion failed, FUNCT. return status [octal]
NMS	Not enough memory to load symbols, FUNCT. return status [octal]
NRS	No relocation table for symbols
NSA	No start address for [link]
NSD	No such device for [file]
OEF	Output error for file [file] [jserr]
OEF	Output error for file [file], status [octal]
OPE	Output positioning error for file [file] [jserr]
OPE	Output positioning error for file [file], status [octal]
OPP	Overlay handler in private page
RLL	Relocating [link] at [octal]
RLN	Reading [link] after [time]
RMP	RMAP% JSYS failed [jserr]
RPA	RPACS% JSYS failed [jserr]
STS	OTS reserved space too small
ULN	Unknown link name [symbol]
USC	Undefined subroutine [symbol] called from PC = [octal]
WLN	Writing [link] after [time]
\
SUBTTL	DATA AREAS


	SEGMENT	LOW

;THE FOLLOWING DATA DO NOT NEED TO BE ZEROED UPON OVRLAY INITIALIZATION.

.OVRWA::BLOCK	1		;[100] -1 IF WARNINGS TYPED (SET BY LINK)
.OVRLO::BLOCK	1		;[100] -1 IF LOG FILE ON TTY (SET BY LINK)
OVLNAM:	ASCIZ /OVL/		;[100] OVERLAY HANDLER'S MNEMONIC
PRNCHR:	BLOCK	1		;[100] OUTPUT ROUTINE--EITHER OUTTTY OR OUTLOG
DI:	BLOCK	DI.LEN		;[100] OVERLAY FILE DIRECTORY
PH:	BLOCK	PH.LEN		;[100] OVERLAY FILE PREAMBLE FOR EACH LINK
OVLSPC:	BLOCK	1		;[100] -1 MEANS USER SUPPLIED OVERLAY SPEC
%JBREL:	BLOCK	1		;[100] HOLD .JBREL	**MUST** BE
%JBSA:	BLOCK	1		;[100] HOLD .JBSA	CONSECUTIVE
IFE TOPS20,<			;[100] TOPS-10 ONLY NON-ZEROED DATA
JOBNUM:	BLOCK	1		;[100] SIXBIT JOB #,,BINARY JOB #
MYPPN:	BLOCK	1		;[100] LOGGED IN PPN
> ;END IFE TOPS20
IFN TOPS20,<			;[100] TOPS-20 ONLY NON-ZEROED DATA
TMPNAM:	ASCIZ	/OVERLAY.TMP;T/	;[100] NAME OF THE TEMPORARY FILE
> ;END IFN TOPS20
IFN FTLOG,<			;[100] LOG FILE ONLY NON-ZEROED DATA
ITIME:	BLOCK	1		;RUN TIME AT START
> ;END IFN FTLOG
;THE FOLLOWING DATA MUST BE ZEROED UPON OVERLAY INITIALIZATION.

I.ZZ:!				;FIRST WORD TO ZERO
OW:	BLOCK	WR.LEN		;[100] WRITABLE LINK TABLE
INCIDX:	BLOCK	1		;LOWEST INDEX IN CORE
STATUS:	BLOCK	1		;STATUS ON RETURN FROM OTS
ADDCOR:	BLOCK	1		;ADDRESS OF CORE FOR OTS CALL	**MUST** BE
SIZCOR:	BLOCK	1		;LENGTH OF CALL FOR OTS CALL	CONSECUTIVE
UBLOCK:	BLOCK	1		;NEXT BLOCK FOR I/O
FSTLNK:	BLOCK	1		;POINTER TO CONTROL BLOCK OF FIRST LINK
CURLNK:	BLOCK	1		;POINTER TO CONTROL BLOCK OF LINK MAKING REQUEST
CURNUM:	BLOCK	1		;LINK # OF CURLNK
THSLNK:	BLOCK	1		;POINTER TO TEMP LINK
HILINK:	BLOCK	1		;HIGHEST LINK NUMBER
IFN TOPS20,<
OVRJFN:	BLOCK	1		;[100] JFN OF THE OVERLAY FILE
TMPJFN:	BLOCK	1		;[100] JFN OF THE TEMPORARY FILE
TEMP2:	BLOCK	2		;SAVE ACCS 2 & 3
STRPTR:	BLOCK	1		;[100] POINTER TO OVERLAY FILE
> ;END IFN TOPS20
USERPC:	BLOCK	1		;[44] USER RETURN PC FOR MANUAL CALLS
OKOVLC:	BLOCK	1		;[43] -1 = OK TO OVERLAY CALLER (RUNOV.)

IDXBFR:	BLOCK	200		;200 WORD WINDOW OF LINK POINTERS
INBFR:	BLOCK	200		;200 WORD WINDOW OF FILE
I.END==.-1			;LAST WORD TO ZERO

	SEGMENT	HIGH
	PURGE	%SEG%
SUBTTL	THE END


	END