	.TITLE .SYSLD
 
/ .... EDIT #24 .... 6 MAR 70
 
/ COPYRIGHT 1968, 1969, 1970 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
 
	.ABS
	.LOC 14000
 
/ VERSION V1A - JEAN-CLAUDE P. PROTEAU
/ PDP-9 BACKGROUND/FOREGROUND SYSTEM PROGRAM.
/ WHEN DOING A FOREGROUND LOAD, THIS IS THE LINKING LOADER.
/ WHEN DOING A BACKGROUND LOAD, SYSTEM PROGRAMS ARE LOADED.
 
 
/ SEQUENTIAL OPERATION:
 
/  1. BANK BIT INITIALIZE
/  2. INITIALIZE POINTERS
/  3. FOREGROUND OR BACKGROUND LOAD?
 
/ FOREGROUND LINK LOAD (EXCLUDING EXECUTE):
 
/  4. LOAD LOADER'S I/O HANDLERS (EXCEPT FOR PIP)
/  5. READ USER'S COMMAND STRING (EXCEPT FOR PIP)
/  6. LOAD USER'S PROGRAMS (OR LOAD PIP)
/  7. LOAD LIBRARY ROUTINES (FROM .LIBR, .F4LIB, .IOLIB)
/  8. DEFINE COMMON
/  9. MATCH VIRTUAL GLOBALS TO COMMON
/ 10. TEST FOR UNRESOLVED GLOBALS
/ 11. ASSIGN I/O BUFFERS
/ 12. SETUP .SCOM REGISTERS
/ 13. TEST FOR MEMORY OVERLAP
/ 14. CLEAR LOADER'S .DAT SLOTS AND EXIT
 
/ BACKGROUND SYSTEM PROGRAM LOAD (EXCLUDING EXECUTE):
 
/ 15. PROCESS SYSTEM PROGRAM'S .IODEV'S
/ 16. ASSIGN I/O BUFFERS
/ 17. SETUP .SCOM REGISTERS
/ 18. IF LINK LOADER, LOAD IT, MOVE I/O CONVERSION TABLE
/     ABOVE IT, AND EXIT
/ 19. IF OTHER, .TRAN IN THE LOADING INFO. BLOCK
/ 20. BUILD THE .TRAN ROUTINE
/ 21. GO TO .TRAN-.WAIT-.CLOSE-.EXIT
 
	.EJECT
/ FOREGROUND EXECUTE LOAD:
 
/ 22. LOAD EXECUTE'S HANDLER (IF NOT THE RESIDENT HANDLER)
/ 23. OPEN "XCT" FILE TO GET .IODEV INFO, TO TEST ENVIRONMENT
/     COMPATIBILITY AND TO CHECK LIMITS OF FILE'S CORE SPACE.
/ 24. LOAD I/O, INCLUDING ANOTHER COPY OF EXECUTE'S HANDLER,
/     STARTING ABOVE THE SPACE RESERVED FOR THE XCT FILE.
/ 25. LOAD IN EXECUTE
/ 26. SAME AS 11-14
 
/ BACKGROUND EXECUTE LOAD:
 
/ 27. SAME AS 22-23
/ 28. LOAD "XCT" FILE'S I/O
/ 29. ASSIGN I/O BUFFERS
/ 30. LOAD EXECUTE ABOVE THE PROTECT BOUND
/ 31. SET UP .SCOM REGISTERS; THEN EXIT
 
/ FUNCTION OF .DAT SLOTS USED:
 
/ -7	INPUT OF SYSTEM PROGRAMS, FORTRAN LIBRARY, AND I/O LIBRARY
/ -5	USER'S LIBRARY FILE INPUT (IF ANY)
/ -4	USER'S PROGRAMS INPUT (IF ANY)
/ -3	OUTPUT TO THE TELETYPE
/ -2	INPUT FROM THE TELETYPE OR BATCH PROCESSING DEVICE
 
 
/ LABELLING CONVENTIONS:
 
/ PERMANENT LITERALS ARE LABELLED: PLIT## .
/ THOSE WHICH SUGGEST OBVIOUS NAMES ARE SO LABELLED.
/ MOST OF THE BANK-BIT INITIALIZED TRANSFER VECTORS ARE
/ LABELLED: ADR## .
 
 
/ SYMBOL DEFINITIONS:
 
IDX=ISZ		/USED WHEN THE SKIP IS NOT INTENDED.
SET=ISZ		/USED WHEN THE INTENTION IS TO SET A
		/PROGRAM FLAG TO NON-ZERO.
.SCOM=100		/START OF THE SYSTEM COMMUNICATION TABLE
		/WITHIN THE RESIDENT MONITOR.
 
	.EJECT
/ PROGRAM FLAGS:
 
/ ONLY MAJOR PROGRAM FLAGS ARE LISTED BELOW.
 
/ ABSFLG: 0 MEANS IT IS ILLEGAL TO LOAD ABSOLUTE PROGRAMS WITH THE FGD LINK
/ LOADER. SET NON-0, PRIOR TO LOADING FOREGROUND USER PROGRAMS, WITH
/ LOWEST FREE CORE ADDRESS. THEN IT IS UPDATED TO CONTAIN THE FIRST FREE
/ LOCATION ABOVE THE ABSOLUTE PROGRAMS. AS SOON AS A RELOCATABLE PROGRAM
/ OR A LIBRARY IS ENCOUNTERED, THIS FLAG IS USED TO SET THE FREE CORE
/ BOUND FOR LOADING, AND THEN IT IS SET TO 0.
 
/ LLIOFLG: WHEN THE SYSTEM LOADER LOADS THE FOREGROUND JOB, IT MUST FIRST
/ LOAD I/O HANDLERS FOR .DAT SLOTS -4 AND -5 IF NOT ALREADY IN CORE.
/ LLIOFLG IS SET NON-0 THEN. SUBROUTINE FIT WILL SETUP TO LOAD THE
/ FOREGROUND LINK LOADER HANDLERS DOWN FROM THE TOP OF FREE CORE.
 
/ IOFLAG: IF LLIOFLG OR IOFLAG IS SET, SUBROUTINE FIT WILL GIVE A LOAD
/ ADDRESS DIVISIBLE BY 4, WHICH IS NECESSARY FOR I/O HANDLERS.
 
/ NUFILE: IS SET NON-0 WHENEVER ENTRY TO SUBROUTINE LDPROG WAS PRECEDED
/ BY A .SEEK . IF NUFILE=0, WE ARE SOMEWHERE WITHIN A LIBRARY FILE
/ AND A .READ HAS ALREADY BEEN ISSUED.
 
/ LIBFLG: IS SET NON-0 WHEN IN LIBRARY SEARCH MODE. EACH LIBRARY FILE
/ CONSISTS OF PROGRAM UNITS (PROGRAM SIZE, INTERNAL GLOBALS, LOAD
/ ADDRESS, DATA WORDS, VIRTUAL GLOBALS, END CODE) AND IS TERMINATED BY
/ AN END-OF-FILE CODE. IF LIBFLG IS SET, A LIBRARY PROGRAM IS NOT LOADED
/ UNLESS ONE OF ITS INTERNAL GLOBALS MATCHES A VIRTUAL GLOBAL REQUEST IN
/ THE SYMBOL TABLE. IF MATCH FOUND, THEN LIBFLG IS CLEARED BOTH TO LOAD
/ IN THE REST OF THE PROGRAM AND TO SIGNAL THE LIBRARY SEARCHING ROUTINE
/ THAT A GLOBAL WAS RESOLVED.
 
/ BLKFLG: IS BOTH A FLAG AND A RELOCATION FACTOR. IT IS 0 WHEN NOT LOADING
/ A BLOCKDATA SUBPROGRAM. WHEN A BLOCKDATA SUBPROGRAM IS ENCOUNTERED, THE
/ LOAD ADDRESS OF THE SUBPROGRAM IS STORED IN BLKFLG, WHICH ALSO SETS THE
/ FLAG. BLKFLG IS TURNED OFF WHEN THE END-OF-PROGRAM CODE IS ENCOUNTERED.
 
 
/ COMFLG: IS SET NON-0 WHEN DEFINING COMMON BLOCKS WHICH ARE NOT PART
/ OF BLOCKDATA SUBPROGRAMS OR WHEN ASSIGNING CORE SPACE FOR I/O
/ HANDLER BUFFERS.
 
/ XCTFLG: IS SET NON-0 TO INFORM SUBROUTINE LDPROG THAT IT IS SEARCHING
/ AN "XCT" FILE FOR LINK #377777.
 
	.EJECT
FIRST=.
LINBF1=.
 
/ INPUT LINE BUFFER #1: SIZE=62 OCTAL (50 DECIMAL) BASED ON
/ IOPS BINARY BLOCK SIZE. PROGRAM LOADING IS DOUBLE-BUFFERED.
 
.SYSLD	LAC* (.SCOM		/HIGHEST REGISTER IN CORE.
	AND (60000		/GET BANK BITS TO ADD INTO
	DAC BNKBTS		/15-BIT ADDRESSES.
BKLOOP	LAC BNKTAB
	IDX .-1
	XOR BNKBTS
	DAC BNKTAB
	IDX .-1
	LAC* BNKTAB
	IDX .-1
	XOR BNKBTS
	DAC* BNKTAB
	IDX .-1
	ISZ BNKCNT
	JMP BKLOOP
	JMP BKDONE
BNKTAB	ADR1
	ADR2
	ADR3
	ADR4
	ADR5
	ADR8
	ADR9
	ADR10
	ADR11
	ADR12
	ADR13
	ADR15
	ADR16
	SEEKPT
	LIBPTR
	BANKS
	PBANK0
	PLIT2
BNKCNT	BNKTAB-.
 
	.EJECT
BKDONE	LAC* (.SCOM+2		/CONTAINS LOWEST FREE CORE ADDRESS.
	DAC TEMP1
	LAC* (.SCOM+26		/0=FGD.
	SZA
	JMP NTFPIP		/BGD.
	LAC* (.SCOM+5		/LOOK AT LOADER CODE.
	SAD (3
	SKP			/PIP TO BE LOADED IN FGD.
NTFPIP	CLA!SKP
	LAC* (.SCOM+25		/$FCORE
	TAD TEMP1			/C(.SCOM+2)
	JMS CORE			/SETUP INFO. ABOUT FREE CORE.
	LAC* (.SCOM+3		/HIGHEST FREE ADDRESS BELOW .SYSLD.
	DAC IOCPTR		/PTR. TO REGISTER BELOW I/O TABLE.
	DAC DIRPTR		/POINTER TO PROGRAM DIRECTORIES TABLE.
 
/ END OF LINE BUFFER #1.
/ INPUT LINE BUFFER #2: SIZE=62 OCTAL (50 DECIMAL).
 
LINBF2	DAC SYMBEG		/POINTER TO BEG. OF SYMBOL TABLE.
	DAC SYMEND		/POINTER TO END OF SYMBOL TABLE.
	DZM* TEMP1		/ZERO ALL OF FREE CORE.
	SAD TEMP1
	JMP .+3
	IDX TEMP1
	JMP .-4
	LAC* (.SCOM+26		/0=FGD RUNNING; 1=BGD RUNNING
	SZA
	IDX DAT			/DAT INITIALLY CONTAINS .SCOM+16,
	SZA			/FCTL.P INITIALLY CONTAINS .SCOM+67.
	IDX FCTL.P		/CHANGE TO POINT TO .SCOM+70 FOR BGD.
	LAC* DAT			/WHICH POINTS AT .DATF.
	DAC DAT			/DAT NOW POINTS AT .DATF OR .DATB.
	LAC* IOINPTR		/GET POINTER TO .IOIN TABLE.
	DAC IOINPTR
	TAD PLUS1			/SETUP POINTER TO WORD WHICH CONTAINS
	DAC IOINMAX		/MAXIMUM SIZE OF THE .IOIN TABLE.
	LAC* MUDPTR		/GET POINTER TO .MUD TABLE.
	DAC MUDPTR
	LAC* .BFPTR		/GET POINTER TO .BFTAB .
	DAC .BFPTR
	TAD PLUS1
	DAC .BFMAX		/POINTER TO MAX. SIZE OF .BFTAB .
 
	.EJECT
	LAC* FCTL.P	/GET PTR TO FGD OR BGD CTL CHAR TABLE,
	TAD PLUS1		/ADD 1 TO POINT TO ^P REGISTER.
	DAC FCTL.P
	LAC* (.SCOM+26
	SZA
	JMP BKGRND	/THIS IS A BACKGROUND LOAD.
	LAC* (.SCOM+5	/CHECK LOAD CODE.
	SAD (3		/PIP.
	JMP FGDPIP
	SNA		/SKIP IF EXECUTE.
	JMP FGLLDR	/NO. LINK LOADER.
	LAW -4
	TAD DAT
	DAC DATM4		/POINTER TO .DATF -4
	LAC* DATM4
	DAC CDATM4	/SAVE ITS CONTENTS.
	LAW -4
	JMP FGDXCT
 
/ FOR A FOREGROUND LOAD, FIRST BRING IN ANY I/O
/ HANDLERS NEEDED BY THE LINKING LOADER WHICH
/ ARE NOT ALREADY IN CORE.  THEY WILL BE LOADED
/ BELOW THE SYSTEM LOADER.
 
FGLLDR	SET LLIOFLG	/TELL SUBROUTINES FIT AND IODEV.
			/THAT FGD LINK LOADER I/O HANDLERS
			/ARE NOW BEING LOADED.
 
/ CALL SUBROUTINE IODEV. WITH THE LINK LOADER'S
/ .DAT SLOT NUMBERS. IF I/O HANDLERS NEED TO BE
/ LOADED, ENTRIES WILL BE MADE IN THE SYMBOL TABLE.
 
	LAW -4
	JMS IODEV.
	LAW -5
	JMS IODEV.
	LAW -3		/RESET .IOIN ENTRY COUNT.
	DAC* IOINPTR	/IF NEEDED BY USER, THESE HANDLERS
			/MUST BE RELOADED.
	JMS LOADIO	/LOAD IN THE I/O HANDLERS.
 
/ END OF LINE BUFFER #2.
 
	DZM LLIOFLG
	DZM F4FLAG
 
	.EJECT
/ TELL THE USER THAT THIS IS THE LOADER AND PREPARE TO ACCEPT,
/ FROM THE TELETYPE, THE LIST OF NAMES OF PROGRAMS TO BE LOADED.
 
/ IF THE USER TYPES CONTROL P WHILE THE LOADER IS ACCEPTING PROGRAM
/ NAMES, THE LOADER WILL RESTART HERE.
 
RESTART	LAC DIRPTR	/CLEAR OUT PROGRAM DIRECTORIES TABLE
	DAC SYMEND	/BY RESETTING THE END OF SYMTAB PTR.
	DZM OPFLAG	/INIT OPTION PROCESSING.
	DZM MAPFUNC	/INIT MEM. MAP FUNCTION BITS.
 
	CAL 1775		/.INIT -3; PRINT CR LF; SETUP TO XFER
	1		/TO LOCATION 'RESTART' IF USER TYPES
ADR1	RESTART		/CONTROL P.
TEMP1	0
 
	CAL 2775		/.WRITE -3 IOPS ASCII ON THE TTY.
	11
ADR2	MSG1		/MESSAGE: 'FGLOAD V1A'<15>.
PLIT16	177
 
NEXLIN	CAL 2775		/.WRITE -3 IOPS ASCII ON THE TTY.
	11
ADR3	MSG2		/MESSAGE: '>'<175>.
PLIT26	776000
 
	CAL 2776		/.READ -2 IOPS ASCII FROM THE TTY
	10
PLIT2	LINBF1		/INTO LINE BUFFER #1.
	-62
 
	CAL 776		/.WAIT -2 FOR COMPLETION OF READIN.
	12
 
	LAC PLIT2		/(LINBF1
	TAD (2		/SETUP POINTER TO 1ST DATA WORD.
	DAC TEMP1
MINUS1	LAW -1
	DAC TEMP2		/INIT 5/7 ASCII BYTE COUNT.
 
NEXNAM	DZM SYMFLG	/0 FLAG MEANS SYMBOL NOT FULL.
	DZM DLMITR	/0 SYMBOL DELIMITER MEANS
			/DELIMITER NOT YET ENCOUNTERED.
MINUS2	LAW -2
	DAC TEMP3		/INIT 2-WORD-PER-SYMBOL COUNT.
 
	.EJECT
NEXHAF	DZM SYM2		/0 TEMP. ACCUMULATOR OF SYMBOL.
MINUS3	LAW -3
	DAC TEMP4		/INIT 3-CHARS-PER-WORD COUNT.
	JMP DELTST
 
GETCHAR	ISZ TEMP2		/SKIP IF WORD PAIR EXHAUSTED.
	JMP GETNEX
	LAW -5		/RESET BYTE COUNT TO 5.
	DAC TEMP2
	LAC* TEMP1	/PICKUP NEXT ASCII WORD PAIR.
	DAC TEMP5		/SAVE WORD 1.
	IDX TEMP1
	LAC* TEMP1
	DAC TEMP6		/SAVE WORD 2.
	IDX TEMP1
 
GETNEX	LAW -10		/SETUP SHIFT COUNT TO DO 7+1/2 SHIFTS.
	DAC TEMP7
 
ROTATE	LAC TEMP6		/SHIFT WORD 2 WITH THE LINK.
	RAL
	ISZ TEMP7		/IS THE CHAR IN POSITION?
	JMP ROTWD1	/NO. SHIFT WORD 1 TOO.
	AND PLIT16	/YES. MASK TO 7 BITS: (177.
	DAC TEMP7		/SAVE CHAR FOR FURTHER REFERENCE.
	LAC OPFLAG	/ARE OPTIONS BEING READ OR
	SZA		/PROGRAM NAMES?
	JMP NAMES
	LAC TEMP7		/CHECK FOR OPTION CHARACTER.
	SAD (103
	JMP C
	SAD (107
	JMP G
	SAD (120
	JMP P
	SAD (137		/_ OPTION TERMINATOR.
	DAC OPFLAG	/SET FLAG NON-0 TO TERMINATE OPTIONS.
	SAD (175		/ALT MODE?
	JMP RESTART	/YES. START OVER.
	SAD (15		/CAR RET?
	JMP NEXLIN	/YES. GO TO NEXT LINE.
	JMP DELTST	/IGNORE THE CHAR.
C	LAC (4		/COMMON BLOCKS.
	SKP
G	LAC (2		/GLOBAL SYMBOLS.
	SKP
P	LAC PLUS1		/PROGRAM NAMES.
	XOR MAPFUNC
	DAC MAPFUNC	/INSERT IN FUNCTION BITS.
	JMP DELTST	/GET NEXT CHAR.
 
	.EJECT
NAMES	LAC TEMP7
	SAD SPACE
	JMP DELTST	/IGNORE SPACES.
	SAD (54
	JMP DELIMIT	/COMMA IS A DELIMITER.
	SAD (175
	JMP DELIMIT	/ALT MODE IS A DELIMITER.
	SAD PLIT14	/(15
	JMP DELIMIT	/CAR RET IS A DELIMITER.
	SAD PLIT15	/(12
	JMP DELTST	/IGNORE LINE FEEDS.
	LAC SYMFLG	/IS SYMBOL FULL?
	SZA!CLL
	JMP DELTST	/YES. IGNORE THIS CHARACTER.
	LAC TEMP7		/NO.
	AND (77		/TRIM TO 6 BITS.
FILLIT	XOR SYM2		/ADD IN ACCUMULATED SYMBOL.
	ISZ TEMP4		/IS THIS CHAR #3 OR #6?
	JMP MAKROOM	/NO.
	ISZ TEMP3		/YES. IS THIS CHAR #6?
	JMP HAFFUL	/NO. SYMBOL ONLY HALF FULL.
	SET SYMFLG	/NON-ZERO FLAG MEANS SYMBOL IS FULL.
	JMP STORE2
 
	.EJECT
HAFFUL	DAC SYM1		/STORE FIRST HALF OF SYMBOL.
	JMP NEXHAF
MAKROOM	RTL		/SHIFT PARTIAL SYMBOL WORD TO MAKE
	RTL		/ROOM FOR NEXT CHARACTER.
	RTL
STORE2	DAC SYM2
	JMP DELTST
ROTWD1	DAC TEMP6		/WORD2.
	LAC TEMP5		/SHIFT WORD 1 TOO.
	RAL
	DAC TEMP5
	JMP ROTATE	/CONTINUE SHIFTING.
DELIMIT	DAC DLMITR	/SAVE SYMBOL DELIMITER.
DELTST	CLA!CLL
	SAD DLMITR	/HAS DELIMITER BEEN ENCOUNTERED?
	JMP GETCHAR	/NO. GET NEXT CHARACTER.
	SAD SYMFLG	/YES. IS SYMBOL FULL?
	JMP FILLIT	/NO. FILL IT WITH 0'S.
 
/ SYMBOL IS FULL AND SYMBOL DELIMITER WAS SEEN. ENTER THE PROGRAM
/ NAME, WITH AN EXTENSION OF 'BIN', IN THE PROGRAM DIRECTORIES TABLE.
 
	LAC BIN
	JMS ENTSYM
	LAC SYM2
	JMS ENTSYM
	LAC SYM1
	JMS ENTSYM
 
	LAC DLMITR	/TEST DELIMITER.
	SAD (54		/COMMA?
	JMP NEXNAM	/YES. GET NEXT PROGRAM NAME.
	SAD PLIT14	/(15 CAR RET?
	JMP NEXLIN	/YES. READ IN NEXT COMMAND LINE.
 
/ DELIMITER WAS ALT MODE SIGNIFYING END OF INPUT.
 
	CAL 775		/.INIT -3; PRINT CR LF.
	1
	0		/SHUT OFF CONTROL P.
TEMP3	0
 
	JMP SETBEG
FGDPIP	LAC BIN		/SET UP FILE DIRECTORY ENTRY BLOCK
	JMS ENTSYM	/TO LOAD .SIXBT /PIP@@@BIN/.
	CLA
	JMS ENTSYM
	LAC PIP
	JMS ENTSYM
	LAC PIPOUT	/SET IODEV PROCESSOR TO IGNORE
	DAC PIPZER	/0 CONTENTS .DAT SLOT.
LDFRM7	LAW -4
	TAD DAT
DATM4	DAC .		/POINTER TO .DATF-4
CDATM4	TAD MINUS3	/FGD STORES C(.DATF -4) HERE.
	DAC .		/POINTER TO .DATF-7
	LAC* .-1		/SET UP .DATF-4 SO THAT PIP WILL
	DAC* DATM4	/LOAD FROM SYSTEM TAPE.
SETBEG	LAC SYMEND	/SET BEGINNING OF SYMBOL TABLE JUST
	DAC SYMBEG	/BELOW THE PROGRAM DIRECTORIES TABLE.
	JMP USRPRG
 
FGDXCT	JMS IODEV.	/.IODEV -4 FOR EXECUTE'S HANDLER.
	JMS IOLOAD
	LAW -3		/RESET .IOIN ENTRY COUNT & SYMBOL
	DAC* IOINPTR	/TABLE TO DISCARD EXECUTE'S HANDLER,
	LAC SYMBEG	/WHICH WILL BE RELOADED LATER.
	DAC SYMEND
	JMS XCTFIL	/READ INFO FROM "XCT" FILE.
	LAC* (.SCOM+2	/REGISTER ABOVE THE MONITOR.
	JMS TWOS
	TAD X.LOW		/LOWEST REGISTER IN "XCT" FILE.
	SPA
	JMP ERR121	/"XCT" FILE OVERLAYS THE MONITOR.
	LAC SYMEND
	JMS TWOS
	TAD X.HIGH	/HIGHEST REGISTER IN "XCT" FILE.
	SMA
	JMP ERR122	/XCT FILE OVERLAYS THE SYMBOL TABLE.
	LAC CDATM4	/RESTORE .DATF -4 SO THAT EXECUTE'S
	DAC* DATM4	/HANDLER CAN BE RELOADED (THIS TIME
	LAW -4		/ABOVE THE "XCT" FILE'S CORE SPACE).
	JMS IODEV.	/.IODEV -4
	LAC X.HIGH
	TAD PLUS1
	JMS CORE		/FREE CORE NOW STARTS ABOVE "XCT" CORE.
	JMS IOLOAD	/LOAD HANDLERS.
	LAC SKPLIT	/(SKP
	DAC SKIP1		/DO NOT RECOMPUTE FREE CORE POINTERS
	DAC SKIP2		/AND DO NOT CLEAR .DATF -4 AND -5.
	DAC SKIP3
	JMP EXE		/LOAD EXECUTE AND RETURN HERE.
FX.RET	LAC* (.SCOM+5	/START ADDRESS BELONGS IN .SCOM+6.
	AND (77777
	XOR (200000	/SET $GLOAD BIT.
	DAC* (.SCOM+6
	JMP FGDBUF	/ASSIGN I/O BUFFERS.
 
	.EJECT
/ LOAD IN EACH REQUESTED PROGRAM FROM THE USER'S INPUT DEVICE.
/ ABSFLG TURNED ON TO ALLOW LOADING ABSOLUTE PROGRAMS IN FOREGROUND.
 
USRPRG	LAC LOSYM		/LOWEST FREE REGISTER.
	DAC ABSFLG
 
NEXPRG	LAC DIRPTR	/ARE THERE ANY MORE TO LOAD?
	SAD SYMBEG
	JMP CKFPIP	/NO. CHECK IF PIP IN FGD.
	TAD MINUS2
	DAC PRGDIR
	TAD MINUS1	/UPDATE POINTER TO
	DAC DIRPTR	/NEXT DIRECTORY ENTRY.
 
	CAL 774		/.INIT -4 FOR INPUT OF USER'S PROGRAM.
	1
TEMP4	0
TEMP5	0
 
PLIT3	CAL 774		/.SEEK ON -4 THE USER'S PROGRAM.
	3
PRGDIR	XX		/POINTER TO ENTRY IN PROGRAM DIRECTORIES TABLE.
 
	SET NUFILE	/SET FLAG THAT SAYS A .SEEK WAS JUST DONE.
 
	LAC PLIT3		/(CAL 774
	JMS LDPROG	/LOAD IN USER'S PROGRAM, RETURNING
			/15-BIT STARTING ADDRESS IN THE AC.
	DAC TEMP1
	LAC* (.SCOM+6
	AND PLIT6		/(700000 SAVE CODE BITS.
	XOR TEMP1		/ADD START ADDRESS.
	DAC TEMP1		/SAVE CODE BITS+USER'S STARTING ADDRESS.
 
	CAL 774		/.CLOSE -4, USER'S PROGRAM INPUT DEVICE.
	6
 
	LAC MAINFLG	/FLAG IS NON-0 ONLY THE 1ST TIME THROUGH
	SNA		/INDICATING THAT THE MAIN PROGRAM WAS
	JMP NEXPRG	/JUST LOADED.
	DZM MAINFLG	/SET FLAG TO ZERO.
	LAC TEMP1
	DAC* (.SCOM+6	/STORE USER'S STARTING ADDRESS + CODE BITS.
	JMP NEXPRG	/LOAD IN NEXT SUBPROGRAM.
 
	.EJECT
CKFPIP	LAC* (.SCOM+5	/CHECK LOAD CODE.
	SAD (3		/PIP?
	SKP
	JMP SUBRS		/NO. LOAD LIBRARY SUBRS.
 
/ I/O FOR PIP IN FGD MUST LOAD ABOVE PIP BECAUSE PIP ASSUMES TOP OF
/ FREE CORE IS IMMEDIATELY BELOW ITSELF.
 
	LAC* (.SCOM+6	/PIP START ADDRESS IS ALSO LOAD ADDRESS.
	AND (77777
	TAD MINUS1
	DAC PIPSC3	/TOP OF FGD FREE CORE.
	LAC LOSYM		/REGISTER ABOVE PIP.
	JMS CORE		/REDO FREE BANK POINTERS.
 
/ ARE THERE ANY VIRTUAL GLOBAL ENTRIES IN THE SYMBOL
/ TABLE? IF SO, FIRST SEARCH THE USER'S LIBRARY (IF ANY)
/ AND THEN SEARCH THE SYSTEM LIBRARIES.
 
SUBRS	JMS ABSOFF	/ABS. PROGRAMS CAN NO LONGER BE LOADED.
	JMS VIRTUAL	/ANY UNRESOLVED GLOBALS?
	JMP COMMON	/NO. DEFINE COMMON.
	LAW -5		/YES. CHECK IF .DAT SLOT -5
	TAD DAT		/IS NON-ZERO.
	JMS EXAMIN
	SNA
	JMP F4LIBR	/IT'S ZERO; NO USER LIBRARY.
	LAC ADR5		/(USRLIB
	DAC LIBPTR	/USER FILE:'.LIBR BIN'.
	LAW -5
	JMS LIBRARY
	JMS VIRTUAL	/ANY UNRESOLVED GLOBALS LEFT?
	JMP COMMON	/NO. DEFINE COMMON.
F4LIBR	LAC F4FLAG	/SKIP IF FLAG INDICATES A SEARCH
	SPA!SNA		/THRU FORTRAN LIBRARY IS NEEDED.
	JMP IOLIBR
	LAC ADR5
	TAD (3		/(F4LIB=(USRLIB+3
	DAC LIBPTR	/FORTRAN LIBRARY:'.F4LIB BIN'.
	LAW -7
	JMS LIBRARY
	JMS VIRTUAL	/ANY UNRESOLVED GLOBALS LEFT?
	JMP COMMON	/NO. DEFINE COMMON.
IOLIBR	LAC ADR5
	TAD PLIT10	/(IOLIB=(USRLIB+6
	DAC LIBPTR	/I/O HANDLERS LIBRARY:'.IOLIB BIN'.
	SET IOFLAG
	LAW -7
	JMS LIBRARY
 
	.EJECT
/ THERE MAY STILL BE SOME UNRESOLVED GLOBALS IN THE
/ SYMBOL TABLE AT THIS POINT. PROGRAM LOADING IS NOW
/ COMPLETE. DEFINE ALL UNDEFINED COMMON BLOCKS.
 
COMMON	DZM IOFLAG
	SET COMFLG	/TELL SUBROUTINE FIT THAT COMMON
			/IS BEING DEFINED.
COMLOOP	JMS BEGSYM	/SEARCH FROM BEG OF SYMTAB.
	JMS FINDCOD	/SEARCH FOR
PLIT6	700000		/UNDEFINED COMMON BLOCKS.
	JMP GLOBE		/NONE REMAINING.
 
	JMS NEXSYM	/PICKUP 1ST WORD OF NAME.
	DAC SYM1
	SPA		/IS IT A 2-WORD NAME?
	JMS NEXSYM	/YES.
	DAC SYM2
	JMS DECSPT
	LAC SYMPTR	/SETUP THE POINTER TO THE
	DAC COMCHN	/COMMON CHAIN POINTER
	TAD MINUS1
	DAC COMDEF	/AND TO THE COMMON BLOCK START ADDRESS.
 
	LAC* SYMWD1	/CHANGE CODE 7(UNDEFINED) TO
	AND (377777	/CODE 3(DEFINED).
	DAC* SYMWD1
	AND (77777	/GET BLOCK SIZE AND NEGATE IT.
	JMS TWOS
	DAC SIZE
	JMS FIT		/COMPUTE THE LOAD ADDRESS OF THE BLOCK,
			/IF IT FITS IN CORE.
	LAC LOADADR
	DAC* COMDEF	/SET BASE ADDRESS OF BLOCK.
	LAC MAPFUNC	/MEMORY MAP?
	AND (4		/TEST FOR COMMON BLOCK BIT.
	SNA
	JMP .+3
	LAC (103		/ASCII FOR C.
	JMS MEMMAP
	JMS DEFCOM	/DEFINE ALL EXISTING LINKS IN THE COMMON CHAIN.
	JMP COMLOOP	/SEE IF THERE ARE ANY MORE UNDEFINED BLOCKS.
 
	.EJECT
/ IF ANY UNRESOLVED GLOBAL REMAINS, SEARCH FOR A COMMON
/ BLOCK WITH THE SAME NAME. IF FOUND, DEFINE THE GLOBAL AS THE ADDRESS
/ OF THE COMMON BLOCK.
 
GLOBE	JMS BEGSYM	/START AT BEG OF SYMTAB.
NXGLOB	JMS FINDCOD	/SEARCH FOR
PLIT7	100000		/VIRTUAL GLOBALS.
	JMP ALLDEF	/NONE LEFT THAT CAN BE RESOLVED.
 
	LAC SYMWD1	/YES. SAVE POINTER TO IT.
	DAC TEMP5
	JMS NEXSYM	/PICKUP GLOBAL'S NAME.
	DAC SYM1
	JMS NEXSYM
	DAC SYM2
PLIT8	LAW		/SET BIT 1-2 FOR CODE 3 SEARCH.
	JMS SCAN		/IS THERE A COMMON BLOCK WITH SAME NAME?
	SKP		/YES.
	JMP GLBRET	/NO. TRY NEXT GLOBAL.
 
	JMS DECSPT
	JMS NEXSYM	/GET ADDRESS OF THE COMMON BLOCK.
	JMS COD10.	/LET CODE 10 PROCESSOR DEFINE THE GLOBAL.
 
GLBRET	LAC TEMP5
	DAC SYMWD1	/RESTORE POINTER TO THE GLOBAL.
	JMS NXNTRY	/SKIP TO NEXT SYMTAB ENTRY.
	JMP NXGLOB
 
/ AT THIS POINT ALL GLOBALS SHOULD BE DEFINED.
 
ALLDEF	JMS VIRTUAL	/ARE THERE ANY MORE VIRTUAL GLOBALS?
	SKP		/NO. GOOD.
	JMP GLBERR	/YES.
FGDBUF	JMS ASGBUF	/ASSIGN CORE SPACE FOR I/O BUFFERS.
	JMP DOSCOM
 
	.EJECT
/ SUBROUTINE ASGBUF:
/ GO THRU THE .MUD TABLE TO SEE WHICH DEVICES, IF ANY, NEED BUFFERS.
 
ASGBUF	0
 
	LAC* .BFPTR
	JMS TWOS
	RCL
	TAD (2
	TAD .BFMAX
	DAC TEMP5		/POINTER TO 1ST FREE .BFTAB ENTRY.
DFILES	LAC* MUDPTR
	DAC MUDCNT	/2'S COMP. COUNT OF .MUD ENTRIES.
MOREMUD	IDX MUDPTR
	LAC* MUDPTR	/GET 1ST WORD OF NEXT ENTRY.
	AND (77		/GET $FILES COUNT.
	IDX MUDPTR
	SNA
	JMP NOBUF		/$FILES=0.
	JMS TWOS
	DAC DFILES
	LAC* (.SCOM+26	/SKIP IF FOREGROUND RUNNING.
	SZA
	JMP .+4
	LAC* MUDPTR	/SUBTRACT $FILES COUNT FROM THE
	TAD DFILES	/MAXIMUM COUNT IN WORD 2; REMAINDER
	DAC* MUDPTR	/IS WHAT IS LEFT FOR BACKGROUND.
 
	LAC* MUDPTR	/2ND WORD OF .MUD ENTRY CONTAINS THE BUFFER
	RTR		/SIZE IN BITS 0-11.
	RTR
	RTR
	AND PLIT20	/(7777
	DAC BUFSIZ
	SNA		/0 IS A LEGAL BUFFER SIZE.
	JMP NOBUF
	JMS TWOS
	DAC SIZE		/2'S COMPLEMENT OF BUFFER SIZE.
	LAC* (.SCOM+26
	SNA!CLA!STL
	JMP ONEMORE
	RAR		/BITS FOR NON-BUSY BGD BUFFER.
	TAD BUFSIZ
	DAC BUFSIZ
 
	.EJECT
/ FOR EACH REQUESTED BUFFER, ASSIGN A CORE POSITION FOR IT AND MAKE AN
/ ENTRY IN .BFTAB .
 
ONEMORE	JMS FIT		/ASSIGN BUFFER SPACE.
	LAC* .BFPTR
	SAD* .BFMAX	/ANY MORE ROOM IN .BFTAB?
	JMP ERR102	/NO.
	TAD MINUS1
	DAC* .BFPTR
	LAC BUFSIZ	/ALREADY SETUP FOR NON-BUSY FGD OR BGD BUFFER.
	DAC* TEMP5
	IDX TEMP5
	LAC RELOC		/1ST ADDRESS OF THIS BUFFER.
	DAC* TEMP5
	IDX TEMP5
	ISZ DFILES	/ANYMORE BUFFERS TO BE ASSIGNED?
	JMP ONEMORE
 
NOBUF	ISZ MUDCNT	/ARE THERE ANY MORE DEVICES TO CHECK ON?
	JMP MOREMUD	/YES.
	JMP* ASGBUF
 
	.EJECT
/ DETERMINE WHERE THE MEMORY PROTECT BOUND SHOULD GO (2000, 4000, ...)
/ AND SETUP THE .SCOM REGISTERS.
 
DOSCOM	LAC* (.SCOM+5	/CHECK LOAD CODE.
	SAD (3
	SKP		/PIP.
	JMP .+3
	LAC LOSYM		/FREE CORE FOR PIP IN FGD WAS
	JMP STBNDS	/PREVIOUSLY SET UP BELOW PIP.
	LAC LOSYM		/REGISTER ABOVE FGD PROGRAMS.
	DAC* (.SCOM+2	/LOW LIMIT OF FGD FREE CORE.
	TAD* (.SCOM+25	/CONTAINS $FCORE COUNT.
STBNDS	DAC* (.SCOM+25	/REGISTER ABOVE THE FGD JOB.
	JMS BOUNDS	/SET SOFT & HARD MPB; CHECK FOR MEMORY OVERLAP.
	LAC* (.SCOM+5	/CHECK LOAD CODE.
	SAD (3
	SKP		/PIP.
	JMP .+3
	LAC PIPSC3	/TOP OF FREE CORE IS BELOW PIP IN FGD.
	DAC* (.SCOM+3
	IDX .BFMAX	/PUT .BFTAB ENTRY COUNT IN
	LAC* .BFPTR	/FGD .BFTAB COUNT (WORD 3).
	DAC* .BFMAX
 
/ CLEAR THE FGD LOADER'S .DAT SLOTS IN CASE THE USER
/ INADVERTANTLY TRIES TO USE THEM.
 
	LAW -5
	TAD DAT
SKIP2	DAC TEMP1		/CHANGED TO "SKP" IF FGD EXECUTE.
	DZM* TEMP1	/0 .DAT -5.
SKIP3	IDX TEMP1		/CHANGED TO "SKP" IF FGD EXECUTE.
	DZM* TEMP1	/0 .DAT -4.
EXEXIT	LAC (777
NOTRAN	DAC EXIT.
	LAC SYSNUM
	SNA		/SKIP IF NOT BGD LINK LOADER.
	JMP WAIT.
	LAW -7		/CLEAR SYSTEM LOADER'S .DAT SLOT.
	TAD DAT
	DAC DAT
	DZM* DAT		/0 .DAT -7.
 
WAIT.	CAL 775		/.WAIT FOR ANY TTY OUTPUT TO FINISH.
	12
 
EXIT.	JMP* TRANLOC	/CHANGED TO A CAL FOR .EXIT IF NOT GOING
	15		/TO BGD TRAN-WAIT-CLOSE-EXIT ROUTINE.
 
	.EJECT
/ OVERLAY: THE FOLLOWING REGISTERS ARE USED FOR DATA STORAGE BY THE
/ FOREGROUND LOADER.
 
MAINFLG=.			/NON-0 MEANS MAIN PROGRAM.
SYMFLG=.+1		/NON-0 MEANS SYMBOL IS FULL.
DLMITR=.+2		/CHAR. DELIMITER AFTER LAST COMMAND NAME.
COMCHN=.+3		/POINTER TO WORD 3 OR 4 IN COMMON BLOCK
			/SYMTAB ENTRY, WHICH POINTS TO COMMON
			/SYMBOL REFERENCE CHAIN (IF NON-0).
COM.TV=.+5		/POINTER TO A COMMON SYMBOL'S TRANSFER VECTOR.
COMDEF=.+6		/POINTER TO WORD 4 OR 5 IN COMMON BLOCK
			/SYMTAB ENTRY, WHICH CONTAINS BASE ADDRESS
			/OF THE BLOCK OR 0 IF UNDEFINED.
STRING=.+7		/POINTER TO AN INSTRUCTION WHOSE ADDRESS
			/PART IS TO BE REPLACED (FORTRAN FORWARD REF.).
OPFLAG=.+10		/0 MEANS COMMAND STRING PROCESSING IS
			/LOOKING FOR MEMORY MAP OPTIONS.
 
	.EJECT
/ LOAD A SYSTEM PROGRAM IN THE BACKGROUND.
 
BKGRND	LAC ERRXIT
	TAD (1000
	DAC ERRXIT	/CHANGE ERROR EXIT TO BGD ERROR EXIT.
	LAC ADR4		/SET ^P RETURN ADDRESS POINTER
	TAD PLIT7		/WITH MEM PROT BIT ON.
	DAC ADR4
	LAC* (.SCOM+5	/SYSTEM PROGRAM'S CODE NUMBER.
SYSNUM	DAC .
	TAD (SYSTAB
	TAD BNKBTS
	JMS EXAMIN	/GET INFO POINTER IN SYSTAB.
	TAD BNKBTS
 
/ END OF OVERLAY.
 
	DAC TEMP6
NXIODV	LAC* TEMP6	/GET NEXT .IODEV .
	SAD PLUS1
	JMP ALL		/+1 = .IODEV ALL.
	SMA
	JMP DONE		/END OF .IODEV LIST.
	JMS IODEV.
	IDX TEMP6
	JMP NXIODV
ALL	JMS IODALL
DONE	JMS IOLOAD
	LAC SYSNUM
	SAD (13		/EXECUTE?
	JMP BGDXCT	/YES.
	SZA		/SKIP IF LINK LOADER.
BGDBUF	JMS ASGBUF	/SETUP I/O BUFFERS NEEDED.
	LAC* (.SCOM+32	/SAVE CURRENT HARDWARE MPB.
TRANLOC	DAC .
	LAC LOSYM
	DAC* (.SCOM+2	/LOWEST FREE REGISTER FOR SYSTEM PROGRAM.
	JMS BOUNDS	/SET SOFT AND HARD MEM PROTECT BOUNDS
			/AND CHECK FOR MEMORY OVERLAP.
 
	CAL 771		/.INIT -7 FOR INPUT FROM SYSTEM DEVICE.
	1
TEMP2	0
TEMP6	0
 
	LAC SYSNUM
	SNA
	JMP LL		/IT'S THE LINK LOADER.
	SAD (13
	JMP EXE		/IT'S EXECUTE.
 
	.EJECT
	LAC* (.SCOM+32	/IF OLD (CURRENT) HARDWARE MPB
	JMS TWOS		/IS < NEW HARDWARE MPB,
	CLL		/REPLACE TRANLOC WITH NEW MPB.
	TAD TRANLOC
	LAC* (.SCOM+32
	SNL
	DAC TRANLOC	/LOC. WHERE .TRAN ROUTINE WILL START.
	LAC TRANLOC
	TAD (14
	DAC .		/LAST REGISTER IN .TRAN ROUTINE.
	XOR TRANLOC
	AND PLIT8		/(760000
	SNA		/SKIP IF BANK OVERLAP.
	JMP .+4
	LAC .-5
	AND PLIT8		/(760000
	DAC TRANLOC	/START .TRAN ROUTINE AT BEG. OF NEXT BANK.
 
/ .TRAN IN PART OF THE SPECIAL BLOCK ON THE SYSTEM DEVICE, WHICH
/ CONTAINS LOADING INFORMATION ABOUT THE SYSTEM PROGRAMS.
 
	LAC SYSNUM
	RCL
	RCL
	TAD PLIT2		/(LINBF1
	DAC TEMP3		/POINTER TO 4-WORD BLOCK.
	DAC TEMP2
 
TRAN	CAL 771		/.TRAN IN FORWARD FROM -7.
	13
	101		/BLOCK #.
ADR8	LINBF1
	-120		/COUNT=4 WORDS FOR 20 PROGRAMS.
 
	CAL 771		/.WAIT ON -7.
	12
 
/ ADD BANK BITS TO THE LOAD ADDRESS (HIGHEST BANK). GOING TO BUILD A
/ ROUTINE, STARTING AT THE PROTECT BOUND, TO TRAN-WAIT-CLOSE-EXIT.
/ THE LOAD ADDRESS OF THE SYSTEM PROGRAM AND THE ADDRESS OF THE
/ 4 WORD INFO BLOCK MUST BOTH BE ABOVE THIS ROUTINE.
 
	IDX TEMP3
	LAC* TEMP3	/LOAD ADDRESS (WORD 2 OF 4).
	XOR BNKBTS	/BANK BITS FOR HIGHEST BANK.
	DAC* TEMP3
	JMS TWOS		/LOAD ADDRESS MUST BE AT OR ABOVE
	TAD* (.SCOM+32	/THE NEW HMPB.
	SMA!SZA
	JMP ERR100
 
	.EJECT
	LAC* TEMP3
	JMS TWOS
	TAD TEMP2		/POINTER TO 4 WORD INFO BLOCK.
	SPA		/CHOOSE THE LOWER OF THE TWO.
	JMP .+3
	LAC* TEMP3
	SKP
	LAC TEMP2
	JMS TWOS
	TAD TRANLOC	/STARTING LOC OF THE TRAN ROUTINE.
	TAD PLIT14	/(15 ; 5(TRAN)+2(WAIT)+2(CLOSE)+
	SMA!SZA		/2(EXIT)+2(0 .DAT -7).
	JMP ERR100	/NO ROOM.
	LAC TRANLOC
	DAC TEMP1		/POINTER TO STORE TRAN ROUTINE INSTRUCTIONS.
	LAW -7
	TAD DAT
	JMS DACIDX	/T.V. FOR ZEROING .DATB -7.
	LAC TRAN		/(CAL 771
	JMS DACIDX
	LAC (13
	JMS DACIDX
	LAC* TEMP2	/BLOCK # (WORD 1 OF 4).
	JMS DACIDX
	LAC* TEMP3	/LOAD ADDRESS.
	JMS DACIDX
	TAD MINUS1
	DAC* (.SCOM+3	/HIGHEST FREE REGISTER FOR SYSTEM PROGRAM.
	IDX TEMP3
	LAC* TEMP3	/SIZE (WORD 3 OF 4)(2'S COMP).
	JMS DACIDX
	LAC TRAN
	JMS DACIDX
	LAC PLIT15	/(12 CODE FOR .WAIT .
	JMS DACIDX
	LAC TRAN
	JMS DACIDX
	LAC PLIT10	/(6 CODE FOR .CLOSE .
	JMS DACIDX
	LAC TRANLOC	/ADDRESS OF (.DATB -7
	AND (17777
	TAD (DZM* 0	/DZM* (.DATB-7
	JMS DACIDX
	LAC (777		/SET NEXT WORD TO CAL 777.
	JMS DACIDX
	LAC PLIT14	/(15 CODE FOR .EXIT .
	JMS DACIDX
	IDX TEMP3
	LAC* TEMP3
	XOR BNKBTS
	DAC* (.SCOM+5	/SYSTEM PROGRAM'S START ADDRESS.
	IDX TRANLOC	/MOVE PTR PAST LITERAL TO THE .TRAN.
	JMP WAIT.
 
	.EJECT
BGDXCT	IDX X10SHN	/CHANGE PTR. TO .SCOM+112
	LAC X10SHN
	DAC X.SEKP	/STORE IN .SEEK POINTER.
	IDX X10SHN
	IDX X10SHN	/EXTENSION FOR BGD IS IN .SCOM+114.
	JMS XCTFIL	/READ INFO FROM "XCT" FILE.
	JMS IOLOAD	/LOAD "XCT" FILE'S HANDLERS.
	JMP BGDBUF	/ASSIGN I/O BUFFERS.
 
/ SUBROUTINE XCTFIL: COMMON TO LOADING OF EXECUTE IN FGD OR BGD.
/ LOADS .IODEV INFO FROM "XCT" FILE AND CHECKS ENVIRONMENT COM-
/ PATIBILITY AND FILE'S CORE LIMITS.
 
XCTFIL	0
 
	LAC* X10SHN	/IS THE EXTENSION "XCT" OR "XCS"?
	SAD (300324	/.SIXBT /XCT/
	JMP X.INIT	/"XCT" MEANS LOAD VIA .DAT -4.
	IDX* X10SHN	/CHANGE "XCS" TO "XCT". "XCS" MEANS
	LAC (771		/LOAD VIA .DAT -7.
	DAC X.INIT
	DAC X.SEEK
 
X.INIT	CAL 774		/.INIT -4 OR -7 FOR INPUT.
	1
	0
	0
 
X.SEEK	CAL 774		/.SEEK VIA -4 OR -7.
	3
X.SEKP	.SCOM+107		/.SCOM+107 FOR FGD; .SCOM+112 FOR BGD.
 
	SET NUFILE	/A SEEK WAS JUST DONE.
	SET XCTFLG	/NOW SEARCHING THRU "XCT" FILE.
	LAC X.INIT	/CAL FOR .DAT -4 OR -7.
	JMS LDPROG	/GET INFO FROM "XCT" FILE.
	DZM XCTFLG
	JMP* XCTFIL
 
/ LOAD IN THE LINK LOADER OR EXECUTE.
 
LL	IDX SEEKPT	/CHANGE .SEEK POINTER TO FILE DIRECTORY
	IDX SEEKPT	/ENTRY BLOCK FOR BGD LINK LOADER.
	IDX SEEKPT
 
/ WILL JMP HERE WHEN LOADING EXECUTE IN THE FOREGROUND.
 
EXE	CAL 771		/.SEEK LINK LOADER OR EXECUTE.
	3
SEEKPT	EXECUT
 
	SET NUFILE
 
	.EJECT
SKIP1	LAC* (.SCOM+32	/POINTER TO NEW HARDWARE MPB; CHANGED
			/TO "SKP" IF LOADING EXECUTE IN FGD.
	JMS CORE		/SETUP INFO ABOUT FREE CORE.
	LAW -7
	JMS LDPROG	/LOAD PROGRAM THRU .DATB -7.
	DAC* (.SCOM+5	/SAVE PROGRAM'S START ADDRESS.
 
	CAL 771		/.CLOSE -7.
	6
 
	LAC* (.SCOM+26	/IF DOING A FGD LOAD, RETURN
	SNA		/TO LOADING OF FGD EXECUTE.
	JMP FX.RET
	LAC SYSNUM	/DO NOT MOVE IOC TABLE
	SZA		/FOR EXECUTE.
	JMP NO.IOC
MOVIOC	IDX IOCPTR	/MOVE IOC TABLE TO JUST ABOVE
	LAC* IOCPTR	/THE LINK LOADER.
	DAC* LOSYM
	IDX LOSYM
	LAC IOCPTR
	SAD ADR9		/(FIRST-1
SKPLIT	SKP		/LITERAL.
	JMP MOVIOC
 
	LAC* IOINPTR	/DISCARD .IOIN ENTRIES MADE FOR
	TAD IOCOUNT	/THE LINK LOADER.
	DAC* IOINPTR
NO.IOC	LAC LOSYM
	DAC* (.SCOM+2
	LAC* (.SCOM
	DAC* (.SCOM+3
	LAC SYSNUM
	SNA		/SKIP IF EXECUTE.
	JMP SYSXIT	/LINK LOADER.
	LAC LOSYM
	CMA
	TAD X.LOW
	SPA
	JMP ERR120	/"XCT" FILE OVERLAYS EXECUTE.
	LAW -1
	TAD X.LOW
	DAC* (.SCOM+3	/TOP OF FREE CORE.
	JMP EXEXIT
SYSXIT	LAC (1000
	JMP NOTRAN
 
	.EJECT
/ SYSTEM PROGRAMS DISPATCH TABLE FOR .IODEV INFORMATION.
 
SYSTAB	LOAD.		/0=$LOAD,$GLOAD,$DDT,$DDTNS
	EDIT.		/1=$EDIT
	MACRO.		/2=$MACRO
	PIP.		/3=$PIP
	F4.		/4=$F4
	SGEN.		/5=$SGEN
	DUMP.		/6=$DUMP
	UPDTE.		/7=$UPDATE
	CONV.		/10=$CONV
	MACRA.		/11=$MACROA
	F4A.		/12=$F4A
	EXEC.		/13=$EXECUTE($E)
	CHAIN.		/14=$CHAIN
	PATCH.		/15=$PATCH
 
/ SYSTEM PROGRAMS .IODEV TABLE. A NUMBER >+1 TERMINATES EACH LIST OF .DAT SLOTS.
 
CHAIN.	-6
	-5
	-4
	-1
PLIT1	55
LOAD.	-7
	-5
	-1
EXEC.	-4
PLIT10	6
MACRO.=.
MACRA.	-10
F4.=.
F4A.	-13
	-12
	-11
PLIT20	7777
UPDTE.	-12
SGEN.=.
EDIT.	-15
PATCH.	-14
	-10
PLIT21	127400
CONV.	-15
DUMP.	-14
	-12
PLIT22	47
PLUS1=.
PIP.	+1		/+1 MEANS .IODEV ALL.
PLIT18	217600
 
	.EJECT
/ MAIN SUBROUTINE LDPROG: LOAD A PROGRAM UNIT VIA THE 'CAL .DAT SLOT' IN
/ THE AC. NORMALLY, RETURN IS BY A JMP* LDPROG WITH THE 15-BIT STARTING
/ ADDRESS (OF THE PROGRAM UNIT JUST LOADED) IN THE AC. WHEN LOADING FROM
/ A LIBRARY FILE, IF END-OF-FILE IS ENCOUNTERED, RETURN IS A 'JMP LIBCLOS'.
/ ALL PROGRAM LOADING IS DOUBLE BUFFERED.
 
LDPROG	0		/CAL .DAT SLOT IS IN THE AC.
 
	AND (777
	DAC WAIT		/SETUP .WAIT CAL.
	DAC READ1		/SETUP INITIAL READ CAL.
	DAC READ		/SETUP DOUBLE BUFFER READ CAL.
	DAC X.CLOS	/SET UP CLOSE CAL FOR "XCT" FILE.
	LAC NUFILE	/AM I ABOUT TO READ A NEW FILE
			/(I.E. WAS A .SEEK JUST DONE) OR AM I
	SNA		/IN THE MIDDLE OF SOME LIBRARY FILE?
	JMP BUFCHK	/IT'S AN OLD FILE (.READ ALREADY ISSUED).
	DZM NUFILE	/SET FLAG 0 SO THAT NEXT TIME IT WILL LOOK
			/LIKE AN OLD FILE.
 
READ1	CAL		/.READ IOPS BINARY INTO LINE BUFFER #1.
	10		/THIS IS THE INITIAL READ FOR A NEW FILE.
ADR10	LINBF1
	-62
 
	JMP SETUP1	/SETUP POINTERS TO MAKE #1 THE CURRENT BUFFER.
 
/ CURRENT BUFFER IS EMPTY.
 
BUFMPTY	LAC BF1OR2	/WHICH BUFFER IS BEING READ INTO?
	SAD PLIT2		/SAD (LINBF1 .
	JMP SETUP1	/BUFFER #1.
	LAC ADR11		/(LINBF2 SETUP BUFFER POINTER TO
	DAC BUFPTR	/BUFFER #2.
	LAC PLIT2		/(LINBF1
	JMP SETREAD	/PREPARE TO READ INTO BUFFER #1.
SETUP1	LAC PLIT2		/(LINBF1
	DAC BUFPTR	/SETUP BUFFER POINTER TO 1ST WORD OF
			/LINE BUFFER #1.
	LAC ADR11		/(LINBF2 PREPARE TO READ INTO BUFFER #2.
SETREAD	DAC TEMP1
 
WAIT	CAL		/.WAIT ON LATEST .READ .
	12
 
	LAC TEMP1		/(LINBF1 OR (LINBF2 .
	DAC BF1OR2
 
	.EJECT
/ TEST THE HEADER WORDS IN THE BUFFER JUST READ INTO.
 
HDRTST	LAC* BUFPTR	/PICKUP HEADER WORD 1.
	AND PLIT11	/(17 MASK TO FUNCTION BITS.
	SAD PLIT10	/(6 END OF MEDIUM?
	JMP PRTEOM
	SAD (5		/END OF FILE?
	JMP E.O.F.	/YES.
	LAC* BUFPTR
	AND (60		/GET BITS 12 AND 13.
	SZA		/PARITY, CHECKSUM, BUFFER OVERFLOW?
	JMP ERR105	/YES.
PLIT9	LAW -1000		/LAC (777000
	TAD* BUFPTR	/PICKUP WORD PAIR COUNT, SUBTRACT
	AND .-2		/1 FOR HEADER PAIR, MULTIPLY BY 2
	CLL!RAL		/TO GET WORD COUNT (IN BITS 0 THRU 8).
	DAC WRDCNT
 
/ HEADER IS OK. NOW UPDATE THE BUFFER POINTER TO 1ST DATA WORD - 1.
/ INITIALIZE CODE WORD COUNT SO 1ST WORD IS TAKEN TO BE A CODE WORD.
/ ISSUE NEXT READ.
 
	IDX BUFPTR
	LAW -1
	DAC CDWCNT
 
READ	CAL		/.READ IOPS BINARY INTO
	10
BF1OR2	XX		/LINE BUFFER #1 OR #2.
	-62
 
/ CHECK IF BUFFER IS EMPTY. RETURN HERE WHENEVER READY TO PROCESS
/ ANOTHER DATA WORD.
 
BUFCHK	IDX BUFPTR	/POINT TO NEXT BUFFER WORD.
	LAC WRDCNT	/IS BUFFER EMPTY?
	SNA
	JMP BUFMPTY	/YES. READ IN SOME MORE.
	TAD PLIT9		/(777000
	DAC WRDCNT	/SUBTRACT 1 FROM THE WORD COUNT.
	LAC XCTFLG
	SZA
	JMP X.LINK	/SEARCHING "XCT" FILE.
	ISZ CDWCNT	/READY FOR NEXT CODE WORD?
	JMP GETCOD	/NO. THERE ARE MORE CODES LEFT IN OLD ONE.
	LAW -4		/YES. RESET COUNT FOR 3 CODES PER WORD.
	DAC CDWCNT
	LAC* BUFPTR	/GET NEXT CODE WORD.
	DAC CODEWD
	JMP BUFCHK
 
	.EJECT
E.O.F.	LAC XCTFLG	/SEARCHING "XCT" FILE?
	SNA
	JMP LIBCLOS	/NO. ABNORMAL EXIT. CLOSE LIBRARY FILE.
X.NEXT	DZM WRDCNT	/YES. IGNORE. CLEAR WORD COUNT SO
	JMP READ		/BUFFER LOOKS EMPTY.
 
/ LOOKING IN "XCT" FILE.
 
X.LINK	LAC* BUFPTR	/CHECK FOR TYPE 1 LINK.
	SAD PLIT7		/(100000
	SKP
	JMP X.NEXT	/NO. READ NEXT DATA BLOCK.
	IDX BUFPTR
	LAC* BUFPTR	/CHECK FOR LINK #377777.
	SAD (377777
	SKP
	JMP X.NEXT	/NO. READ NEXT DATA BLOCK.
 
X.CLOS	CAL		/.CLOSE "XCT" FILE.
	6
 
	LAC BUFPTR
	TAD (5
	DAC BUFPTR
	LAC* BUFPTR	/SAVE LOWEST REGISTER OCCUPIED
	DAC X.LOW		/BY "XCT" FILE.
	IDX BUFPTR
	LAC* BUFPTR	/SAVE HIGHEST REGISTER OCCUPIED
	DAC X.HIGH	/BY "XCT" FILE.
	IDX BUFPTR
 
/ CHECK "ENVIRONMENT" WORD TO MAKE SURE THE "XCT" FILE WAS BUILT
/ TO RUN IN THE PRESENT CONFIGURATION.
 
	LAC* (.SCOM+26	/0=FGD; 1=BGD.
	XOR (3		/3=PDP-9 FGD; 2=PDP-9 BGD.
	XOR* BUFPTR
	AND (3
	SZA
	JMP ERR123	/WRONG CONFIGURATION.
	IDX BUFPTR
 
/ READ NEXT 4 WORDS TO GET .IODEV BIT MAP, STARTING WITH .DAT -18.
 
X.LP1	LAW -22		/18 BITS PER WORD.
	DAC CDWCNT
X.LP2	LAC* BUFPTR
	RAL
	DAC* BUFPTR
	SNL
	JMP .+3		/BIT=0 MEANS NO .IODEV.
	LAC DATNUM	/.DAT SLOT #.
	JMS IODEV.
	IDX DATNUM
	NOP		/IN CASE OF SKIP ON ZERO.
	ISZ CDWCNT
	JMP X.LP2
	IDX BUFPTR
	ISZ DATCNT	/SKIP WHEN 4 WORDS DONE.
	JMP X.LP1
	JMP* LDPROG	/FINISHED GETTING "XCT" FILE INFO.
 
	.EJECT
/ UNPACK THE NEXT CODE.
 
GETCOD	LAC CODEWD	/SHIFT CODE WORD SO THAT NEXT CODE
	RTL		/IS IN LOW ORDER AC BITS (12 THRU 17).
	RTL
	RTL
	DAC CODEWD
	RAL
	AND (77
	DAC TEMP1		/SAVE CODE FOR TESTING.
 
	LAC LIBFLG	/IS LIBRARY SEARCH MODE IN EFFECT?
	SNA
	JMP LOADIT	/NO. ALL LOADER CODES ARE IN EFFECT.
 
/ WHILE LIBRARY SEARCH MODE IS IN EFFECT, EXAMINE ONLY SPECIFIC
/ LOADER CODES; IGNORE ALL OTHERS.
 
	LAC TEMP1
	SAD PLUS1		/CODE 1 - PROGRAM SIZE.
	JMP LOADIT
	SAD (7		/CODE 7 - SYMBOL (1ST 3 CHARS).
	JMP LOADIT
	SAD (10		/CODE 8 - SYMBOL (2ND 3 CHARS).
	JMP LOADIT
	SAD PLIT15	/CODE 10 - INTERNAL GLOBAL DEFINITION.
	JMP LOADIT
	SAD (27		/CODE 23 - END OF PROGRAM UNIT.
	JMP LOADIT
	SAD (13		/CODE 11 - BLOCK DATA SUBPROGRAM.
	SKP
	JMP BUFCHK	/IGNORE ALL OTHER CODES.
	DZM LIBFLG	/CLEAR SELECTIVE LOADING FLAG SO THAT
			/THIS BLOCKDATA SUBPROGRAM IN THE USER'S
			/LIBRARY WILL BE LOADED IN (A FEATURE!!)
 
/ CODE ACCEPTED FOR PROCESSING. PICKUP THE ASSOCIATED DATA WORD AND
/ JUMP TO THE APPROPRIATE DATA PROCESSING ROUTINE.
 
LOADIT	LAW -31		/-25 DECIMAL.
	TAD TEMP1
	SMA		/IS THIS CODE >24 DECIMAL?
	JMP ERR106	/YES. BAD CODE.
 
	TAD ADR12		/(CODTAB+31
	DAC TEMP1		/SAVE DISPATCH ADDRESS.
	LAC* BUFPTR	/PICKUP DATA WORD.
	JMP* TEMP1	/PROCESS IT.
 
	.EJECT
/ DISPATCH TABLE TO CODE PROCESSING ROUTINES.
/ CODES 11 THRU 18, 20 AND 21 ARE GENERATED ONLY BY FORTRAN.
 
CODTAB	JMP ERR106	/CODE 0 IS ILLEGAL.
	JMP CODE1
	JMP CODE2
	JMP CODE3
	JMP CODE4
	JMP CODE5
	JMP CODE6
	JMP CODE7
	JMP CODE8
	JMP CODE9
	JMP CODE10
	JMP CODE11
	JMP CODE12
	JMP CODE8		/CODE 13 IS PROCESSED JUST LIKE CODE 8.
	JMP CODE14
	JMP CODE15
	JMP CODE16
	JMP CODE17
	JMP CODE18
	JMP CODE19
	JMP CODE20
	JMP CODE21
	JMP CODE22
	JMP CODE23
	JMP BUFCHK	/CODE 24 (18-BIT PARAMETER ASSIGNMENT)
			/IS PASSED ON BY MACRO BUT IS IGNORED.
 
/ WHEN END OF MEDIUM IS DETECTED WHILE TRYING TO READ IN A PROGRAM,
/ TRANSFER HERE. PRINT ^P AND WAIT FOR THE USER TO TYPE CONTROL P.
 
PRTEOM	CAL 2775		/.WRITE IOPS ASCII ON THE TTY.
	11
ADR13	MSG3		/MESSAGE: '^P'<175> .
PLIT19	2000
 
	LAC ADR4		/(CNTL.P+200000 (EX MEM BIT)
	DAC* FCTL.P	/SETUP FGD OR BGD ^P REGISTER.
	JMP .		/WAIT HERE WHILE USER SETS UP HIS INPUT DEVICE.
 
CNTL.P	DZM* FCTL.P	/DISABLE FGD ^P REGISTER.
 
	CAL 775		/.CLOSE -3; PRINT CR LF AFTER USER TYPES
	6		/CONTROL P.
 
	JMP READ1		/GO BACK TO INITIAL READ.
 
	.EJECT
/ CODE 1 PROCESSOR: PROGRAM UNIT'S SIZE. COMPUTE LOAD ADDRESS AND
/ RELOCATION FACTORS.
 
CODE1	SPA!CMA		/ABSOLUTE OR RELOCATABLE PROGRAM?
	JMP ABSCHK	/ABSOLUTE.
	TAD PLUS1
	DAC SIZE		/SAVE 2'S COMPLEMENT OF PROGRAM SIZE.
	JMS ABSOFF	/ABS PROGRAMS MAY NO LONGER BE LOADED.
 
/ IF IN LIBRARY SEARCH MODE, DON'T CHECK IF THIS PROGRAM UNIT CAN FIT
/ IN CORE UNTIL IT IS KNOWN THAT IT WILL BE LOADED (SEE CODE 10).
 
	LAC LIBFLG	/ARE WE IN LIBRARY SEARCH MODE?
	SZA
	JMP ABSOLU	/YES. DON'T CHECK FOR FIT YET.
 
/ SEE IF PROGRAM WILL FIT IN AVAILABLE CORE. COMPUTE THE PROGRAM'S
/ LOAD ADDRESS AND RELOCATION FACTOR.
 
	JMS FIT
	JMP BUFCHK
 
ABSCHK	LAC ABSFLG	/ONCE THE FLAG IS ZERO, CAN'T LOAD
	SNA		/ABS PROGRAMS ANYMORE.
	JMP ERR115
 
/ FOR ABSOLUTE PROGRAMS, NO TEST IS MADE TO SEE IF THEY FIT IN
/ ONE BANK OR IF THEY OVERLAY ONE ANOTHER.
 
ABSOLU	DZM RELOC		/0 THE RELOCATION FACTOR.
	JMP BUFCHK	/GO TO PROCESS THE NEXT DATA WORD.
 
	.EJECT
/ CODE 2 PROCESSOR: PROGRAM'S LOAD ADDRESS.
 
CODE2	TAD RELOC		/ADD THE RELOCATION FACTOR
			/(WHICH IS 0 IF PROGRAM IS ABSOLUTE).
	DAC LOADADR
	RAL		/BIT 0=1 IF AN ABSOLUTE LOAD ADDRESS.
	LAC ABSFLG	/NON-0 IF ABS ALLOWED.
	SNA
	SNL!CML		/CHECK THAT ABS AND RELOCATABLE ARE
	SNL		/NOT MIXED IN SAME PROGRAM.
	JMP ERR115
	LAC LOADADR
SAVLAD	AND (77777
	DAC LOADADR
NEWABS	LAC ABSFLG	/IF NON-0, FLAG CONTAINS HIGHEST
	SNA!CMA		/ABS LOAD ADDRESS YET ENCOUNTERED.
	JMP BUFCHK
	TAD LOADADR
	SPA
	JMP BUFCHK
	LAC LOADADR	/CHANGE FLAG - NEW LOAD
	DAC ABSFLG	/ADDRESS IS HIGHER.
	DAC LOSYM		/SYMTAB LOWER BOUND.
	JMP BUFCHK
 
/ CODE 3 PROCESSOR: RELOCATABLE INSTRUCTION.
 
/ CODE 4 PROCESSOR: A NON-MEMORY REFERENCING INSTRUCTION, A NON-
/ RELOCATABLE MEMORY REFERENCING INSTRUCTION, AN ABSOLUTE ADDRESS,
/ OR A CONSTANT.
 
CODE3	JMS MOD13		/ADD IN THE RELOCATION FACTOR
			/(MODULO 13) TO THE ADDRESS PART.
CODE4	DAC* LOADADR	/STORE THE WORD IN CORE.
	LAC LOADADR
	JMS TWOS
	TAD SYMEND
	SPA!SNA
	JMP ERR101	/OVERLAPPED SYMBOL TABLE.
	IDX LOADADR
	JMP NEWABS
 
/ CODE 5 PROCESSOR: RELOCATABLE PROGRAM ADDRESS (VECTOR).
 
CODE5	TAD RELOC		/ADD IN THE 15-BIT
	JMP CODE4		/RELOCATION FACTOR.
 
	.EJECT
/ CODE 6 PROCESSOR: NON-COMMON VARIABLE AND ARRAY STORAGE ALLOCATION.
 
CODE6	TAD LOADADR	/INCREASE THE PRESENT LOAD ADDRESS BY THE
	JMP SAVLAD	/STORAGE SIZE. THIS STORAGE AREA HAS BEEN
			/PREVIOUSLY INITIALIZED TO 0.
 
 
/ CODE 7 PROCESSOR: 1ST 3 CHARACTERS OF A SYMBOL.
 
CODE7	DAC SYM1		/SAVE RADIX 50 SYMBOL CODE.
	JMP BUFCHK
 
 
/ CODE 8 PROCESSOR: LAST 3 CHARACTERS OF A SYMBOL.
/ (CODE 13 ALSO STARTS HERE).
 
CODE8	DAC SYM2		/SAVE RADIX 50 SYMBOL CODE.
	JMP BUFCHK
 
 
/ CODE 9 PROCESSOR: VIRTUAL (EXTERNAL) GLOBAL SYMBOL REFERENCE.
/ CONTAINS UNRELOCATED ADDRESS OF A TRANSFER VECTOR, WHICH
/ HAS BEEN SETUP TO POINT TO ITSELF.
 
CODE9	TAD RELOC		/ADD RELOCATION FACTOR,
	TAD PLIT7		/ADD CODE (1) FOR A VIRTUAL GLOBAL,
	JMS SCAN		/SCAN THE SYMBOL TABLE TO SEE IF THIS SYMBOL
			/HAS ALREADY BEEN ENTERED.
	JMP .+4		/YES.
	IDX F4FLAG	/ADD 1 TO VIRTUAL GLOBAL COUNT.
NTRSYM	JMS DEFSYM	/ENTER IN SYMTAB.
	JMP BUFCHK
 
/ GLOBAL SYMBOL IS ALREADY IN THE SYMBOL TABLE. IF UNRESOLVED, AC HAS
/ THE ADDRESS OF THE 1ST TRANSFER VECTOR IN THE CHAIN. IF RESOLVED,
/ AC HAS TRUE ADDRESS OF THE GLOBAL. IN EITHER CASE, STORE THIS
/ ADDRESS IN THE TRANSFER VECTOR.
 
	DAC* SYMDEF	/STORE 15-BIT DEFINITION IN THE TRANSFER
			/VECTOR. BITS 0-2 ARE 0.
 
	LAC* SYMWD1	/GET 1ST WORD OF GLOBAL ENTRY.
	SPA		/IS IT STILL VIRTUAL?
	JMP BUFCHK	/NO. PROCESS NEXT DATA WORD.
 
/ SINCE THE GLOBAL IS STILL VIRTUAL, ENTER THE ADDRESS OF THE LATEST
/ TRANSFER VECTOR INTO THE SYMBOL TABLE ENTRY FOR THE GLOBAL, THEREBY
/ RECLOSING THE CHAIN.
 
	LAC SYMDEF
	DAC* SYMWD1
	JMP BUFCHK
 
	.EJECT
/ CODE 10 PROCESSOR: INTERNAL GLOBAL SYMBOL DEFINITION. WHEN ENCOUNTERED
/ IN LIBRARY SEARCH MODE, INTERNAL GLOBAL DEFINITION DETERMINES WHETHER
/ OR NOT THE LIBRARY PROGRAM WHICH FOLLOWS IS TO BE LOADED. IF SO, ONLY
/ THEN IS THE LIBRARY PROGRAM TESTED TO SEE IF IT WILL FIT IN CORE AND
/ THE LOAD ADDRESS AND RELOCATION FACTOR COMPUTED.
 
CODE10	TAD RELOC		/ADD RELOCATION FACTOR.
	JMS COD10.
	LAC* (.SCOM+26	/GLOBALS PRINTED IN MEMORY MAP
	TAD LLIOFLG	/ONLY FOR THE FGD USER PROGRAMS.
	SZA
	JMP BUFCHK
	LAC MAPFUNC	/ARE GLOBALS TO BE PRINTED
	AND (2		/IN THE MEMORY MAP?
	SNA
	JMP BUFCHK	/NO.
	LAC RELOC		/SAVE RELOC FACTOR TEMPORARILY.
	DAC TEMP5
	LAC MAPDEF	/GLOBAL'S DEFINITION.
	DAC RELOC
	LAC (107		/ASCII FOR G.
	JMS MEMMAP
	LAC TEMP5		/RESTORE RELOCATION FACTOR.
	DAC RELOC
	JMP BUFCHK
MAPDEF	0		/GLOBAL'S DEFINITION.
 
COD10.	0		/ALSO CALLED BY GLOBE ROUTINE.
 
	DAC TEMP3
	DAC MAPDEF
	TAD PLIT12	/(500000 ADD CODE FOR DEFINED GLOBAL.
	JMS SCAN		/IS THERE A GLOBAL WITH THE SAME NAME
			/ALREADY IN THE SYMBOL TABLE?
	JMP INTABLE	/YES.
 
/ GLOBAL NOT IN THE SYMBOL TABLE YET. IF IN LIBRARY SEARCH MODE,
/ IGNORE THIS GLOBAL SINCE IT WAS NOT REQUESTED. OTHERWISE, ENTER
/ THE GLOBAL IN THE SYMBOL TABLE.
 
	SAD LIBFLG	/SKIP IF IN LIBRARY SEARCH MODE.
	SKP
	JMP BUFCHK
	JMS DEFSYM	/ENTER SYMBOL AND ITS DEFINITION.
	JMP* COD10.
 
	.EJECT
/ GLOBAL ALREADY IN SYMBOL TABLE.
 
INTABLE	DAC TEMP4		/SAVE 15-BIT DEFINITION FROM SYMTAB ENTRY.
	LAC* SYMWD1	/IS IT ALREADY DEFINED?
	SPA!CLA
	JMP BUFCHK	/YES. IGNORE THIS DATA WORD.
	SAD LIBFLG	/NO. ARE WE IN LIBRARY SEARCH MODE?
	JMP RESOLVE	/NO. DEFINE THE GLOBAL ENTRY.
 
/ LIBFLG ON MEANS THE LOADER IS SEARCHING THRU SOME LIBRARY FOR INTERNAL
/ (DEFINED) GLOBALS WHICH ARE REQUESTED IN THE SYMBOL TABLE. JUST FOUND
/ ONE. NOW TEST IF THIS LIBRARY PROGRAM WILL FIT IN AVAILABLE CORE AND
/ SETUP THE RELOCATION FACTOR. IF IT FITS,
/ CLEAR LIBFLG TO INDICATE THAT A GLOBAL WAS RESOLVED (SEE INSTRUCTIONS
/ AT NEXLIB) AND ALSO SO THAT THE REMAINDER OF THIS PROGRAM ( UP TO THE
/ END-OF-PROGRAM CODE (23) ) WILL BE LOADED IN (INCLUDING SUBSEQUENT
/ GLOBAL DEFINITIONS).
 
	JMS FIT		/TEST IF LIBRARY PROGRAM FITS IN CORE AND
			/COMPUTE LOAD ADDRESS AND RELOC FACTOR.
	DZM LIBFLG	/CLEAR LIBRARY MODE FLAG SO REST OF PROGRAM
			/WILL BE LOADED AND TO SIGNAL THAT IT WAS.
	LAC TEMP3		/ADD RELOCATION FACTOR AGAIN (TO GLOBAL
	TAD RELOC		/ADDRESS) BECAUSE IT WAS 0 PREVIOUSLY.
	DAC TEMP3
	DAC MAPDEF
	LAC LLIOFLG	/I/O HANDLER?
	TAD IOFLAG
	SNA
	JMP .+5
	LAC TEMP3		/YES. DEFINITION SHOULD BE ADDRESS/4.
	RCR
	RCR
	DAC TEMP3
	LAC TEMP3
	TAD PLIT12	/(500000
	DAC SYMDEF	/SAVE FOR SYMBOL DEFINITION.
 
	.EJECT
/ RESOLVE THE VIRTUAL GLOBAL ENTRY IN THE SYMBOL TABLE BY FOLLOWING THE
/ CHAIN (OF TRANSFER VECTORS POINTING TO OTHER TRANSFER VECTORS) AND
/ REPLACING EACH LINK WITH THE REAL DEFINITION.
 
RESOLVE	LAC SYMDEF	/DEFINE THE SYMBOL IN THE TABLE AS AN
	DAC* SYMWD1	/INTERNAL GLOBAL.
	LAW -1		/SUBTRACT 1 FROM COUNT OF VIRTUAL
	TAD F4FLAG	/GLOBALS IN THE SYMTAB.
	DAC F4FLAG
 
NXLINK	LAC* TEMP4	/CONTENTS OF NEXT CHAIN LINK.
	AND (77777	/POINTS TO ANOTHER LINK.
	DAC TEMP1		/SAVE POINTER TO OTHER LINK.
	LAC LLIOFLG	/IF I/O HANDLER GLOBAL, THE ADDRESS IS ONLY 13 BITS.
	TAD IOFLAG	/UNIT # IS IN BITS 2-4.
	SNA
	JMP .+7
	LAC TEMP1
	AND (17777
	DAC TEMP1
	XOR* TEMP4	/PRESERVE UNIT #.
	AND (177777	/CLEAR BITS 0 AND 1 IN .DAT SLOT.
	XOR (400000	/ADD "SETUP" BIT.
	XOR TEMP3		/ADD GLOBAL'S REAL ADDRESS.
	DAC* TEMP4	/STORE REAL DEFINITION IN THE NEXT
			/LINK (TRANSFER VECTOR).
 
	LAC TEMP1		/LAST LINK IN CHAIN POINTS TO
	SAD TEMP4		/ITSELF.
	JMP* COD10.	/CHAIN IS RESOLVED.
 
	DAC TEMP4		/OTHER LINK BECOMES NEXT LINK.
	JMP NXLINK
 
/ CODE 11 PROCESSOR: BLOCK DATA SUBPROGRAM DECLARATOR.
 
CODE11	JMS TWOS
	DAC SIZE		/2'S COMPLEMENT OF BLOCKDATA PROGRAM SIZE.
	DAC BLKFLG	/TELL FIT THAT BLOCKDATA IS BEING LOADED.
	JMS FIT		/SEE IF BLOCK FITS IN CORE; COMPUTE LOAD
			/ADDRESS AND RELOCATION FACTOR.
	LAC RELOC		/NEW RELOCATION FACTOR STORED AS BLOCK
	DAC BLKFLG	/BASE ADDRESS IN BLOCK DATA FLAG WHICH
	JMP BUFCHK	/SETS THE FLAG NON-ZERO.
 
	.EJECT
/ CODE 12 PROCESSOR: COMMON BLOCK DEFINITION (SIZE). IF BLOCK DATA FLAG
/ IS SET, THEN THE COMMON BLOCK IS DEFINED NOW RATHER THAN AFTER ALL THE
/ LIBRARY PROGRAMS HAVE BEEN LOADED.
 
CODE12	DAC TEMP1		/SAVE COMMON BLOCK SIZE.
	LAC BLKFLG	/IS BLOCK DATA FLAG ON?
	SNA!CLA
	TAD (400000	/NO. ADD UNDEFINED BLOCK CODE (7).
	TAD (300000	/YES. ADD DEFINED BLOCK CODE (3).
	TAD TEMP1
	JMS SCAN		/DOES THE SYMBOL TABLE ALREADY HAVE AN
			/ENTRY FOR THIS COMMON BLOCK?
	JMP COM.IN	/YES.
 
/ NO. THIS IS THE FIRST TIME THIS COMMON BLOCK NAME HAS BEEN SEEN.
/ ENTER IT INTO THE SYMBOL TABLE.
 
	JMS DEFSYM	/ENTER INTO SYMBOL TABLE.
	LAC SYMEND	/SETUP POINTER TO COMMON CHAIN POINTER IN
	DAC COMCHN	/THE SYMTAB ENTRY.
	DZM* COMCHN	/INIT ENTRY'S POINTER TO 0 TO INDICATE
			/THERE'S NO CHAIN YET.
	JMS UPSYM		/MOVE SYMEND DOWN ONE.
	LAC SYMEND	/SETUP POINTER TO THE WORD IN THE COMMON
	DAC COMDEF	/BLOCK ENTRY WHICH HAS THE BLOCK ADDRESS.
	JMS UPSYM		/MOVE SYMEND DOWN ONE.
 
/ IF BLKFLG=0, THE BASE ADDRESS OF THIS COMMON BLOCK IS SET TO 0
/ INDICATING THAT IT IS UNDEFINED. OTHERWISE, BLKFLG CONTAINS THE
/ BASE ADDRESS OF THE COMMON BLOCK.
 
DACDEF	LAC BLKFLG	/SET COMMON BLOCK BASE ADDRESS IN THE
	DAC* COMDEF	/SYMBOL TABLE ENTRY.
	SNA		/IS BLOCK DATA MODE ON?
	JMP BUFCHK	/NO. PROCESS NEXT DATA WORD.
	DAC RELOC
	TAD TEMP1		/YES. ADD THE COMMON BLOCK SIZE
	DAC BLKFLG	/TO GET THE BASE ADDRESS OF THE NEXT
			/COMMON BLOCK.
	LAC MAPFUNC	/ARE COMMON BLOCKS TO BE PRINTED
	AND (4		/IN THE MEMORY MAP?
	SNA
	JMP .+3		/NO.
	LAC (103		/ASCII FOR C.
	JMS MEMMAP
	JMS DEFCOM	/DEFINE ALL MEMBERS OF THE COMMON CHAIN.
	JMP BUFCHK
 
	.EJECT
/ AN ENTRY FOR THIS COMMON BLOCK ALREADY EXISTS IN THE SYMBOL TABLE.
 
COM.IN	DAC TEMP2		/SAVE THE BLOCK SIZE PICKED UP
			/FROM THE SYMTAB ENTRY.
	LAC SYMPTR	/SETUP POINTERS TO THE COMMON CHAIN POINTER
	TAD MINUS1	/AND THE COMMON BLOCK ADDRESS.
	DAC COMCHN
	TAD MINUS1
	DAC COMDEF
 
/ IF THE BLOCK HAS ALREADY BEEN DEFINED AND THE NEW SIZE IS LARGER THAN
/ THE ONE IN THE SYMBOL TABLE, THAT'S AN ERROR.
 
	LAC TEMP2		/SYMTAB BLOCK SIZE.
	CMA
	TAD TEMP1		/NEW BLOCK SIZE.
	SPA		/SKIP IF NEW SIZE > OLD SIZE.
	JMP EQLTST
 
DEFTST	LAC* COMDEF	/IS BLOCK ALREADY DEFINED?
	SZA
	JMP ERR107	/YES. ERROR.
 
	LAC SYMDEF	/NO. REPLACE OLD SIZE WITH THE NEW ONE.
	DAC* SYMWD1
	JMP DACDEF
 
/ IF BLOCK DATA MODE IS ON, THE SIZES HAD BETTER BE THE SAME.
 
EQLTST	SAD MINUS1	/(-1
	SKP!CLA		/SIZES ARE EQUAL.
	JMP LESSTH	/NOT EQUAL.
 
	SAD BLKFLG	/BLOCK DATA MODE ON?
	JMP BUFCHK	/NO. PROCESS NEXT DATA WORD.
	JMP DEFTST	/YES. EVEN THOUGH THE SIZES ARE THE
			/SAME, SINCE THIS IS BLOCK DATA MODE,
			/THE BLOCK HAD BETTER NOT BE DEFINED YET.
 
/ NEW SIZE < OLD SIZE. BLOCK DATA MODE BETTER BE OFF.
 
LESSTH	LAC BLKFLG
	SNA
	JMP BUFCHK	/OK.
	JMP ERR107	/BLOCK DATA MODE ON AND THE BLOCK SIZE
			/IN THE SYMBOL TABLE IS LARGER THAN THE
			/ONE IN THIS BLOCKDATA SUBPROGRAM.
 
	.EJECT
/ CODE 13 PROCESSOR: COMMON SYMBOL DEFINITION (ADDRESS RELATIVE TO THE
/ START OF THE COMMON BLOCK). USE SAME CODE AS CODE8.
 
 
/ CODE 14 PROCESSOR: COMMON SYMBOL REFERENCE DEFINITION (UNRELOCATED
/ ADDRESS OF THE TRANSFER VECTOR).
 
CODE14	TAD RELOC		/ADD THE RELOCATION FACTOR TO
	DAC SYM1		/POINT TO WHERE THE T.V. IS NOW.
 
	LAC* COMDEF	/0 OR THE BLOCK'S BASE ADDRESS.
	TAD SYM2		/COMMON SYMBOL'S RELATIVE POSITION.
	DAC* SYM1		/STORE IN THE TRANSFER VECTOR.
	LAC* COMDEF	/IS THE BLOCK DEFINED?
	SZA
	JMP BUFCHK	/YES. DONE.
 
/ BLOCK IS NOT DEFINED. MAKE AN ENTRY IN THE SYMBOL TABLE AND INSERT
/ THE ENTRY IN THE COMMON CHAIN.
 
NOTDEF	LAC* COMCHN	/POINTER TO 1ST LINK IN CHAIN.
	TAD (400000	/TACK ON CODE 4.
	DAC SYMDEF
	LAC SYMEND	/END OF SYMBOL TABLE IS WHERE THE 1ST
			/WORD OF THIS ENTRY WILL GO.
	DAC* COMCHN	/MAKE THE NEW ENTRY BECOME THE 1ST LINK.
	JMP NTRSYM	/MAKE 2-WORD ENTRY IN THE SYMBOL TABLE.
 
 
/ CODE 15 PROCESSOR: DATA INITIALIZATION CONSTANT (1ST WORD).
 
CODE15	DAC DATA1
	JMP BUFCHK
 
 
/ CODE 16 PROCESSOR: DATA INITIALIZATION CONSTANT (2ND WORD).
 
CODE16	DAC DATA2
	JMP BUFCHK
 
	.EJECT
/ CODE 17 PROCESSOR: DATA INITIALIZATION CONSTANT (3RD WORD).
 
CODE17	DAC DATA3
	JMP BUFCHK
 
 
/ CODE 18 PROCESSOR: DATA INITIALIZATION CONSTANT DEFINITION. CODE BITS
/ (1-2) TELL WHAT TYPE OF CONSTANT WAS JUST LOADED (CODES 15-17).
/ REMAINDER CONTAINS UNRELOCATED LOAD ADDRESS FOR THE CONSTANT.
 
CODE18	DAC TEMP1		/SAVE DATA WORD.
 
/ IF BLKFLG=0, ADD THE RELOCATION FACTOR TO THE RELATIVE
/ LOAD ADDRESS; OTHERWISE, ADD THE BASE ADDRESS OF THE LAST COMMON
/ BLOCK REFERENCED.
 
	LAC BLKFLG	/IF BLKFLG IS NON-0, COMMON
	SNA		/BLOCK IS ALREADY DEFINED.
	JMP .+3
	LAC* COMDEF	/BLOCK'S BASE ADDRESS.
	SKP
	LAC RELOC		/USE RELOCATION FACTOR INSTEAD.
	TAD TEMP1		/ADD RELATIVE ADDRESS.
	DAC TEMP1		/LOAD ADDRESS FOR CONSTANT.
 
	LAC DATA1		/STORE 1ST CONSTANT WORD.
	JMS DACIDX
 
/ CODE BITS ARE IN THE LOAD ADDRESS WORD. 00 (INTEGER - 1 WORD);
/ 01 (REAL - 2 WORDS); 10 (DOUBLE - 3 WORDS); 11 (LOGICAL - 1 WORD).
 
	LAC TEMP1		/GET CODE BITS (1-2).
	AND (300000
	SZA
	SAD (300000
	JMP BUFCHK	/CODES 00 OR 11 HAVE ONLY 1 WORD.
 
	RTL		/LINK=0 IF CODE 01; LINK=1 IF CODE 10.
	LAC DATA2		/STORE 2ND CONSTANT WORD.
	JMS DACIDX
 
	LAC DATA3
	SZL		/SKIP IF CODE IS 01.
	DAC* TEMP1
	JMP BUFCHK
 
	.EJECT
/ CODE 19 PROCESSOR: INTERNAL SYMBOL DEFINITION OR PROGRAM NAME.
 
CODE19	SMA		/SKIP IF A PROGRAM NAME.
	JMP BUFCHK	/IGNORE INTERNAL SYMBOL.
	LAC* (.SCOM+26	/0=FGD RUNNING.
	TAD LLIOFLG	/0=NOT FGD LINK LOADER I/O.
	SZA		/SKIP IF FGD USER PROGRAM.
	JMP BUFCHK
	LAC MAPFUNC	/ARE PROGRAM NAMES TO BE PRINTED
	AND PLUS1		/IN THE MEMORY MAP?
	SNA
	JMP BUFCHK	/NO.
	LAC (120		/ASCII FOR P.
	JMS MEMMAP	/OUTPUT PROGRAM NAME IN THE MEMORY MAP.
	JMP BUFCHK
 
/ CODE 20 PROCESSOR: STRING CODE (FIRST HALF) - UNRELOCATED POINTER
/ TO AN INSTRUCTION WHOSE ADDRESS PART IS TO BE REPLACED (CODE 21).
 
CODE20	TAD RELOC		/ADD RELOCATION FACTOR.
	DAC STRING	/SAVE POINTER TO THE INSTRUCTION.
	JMP BUFCHK
 
/ CODE 21 PROCESSOR: STRING CODE (SECOND HALF) - UNRELOCATED ADDRESS
/ WHICH IS TO REPLACE THE ADDRESS PART OF AN INSTRUCTION (SEE CODE 20).
 
CODE21	JMS MOD13		/ADD THE RELOCATION FACTOR
	DAC TEMP1		/MODULO 13 TO THIS ADDRESS.
	LAW
	AND* STRING	/SAVE INSTRUCTION PART AND INDIRECT BIT.
	TAD TEMP1		/ADD THE REPLACEMENT ADDRESS.
	DAC* STRING
	JMP BUFCHK
 
/ CODE 22 PROCESSOR: .IODEV REQUEST.
 
CODE22	SPA		/IF BIT0=1, REQUEST IS .IODEV ALL.
	JMP .+3
	JMS IODEV.	/REQUEST ONLY THIS .DAT SLOT.
	JMP BUFCHK
 
/ .IODEV ALL REQUESTS ALL POSITIVE .DAT SLOTS WITH NON-0 CONTENTS.
 
	JMS IODALL
	JMP BUFCHK
 
/ CODE 23 PROCESSOR: END OF PROGRAM UNIT (PROGRAM START ADDRESS).
 
CODE23	DZM BLKFLG	/TURN OFF BLOCKDATA SUBPROGRAM FLAG
			/IN CASE IT WAS ON.
	TAD RELOC		/ADD RELOCATION FACTOR TO THE
	AND (77777	/PROGRAM START ADDRESS.
	JMP* LDPROG	/PROGRAM UNIT HAS BEEN LOADED. RETURN.
 
	.EJECT
/ SUBROUTINE FIT: DETERMINE IF PROGRAM SEGMENT WILL FIT INTO AVAILABLE
/ CORE AND COMPUTE THE LOAD ADDRESS AND RELOCATION FACTOR.
 
FIT	0
 
	LAC LLIOFLG	/LOADING FGD LINK LOADER I/O?
	SNA!CLC
	JMP NOTLLIO
	LAC DIRPTR	/POINTING AT HIGHEST FREE REGISTER.
	TAD SIZE
	TAD PLUS1
	AND MINUS4
	DAC LOADADR
	DAC RELOC
	TAD MINUS1
	DAC DIRPTR	/NEW HIGHEST FREE REGISTER.
	JMP* FIT
 
NOTLLIO	TAD PBANK0	/(BANK0
	DAC TEMP1		/START WITH LOWEST CORE BANK.
NXBANK	IDX TEMP1
	LAC TEMP1		/ANY REMAINING BANKS?
	SAD BANKS		/(BANK0+4
	JMP ERR100	/NO.
	DAC TEMP2		/SAVE POINTER TO BANK.
	LAC* TEMP1
	SNA!CLA		/0 CONTENTS MEANS BANK USED UP.
	JMP NXBANK	/TRY NEXT HIGHER ONE.
	SAD IOFLAG	/I/O HANDLERS BEING LOADED NOW?
	JMP .+5
	LAC* TEMP1	/YES. LOAD ADDRESS MUST BE EVENLY
	TAD (3		/DIVISIBLE BY 4.
	AND MINUS4
	SKP
	LAC* TEMP1
	DAC RELOC
	DAC LOADADR
	LAC SIZE		/2'S COMP.
	CMA
	TAD RELOC
	DAC LAST		/PROGRAM'S LAST REGISTER.
	XOR* TEMP1	/WILL IT FIT IN ONE BANK?
	AND PLIT8		/(760000
	SNA
	JMP ONEBNK	/YES.
	LAC BLKFLG	/BLOCKDATA SUBPROGRAM?
	TAD COMFLG	/NON-BLOCKDATA COMMON OR I/O BUFFER?
	SNA
	JMP NXBANK	/NO. TRY ANOTHER BANK.
 
	.EJECT
BNKLOOP	IDX TEMP2		/ARE THERE ANY BANKS ABOVE THE
	LAC TEMP2		/PRESENT ONE?
	SAD BANKS		/(BANK0+4
	JMP ERR100	/NO. NO ROOM.
	LAC* TEMP2	/IS NEXT BANK UNUSED
	AND (17777	/(POINTING AT XXX20)?
	SAD (20
	SKP
	JMP NXBANK	/NO. RESTART WITH HIGHER BANK.
	LAC LAST		/IS LAST ADDRESS IN THIS BANK?
	XOR* TEMP2
	AND PLIT8		/(760000
	SZA
	JMP BNKLOOP	/NO. NEED TO GO IN ANOTHER BANK.
ZLOOP	LAC TEMP1		/ZERO ALL LOWER BANKS USED UP.
	SAD TEMP2
	JMP .+4
	DZM* TEMP1
	IDX TEMP1
	JMP ZLOOP
ONEBNK	LAC COMFLG	/NON-BLOCKDATA COMMON OR I/O BUFFER?
	SZA
	JMP NUBPTR	/YES.
SYMLAP	LAC SYMEND	/PROGRAM (INCLUDING BLOCKDATA) MAY NOT
	JMS TWOS		/OVERLAP THE SYMBOL TABLE.
	TAD LAST
	SMA
	JMP ERR101
NUBPTR	LAC LAST		/CHANGE HIGHEST BANK POINTER USED,
	AND (17777	/UNLESS THE LAST ADDRESS IS < XXX20.
	TAD (-20
	IDX LAST		/POINT TO 1ST FREE REGISTER.
	SPA
	JMP NULOSYM	/IT IS - NO CHANGE.
	LAC LAST
	DAC* TEMP1
	AND (17777
	SNA
	DZM* TEMP1	/BANK USED UP.
NULOSYM	LAC LOSYM		/CALCULATE LOWEST REGISTER AVAILABLE
	JMS TWOS		/TO THE SYMBOL TABLE.
	TAD LAST
	SPA
	JMP* FIT
	LAC LAST
	DAC LOSYM
	JMP* FIT
 
	.EJECT
/ SUBROUTINE IOLOAD:
 
IOLOAD	0
 
	SET IOFLAG
	JMS LOADIO
	DZM IOFLAG
	JMP* IOLOAD
 
/ SUBROUTINE LOADIO: IF THERE ARE ANY UNRESOLVED GLOBALS IN THE SYMBOL
/ TABLE, CALL LIBRARY WITH .DAT -7 TO LOAD IN I/O HANDLERS.
 
LOADIO	0
 
	JMS VIRTUAL	/ANY UNRESOLVED GLOBALS?
	JMP* LOADIO	/NO.
	LAW -7
	JMS LIBRARY
	JMS VIRTUAL	/SKIP IF GLOBALS MISSING.
	JMP* LOADIO
 
/ UNRESOLVED GLOBALS: PRINT THE NAMES OF THE MISSING GLOBALS
/ IN THE MEMORY MAP WITH A LOAD ADDRESS OF ZERO.
 
GLBERR	JMS VIRTUAL	/ANY UNDEFINED GLOBALS?
	JMP NOMORE
	DZM* SYMWD1	/YES. KILL THE ENTRY IN THE SYMBOL TABLE
			/TO AVOID SEEING IT AGAIN.
	DZM RELOC		/SET LOAD ADDRESS TO 0 FOR PRINTOUT.
	JMS NEXSYM	/PICKUP THE GLOBAL'S NAME.
	DAC SYM1
	JMS NEXSYM
	DAC SYM2
	LAC (107		/ASCII FOR G.
	JMS MEMMAP	/PRINT IN MEMORY MAP.
	JMP GLBERR	/CONTINUE UNTIL THEY'RE ALL DONE.
 
NOMORE	CAL 775		/WAIT FOR LAST MESSAGE TO FINISH.
	12
 
	JMP ERR110	/MISSING GLOBAL(S).
 
	.EJECT
/ SUBROUTINE VIRTUAL: SEARCH FOR A VIRTUAL GLOBAL IN SYMBOL TABLE.
 
VIRTUAL	0
 
	JMS BEGSYM	/START AT BEG OF SYMTAB.
	JMS FINDCOD	/SEARCH FOR
	100000		/VIRTUAL GLOBAL ENTRY.
	JMP* VIRTUAL	/RETURN HERE IF NONE FOUND.
	IDX VIRTUAL	/HERE IF FOUND.
	JMP* VIRTUAL
 
/ SUBROUTINE FINDCOD: STARTING AT THE CURRENT POSITION OF SYMWD1, SEARCH THRU
/ THE SYMBOL TABLE FOR AN ENTRY WHOSE CODE MATCHES THE CODE FOLLOWING THE
/ JMS FINDCOD. SKIP ON RETURN IF FOUND.
 
FINDCOD	0
 
	LAC SYMWD1	/ARE WE AT THE END OF
NEXCOD	SAD SYMEND	/THE SYMBOL TABLE?
	JMP NOFIND	/YES.
 
	LAC* SYMWD1	/GET 1ST WORD OF ENTRY IN SYMTAB.
	AND PLIT6		/(700000 MASK TO CODE BITS.
	SAD* FINDCOD	/MATCH?
	JMP .+3		/YES.
 
NOMATCH	JMS NXNTRY	/MOVE POINTER TO THE NEXT ENTRY.
	JMP NEXCOD
 
FOUND	IDX FINDCOD
NOFIND	IDX FINDCOD
	JMP* FINDCOD
 
	.EJECT
/ LIBRARY SEARCH SUBROUTINE: LOAD IN ALL REQUESTED
/ LIBRARY ROUTINES.
 
LIBRARY	0
	AND (777
	DAC LIBINIT		/SETUP LIBRARY .INIT.
	DAC LIBSEEK		/SETUP LIBRARY .SEEK.
	DAC LIBCLOS		/SETUP LIBRARY .CLOSE.
 
LIBINIT	CAL .			/.INIT FOR LIBRARY INPUT (-1, -5, OR -7).
	1
	0
	0
 
LIBSEEK	CAL .			/.SEEK THE LIBRARY FILE.
	3
LIBPTR	IOLIB			/THIS LOCATION CHANGED EXTERNALLY:
				/IOLIB, F4LIB, OR USRLIB.
	SET NUFILE		/TELL SUBROUTINE LDPROG THAT A .SEEK
				/WAS JUST DONE.
MORLIB	SET LIBFLG		/SET LIBR MODE FLAG FOR SELECTIVE
				/LOADING.
	JMS VIRTUAL		/ARE THERE ANY UNRESOLVED GLOBALS?
	JMP LIBCLOS		/NO.
 
NEXLIB	LAC LIBSEEK		/GET CAL TO THE CORRECT DAT SLOT.
	JMS LDPROG		/LOAD IN LIBRARY SUBPROGRAM ONLY
				/IF IT IS REQUESTED IN THE SYMBOL
				/TABLE AS A VIRTUAL GLOBAL. IF
				/LIBRARY END OF FILE IS ENCOUN-
				/TERED, CONTROL IS RETURNED TO
				/LOCATION 'LIBCLOS'. IF THE NEXT
				/PROGRAM IN THE LIBRARY WAS
				/INDEED LOADED, LIBFLG WILL BE 0
				/ON RETURN.
	LAC LIBFLG		/WAS NEXT LIBR PROGRAM READ IN?
	SZA
	JMP NEXLIB		/NO. TRY NEXT SUBPROGRAM.
	JMP MORLIB		/YES. DO ANY MORE NEED TO BE READ IN?
 
/ IF SUBROUTINE LDPROG DETECTS THE LIBRARY END-OF-FILE,
/ IT WILL RETURN CONTROL HERE.
 
LIBCLOS	CAL .			/.CLOSE THE LIBRARY FILE.
	6
 
	DZM LIBFLG
	JMP* LIBRARY
 
	.EJECT
/ SUBROUTINE IODALL: .IODEV ALL POSITIVE .DAT SLOTS WITH NON-0 CONTENTS.
 
IODALL	0
 
	DZM TEMP5
 
NEXPOS	IDX TEMP5		/INDEX SLOT #.
	LAC TEMP5
	TAD DAT		/.DATF OR .DATB .
	DAC TEMP4		/.DAT SLOT ADDRESS.
	SAD* DAT		/POINTER TO .DATND .
	JMP* IODALL
	LAC* TEMP4	/NO. CONTENTS OF SLOT=0?
	SNA
	JMP NEXPOS	/YES. IGNORE IT.
	LAC TEMP5
	JMS IODEV.
	JMP NEXPOS
 
/ SUBROUTINE IODEV.: CALLED WITH .DAT SLOT NUMBER IN THE AC.
 
IODEV.	0
 
	AND (777
	SNA
	JMP ERR111	/.DAT SLOT 0 IS ILLEGAL.
	DAC TEMP1
	AND (400
	SZA		/TEST IF .DAT SLOT NEGATIVE.
	777000		/YES.
	XOR TEMP1
	TAD DAT		/.DATF OR .DATB .
 
/ TEST LEGALITY OF .DAT SLOT. IF FOREGROUND USER .IODEV'S -1, -4, -5
/ OR -7 HE'LL LOSE AS SOON AS HE TRIES TO .INIT THEM BECAUSE
/ THEY'LL CONTAIN ZERO.
 
	DAC SLOT		/POINTER TO .DAT SLOT.
	JMS TWOS
	TAD* DAT		/GET ADDRESS OF END OF TABLE.
	SNA!SPA
	JMP ERR111	/.DAT SLOT # TOO HIGH.
	LAC* DAT
	JMS EXAMIN	/GET ADDRESS OF BEG. OF .DAT TABLE.
	JMS TWOS
	TAD SLOT
	SPA
	JMP ERR111	/.DAT SLOT # TOO LOW.
 
	.EJECT
/ CHECK CONTENTS OF .DAT SLOT. IF BIT0=1, THE SLOT IS ALREADY SETUP
/ SO IGNORE IT. IF CONTENTS=0, IGNORE REQUEST UNLESS IT IS A FOREGROUND
/ USER REQUEST (ERROR).
 
	LAC* SLOT		/.DAT SLOT CONTENTS.
	DAC IORQST
	SPA
	JMP* IODEV.	/SLOT ALREADY SETUP.
	SZA
	JMP CKIOIN
	LAC* (.SCOM+26	/0=FOREGROUND RUNNING.
	TAD LLIOFLG	/0=NOT LINK LOADER I/O.
PIPZER	SZA		/THIS LOC CHANGED TO JMP* IODEV.
PIPOUT	JMP* IODEV.	/WHEN LOADING PIP IN FGD.
	JMP ERR112	/FOREGROUND USER .IODEV OF 0 CONTENTS SLOT.
 
/ SLOT REQUEST O.K. SO FAR. SEARCH THRU THE .IOIN TABLE TO SEE IF THE
/ HANDLER IS ALREADY THERE.
 
CKIOIN	DZM HANDLR	/HANDLER ADDRESS; 0=NOT IN TABLE.
	LAC* IOINPTR
	DAC IOINCT	/C(.IOIN)=ENTRY COUNT (2'S COMP).
	LAC IOINMAX	/POINTER TO .IOIN+1 .
	DAC TEMP1
	IDX TEMP1
NXIOIN	IDX TEMP1		/MATCH 1ST WORD OF NEXT .IOIN ENTRY
	LAC* TEMP1	/AGAINST .DAT SLOT REQUEST.
	IDX TEMP1		/POINT TO 2ND ENTRY WORD.
	XOR IORQST
	DAC IOINWD
	SNA
	JMP EXACT		/EXACT MATCH.
	AND PLIT18	/(217600 CHECK FOR DEVICE MATCH.
	SZA
	JMP DIFDVC	/IGNORE. DIFFERENT DEVICE.
 
/ DEVICES MATCH. IF LT19 BIT IS SET, THE HANDLER IS FOUND.
 
	LAC IORQST	/C(.DAT SLOT).
	RAL
	SPA
	JMP GOTHND	/LT19 HANDLER.
	LAC IOINWD	/CHECK FOR OTHER HANDLER MATCH.
	AND PLIT16	/(177
	SZA
	JMP ERR113	/SAME DEVICE - DIFFERENT HANDLERS.
 
	.EJECT
/ FOUND DEVICE AND HANDLER MATCH. SAVE A POINTER TO THE SECOND WORD
/ IN THIS .IOIN ENTRY.
 
GOTHND	LAC TEMP1
	DAC HANDLR
DIFDVC	ISZ IOINCT	/ANYMORE ENTRIES?
	JMP NXIOIN	/YES.
	LAC HANDLR	/WAS HANDLER FOUND?
	SNA
	JMP NOTIN		/NO.
 
/ THE HANDLER'S IN THE TABLE (NOT NECESSARILY IN CORE YET), BUT A NEW
/ UNIT HAS BEEN REQUESTED. THE NON-RESIDENT MONITOR HAS MADE SURE
/ THAT IF BGD AND FGD HAVE .DAT SLOTS REQUESTING THE SAME DEVICE
/ THAT THE MULTIUNIT (SHAREABLE) HANDLER IS IN CORE.
 
	JMS IONTRY	/YES. PREPARE TO MAKE .IOIN ENTRY.
FGDCNT	LAC* (.SCOM+26	/CHANGE THE FOREGROUND COUNT (.IOIN+3)
	TAD LLIOFLG	/ONLY IF IT'S A FOREGROUND USER .IODEV .
	SZA
	JMP .+6		/NO.
	LAC IOINMAX	/POINTER TO .IOIN+1 .
	DAC TEMP2
	IDX TEMP2
	LAC* IOINPTR
	DAC* TEMP2
	LAC IORQST
	JMS DACIDX	/C(.DAT SLOT) IS 1ST WORD IN ENTRY.
	LAC* HANDLR	/IF BIT0=0 IN THE HANDLER'S DEFINITION,
	SPA		/IT'S PART OF A VIRTUAL GLOBAL CHAIN.
	JMP IN
	JMS CHNEND	/FIND END OF CHAIN.
	XOR* HANDLR
	XOR TEMP1
	DAC* HANDLR	/MAKE IT POINT TO NEW END OF CHAIN.
	LAC TEMP1		/2ND WORD OF NEW ENTRY (END OF CHAIN)
	DAC HANDLR
IN	DAC* TEMP1	/POINTS TO ITSELF.
	JMP SETDAT	/SETUP THE .DAT SLOT.
 
	.EJECT
/ HANDLER NOT IN THE TABLE. ENTER VIRTUAL GLOBAL REFERENCE INTO
/ THE SYMBOL TABLE AND .IOIN TABLE.
 
NOTIN	LAC IORQST
	AND PLIT16	/(177 GET HANDLER CODE.
	SNA
	JMP ERR114	/CODE 0 IS ILLEGAL.
	TAD IOCPTR	/POINTER TO 1ST REGISTER BELOW IOC TABLE.
	JMS EXAMIN	/GET HANDLER NAME.
	DAC SYM1
	LAC PLIT21	/RADIX 50 FOR PERIOD.
	DAC SYM2
	LAC ADR9		/(FIRST-1 POINTER TO HIGHEST
	JMS TWOS		/REGISTER IN IOC TABLE.
	TAD TEMP1
	SMA
	JMP ERR114	/HANDLER CODE TOO HIGH.
	JMS IONTRY	/PREPARE TO MAKE .IOIN ENTRY.
	TAD PLUS1
	DAC HANDLR	/POINTER TO 1ST FREE .IOIN ENTRY(2ND WORD).
	DAC* HANDLR	/MAKE IT POINT TO ITSELF.
	XOR PLIT7		/(100000 ; VIRTUAL GLOBAL CODE.
	DAC SYMDEF
	JMS DEFSYM	/MAKE SYMTAB ENTRY.
	LAC LLIOFLG	/LOADING LOADER'S I/O?
	SNA!CLC
	JMP FGDCNT
	TAD SYMEND	/YES. MAKE ROOM SO SYMTAB OVERFLOW TEST
	DAC DIRPTR	/WON'T FAIL.
	JMP FGDCNT	/MAKE .IOIN ENTRY.
 
/ CONTENTS OF THE .DAT SLOT EXACTLY MATCHES THE .IOIN ENTRY. THE
/ NON-RESIDENT MONITOR ALREADY MADE SURE THIS ISN'T A BGD/FGD
/ CONFLICT. .DAT CONTENTS ARE ILLEGAL ONLY IF FGD USER PROGRAM IS
/ TRYING TO REFERENCE THE SYSTEM DEVICE UNIT.
 
EXACT	LAC TEMP1		/GET POINTER TO ENTRY WORD 2.
	DAC HANDLR
	LAC* (.SCOM+26	/0=FOREGROUND RUNNING.
	TAD LLIOFLG	/0=NOT LINK LOADER I/O.
	SZA
	JMP SETDAT	/O.K. SETUP THE .DAT SLOT.
MINUS4	LAW -4
	TAD TEMP1
	SAD IOINPTR
	JMP SHARE0
 
	.EJECT
/ SETUP THE .DAT SLOT. IF THE HANDLER IS NOT IN CORE, LINK THE SLOT
/ IN THE VIRTUAL GLOBAL CHAIN.
 
SETDAT	LAC* HANDLR
	SPA
	JMP SETUP		/BIT0=1 MEANS DEFINED.
	JMS CHNEND	/FIND END OF CHAIN.
	XOR* HANDLR	/SAVE UNIT #.
	XOR SLOT		/MAKE IT POINT AT THE .DAT SLOT.
	DAC* HANDLR
	LAW
	AND IORQST	/SAVE UNIT #.
	XOR (600000	/ADD "DEFINED" AND "LT19" BITS.
			/DEFINED SO REDUNDANT .IODEV'S W/B
			/IGNORED; LT19 BIT SO THAT STOPIO
			/IN RESMON WON'T CALL NON-EXISTANT HANDLER.
	XOR SLOT		/MAKE SLOT POINT AT ITSELF TO
	JMP DACIT		/TERMINATE THE CHAIN.
SETUP	LAC IORQST	/LT19 OR NOT?
	RAL
	SMA!RAR		/SKIP IF LT19.
	AND PLIT8		/(760000 SAVE UNIT #.
	XOR* HANDLR	/ADD DEFINITION.
DACIT	DAC* SLOT
 
/ IF HANDLER'S IN THE .MUD TABLE AND IF NOT LOADING FOREGROUND LINK
/ LOADER I/O, REQUEST ANOTHER BUFFER FOR THAT HANDLER.
/ SEARCH THRU THE .MUD TABLE TO SEE IF THE HANDLER REQUIRES
/ EXTERNAL BUFFERS.
 
	LAC LLIOFLG	/BUFFERS NOT NEEDED BY EITHER FGD OR BGD
	SZA		/LINK LOADERS. THEY USE RESIDENT BUFFER.
	JMP* IODEV.
	SAD SYSNUM
	JMP* IODEV.
	LAC MUDPTR	/POINTER TO .MUD .
	JMS EXAMIN
	DAC MUDCNT	/ENTRY COUNT (2'S COMP).
NEXMUD	IDX TEMP1
	LAC* TEMP1	/GET WORD 1 OF ENTRY,
	RTR		/SHIFT HANDLER CODE TO
	RTR		/MATCH AGAINST CODE FROM
	RTR		/THE .DAT SLOT.
	AND PLIT16	/(177
	SAD PLUS1		/1=HANDLER CODE FOR TTA. .
	JMP NOPE		/TTA. NEEDS NO EXT. BUFFERS.
	XOR IORQST	/C(.DAT SLOT) BEFORE SETUP.
	AND PLIT16	/(177
	SNA
	JMP GOTMUD
NOPE	IDX TEMP1		/NO MATCH YET.
	ISZ MUDCNT
	JMP NEXMUD
	JMP* IODEV.	/NON-MUD HANDLER: NO BUFFERS NEEDED.
	.EJECT
GOTMUD	LAC* TEMP1	/BIT0=1 IN WORD 1 OF .MUD ENTRY
	SPA		/IF USER ISSUED $FILES COMMAND.
	JMP* IODEV.	/HE DID.
	AND (77
	DAC TEMP2		/CURRENT $FILES COUNT.
	LAC TEMP1
	DAC TEMP3
	IDX TEMP3		/GET MAX. $FILES COUNT.
	LAC* TEMP3
	AND (77
	SAD TEMP2		/OLD $FILES = MAX. $FILES?
	JMP ERR104	/YES. COUNT OVERFLOW.
	IDX* TEMP1	/ADD 1 TO $FILES COUNT.
	JMP* IODEV.
SHARE0	LAC* PLIT16	/(.SCOM+77 FGD USER MAY .IODEV THE SYSTEM DEVICE
	SNA		/UNIT 0 ONLY IF THE $SHARE FLAG IS ON.
	JMP ERR116
	JMP SETDAT
 
/ SUBROUTINE IONTRY: GET POINTER TO FREE ENTRY IN .IOIN TABLE.
 
IONTRY	0
 
	IDX IOCOUNT	/COUNT OF .IOIN ENTRIES MADE.
	LAC* IOINPTR
	SAD* IOINMAX
	JMP ERR103	/NO MORE ROOM IN .IOIN.
	TAD MINUS1
	DAC* IOINPTR
	JMS TWOS
	RCL
	TAD IOINMAX
	DAC TEMP1		/POINTER TO FREE ENTRY.
	JMP* IONTRY
 
	.EJECT
/ SUBROUTINE CHNEND: FIND END OF VIRTUAL GLOBAL CHAIN.
 
CHNEND	0
 
	LAC* HANDLR
	AND (17777
	SAD HANDLR
	JMP* CHNEND
	DAC HANDLR
	JMP .-5
 
/ SUBROUTINE DEFSYM: ENTER 3 WORDS INTO THE SYMBOL TABLE: SYMBOL
/ DEFINITION, SYMBOL 1, AND SYMBOL 2.
 
DEFSYM	0
 
	LAC SYMDEF	/1ST WORD IS THE DEFINITION.
	JMS ENTSYM
	LAC SYM1		/IF BIT0=1, THERE IS A SYM2.
	SMA
	JMP .+3		/SYMBOL NAME IS <4 CHARS.
	JMS ENTSYM	/ENTER 1ST HALF OF SYMBOL NAME.
	LAC SYM2		/2ND HALF OF SYMBOL NAME.
	JMS ENTSYM	/ENTER WORD2 OR WORD3.
	JMP* DEFSYM
 
/ SUBROUTINE ENTSYM: ENTER THE WORD IN THE AC AT THE END OF THE SYMBOL
/ TABLE AND MOVE THE POINTER TO THE END OF THE SYMBOL TABLE UP ONE.
 
ENTSYM	0
 
	DAC* SYMEND	/STORE DATA AT END OF TABLE.
	JMS UPSYM		/INDEX END POINTER.
	JMP* ENTSYM
 
/ SUBROUTINE UPSYM: INDEX POINTER TO END OF SYMBOL TABLE AND TEST
/ FOR OVERFLOW.
 
UPSYM	0
 
	LAW -1
	TAD SYMEND
	DAC SYMEND
	JMS TWOS
	TAD LOSYM		/LOWEST REGISTER AVAILABLE TO SYMTAB.
	SPA!SNA		/OVERFLOW?
	JMP* UPSYM	/NO.
	JMP ERR101
 
	.EJECT
/ SUBROUTINE NXNTRY: MOVE SYMBOL TABLE POINTERS OVER THE CURRENT ENTRY
/ TO THE BEGINNING OF THE NEXT ENTRY.
 
NXNTRY	0
 
	LAC SYMWD1	/POINTER TO 1ST WORD OF CURRENT ENTRY.
	DAC SYMPTR
	JMS NEXSYM	/GET 1ST HALF OF SYMBOL NAME.
	SPA		/IF BIT0=1, NAME IS 2 WORDS LONG.
	JMS DECSPT
	JMS DECSPT
 
	LAC* SYMWD1	/LOOK AT CODE BITS IN WORD 1.
	AND (300000	/LOOK FOR COMMON BLOCK CODE: 3 OR 7.
	SAD (300000	/COMMON BLOCK?
	SKP		/YES.
	JMP .+3		/NO.
	JMS DECSPT	/COMMON BLOCK ENTRY IS 2 WORDS LONGER
	JMS DECSPT	/THAN ALL OTHERS.
 
	LAC SYMPTR	/POINTING AT 1ST WORD OF NEXT ENTRY.
	DAC SYMWD1
	JMP* NXNTRY
 
/ SUBROUTINE NEXSYM: INDEX THE SYMBOL TABLE POINTER AND PICK UP THE
/ NEXT WORD.
 
NEXSYM	0
 
	JMS DECSPT
	LAC* SYMPTR
	JMP* NEXSYM
 
/ SUBROUTINE DECSPT:
 
DECSPT	0
 
	LAW -1
	TAD SYMPTR
	DAC SYMPTR
	JMP* DECSPT
 
/ SUBROUTINE BEGSYM:
 
BEGSYM	0
 
	LAC SYMBEG
	DAC SYMWD1
	DAC SYMPTR
	JMP* BEGSYM
 
	.EJECT
/ SUBROUTINE SYMSCAN: SEARCH FROM THE BEGINNING OF THE SYMBOL TABLE
/ FOR A GLOBAL OR A COMMON ENTRY (3 OR 7 = COMMON; 1 OR 5 = GLOBAL)
/ WHOSE NAME MATCHES SYM1 AND SYM2. RETURN 0 IF NOT FOUND. RETURN
/ 15-BIT DEFINITION OF THE ENTRY IF FOUND.
 
SYMSCAN	0
 
	JMS BEGSYM	/START AT BEGINNING OF SYMTAB.
NEXSCAN	SAD SYMEND	/END OF SYMBOL TABLE?
	JMP RTNZERO	/YES. NO MATCH. RETURN 0.
 
	LAC* SYMWD1	/PICKUP ENTRY'S 1ST WORD.
	XOR SYMDEF	/MATCH WITH SEARCH CODE BITS.
	AND (300000
	SZA		/SKIP IF PROPER CODE.
	JMP MORSCAN
 
	JMS NEXSYM	/GET 1ST HALF OF SYMBOL NAME.
	SAD SYM1		/MATCH?
	SKP		/YES.
	JMP MORSCAN	/NO.
 
	SMA		/IS NAME 2 WORDS LONG?
	JMP RTNDEF	/NO. ENTRY HAS BEEN FOUND.
 
	JMS NEXSYM	/GET 2ND HALF OF SYMBOL NAME.
	SAD SYM2		/MATCH?
	JMP RTNDEF	/YES. ENTRY HAS BEEN FOUND.
 
MORSCAN	JMS NXNTRY	/NO. SKIP TO BEGINNING OF NEXT ENTRY.
	JMP NEXSCAN
 
RTNZERO	CLA!SKP		/RETURN 0 IN AC WHEN NOT FOUND.
RTNDEF	LAC* SYMWD1	/RETURN 15-BIT DEFINITION OF THE ENTRY
	AND (77777	/WITHOUT THE CODE BITS.
	JMP* SYMSCAN
 
/ SUBROUTINE SCAN: SCAN SYMBOL TABLE TO SEE IF ENTRY HAS ALREADY BEEN MADE.
 
SCAN	0
 
	DAC SYMDEF	/SAVE SYMBOL DEFINITION WITH CODE BITS.
	JMS SYMSCAN	/SEARCH SYMTAB FOR CODE AND NAME MATCH.
	SNA		/0 RETURNED IN AC IF NOT FOUND.
	IDX SCAN		/NOT FOUND.
	JMP* SCAN		/FOUND.
 
	.EJECT
/ SUBROUTINE DEFCOM: GO THROUGH THE COMMON BLOCK CHAIN AND DEFINE
/ EACH MEMBER (IF ANY) OF THE COMMON BLOCK.
 
DEFCOM	0
 
	LAC* COMCHN	/GET STARTING ADDRESS OF THE CHAIN.
	DZM* COMCHN	/SET CHAIN WORD TO 0 TO INDICATE THAT
			/THERE ARE NO UNRESOLVED CHAIN MEMBERS.
 
DEFLOOP	SNA		/ARE THERE ANY MORE CHAIN MEMBERS?
	JMP* DEFCOM	/NO.
 
	DAC COMCHN	/SET POINTER TO NEXT CHAIN ENTRY.
	TAD MINUS1	/SET POINTER TO WORD2 OF CHAIN ENTRY
	DAC COM.TV	/(WHICH POINTS AT A TRANSFER VECTOR).
	LAC* COM.TV
	DAC COM.TV	/SAVE ADDRESS OF THE TRANSFER VECTOR.
	LAC* COM.TV	/GET CONTENTS OF THE VECTOR: THE ADDRESS
			/OF THIS COMMON ENTRY RELATIVE TO THE
			/BEGINNING OF THE COMMON BLOCK.
	TAD* COMDEF	/ADD THE COMMON BLOCK BASE ADDRESS.
	DAC* COM.TV	/STORE TRUE ADDRESS IN THE TRANSFER VECTOR.
 
	LAC* COMCHN	/GET POINTER TO NEXT CHAIN ENTRY.
	AND (77777	/MASK OFF THE CODE BITS.
	JMP DEFLOOP
 
/ SUBROUTINE EXAMIN:
 
EXAMIN	0
 
	DAC TEMP1
	LAC* TEMP1
	JMP* EXAMIN
 
/ SUBROUTINE DACIDX:
 
DACIDX	0
 
	DAC* TEMP1
	IDX TEMP1
	JMP* DACIDX
 
	.EJECT
/ SUBROUTINE MOD13: TO THE ADDRESS PART OF THE RELOCATABLE INSTRUCTION
/ IN THE AC, ADD THE RELOCATION FACTOR (MODULO 13).
 
MOD13	0
 
	DAC TEMP1
	LAC RELOC
	AND (17777
	TAD TEMP1
	JMP* MOD13
 
/ SUBROUTINE TWOS:
 
TWOS	0
 
	CMA
	TAD PLUS1
	JMP* TWOS
 
/ SUBROUTINE BOUNDS:
 
BOUNDS	0
 
	DAC* (.SCOM+31	/SOFTWARE MEMORY PROTECT BOUND.
	TAD MINUS1
	DAC* (.SCOM+3	/UPPER LIMIT OF FOREGROUND FREE CORE.
	AND PLIT26	/(776000
	TAD PLIT19	/(2000
	DAC* (.SCOM+32	/HARDWARE MEMORY PROTECT BOUND.
	JMS TWOS
	TAD* (.SCOM	/HIGHEST LOCATION IN CORE.
	SPA
	JMP ERR100	/MEM. PROT. BOUND ABOVE CORE LIMIT.
	JMP* BOUNDS
 
	.EJECT
/ SUBROUTINE CORE: PREPARE INFORMATION ABOUT FREE CORE.
 
CORE	0
 
	DAC LOSYM		/LOWEST REGISTER AVAILABLE FOR
	AND (17777	/BUILDING THE SYMBOL TABLE.
	TAD (-20		/IF IT LIES WITHIN 0-17 OF ANY
	SMA		/BANK, SET IT TO XXX20 TO PREVENT
	JMP .+5		/LOADING EXECUTABLE CODE INTO
	LAW		/THE 1ST 20 REGISTERS.
	AND LOSYM
	TAD (20
	DAC LOSYM
	LAC LOSYM		/GET THE BANK BITS.
	RTL
	RTL
	RTL
	AND (3
	TAD PBANK0	/(BANK0
	DAC TEMP2
 
/ FOR EACH OF 4 CORE BANKS, SETUP A POINTER TO THE 1ST FREE REGISTER.
/ ZERO A POINTER TO INDICATE THE BANK IS USED UP.
 
	LAC LOSYM		/LOWEST FREE REGISTER GOES TO BANK POINTER.
	DAC* TEMP2
	LAC TEMP2
	SAD PBANK0	/(BANK0
	JMP* CORE
	TAD MINUS1
	DAC TEMP2		/ALL LOWER BANK POINTERS ARE ZEROED
	DZM* TEMP2	/TO INDICATE BANK USED UP.
	JMP .-5
 
/ SUBROUTINE ABSOFF: ABSOLUTE PROGRAMS MAY NO LONGER BE LOADED EITHER
/ BECAUSE A RELOCATABLE USER PROGRAM IS COMING IN OR BECAUSE LIBRARIES
/ ARE ABOUT TO BE OPENED.
 
ABSOFF	0
 
	LAC ABSFLG	/ABS MODE STILL ON?
	SNA
	JMP* ABSOFF	/NO. GO AWAY.
	JMS CORE		/SETUP FREE CORE POINTERS.
	DZM ABSFLG
	JMP* ABSOFF
 
	.EJECT
/ SUBROUTINE MEMMAP: PRINT PROGRAM NAME, GLOBAL SYMBOL, OR COMMON
/ BLOCK, AND THE DEFINITION IN THE MEMORY MAP.
 
MEMMAP	0
 
	DAC TEMP1		/STORE IDENTIFIER CHARACTER.
 
	CAL 775		/.WAIT FOR ANY PREVIOUS TYPEOUT TO FINISH.
	12
 
	LAC TEMP1
	DAC CHAR1
	LAC ADR15		/(SYMBOL SETUP POINTER FOR STORING
	DAC TEMP1		/IN THE WRITE BUFFER.
	LAC SYM1		/GET 1ST HALF OF SYMBOL.
	AND (377777	/MASK OFF THE CODE BIT.
	JMS CONVERT	/UNPACK RADIX 50, CONVERT TO ASCII,
			/AND STORE IN THE WRITE BUFFER.
	LAC SYM1		/BIT0=0 MEANS THERE'S NO SYM2.
	SPA!CLA		/IF SO, INSERT 3 SPACES.
	LAC SYM2
	JMS CONVERT
	IDX TEMP1		/SKIP OVER THE SPACE CHARACTER.
 
/ CONVERT THE LOAD ADDRESS TO OCTAL ASCII AND STORE IN WRITE BUFFER.
 
	LAW -5		/SETUP 5-DIGIT COUNT.
	DAC TEMP2
	LAC RELOC		/LOAD ADDRESS.
	RTL
	RTL
NXDGIT	RTL
	RAL
	DAC TEMP3		/SAVE REMAINDER.
	AND (7
	TAD (60		/CONVERT TO ASCII.
	DAC* TEMP1	/STORE DIGIT IN WRITE BUFFER.
	IDX TEMP1
	LAC TEMP3
	ISZ TEMP2
	JMP NXDGIT
 
/ WRITE LINE IN THE MEMORY MAP.
 
	CAL 3775		/.WRITE IMAGE ALPHA ON TTY.
	11
ADR16	MEMBUF
PLIT23	33
 
	JMP* MEMMAP
 
	.EJECT
/ MEMORY MAP LINE BUFFER (IMAGE ALPHA).
 
MEMBUF	11000
PLIT24	34
 
CHAR1	XX		/P, C, OR G.
	40
SYMBOL	.BLOCK 6		/PROGRAM, GLOBAL, OR COMMON BLOCK NAME.
SPACE	40
	.BLOCK 5		/5-DIGIT OCTAL LOAD ADDRESS.
PLIT14	15		/CAR. RET.
PLIT15	12		/LINE FEED.
 
/ SUBROUTINE CONVERT: UNPACK CHARACTERS FROM RADIX 50 WORD IN THE AC.
/ CHANGE TO ASCII AND STORE SEQUENTIALLY IN THE MEMORY MAP BUFFER.
 
CONVERT	0
 
	JMS DIVIDE
	-3100		/50 X 50 OCTAL.
	JMS DIVIDE
	-50
	JMS DIVIDE
	-1
	JMP* CONVERT
 
/ SUBROUTINE DIVIDE: DIVIDEND IN THE AC; DIVISOR (2'S COMPLEMENT)
/ FOLLOWS THE JMS DIVIDE. STORE QUOTIENT IN WRITE BUFFER.
 
DIVIDE	0
 
	DZM TEMP3		/THE QUOTIENT.
 
DIVLOOP	DAC TEMP2		/SAVE REMAINDER.
	TAD* DIVIDE	/SUBTRACT DIVISOR.
	SPA
	JMP .+3		/DONE.
	IDX TEMP3
	JMP DIVLOOP
 
	.EJECT
/ CONVERT RADIX 50 OCTAL TO ASCII.
 
	LAC TEMP3		/QUOTIENT=RADIX 50 CHARACTER.
	SNA		/SPACE?
	LAW -40
	SAD PLIT23	/(33 % ?
PLIT17	LAW -33
	SAD PLIT24	/(34 . ?
	LAC PLIT23	/(33
	SAD PLIT22	/(47 # ?
	LAW -35
	TAD PLIT17	/(-33
	SPA
	TAD PLIT1		/(55 : A - Z
	TAD (56		/0 - 9
	JMS DACIDX
	LAC TEMP2		/PICKUP REMAINDER.
	IDX DIVIDE
	JMP* DIVIDE
 
/ EXIT TO THE MONITOR WITH THE CODE FOR THE ERROR MESSAGE TO BE PRINTED.
 
ERR123	IDX ERRXIT	/"XCT" FILE NOT BUILT FOR THIS CONFIG.
ERR122	IDX ERRXIT	/"XCT" FILE OVERLAPS THE SYMBOL TABLE.
ERR121	IDX ERRXIT	/"XCT" FILE OVERLAPS THE MONITOR.
ERR120	IDX ERRXIT	/"XCT" FILE OVERLAYS EXECUTE.
	IDX ERRXIT
ERR116	IDX ERRXIT	/FGD CAN'T USE SYSTEM TAPE.
ERR115	IDX ERRXIT	/ABSOLUTE PROGRAM ERROR.
ERR114	IDX ERRXIT	/ILLEGAL HANDLER CODE.
ERR113	IDX ERRXIT	/SAME DEVICE - DIFFERENT HANDLERS.
ERR112	IDX ERRXIT	/.DAT CONTENTS = 0.
ERR111	IDX ERRXIT	/ILLEGAL .DAT #.
ERR110	IDX ERRXIT	/MISSING GLOBAL(S).
ERR107	IDX ERRXIT	/COMMON BLOCK SIZE ERROR.
ERR106	IDX ERRXIT	/ILLEGAL LOADER CODE.
ERR105	IDX ERRXIT	/PARITY, CHECKSUM, OR BUFFER OVERFLOW.
ERR104	IDX ERRXIT	/$FILES OVERFLOW.
ERR103	IDX ERRXIT	/.IOIN OVERFLOW.
ERR102	IDX ERRXIT	/.BFTAB OVERFLOW.
ERR101	IDX ERRXIT	/PROGRAM & SYMBOL TABLE OVERLAP.
 
ERR100	CAL 775		/.INIT -3 TO STOP .READ,
	1		/DISABLE ^P, AND PRINT
	0		/CAR. RET. LINE FEED.
	0
 
/ CAL 5XXX = FGD TERMINAL ERROR. CAL 6XXX = BGD TERMINAL ERROR.
 
ERRXIT	CAL 5100		/NO ROOM.
	16		/ERROR EXIT CODE.
 
	.EJECT
/ TELETYPE MESSAGES:
 
MSG1=.-2
	.ASCII /FGLOAD V1A/<15>
	.LOC .-1
MSG2=.-2
	.ASCII />/<175>
	.LOC .-1
MSG3=.-2
	.ASCII /^P/<175>
PLIT12=.-1		/(500000
 
/ COUNTS & DATA WORDS:
 
MAPFUNC	0		/MEMORY MAP FUNCTION BITS (15=COMMON,
			/16=GLOBAL AND 17=PROGRAM NAME).
BUFSIZ	0		/BUFFER SIZE.
SIZE	0		/2'S COMPLEMENT OF PROGRAM SIZE.
WRDCNT	0		/IOPS BINARY BLOCK WORD COUNT.
CDWCNT	0		/CODE WORD BLOCK COUNTER.
MUDCNT	0		/C(.MUD)=ENTRY COUNT (2'S COMP).
IOINCT	0		/C(.IOIN)=ENTRY COUNT.
IOCOUNT	0		/COUNT OF .IOIN ENTRIES MADE.
IOINWD	0		/C(.DAT SLOT) XOR'ED WITH C(.IOIN ENTRY).
IORQST	0		/C(.DAT SLOT).
CODEWD	0		/CODE WORD CONTAINS 3 LOADER CODES.
SYMDEF	0		/TEMP REGISTER FOR THE 1ST WORD OF A SYMTAB
			/ENTRY: CODE + DEFINITION.
SYM1	0		/1ST 3 CHARS OF A SYMBOL.
SYM2	0		/2ND 3 CHARS OF A SYMBOL.
BNKBTS=.			/EXTENSION BITS FOR THE BANK .SYSLD IS IN.
DATA1	0		/TEMP STORAGE FOR A DATA INITIALIZATION CONSTANT.
DATA2	0
DATA3	0
TEMP7	0
PLIT11	17
PIPSC3	0		/TEMP STORE OF .SCOM+3 FOR FGD PIP.
DATCNT	-4		/.IODEV BIT MAP IN "XCT" FILE HAS 4 WORDS,
DATNUM	-22		/STARTING WITH .DAT -18.
 
	.EJECT
/ DIRECTORIES:
 
EXECUT	.SIXBT /EXECUTBIN/
	.SIXBT /BFLOADBIN/
USRLIB	.SIXBT /.LIBR@BIN/
F4LIB	.SIXBT /.F4LIBBIN/
IOLIB	.SIXBT /.IOLIBBIN/
BIN=.-1
PIP	.SIXBT /PIP/
 
/ BANK-BIT INITIALIZED LITERALS (TRANSFER VECTORS):
 
ADR4	CNTL.P+200000	/WITH EX MEM BIT.
ADR5	USRLIB
ADR9	FIRST-1
ADR11	LINBF2
ADR12	CODTAB+31
ADR15	SYMBOL
 
	.EJECT
/ POINTERS:
 
DIRPTR	0		/TO BEG OF PROGRAM DIRECTORIES TABLE.
IOCPTR	0		/TO LOWEST IOC TABLE REGISTER -1.
SYMBEG	0		/TO BEG OF SYMBOL TABLE.
SYMEND	0		/TO LAST SYMTAB REGISTER - 1.
SYMWD1	0		/TO 1ST WORD OF A SYMTAB ENTRY.
SYMPTR	0		/TO SOMEWHERE WITHIN A SYMTAB ENTRY.
LOSYM	0		/TO LOWEST REGISTER SYMTAB CAN USE.
LOADADR	0		/PROGRAM'S LOAD ADDRESS.
LAST	0		/PROGRAM'S LAST REGISTER.
RELOC	0		/RELOCATION FACTOR.
BUFPTR	0		/TO LINE BUFFER #1 OR #2.
IOINPTR	.SCOM+13		/C(.SCOM+13)=.IOIN ; .IOIN STORED HERE.
IOINMAX	0		/TO .IOIN+1.
MUDPTR	.SCOM+14		/C(.SCOM+14)=.MUD ; POINTER TO .MUD STORED HERE.
.BFPTR	.SCOM+15		/C(.SCOM+15)=.BFTAB ; POINTER TO .BFTAB STORED HERE.
.BFMAX	0		/TO .BFTAB+1.
SLOT	0		/TO .DAT SLOT ADDRESS.
HANDLR	0		/TO .IOIN ENTRY WORD 2.
DAT	.SCOM+16		/INITIALLY TO .SCOM+16, WHICH POINTS AT .DATF.
			/THEN EITHER .DATF OR .DATB IS STORED HERE.
BANK0	20		/TO LOWEST FREE REGISTER FOR EACH OF 4
BANK1	20020		/POSSIBLE MEMORY BANKS.
BANK2	40020
BANK3	60020
BANKS	.		/(BANK0+4
PBANK0	BANK0		/USED AS A LITERAL.
FCTL.P	.SCOM+67		/POINTER TO FGD OR BGD CTL CHAR TABLE;
			/CHANGED TO POINT TO FGD OR BGD ^P REGISTER.
X.LOW	0		/LOWEST REGISTER OCCUPIED BY "XCT" FILE.
X.HIGH	0		/HIGHEST REGISTER OCCUPIED BY "XCT" FILE.
X10SHN	.SCOM+111		/FILE DIRECTORY ENTRY BLOCK FOR "XCT" FILE
			/IS IN .SCOM+107 THRU 111 FOR FGD AND IN
			/.SCOM+112 THRU 114 FOR BGD.
 
/ FLAGS:
 
LLIOFLG	0		/SET NON-0 WITH SIZE OF RESIDENT SYSTEM DEVICE BUFFER.
IOFLAG	0		/SET NON-0 WHEN LOADING HANDLERS OTHER THAN
			/THOSE FOR THE FOREGROUND LINK LOADER.
ABSFLG	0		/0 MEANS IT'S ILLEGAL TO LOAD AN ABSOLUTE
			/PROGRAM WITH THE FGD LINK LOADER. IF NON-0,
			/IT CONTAINS THE ADDRESS ABOVE THE HIGHEST
			/LOCATION LOADED BY ABSOLUTE PROGRAMS.
NUFILE	0		/SET NON-0 AFTER A .SEEK.
LIBFLG	0		/SET NON-0 WHEN IN LIBRARY SEARCH MODE.
BLKFLG	0		/SET NON-0 (WITH THE LOAD ADDRESS) WHEN
			/A BLOCKDATA SUBPROGRAM IS BEING LOADED.
COMFLG	0		/SET NON-0 WHEN DEFINING NON-BLOCKDATA COMMON
			/OR WHEN ASSIGNING I/O BUFFERS.
F4FLAG	0		/SET + AND NON-0 TO INDICATE GLOBAL SEARCH
			/IN .F4LIB IS NECESSARY.
XCTFLG	0		/SET NON-0 WHEN SEARCHING "XCT" FILE.
 
	.END .SYSLD
