Google
 

Trailing-Edge - PDP-10 Archives - decus_20tap5_198111 - decus/20-0136/lnkx11.mac
There are 2 other files named lnkx11.mac in the archive. Click here to see a list.
;	V022		28-APR-72


;	PDP-11 LINKER, LINK-11 V005A
;	COPYRIGHT 1970,1971,1972 DIGITAL EQUIPMENT CORPORATION

	IFNDEF	NONREN,
<
	TWOSEG
	RELOC	400000
>

	IFNDEF	CCLSW,	<CCLSW==1>

	TITLE	LNKX11

	ENTRY	LINK

	EXTERNAL	CCLFLA

	EXTERNAL	SWTLEN,	SWTNAM,	SWTARG,	SIXM40
	INTERNAL	OBJDEV,	OBJNAM,	OBJEXT

	SPLEN=	100


;	DEFINE REGISTERS

	R0=0+5
	R1=1+5
	R2=2+5
	R3=3+5
	R4=4+5
	R5=5+5
	SP=6+5

	PDP=	17

	T0=	0
	T1=	1
	T2=	2
	T3=	3


;	SYMBOL TABLE PARAMETERS

	BPSYM=5			;# OF BYTES PER SYMBOL
	BASE=4			;DISTANCE TO BASE OF A SECTION
	FLAGS=2			;DISTANCE TO FLAGS OF AN ENTRY
	VALR=3			;DISTANCE TO RELOCATABLE VALUE OF AN ENTRY
	NAME2=2			;DISTANCE TO 2ND WORD ON AN ENTRY
	OBJMN=0			;OBJECT MODULE NAME
	SECTN=1			;SECTION NAME
	SYMN=4			;SYMBOL ENTRY
	ABSREL=40		;ABS/REL BIT (0/1)
	UNDEF=10		;UNDEFINED/DEFINED (0/1)
	INTGLB=100		;INTERNAL/GLOBAL (0/1)
	MONCND=1		;MONITOR ROUTINE CANDIDATE

	GSDBLK=	1
	GSDEND=	2
	ALODSZ=	320		;ABSOLUTE LOADER SIZE
	HGHMEM=	^D16384+100000		;HIGH MEMADR +1
	INBLN=	324

;	BLOCK TYPE COMMANDS

	GSDBLK=	1
	GSDEND=	2
	TXTBLK=	3
	RLDBLK=	4
	ISDBLK=	5
	MODEND=	6
	LIBBLK=	7
	LIBEND=	10

	PCMD1=	7
	PCMD2=	8

	LANG=	"<"
	RANG=	">"
	TAB=	11
	CRR=	15
	LF=	12


	EOF=	100
	OPDEF	FAIL	[CALLI 12]	;FATAL ERROR EXIT

	SYN	JRST,	BR
	SYN	JRST,	JMP
	SYN	EXP,	.WORD
	SYN	EXP,	.BYTE
	SYN	SETZM,	CLR
	SYN	SETZM,	CLRB
	SYN	AOS,	INC
	SYN	AOS,	INCB
	SYN	BLOCK,	.BLKB
	SYN	BLOCK,	.BLKW

	OPDEF	JSR	[PUSHJ PDP,]
	OPDEF	RTS	[POPJ PDP,]
	OPDEF	TST	[MOVE T0,]
	OPDEF	TSTB	[MOVE T0,]
	OPDEF	BNE	[JUMPN T0,]
	OPDEF	BEQ	[JUMPE T0,]

CPOPJ1:	AOS	(PDP)
CPOPJ:	RTS


OPDEF	.TYPE	[1B8]
OPDEF	.WRITE	[2B8]
OPDEF	.HEAD	[3B8]
OPDEF	.READ	[4B8]
OPDEF	.CSI	[5B8]
OPDEF	.SETP2	[6B8]
OPDEF	.WBIN	[7B8]
OPDEF	.CORE	[10B8]


	INTERNAL	JOBFF,JOBREL

	JOBREL=	44
	JOBFF=	121

	SYN	JOBFF,	USYME
	SYN	JOBREL,	ENDM
LINK:				;START OF PROG
	MOVSI	T1,-<EZCOR-BZCOR>
	SETZM	BZCOR(T1)	;CLEAR IMPURE CORE
	AOBJN	T1,.-1
	MOVE	SP,[IOWD SPLEN,SPBLK]	;SET STACK POINTER
	MOVE	T1,USYME	;SET BOTTOM
	MOVEM	T1,SYMB
	MOVEM	T1,SYME
	MOVEI	T1,HGHMEM-ALODSZ
	MOVEM	T1,TOPMEM

START2:
RESE05:


	PUSHJ	PDP,LINK84	;CALL PASS 1
	PUSHJ	PDP,ENDP00	;FINISH PASS 1

	.HEAD			;TYPE THE HEADER

	PMAP			;PRINT MAP

	AOS	PASS		;SET FOR PASS 2

	SETLST			;INIT BUFFER

	.SETP2			;SET I/O FOR PASS 2
	CLR	PTRG		;CLEAR POINTER
	PUSHJ	PDP,LINK84	;PROCESS PASS 2

DONE:				;FINI, OUTPUT STARTING ADDRESS
	MOVEI	T1,INBLN-6
	MOVEM	T1,INB
	MOVEI	T1,2
	MOVEM	T1,INB+1	;BYTE COUNT
	MOVE	T1,TRA
	MOVEM	T1,INB+2	;TRANSFER ADDRESS
	PUSHJ	PDP,DMPTXT	;OUTPUT THE TEXT

	POPJ	PDP,		;RETURN TO EXEC
LINK84:				;PROCESS FILE
	.CSI	R0		;GET THE NEXT COMMAND
	CLRB	CONCAT		;CLEAR CONCATENATION COUNT
	CLRB	UNDFLG		;  AND UNDEFINED'S LISTING FLAG
L84X1:	MOVNI	R1,SWTLEN
	HRLZS	R1		;SET INDEX FOR SWITCHES
	SKIPN	SWTNAM(R1)	;LOOK FOR A SWITCH
	AOBJN	R1,.-1
	JUMPG	R1,L84X2	;BRANCH IF END
	MOVEI	R0,PRESW	;SET FOR PRESWITCHES
	SWSR
	JRST	L84X1		;TRY FOR MORE

L84X2:	MOVE	R2,PASS
	SKIPE	OBJDEV		;SKIP IF NO FILE SPECIFIED
	JSR	@L84X2T(R2)	;CALL PROPER ROUTINE
	SKIPE	UNDFLG		;UNDEFINED'S REQUESTED?
	JSR	PUNDEF		;  YES, LIST THEM
	SKIPN	ENDFLG		;END OF INPUT FILES?
	JRST	LINK84		;  NO, DO NEXT
	SETZM	ENDFLG
	POPJ	PDP,		;YES, EXIT


L84X2T:	.WORD	GSD00		;PASS 1
	.WORD	PTXT00		;PASS 2
SWSR00:				;PROCESS SWITCH
	SAVREG			;SAVE REGISTERS
SWSR01:	SKIPN	T1,(R0)		;END?
	JRST	SWSR03		;  YES
	CAMN	T1,SWTNAM(R1)	;NO, MATCH?
	JRST	SWSR02		;  YES
	ADDI	R0,2		;NO, MOVE TO NEXT ENTRY
	JRST	SWSR01		;TRY AGAIN

SWSR02:	SETZM	SWTNAM(R1)	;FOUND, CLEAR ENTRY
	EXCH	R0,R1
	MOVEI	R0,SWTARG(R0)	;GET POINTER
	HRLI	R0,(POINT 6,)	;FORM SIXBIT POINTER
	PUSHJ	PDP,@1(R1)	;CALL ROUTINE
	CAIA
SWSR03:	S203			;SWITCH ERROR
	RESREG			;RESET REGISTERS
	RTS


PRESW:

	SIXBIT	/T/
	.WORD	LINK68

	SIXBIT	/B/
	.WORD	LINK67

	SIXBIT	/OD/
	.WORD	LINK65

	SIXBIT	/TR/
	.WORD	LINK69

	SIXBIT	/CC/
	.WORD	LINK14

	SIXBIT	/L/
	.WORD	CPOPJ		;DUMMY

	SIXBIT	/U/
	.WORD	LINK15

	SIXBIT	/E/
	.WORD	LINK12

	0
;TOP

LINK68:	SKIPN	PASS		;IF PASS 2
	SKIPE	TOPF		;  OR ALREADY SET,
	RTS			;  EXIT
	ONEVAL
	PUSHJ	PDP,OCTOBI	;CONVERT OCTAL
	AOS	TOPF
	MOVEM	R1,TOPMEM	;SET NEW TOP
	TRNE	R1,1		;ODD?
	S203			;  YES, ERROR
	RTS


;  BOTTOM

LINK67:	SKIPN	PASS		;IF PASS 2
	SKIPE	TOPF		;  OR TOP SET
	RTS			;  EXIT
	ONEVAL
	PUSHJ	PDP,OCTOBI	;CONVERT TO OCTAL
	AOS	BOTF		;SET FLAG AND
	MOVEM	R1,BOTMEM	;    VALUE
	TRNE	R1,1		;ODD?
	S203
	RTS


;	ODT
LINK65:	NOVAL
	AOS	ODTF		;SET FLAG
	SKIPN	PASS
	AOS	DDTF
	RTS
;	TRANSFER ADDRESS

LINK69:	SKIPE	PASS
	RTS			;EXIT IF PASS 2
	SKIPN	(R0)		;DOES IT HAVE A VALUE?
	JRST	LNK69C		;NO VALUE-
	MOVE	T1,R0
	ILDB	T1,T1
	CAIL	T1,"0"-40		;NUMERIC?
	CAILE	T1,"9"-40
	CAIA
	JRST	LNK69A		;  YES
	PUSHJ	PDP,RATOBI	;NO, SYMBOL,  CONVERT TO RAD50
	HLRZM	R1,TRABLK+2
	HRRZM	R1,TRABLK+3
	AOS	STRA
	AOS	TRAF
	RTS

;	NUMBER
LNK69A:	PUSHJ	PDP,OCTOBI	;DO OCTAL CONV
	MOVEM	R1,TRA
	TRNE	R1,1
	S203
	AOS	FTRA
	AOS	TRAF
	RTS

LNK69C:	AOS	UTRA
	RTS
;	/E-	END OF COMMANDS

LINK12:	NOVAL
	AOS	ENDFLG
	RTS

LINK14:	NOVAL
	AOS	CONCAT
	RTS

LINK15:	NOVAL
	SKIPN	PASS		;IGNORE IF PASS 2
	AOS	UNDFLG		;FLAG /U
	RTS
NOV00:				;TEST FOR NO VALUE
	SKIPE	(R0)
	S203
	RTS

ONEV00:				;TEST FOR ONE VALUE
	SKIPN	(R0)
	S203
	RTS

OCTOBI:				;OCTAL TO BINARY CONVERSION
	MOVEI	R1,0
OCTOB1:	ILDB	T1,R0		;GET CHARACTER
	JUMPE	T1,OCTOB2	;BRANCH IF NOT SIXBIT
	IMULI	R1,8
	ADDI	R1,-<"0"-40>(T1)
	TLNE	R0,770000	;OUT OF BYTE POINTER?
	JRST	OCTOB1		;  NO
OCTOB2:	RTS			;YES, EXIT


RATOBI:				;RADIX 50 PACK
	MOVE	T0,(R0)		;PLACE IN T0
	PUSHJ	PDP,SIXM40	;CONVERT
	MOVE	T1,T0
	RTS			;EXIT
ENDP00:	MOVE	R0,SYME		;GET BEGINNING OF UNDEFINES
	MOVEM	R0,SSYME	;SAVE FOR PMAP
ENDP1:	CAML	R0,USYME	;ANY UNDEFINES LEFT?
	JRST	ENDP5		;NO-GO SEE ABOUT MAP.

ENDP2:	LDB	T1,[POINT 8,FLAGS(R0),35]
	TRZ	T1,ABSREL	;NO-MAKE ABSOLUTE
	TRO	T1,UNDEF+INTGLB	;MAKE DEFINED AND GLOBAL.
	DPB	T1,[POINT 8,FLAGS(R0),35]
	MOVEI	T1,SYMN
	DPB	T1,[POINT 8,FLAGS(R0),35-8]	;MAKE IT A SYMBOL DEFINITION.
	CLR	VALR(R0)
	CLR	BASE(R0)
ENDP3:	ADDI	R0,BPSYM	;UPDATE R0 TO NEXT SYMBOL.
	BR	ENDP1


ENDP5:

ENDP6:	CLRB	SECTIM
;	INITIALIZE FOR PASS 2
	MOVE	T1,SYMB
	CAME	T1,SYME		;ANY SYMBOLS?
	JRST	ENDP7		;YES
	S206			;  NO, ERROR

ENDP7:	SETOM	TMP1		;SET ADDRESS REPEAT FLAG
	MOVE	T1,TOPMEM
	MOVEM	T1,CURPC	;GET TOP OF MEMORY INTO CURRENT

;	ASSIGN ADDRESSES, CALCULATE TOTAL SIZE, KEEP LOWEST ADDRESS LOADED.
ENDP8:	MOVE	R0,SYMB		;SET PTR TO FIRST MODULE NAME.
	MOVEM	R0,PTRG
	CLR	PRSIZE		;0 TO PROGRAM SIZE
	BR	ENDP11
ENDP10:	ADDI	R0,BPSYM	;MOVE TO NEXT ENTRY
ENDP11:	CAML	R0,SYME		;DONE?
	JRST	ENDP40		;YES-GET OUT
	LDB	R1,[POINT 8,FLAGS(R0),35-8]	;GET FLAG TO HIGH BYTE (ENTRY TYPE)
	LDB	R2,[POINT 8,FLAGS(R0),35]	;GET FLAG LOW BYTE
	CAIN	R1,OBJMN	;OBJ-MODULE NAME?
	JRST	ENDP10		;YES-IGNORE
	CAIN	R1,SYMN		;SYMBOL ENTRY?
	JRST	ENDP20		;YES-GO
	CAIN	R1,SECTN	;SECTION NAME?
	JRST	ENDP30		;YES-GO
	BR	ENDP10		;IGNORE ALL OTHER THINGS.


;	ENTRY POINT
ENDP20:	TRNN	R2,ABSREL	;ABS OR REL?
	JRST	ENDP21		;ABS
	MOVE	R3,PTSECT
	MOVE	T1,BASE(R3)	;GET SECTION BASE
	ADD	T1,VALR(R0)	;RELOCATE
	MOVEM	T1,BASE(R0)
	BR	ENDP10		;DO NEXT ENTRY

ENDP21:	MOVE	T1,VALR(R0)
	MOVEM	T1,BASE(R0)	;SET ABS VALUE
	BR	ENDP10

;	SECTION NAME

ENDP30:	TRNE	R2,ABSREL	;ABS OR REL?
	JRST	ENDP31		;GO IF REL
	CLR	BASE(R0)	;SET BASE AND
	CLR	VALR(R0)	;SIZE TO 0
	BR	ENDP33

ENDP31:	MOVE	R3,VALR(R0)	;GET SECTION SIZE
	TRZE	R3,1		;MAKE SIZE EVEN
	ADDI	R3,2
	ADDM	R3,PRSIZE	;SUM UP FOR TOTAL SIZE
	TSTB	TMP1		;IS THIS FIRST TIME?
	BNE	ENDP32		;FIRST
	MOVE	T1,CURPC
	MOVEM	T1,BASE(R0)	;SECOND--SET BASE
	ADDM	R3,CURPC	;ADJUST PC
	BR	ENDP33

ENDP32:	MOVN	T1,R3
	ADDB	T1,CURPC	;ADJUST PC BY SIZE.
	MOVEM	T1,BASE(R0)	;SET BASE OF SECTION TO NEW PC.
ENDP33:	MOVEM	R0,PTSECT	;SAVE PTR TO THIS SECTION.
	BR	ENDP10		;DO NEXT ONE.
ENDP40:


;	IF BOTTOM SET, CALCULATE NEW TOP AND 
;	ASSIGN ADDRESSES AGAIN.
	TSTB	BOTF
	BEQ	ENDP41		;NO BOTTOM.
	CLRB	BOTF
	MOVN	T1,CURPC
	ADD	T1,BOTMEM
				;CALCULATE NEW TOP AS
	ADDM	T1,TOPMEM	;  TOP-(CURRENT-BOTTOM)
ENDP41:	TSTB	TMP1		;DONE TWICE?
	BEQ	ENDP50		;YES
	CLRB	TMP1
	MOVE	T1,TOPMEM	;CALCULATE LOWADR
	SUB	T1,PRSIZE
	MOVEM	T1,LOWADR
	MOVEM	T1,CURPC
	JMP	ENDP8
;	FINALIZE THE TRANSFER ADDRESS

ENDP50:	MOVE	T1,TOPMEM
	CAML	T1,PRSIZE
	JRST	ENDP51
	AOS	BELOW0
ENDP51:	TSTB	TRAF		;IS THERE ONE?
	BNE	ENDP52		;YES
	MOVEI	T1,1
	MOVEM	T1,TRA		;ASSUME 1
	BR	ENDP60

ENDP52:	TSTB	FTRA		;WAS ONE FORCED?
	BNE	ENDP60		;YES-
	TSTB	STRA		;MUST WE SEARCH?
	BEQ	ENDP53		;NO-
	MOVEI	R0,1		;YES- SEARCH
	MOVEI	R4,TRABLK+2
	SRGLOB
	MOVEM	R0,R4
	MOVEM	R4,TRA
	BR	ENDP60

ENDP53:	MOVEI	R4,TRABLK
	SRMODN			;SEARCH FOR MODULE NAME
	 BR	ENDP54		;FOUND
	S216			;MODULE NAME MUST BE THERE.
ENDP54:	MOVEM	R4,PTRG		;SET PTRG TO CURRENT NAME.
	MOVEI	R4,TRABLK+2
	GETSEC			;SEARCH FOR SECTION NAME.
	S217			;MUST BE THERE.
	MOVE	T1,BASE(R4)
	ADDM	T1,TRA		;CALCULATE TRA
;  FINALIZE DDT TRA
ENDP60:
	TSTB	SDDTRA	;HAVE WE SEEN ONE?
	BEQ	ENDP62		;NO-
	MOVEI	R4,DDTTRA	;YES-FIX IT UP
	SRMODN
	 BR	ENDP61
	S216
ENDP61:	MOVEM	R4,PTRG
	MOVEI	R4,DDTTRA+2
	GETSEC
	 S217
	MOVE	T1,BASE(R4)
	ADDM	T1,TRADDT

ENDP62:	MOVE	T1,USYME
	CAME	T1,SYME		;ANY UNDEFINEDS LEFT?
	W322			;  YES
	JSR	SETBIN		;SET FOR BINARY OUTPUT
	HRL	T1,SYMB
	HRRI	T1,SYMSAV
	BLT	T1,SYMSAV+1	;MOVE NAME
	MOVEI	R2,0		;INIT INDEX
ENDP63:	SKIPN	R0,ENDP6T(R2)	;END?
	BR	ENDP64		;  YES
	MOVE	R0,(R0)		;NO, GET ACTUAL VALUE
	JSR	STOBIN
	AOJA	R2,ENDP63	;TRY FOR MORE

ENDP64:	JSR	DMPBIN		;DUMP THE BINARY
	RTS			;EXIT

ENDP6T:				;ADDRESS FOR INITIAL BLOCK
	.WORD	LOWADR,	[3401],	LOWADR,	PRSIZE,	TRA
	.WORD	TRADDT,	[0],	SYMSAV,	SYMSAV+1,	[2],	[0]
	0			;TERMINATOR
STOBIN:				;STORE BINARY WORD
	MOVE	T1,INB+1	;GET CURRENT BYTE COUNT
	CAIL	T1,INBLN-20	;ROOM TO STORE?
	JSR	DMPBIN		;  NO
	MOVEI	T1,2
	ADDM	T1,INB+1	;UPDATE COUNT
	IDPB	R0,R1		;STORE THE WORD
	RTS

DMPBIN:				;DUMP BINARY BUFFER
	JSR	DMPTXT
SETBIN:				;INIT BINARY BUFFER
	MOVEI	T1,INBLN-6
	MOVEM	T1,INB		;INIT BUFFER
	SETZM	INB+1		;CLEAR COUNT
	MOVE	R1,[POINT 36,INB+2]	;INIT INDEX
	RTS
;	GET GSD (GGSD)

;	READ GSD OFF A TAPE AND BUILDS A SYMBOL TABLE.


GSD00:				;PROCESS GSD (PASS 1)
	CLR	GSDFLG		;CLEAR ERROR FLAG
	JSR	GSD18		;CLEAR ALL OTHER FLAGS
	IOIG			;GET THE NEXT BLOCK
	 JRST	GSD18		;  EOF, QUIT
	CAIE	R2,LIBBLK	;LIBRARY?
	JRST	GSD02		;  NO
	IOIG			;YES, BYPASS BLOCK
	 S202			;  EOF
GSD01:	SYMOVF			;TEST CORE
	MOVE	T1,USYME
	CAMG	T1,SYME		;ANY UNDEFINEDS LEFT?
	JMP	GSD18		;  NO, EXIT
	ADDI	T1,BPSYM	;LEAVE GAP AFTER UNDEFINEDS
	MOVEM	T1,LSYMB	;START OF LIBRARY SYMS
	MOVEM	T1,LSYME	;END
	MOVEI	T1,1
	MOVEM	T1,LIBMOD	;SET LIBMOD PNZ
	MOVEM	T1,LIBF		;SET LIBRARY FLAG
GSD02:	CAIE	R2,GSDBLK	;GSD BLOCK?
	S213			;  NO, FATAL ERROR
	LDB	T1,[POINT 8,1+FLAGS(R1),35-8]
	CAIE	T1,OBJMN	;OBJECT MODULE NAME?
	S214			;  NO, ERROR
GSD03:	MOVE	R2,(R1)		;GET BLOCK TYPE
	ADDI	R1,1		;MOVE POINTER
	MOVNI	T1,2
	ADDM	T1,(R0)		;DECREMENT COUNT
	CAIN	R2,GSDEND	;GSD END?
	JRST	GSD10		;  YES
	CAIE	R2,GSDBLK	;GSD BLOCK?
	S213			;  NO, ERROR
GSD04:	MOVNI	T1,8
	ADDB	T1,(R0)		;DECREMENT BYTE COUNT
	JUMPGE	T1,GSD04A	;BRANCH IF NOT END
	IOIG			;END, GET NEXT BLOCK
	 S202			;  EOF, ERROR
	JRST	GSD03		;TEST TYPE

GSD04A:	MOVE	R4,R1		;MOVE POINTER TO WORK REGISTER
	ADDI	R1,4		;MOVE BASIC POINTER AHEAD
GSD05:	LDB	R2,[POINT 8,FLAGS(R4),35-8]
	CAILE	R2,GSDMAX	;TYPE IN RANGE?
GSD05A:	S220			;  NO
	SKIPLE	LIBMOD		;LIBRARY SEARCH?
	JRST	GSD07		;  YES, SPECIAL CASE
	JSR	@GSDTBL(R2)	;PROCESS BY TYPE
	SKIPE	GSDFLG		;ERROR?
	JRST	GSD18		;  YES, QUIT
	SKIPN	LIBMOD		;LIBRARY MODE?
	JRST	GSD04		;  NO, GET NEXT INPUT ENTRY
GSD06:	MOVE	R4,LSYMB	;YES, POINT TO CURRENT LIBRARY ENTRY
	MOVEI	T1,BPSYM
	ADDB	T1,LSYMB	;UPDATE CORE COPY
	CAMGE	R4,LSYME	;FINISHED?
	JRST	GSD05		;  NO, PROCESS IT
	JSR	GSD19		;YES, CLEAR FLAGS
	JRST	GSD04		;BACK TO MAIN STREAM

GSD07:	SYMOVF			;LIBRARY SEARCH, TEST CORE
	HRLI	T1,(R4)
	HRR	T1,LSYME	;POINTER FOR XFER
	MOVEI	T2,BPSYM
	ADDB	T2,LSYME	;UPDATE END POINTER
	BLT	T1,-1(T2)	;MOVE ENTRY TO STORAGE
	CAIE	R2,SYMN		;SYMBOL ENTRY?
	JRST	GSD04		;  NO, TRY AGAIN
	LDB	T1,[POINT 8,FLAGS(R4),35]
	TRNE	T1,UNDEF	;IF UNDEFINED,
	PTGLOB			;  ORNOT IN TABLE,
	 JRST	GSD04		;  TRY FOR MORE
	LDB	T1,[POINT 8,FLAGS(R4),35]
	TRNE	T1,UNDEF	;FOUND, REFERENCE TO DEFINED?
	JRST	GSD04		;  YES, IGNORE
	SETOM	LIBMOD		;MATCH, FLAG FOR INCORPORATION
	JRST	GSD06		;INSERT IN MAIN TABLE
GSD10:	JSR	GSD19		;END OF MODULE, CLEAR FLAGS
	SKIPN	LIBF		;LIBRARY MODE?
	JRST	GSD11		;  NO
	IOIG			;YES, GET NEXT BLOCK
	 S202			;  ERROR IF EOF
	CAIN	R2,GSDBLK	;MORE TO COME?
	JRST	GSD01		;  YES
	CAIE	R2,LIBEND	;NO, END OF LIBRARY?
	S270			;  NO, ERROR
GSD11:	SKIPE	CONCAT		;CONCATENATED FILE?
	IOIG			;  YES, MORE BLOCKS ON TAPE?
	 JRST	GSD18		;  NO, EXIT
	CAIE	R2,GSDBLK	;GSD BLOCK?
	JRST	GSD11		;  NO, IGNORE ALL ELSE
	SKIPN	LIBF		;YES, LIBRARY FILE?
	JRST	GSD02		;  NO
	JRST	GSD01		;  YES


GSD18:	CLR	LIBF		;END, CLEAR LIBRARY FLAG
GSD19:	CLR	LSYMB		;CLEAR OTHER CELLS
	CLR	LSYME
	CLR	LIBMOD
	RTS			;RETURN TO THE WORD
GSDTBL:	+GGSD06	;MODULE NAME
	+GGSD07	;SECTION NAME
	+CPOPJ	;ISD SIZE (IGNORE)
	+GGSD08	;TRA SPECIFICATION
	+GGSD09	;SYMBOL
	+GSD05A	;ERROR
	+GGSDID	;IDENT
GSDMAX=	.-GSDTBL-1

;	MODULE NAME

GGSD06:	MOVEM	R4,R2		;SAVE R4
	SRMODN			;CHECK IF MODULE NAME IS UNIQUE
	 BR	GGSD10		;ERROR IF NOT UNIQUE
	MOVEM	R2,R4
	MOVE	T1,SYME		;SET PTR TO MODULE NAME
	MOVEM	T1,PTRG
	INSYME			;INSERT AT SYME + UPDATE PTRS
	RTS			;DO NEXT ENTRY

GGSD10:	W300			;MODULE NAME NOT UNIQUE
	SETOM	GSDFLG		;MARK DUMMY END
	RTS


;	SECTION NAME

GGSD07:	MOVEM	R4,R2		;GIND THE GLOBAL + GET
	PTGLOB			;PTR (R4) TO IT.
	 BR	GGSD11		;NOT FOUND, GO INSERT IT.
	LDB	T1,[POINT 8,FLAGS(R4),35] ;IS IT DEFINED
	TRNE	T1,UNDEF
	JRST	GGSD12		;YES
	SQUISH			;NO - REMOVE THE UNDEFINED SYMBOL
	MOVNI	T1,BPSYM
	ADDM	T1,USYME
GGSD11:	MOVEM	R2,R4		;INSERT AT SYME AND UPDATE PTRS.
	MOVE	T1,SYME
	MOVEM	T1,PTRH
	INSYME
	RTS


GGSD12:	LDB	T1,[POINT 8,FLAGS(R4),35-8] ;IS IT A SECTION NAME?
	CAIE	T1,SECTN
	JRST	GGSD13		;NO - ERROR - MULT DEFINITION.
	MOVEM	R4,PTRH
	MOVE	T1,VALR(R2)	 ;WHICH SIZE IS BIGGEST
	CAMLE	T1,VALR(R4)
	MOVEM	T1,VALR(R4)	 ;GET BIGGEST SIZE.
	RTS			;GO DO NEXT ENTRY

GGSDID:				;IDENT
	MOVE	T1,0(R4)
	HRROM	T1,IDENT
	MOVE	T1,1(R4)
	MOVEM	T1,IDENT+1
	RTS
;	TRA SPECIFICATION

GGSD08:	TSTB	DDTF		;IS THIS THE DEBUG FILE?
	BEQ	GG8$1		;NO-
	AOS	SDDTRA
	MOVEI	R2,DDTTRA
	BR	GG8$4

GG8$1:	TSTB	UTRA		;SHOULD WE USE THIS ONE?
	BEQ	GG8$2
	CLRB	UTRA
	AOS	TRAF
	BR	GG8$3

GG8$2:	TSTB	TRAF		;IS THERE ONE ALREADY?
	BNE	CPOPJ		;YES, GET OUT
GG8$3:	MOVEI	R2,TRABLK
;	GET CURRENT OBJ MODULE NAME
GG8$4:	MOVE	R3,PTRG
	MOVE	T1,0(R3)
	MOVEM	T1,0(R2)
	MOVE	T1,1(R3)
	MOVEM	T1,1(R2)
;	GET TRA SPEC
	MOVE	T1,0(R4)	;SECTION NAME
	MOVEM	T1,2(R2)
	MOVE	T1,1(R4)
	MOVEM	T1,3(R2)
	MOVE	T1,3(R4)	;CONSTANT
	MOVEM	T1,4(R2)
	MOVE	T1,DDTF		;IS THIS THE DDT TRA?
	CLRB	DDTF
	TST	T1
	BNE	CPOPJ		;YES-DO NOT TEST FOR ODD VALUE
	MOVE	T0,4(R2)	;IS IT ODD?
	TRNN	T0,1
	AOS	TRAF		;NO - SET FLAG
	RTS
;	SYMBOL DEFINITION


GGSD09:	MOVEM	R4,R2		;SAVE R4
	LDB	T1,[POINT 8,FLAGS(R2),35] ;REF OR DEF?
	TRNN	T1,UNDEF
	JRST	GGSD15		;REF
	PTGLOB			;SEARCH FOR IT AND SET R4
	 BR	GGSD16		;NOT FOUND
	LDB	T1,[POINT 8,FLAGS(R4),35] ;FOUND, IS IT DEFINED
	TRNE	T1,UNDEF
	JRST	GGSD13		;YES - ERROR
	SQUISH
	MOVNI	T1,BPSYM
	ADDM	T1,USYME
GGSD16:	MOVEM	R2,R4
	INPTRH
	RTS

;	MULTIPLY DEFINED SYMBOL--BROADCAST IT

GGSD13:
	W302
	RTS

;	REFERENCE TO A GLOBAL

GGSD15:	PTGLOB
	 CAIA			;NOT THERE - INSERT IT.
	RTS			;IF THERE, IGNORE
	MOVEM	R2,R4
	INUSYM			;INSERT AS UNDEFINED SYMBOL
	RTS


IOIG00:
	MOVEI	T1,INBLN
	MOVEM	T1,INA
	MOVEI	R0,INA
	.READ	R0
	SKIPN	R0		;EOF?
	AOS	(PDP)		;  NO
	MOVEI	R0,INA+1
	MOVEI	R1,INA+2
	MOVE	R2,(R1)		;SET BLOCK TYPE
	RTS
PTXT00:				;PROCESS TEXT (PASS 2)
	SKIPE	PTRG		;FIRST TIME AROUND?
	JMP	PTXT10		;  YES
	MOVE	T1,SYMB		;YES, SET TO START OF SYMBOLS
	SUBI	T1,BPSYM	;BACK UP ONE SLOT
	MOVEM	T1,PTRG		;STORE POINTER
	JSR	ADVOMN		;ADVANCE TO FIRST OBJ MOD NAME
PTXT10:	MOVE	T1,PTRG
	CAMGE	T1,SYME		;IF PAST END,
	IOIG			;  OR NO MORE INPUT,
	 JMP	PTXT50		;  EXIT
	CAIE	R2,LIBBLK	;OK, LOOKING AT LIBRARY?
	JMP	PTXT20		;  NO
PTXT11:	IOIG			;YES, BYPASS GSD'S
	 S202			;SHOULDN'T HAPPEN!
	CAIE	R2,LIBEND	;END OF LIBRARY?
	JMP	PTXT11		;  NO, TRY FOR MORE
	IOIG			;YES, MOVE TO NEXT BLOCK
	 S202
	SETOM	LIBF		;MARK AS LIBRARY
PTXT20:	CAIE	R2,GSDBLK	;GSD BLOCK?
	S213			;  NO, ERROR
	LDB	T1,[POINT 8,3(R1),35-8]
	CAIE	T1,OBJMN	;FIRST ENTRY OBJ MOD NAME?
	S214			;  NO, ERROR
	MOVE	T1,PTRG		;YES, GET POINTER
	MOVE	T0,1(R1)	;TEST FOR MATCH
	CAME	T0,0(T1)
	JMP	PTXT21		;  NO
	MOVE	T0,2(R1)
	CAMN	T0,1(T1)	;YES, TRY SECOND
	JMP	PTXT30		;  YES, ALL SET
PTXT21:	SKIPN	LIBF		;NO MATCH, LIBRARY?
	S271			;  NO, ERROR
PTXT22:	IOIG			;YES, BYPASS
	 S202
	CAIE	R2,MODEND	;MODULE END?
	JMP	PTXT22		;  NO, KEEP MOVING!
	IOIG			;YES, READ NEXT BLOCK
	 JMP	PTXT50		;  EOF, EXIT
	JMP	PTXT20		;OK, TRY AGAIN FOR MATCH
PTXT30:	IOIG			;BYPASS GSD'S
	 S202
	CAIN	R2,GSDBLK
	JMP	PTXT30		;LOOP IF NOT END
	CAIE	R2,GSDEND	;GSD END?
	S272			;  NO, ERROR
	CLR	INB		;CLEAR TEXT OUTPUT BLOCK
PTXT31:	IOIG			;READ THE NEXT BLOCK
	 S202
	PUSH	PDP,R2		;SAVE A COPY
	CAIN	R2,RLDBLK	;RLD?
	PRLD			;  YES, PROCESS IT
	JSR	DMPTXT		;OUTPUT TEXT, IF ANY
	MOVE	R2,(PDP)
	CAIN	R2,TXTBLK	;TEXT BLOCK?
	JSR	MOVTXT		;  YES, MOVE INTO SPECIAL BUFFER
	POP	PDP,R2		;RESTORE R2
	CAIE	R2,MODEND	;MODULE END?
	JMP	PTXT31		;  NO, LOOP
	JSR	DMPTXT		;YES, MAKE SURE BUFFER IS EMPTY
	JSR	ADVOMN		;ADVANCE TO NEXT OBJECT MODULE
	SKIPN	LIBF		;MODULE END.  IF IN LIBRARY
	SKIPE	CONCAT		;  OR CONCATENATION,
	JMP	PTXT10		;  CONTINUE

PTXT50:	CLR	LIBF		;CLEAR LIBRARY FLAG
	RTS			;EXIT


ADVOMN:				;ADVANCE TO NEXT OBJECT MODULE NAME
	MOVE	T1,PTRG		;GET CURRENT POINTER
	ADDI	T1,BPSYM	;ADVANCE ONE ENTRY LENGTH
	CAML	T1,SYME		;TOO FAR?
	RTS			;  YES, EXIT
	MOVEM	T1,PTRG		;NO, SET NEW POINTER
	LDB	T2,[POINT 8,FLAGS(T1),35-8]
	CAIE	T2,OBJMN	;OBJECT MODULE NAME?
	JMP	ADVOMN		;  NO, TRY AGAIN
	RTS			;YES, EXIT
;	SUBROUTINE TO PROCESS RLD

;	INPUT --
;		R0 PTS TO RLD BC
;		R1 PTS TO BYTE FOLLOWING RLD BLK WORD
;		STACKED R0 AND R1 POINT TO PREVIOUS TXT BLOCK (IF ANY).

PRLD00:
	HRLI	R1,(POINT 8,,35) ;SET BYTE POINTER
PRLD01:	PUSHJ	PDP,ADVR1W	;MOVE PAST HEADER
PRLD02:	SKIPG	(R0)		;DONE WITH RLD?
	RTS			;YES

;	PROCESS NEXT COMMAND

	LDB	R2,R1		;GET COMMAND
	PUSHJ	PDP,ADVR1B
	LDB	R3,R1		;GET OFFSET
	PUSHJ	PDP,ADVR1B
	SUBI	R3,2		;COMPENSATE FOR HEADER
	MOVEM	R3,OFFSET	;SAVE IT
	PUSH	PDP,R4		;STACK REG
	LSHC	R3,-1		;DIVIDE BY TWO
	ADDI	R3,INB+2	;FORM POINTER
	HRLI	R3,(POINT 8,,35)
	SKIPGE	R4		;ODD?
	HRLI	R3,(POINT 8,,35-8)
	POP	PDP,R4		;RESTORE R4
	PUSH	SP,R2		;STACK COMD
	ANDI	R2,177		;SAVE LOW 7 BITS
	MOVE	R5,PTSECT
	CAIL	R2,CMDMAX
PRLD04:	S220
	JSR	@ PRLD09 (R2)	;GO EXECUTE PROPER HANDLER
	JRST	PRLD02

PRLD09:	EXP	PRLD04,	PRLD10,	PRLD20,	PRLD30,	PRLD40,	PRLD50,	PRLD60
	EXP	PRLD70, PRLD80,	PRLD90,	PRLD20,	PRLD04,	PRLD40,	PRLD50,	PRLD60
CMDMAX=	.-PRLD09
;	CMD #1 -- INTERNAL RELOC

PRLD10:	MOVE	R4,(R1)		;GET REL VALUE
	PUSHJ	PDP,ADVR1W
	ADD	R4,BASE(R5)	;RELOCATE IT
PRLD11:	TXTPUT
	RTS

;	CMD #2 -- GLOBAL RELOC

PRLD20:	MOVEM	R1,R4		;SET ADR OF NAME
	PUSHJ	PDP,ADVR1D
	SRGLOB			;SEARCH FOR GLOBAL NAME
	 S211		;ERROR
PRLD21:	TXTPUT
	RTS


;	CMD #3 -- INTERNAL DISPLACED RELOC

PRLD30:	GETPC			;GET PC AT CURRENT PLACE.
	MOVNS	R4
	ADD	R4,(R1)		;FORM (X - (.+2))
	PUSHJ	PDP,ADVR1W
	BR	PRLD11

;	CMD #4 -- GLOBAL DISPLACED RELOC

PRLD40:	GETPC			;GET PC NOW
	MOVEM	R4,TMP1
	MOVEM	R1,R4
	PUSHJ	PDP,ADVR1D
	SRGLOB			;GET GLOBAL VALUE
	 S211		;ERROR
PRLD41:	SUB	R4,TMP1		;FORM (X-(.+2))
	BR	PRLD21
;	CMD #5 -- GLOBAL ADDITIVE RELOC

PRLD50:	MOVEM	R1,R4
	SRGLOB			;GET GLOBAL VALUE
	 S211			;ERROR
	PUSHJ	PDP,ADVR1D
	ADD	R4,(R1)		;ADDITIVE CONSTANT
	PUSHJ	PDP,ADVR1W
	BR	PRLD21

;	CMD #6 -- GLOBAL ADDITIVE DISPLACED

PRLD60:	GETPC			;GET PC NOW
	MOVEM	R4,TMP1
	MOVEM	R1,R4
	PUSHJ	PDP,ADVR1D
	SRGLOB
	 S211		;ERROR
	ADD	R4,(R1)
	PUSHJ	PDP,ADVR1W
	BR	PRLD41

;	CMD #7 -- SET PC

PRLD70:	MOVEM	R1,R4
	PUSHJ	PDP,ADVR1D
	GETSEC			;GET SECTION POINTER
	 S215		;FATAL ERROR
	MOVEM	R4,PTSECT	;SET PTSECT
	MOVEM	R4,R5
	BR	PRLD80
;	CMD #8 -- PC MODIFICATION

PRLD80:	JSR	DMPTXT		;BE SURE TEXT BUFFER IS DUMPED
	MOVE	R4,BASE(R5)	;GET SECTION BASE VALUE
	ADD	R4,(R1)		;MODIFY
	PUSHJ	PDP,ADVR1W
	MOVEM	R4,CURPC
	PUSHJ	PDP,ADVR1W
	POP	SP,(SP)		;PRUNE STACK POINTER

;	PC COMMANDS MUST BE LAST IN RLD
	SKIPG	(R0)
	RTS
;	IF NOT DONE, NEXT COMMAND MUST ALSO BE PC TYPE
	MOVE	T1,(R1)
	CAIE	T1,PCMD1
	CAIN	T1,PCMD2
	RTS

;	ERROR --- CMD MUST BE PC TYPE.

	S212		;FATAL ERROR


;	CMD #9---SET PROGRAM LIMITS

PRLD90:	MOVE	R4,LOWADR	;SET LOW LIMIT
	PUSH	SP,(SP)		;GET TWO COPIES OF FLAG
	TXTPUT
	MOVE	R4,TOPMEM	;SET HIGH LIMIT
	TXTPUT
	RTS
ADVR1D:	PUSHJ	PDP,ADVR1W	;ADVANCE DOUBLE WORD
ADVR1W:	PUSHJ	PDP,ADVR1B	;ADVANCE ONE WORD
ADVR1B:				;ADVANCE ONE BYTE
	TLCE	R1,(POINT 0,,35-8)
	ADDI	R1,1		;MOVE TO NEXT WORD
	SOS	(R0)		;DECREMENT BYTE COUNT
	POPJ	PDP,
;	SUBROUTINE TXTPUT

;	PUT INFO INTO TXT BLOCK
;	THE RLD COMMAND IS STACKED

;		THIS ROUTINE REMOVES 1 WORD
;		FROM THE STACK,SP

TXTP00:	POP	SP,T1		;MOVE INDEX INTO T1
	TRNE	T1,000200	;BYTE OR WORD COMMAND
	JRST	TXTP01		;GO IF BYTE COMMAND.
	PUSHJ	PDP,TXTP03	;PUT IN FIRST BYTE
	LSH	R4,-8		;PREPARE FOR SECOND BYTE.
TXTP01:	PUSHJ	PDP,TXTP03	;PUT IN BYTE
	TRNE	R4,177400	;ERROR IF UNUSED PORTION
	TRNN	T1,000200
	CAIA
	W301			; BYTE RELOC ERROR!
	RTS			;RETURN

TXTP03:	DPB	R4,R3
	TLCE	R3,(POINT 0,,35-8)
	ADDI	R3,1
	POPJ	PDP,


;	SUBROUTINE GETPC
;	GET PC FOR CURRENT PLACE IN TXT BLOCK

GETP00:	MOVE	R4,CURPC	;GET PC AT ENTRY TO BLOCK
	ADD	R4,OFFSET	;ADD CURRENT PLACE.
	RTS
MOVTXT:
	MOVE	T1,[XWD INA+1,INB]
	BLT	T1,INB+<INBLN/2>-1
	MOVEI	T1,INBLN-6
	MOVEM	T1,INB
	MOVE	T1,INA+1
	SUBI	T1,2
	MOVEM	T1,INB+1
	MOVE	T1,CURPC
	MOVEM	T1,INB+2
	POPJ	PDP,


DMPTXT:
	SKIPN	INB		;ANY TEXT?
	RTS			;  NO
	MOVE	T1,INB+1
	SUBI	T1,2
	ADD	T1,INB+2
	MOVEM	T1,CURPC	;UPDATE PC
	.WBIN	INB
	SETZM	INB
	RTS
;	SUBROUTINE TO PRINT THE LOAD MAP (PMAP)

PMAP00:				;PRINT SYMBOL TABLE MAP
	SETLST			;INIT THE LISTING POINTER
	MOVEI	R0,PMAP86	;PRINT HEADER
	MOVSTR
	MAPTYP
	JSR	TTRAM		;PRINT TRANSFER BLURB
	SKIPA	R2,SYMB		;INIT BASIC POINTER AND SKIP
PMAP01:	ADDI	R2,BPSYM	;MOVE TO NEXT ENTRY
	CAML	R2,SYME		;END?
	JRST	PMAP10		;  YES, TEST FOR UNDEFINEDS
	LDB	R3,[POINT 8,FLAGS(R2),35-8]
	CAILE	R3,PMAX		;TYPE IN RANGE?
	S220			;  NO
	JSR	@PMAPJT(R3)	;YES, CALL THE PROPER ROUTINE
	JMP	PMAP01		;AGAIN

PUNDEF:				;ENTRY FOR /U
	SETLST
	MOVEI	T1,1		;SET FOR TTY OUTPUT
	CAIA
PMAP10:	MOVEI	T1,2		;SET FOR LISTING OUTPUT
	MOVEM	T1,LSTMOD
	SKIPA	R2,SYME		;TEST FOR UNDEFINEDS
PMAP11:	ADDI	R2,BPSYM	;MOVE TO NEXT ENTRY
	CAML	R2,USYME	;END?
	JMP	PMAP19		;  YES, EXIT
	CAME	R2,SYME		;FIRST TIME AROUND?
	JMP	PMAP12		;  NO
	MOVEI	R0,PMAP80	;YES, PRINT SOME STARS
	MOVSTR
	DMPLST
	MOVEI	R0,PMAP84	;  AND MESSAGE
	MOVSTR
	DMPLST
	DMPLST			;EXTRA CR/LF
PMAP12:	MOVE	R0,R2		;SET POINTER TO NAME
	UNPACK			;UNPACK
	DMPLST
	JMP	PMAP11		;TEST FOR MORE

PMAP19:	RTS			;EXIT
PMAPJT:				;PMAP JUMP TABLE
	.WORD	PMAPT0,	PMAPT1,	PMAPT2,	PMAPT3,	PMAPT4
PMAX=	.-PMAPJT-1		;BOUNDS CHECK

PMAPT0:				;OBJECT MODULE NAME
	MOVEI	R0,PMAP80	;PRINT STARS
	MOVSTR
	MAPTYP
	MOVEI	R0,[ASCIZ /MODULE	/]
	MOVSTR
	MOVE	R0,R2		;POINT TO NAME
	UNPACK
	MAPTYP
	MOVEI	R0,PMAP88	;SECOND LINE OF HEADER
	MOVSTR
	MAPTYP
	RTS

PMAPT1:				;PROG SECTION NAME
	MOVEI	R0,LANG		;"<"
	IDPB	R0,R1		;PLACE IN BUFFER
	MOVE	R0,R2		;POINT TO NAME
	UNPACK
	MOVEI	R0,RANG		;">"
	IDPB	R0,R1
	MOVEI	R0,TAB
	IDPB	R0,R1
	MOVE	R0,BASE(R2)	;SET BASE VALUE
	OTOA
	MOVEI	R0,TAB
	IDPB	R0,R1
	MOVE	R0,VALR(R2)	;GET SIZE
	OTOA
	MAPTYP			;PRINT THE LINE
	RTS

PMAPT2:				;ILLEGAL
PMAPT3:				;ILLEGAL
	S210

PMAPT4:				;ENTRY SYMBOL
	MOVEI	R0,TAB
	IDPB	R0,R1
	MOVE	R0,R2		;POINT TO SYMBOL
	UNPACK
	MOVEI	R0,TAB
	IDPB	R0,R1
	MOVE	R0,BASE(R2)	;GET VALUE
	OTOA
	MAPTYP
	RTS
TTRAM:				;PRINT TRANSFER MESSAGE
	SETLST			;INIT LISTING BUFFER
	DMPLST			;CR/LF
	SKIPN	IDENT
	JRST	TTRAM1
	MOVEI	R0,[ASCIZ /IDENT:  /]
	MOVSTR
	MOVEI	R0,IDENT
	UNPACK
	DMPLST
	DMPLST
TTRAM1:	MOVEI	R0,[ASCIZ /TRANSFER ADDRESS: /]
	MOVSTR
	MOVE	R0,TRA		;PRINT MSG--TRA,LOW ADR,ETC
	OTOA
	DMPLST
	MOVEI	R0,[ASCIZ /LOW LIMIT: /]
	MOVSTR
	MOVE	R0,LOWADR
	OTOA
	DMPLST
	MOVEI	R0,[ASCIZ /HIGH LIMIT: /]
	MOVSTR
	MOVE	R0,TOPMEM
	OTOA
	DMPLST
	RTS
;	OUTPUT BUFFERS FOR PMAP

PMAP80:
	ASCIZ	/**********/	;OUTPUT MESSAGE

PMAP84:	ASCIZ	/UNDEFINED REFERENCES/

PMAP86:
	ASCIZ	/LOAD MAP/

PMAP88:
	ASCIZ	/SECTION	ENTRY	ADDRESS	SIZE/


CRLF:
	BYTE	(7) CRR, LF, 0
TYPE00:				;TYPE MESSAGE
	MOVEI	T1,1		;FLAG OF 1
	CAIA
MAPT00:				;PRINT MESSAGE
	MOVEI	T1,2		;FLAG OF 2
	MOVEM	T1,LSTMOD	;SET LISTING MODE
DMPL00:				;DUMP LISTING BUFFER IN CURRENT MODE
	MOVEI	R0,0
	IDPB	R0,R1		;SET ASCIZ TERMINATOR
	MOVE	T1,LSTMOD
	TRNE	T1,1		;TYPE MODE?
	.TYPE	@LSTPNT		;  YES
	TRNE	T1,2		;LIST MODE?
	.WRITE	@LSTPNT		;  YES
				;FALL INTO INIT ROUTINE

SETL00:				;INIT LISTING BUFFER
	MOVE	R1,[POINT 7,LSTBUF]	;POINT R1 TO BUFFER
	MOVEM	R1,LSTPNT	;SAVE (CAN ADD DOUBLE BUFFERING)
	RTS			;EXIT


MOVS00:				;MOVE STRING INTO BUFFER
				;SOURCE IN R0, DEST IN R1
	TLOA	R0,(POINT 7,,)	;SET BYTE POINTER AND SKIP
	IDPB	T1,R1		;STORE CHARACTER
	ILDB	T1,R0		;FETCH THE NEXT
	JUMPN	T1,.-2		;LOOP IF NOT END
	RTS
;	SAVE	REGISTERS


SAVR00:	PUSH	SP,R5
	PUSH	SP,R4
	PUSH	SP,R3
	PUSH	SP,R2
	PUSH	SP,R1
	PUSH	SP,R0
	RTS

;	RESTORE REGISTERS


RESR00:	POP	SP,R0	;RESTORE THEM
	POP	SP,R1
	POP	SP,R2
	POP	SP,R3
	POP	SP,R4
	POP	SP,R5
	RTS			;EXIT
;SUBROUTINE OTOA (OCTAL TO ASCII CONVERSION)
;	ASSUMES	1)  NUMBER IN REGISTER ON ENTRY(R0)
;		2)  BUFFER STORAGE REQD. PTR SET (R1)
;		3)  STACK TOP RATHER THAN 3RD REG.
;	ON EXIT:    CONVERSION IN BUFFER, PTR AT NEXT BYTE
;		    NUMBER REGISTER CLEARED
;		    TOP OF STACK CLEAN

OTOA00:	MOVE	T1,[POINT 3,R0,17]	;SET BYTE POINTER
OTOA01:	ILDB	T2,T1		;GET NEXT CHAR
	ADDI	T2,"0"		;CONVERT TO ASCII
	IDPB	T2,R1		;STORE
	TLNE	T1,770000
	JRST	OTOA01		;MORE TO GO
	RTS			;... & EXIT
;	MOD40 UNPACK

;	INPUT:	R0=ADR OF MOD40 NUMBER (2 WORDS)
;		R1=ADR OF ASCII STRING (6 BYTES)

;	OUTPUT:	R1 POINTS ONE PAST LAST GENERATED CHARACTER


;	IF N IS THE MOD40 NUMBER, THEN
;		N=C1*50^2+C2*50+C3
;	THUS, N/50^2 IS C1 AND THE REMAINDER IS C2*50+C3
;	THE REMAINDER IS DIVIDED BY 50 TO GET C2 ETC.

UNPA00:	SAVREG
	HRLI	R0,-2		;MAJOR LOOP COUNT
UNPA07:	MOVSI	R5,-3		;MINOR LOOP COUNT
UNPA06:	HRRZ	T0,(R0)		;GET MOD40 WORD
	IDIV	T0,COEFF(R5)	;DIVIDE BY PROPER COEFFICIENTS
	IDIVI	T0,50		;ISOLATE CHAR IN T1

UNPA01:	JUMPE	T1,UNPA03	;"BLANK"
	CAIN	T1,33
	JRST	UNPA05		;"$"
	CAIL	T1,33
	JRST	UNPA04		;"." OR "0-9"
	ADDI	T1,40		;"A-Z"
UNPA03:	ADDI	T1,16
UNPA04:	ADDI	T1,11
UNPA05:	ADDI	T1,11
	IDPB	T1,R1		;STORE CHARACTER
	AOBJN	R5,UNPA06	;DONE 3 CHARS?
	AOBJN	R0,UNPA07	;TEST OUTER LOOP
;	DONE--PUT CURRENT R1 ONTO THE STACK
	MOVEM	R1,-1(SP)
	RESREG
	RTS

;	COEFFICIENT TABLE

COEFF:	^D1600			;40.^2
	^D40			;40.^1
	^D1			;40.^0
;	SYMOVF---SYMBOL TABLE OVERFLOW CHECK

SYMO00:	SKIPN	T1,LSYME
	MOVE	T1,USYME
	ADDI	T1,2*BPSYM
	CAMGE	T1,ENDM
	RTS
	.CORE
	 S223			;DIE!!
	RTS			;OK.


;	SRMODN---SEARCH FOR A MODULE NAME.

;	INPUT:	R4 POINTS TO MOD4O NAME
;	OUTPUT: R4 POINTS TO THE NAME IF FOUND

;	CALL:	SRMODN
;		BR		;FOUND
;		BR		;NOT FOUND

SRMO00:	SAVREG	
	MOVE	R0,SYMB		;GET POINTER TO START OF TABLE
SRMO01:	CAMGE	R0,SYME		;DONE
	JRST	SRMO02		;NO
	RESREG			;YES - NOT FOUND
	AOS	(PDP)		;ADJUST RETURN ADDRESS
	RTS			;EXIT

SRMO02:	LDB	T1,[POINT 8,FLAGS(R0),35-8] ;IS THIS AN OBJ MODULE NAME?
	CAIN	T1,OBJMN
	JRST	SRMO03		;YES - SEE IF NAME IS SAME
SRMO04:	ADDI	R0,BPSYM	;NO - TRY NEXT ONE
	BR	SRMO01

SRMO03:	MOVE	T1,(R4)
	CAME	T1,(R0)
	JRST	SRMO04		;NO - GO TO NEXT ENTRY
	MOVE	T2,1(R4)
	CAME	T2,1(R0)
	JRST	SRMO04
;	FOUND!!
	MOVEM	R0,-4(SP)	;PUT CURRENT R0 ONTO STACK
	RESREG
	RTS

;	PTGLOB---SEARCH FOR GLOBAL & RETURN A POINTER TO IT.

;	INPUT:  R4=POINTER TO NAME
;	OUTPUT:  R4=POINTER TO ENTRY IF FOUND.

;	CALL	PTGLOB

;		BR		;NOT FOUND
;		BR		;FOUND

PTGL00:	SAVREG
	SKIPN	(R4)		;IS THIS THE SPECIAL
				;CASE OF 6 BLANKS?
	JRST	PTGL01		;YES
	MOVE	R0,SYMB		;SET LIMITS FOR SEARCH
	BR	PTGL02

PTGL01:	MOVE	R0,PTRG		;START AT CURRENT OBJ MODULE IF 6 BLANKS
PTGL02:	CAMGE	R0,USYME	;DONE SEARCHING
	JRST	PTGL03		;NO-
	RESREG			;YES - EXIT
	RTS

PTGL03:	MOVE	T1,(R0)		;CHECK FIRST WORD
	CAME	T1,(R4)
	JRST	PTGL04		;NO MATCH.
	MOVE	T2,1(R0)
	CAME	T2,1(R4)
	JRST	PTGL04
;	MATCH---
	LDB	T1,[POINT 8,FLAGS(R0),35-8] ;FILTER OUT OBJ MODULE NAMES.
	CAIN	T1,OBJMN
	JRST	PTGL04
	MOVEM	R0,-4(SP)
	RESREG
	AOS	(PDP)
	RTS

;	NO MATCH--
PTGL04:	ADDI	R0,BPSYM	;ADVANCE R0 TO NEXT ENTRY
	BR	PTGL02		;TRY AGAIN.
;	GETSEC--GET POINTER TO SECTION NAME.

;	INPUT:  R4 PTS TO NAME.
;	OUTPUT:  R4 PTS TO PROPER ENTRY

;	CALL:	GETSEC
;		BR		;NOT FOUND

GETS00:	PTGLOB			;FIND GLOBAL NAME
GETS01:	 RTS			;NOT FOUND.
;	FOUND, INSURE THAT IT IS A SECTION NAME.
	LDB	T1,[POINT 8,FLAGS(R4),35-8]
	CAIE	T1,SECTN
	JRST	GETS01		;NOT A SECTION NAME
	AOS	(PDP)		;SECT NAME. ADJUST RETURN
	RTS



;	SRGLOB---SEARCH FOR GLOBAL AND RETURN VALUE IN R4

;	INPUT:  R4=ADR OF GLOBAL NAME
;	OUTPUT:  R4=VALUE

;	CALL	SRGLOB
;		BR		;NOT FOUND


SRGL00:	PTGLOB			;GET POINTER TO GLOBAL
	 RTS			;NOT FOUND
	MOVE	R4,BASE(R4)	;FETCH VALUE
	AOS	(PDP)
	RTS			;EXIT


;	INUSYM--INSERT AS UNDEFINED

;	INPUT:  R4=ADR OF WHAT TO INSERT INTO UNDEFINED AREA


INUS00:	SYMOVF
	PUSH	SP,R0		;STACK R0
	MOVE	R0,USYME
	HRLI	R0,-<BPSYM-1>	;MOVE IN THE UNDEFINED SYMBOL
	MOVE	T1,(R4)
	MOVEM	T1,(R0)
	ADDI	R4,1
	AOBJN	R0,.-3
	MOVEI	T1,BPSYM
	ADDM	T1,USYME
	POP	SP,R0
	RTS
;	INSYME

;	INSERT AN ENTRY AT SYME.  R4 POINTS TO THE ENTRY.
;	ADJUST POINTERS SYME AND USYME



INSY00:	SAVREG
	MOVEM	R4,R2
	MOVE	R4,SYME
INSY01:	UNSQUISH		;MAKE A HOLE AT SYME
	MOVEI	T1,BPSYM
	ADDM	T1,SYME
	ADDM	T1,USYME
	MOVSI	T1,(R2)		;MOVE IN THE SYMBOL
	HRRI	T1,(R4)
	BLT	T1,BPSYM-2(R4)
	RESREG
	RTS

;	INPTRH
;	INSERT AN ENTRY AT (PTRH)+BPSYM
;	INSERT THE ENTRY ALPHABETICALLY
;	R4 POINTS TO THE ENTRY
;	UPDATE POINTERS SYME,USYME

INPT00:	SAVREG
	MOVEM	R4,R2		;SET PTRS
	MOVE	R4,PTRH
INPT01:	ADDI	R4,BPSYM	;START LOOP LOOKING FOR END OF SECTION
				;OR AN ENTRY WHICH IS>THEN PRESENT 
				;ENTRY
	CAML	R4,SYME		;CHECK FOR END OF SYMBOLS
	JRST	INPT02
	LDB	T1,[POINT 8,FLAGS(R4),35-8]
	CAIE	T1,SYMN
	JRST	INPT02
	MOVE	T1,(R4)		;DOUBLE PREC COMP
	CAMLE	T1,(R2)
	JRST	INPT02
	CAME	T1,(R2)
	JRST	INPT01
	MOVE	T2,1(R4)
	CAME	T2,1(R0)
	JRST	INPT01
;	INSERT AT (R4)
INPT02:	MOVEI	T1,BPSYM
	CAMGE	R4,PTRG	;UPDATE PTRG IF INSERTING BELOW PTRG
	ADDM	T1,PTRG
	BR	INSY01		;GO INSERT AT R4
;	UNSQUISH---MAKE A HOLE IN TABLE

;	INPUT:  R4 POINTS WHERE TO MAKE HOLE.


UNSQ00:	SYMOVF
	SAVREG
	MOVE	R0,USYME	;SOURCE POINTER
UNSQ01:	CAML	R0,R4		;DONE?
	JRST	UNSQ02		;NO
	RESREG
	RTS
UNSQ02:	MOVE	T1,-1(R0)
	MOVEM	T1,BPSYM-1(R0)
	SOJA	R0,UNSQ01

;	SQUISH---REMOVE AN ENTRY FROM TABLE.

;	INPUT:  R4=ADR OF WHERE TO REMOVE ENTRY


SQUI00:	SAVREG
SQUI01:	CAMGE	R4,USYME	;DONE
	JRST	SQUI02		;NO--
	RESREG			;YES-EXIT
	RTS
SQUI02:	MOVE	T1,BPSYM(R4)
	MOVEM	T1,(R4)
	AOJA	R4,SQUI01
;	NON-FATAL ERRORS

	OPDEF	W300	[JSR .]
	SAVREG
	PUSH	SP,[0]
	PUSH	SP,[1300]
	IOT
	RESREG
	RTS

	OPDEF	W301	[JSR .]
	SAVREG
	GETPC
	SUBI	R4,2
	PUSH	SP,R4
	PUSH	SP,[1301]
	IOT
	RESREG
	RTS

	OPDEF	W302	[JSR .]
	SAVREG
	SETLST
	MOVE	R0,PTRG
	UNPACK
	MOVEI	R0,","
	IDPB	R0,R1
	MOVE	R0,R4
	UNPACK
	TYPE
	PUSH	SP,[0]
	PUSH	SP,[1302]
	IOT
	RESREG
	RTS

	OPDEF	W322	[JSR .]
	SAVREG
	PUSH	SP,[0]
	PUSH	SP,[1322]
	IOT
	RESREG
	RTS
;	MACRO TO GENERATE FATAL ERRORS

	DEFINE	GENERR	(NUMBER,VALUE,DEVNAM)
<
	OPDEF	S'NUMBER	[JSR .]
	PUSH	SP,[EXP VALUE]
	PUSH	SP,[EXP 2000+NUMBER]
	IOT
	IFNB	<DEVNAM>,
 <
	JSR	TYPEDV
 >
	FAIL
>


;	GENERATE FATAL ERRORS

	GENERR	202,EOF,1	;PREMATURE EOF

	GENERR	203,0,		;ILLEGAL SWITCH

	GENERR	206,0,		;NO INPUT FILES

	GENERR	210,0,1		;UNRECOGNIZED SYMBOL TABLE ENTRY

	GENERR	211,0,1		;RLD GLOBAL

	GENERR	212,0,1		;RLD PC

	GENERR	213,0,1		;OBJ MOD DOESN'T START WITH GSD

	GENERR	214,0,1		;FIRST GSD NOT MODULE NAME

	GENERR	215,0,1		;RLD IMAGINARY REFERENCE

	GENERR	216,0,		;TRS

	GENERR	217,0,		;TRA

	GENERR	220,0,		;JUMP OUT OF RANGE

	GENERR	223,0,		;SYMBOL TABLE OVERFLOW

	GENERR	270,0,1		;NO LIBRARY END BLOCK

	GENERR	271,0,1		;MODULES OUT OF ORDER

	GENERR	272,0,1		;GSD BLOCK NOT TERMINATED WITH GSDEND
IOT00:				;SIMULATED IOT
	SETLST			;SET LISTING BUFFER
	POP	SP,T0		;FETCH CODE
	LDB	T1,[POINT 2,T0,35-9]
	MOVE	R0,[EXP "A", "W", "S", "?" ](T1)
	IDPB	R0,R1		;STORE PROPER CHARACTER
	MOVE	T1,[POINT 3,T0,35-9]	;SET INDEX
IOT01:	ILDB	R0,T1		;FETCH NEXT OCTAL BYTE
	ADDI	R0,"0"		;MAKE NUMERIC
	IDPB	R0,R1		;STORE IN BUFFER
	TLNE	T1,770000	;FINISHED?
	BR	IOT01		;  NO
	MOVEI	R0,TAB		;YES, NOW A TAB
	IDPB	R0,R1
	POP	SP,R0		;GET VALUE
	OTOA			;CONVERT
	TYPE			;TYPE LINE
	RTS			;EXIT


TYPEDV:				;TYPE "DEV:FILNAM.EXT"
	SETLST
	MOVE	T0,OBJDEV
	JSR	TYPED1
	MOVEI	R0,":"
	IDPB	R0,R1
	MOVE	T0,OBJNAM
	JSR	TYPED1
	MOVEI	R0,"."
	IDPB	R0,R1
	MOVE	T0,OBJEXT
	JSR	TYPED1
	TYPE			;TYPE THE LINE
	RTS

TYPED1:	MOVSI	T1,(POINT 6,T0)	;SET BYTE POINTER
TYPED2:	ILDB	R0,T1		;GET CHAR
	JUMPE	R0,CPOPJ	;EXIT IF BLANK
	ADDI	R0,40		;CONVERT TO ASCII
	IDPB	R0,R1		;STORE
	BR	TYPED2
	DEFINE	GENTRP	(NAME,ADDR)
<
	OPDEF	NAME	[PUSHJ PDP,ADDR]
>

	GENTRP	UNPACK,UNPA00			;MOD40 UNPACK
;	GENTRP	PACK,PACK00			;MOD 40 PACK
	GENTRP	OTOA,OTOA00			;OCTAL TO ASCII CONVERRSION
	GENTRP	SAVREG,SAVR00			;SAVE REGISTERS
	GENTRP	RESREG,RESR00			;RESTORE REGISTERS
	GENTRP	TXTPUT,TXTP00			;PUT INTO TXT BLOCK
	GENTRP	GETPC,GETP00			;GET CURRENT PC VALUE
	GENTRP	TYPE,TYPE00			;TYPE A BUFFER ON TTY
;	GENTRP	ACCEPT,ACCE00			;READ FROM KBD
	GENTRP	SQUISH,SQUI00			;REMOVE WORDS FROM TABLE
	GENTRP	UNSQUISH,UNSQ00			;MAKE A HOLE IN TABLE
	GENTRP	PMAP,PMAP00			;PRINT LOAD MAP
	GENTRP	MOVSTR,MOVS00		;MOVE STRING INTO BUFFER
	GENTRP	MAPTYP,MAPT00		;TYPE ON MAP DEVICE
	GENTRP	DMPLST,DMPL00		;DUMP LISTING BUFFER
	GENTRP	SETLST,SETL00		;SET LISTING BUFFER
;	GENTRP	IOII,IOII00			;OBJ MODULE INPUT INIT.
	GENTRP	IOIG,IOIG00			;OBJ MODULE INPUT GET
;	GENTRP	IOIC,IOIC00			;OBJ MODULE INPUT CLOSE AND RELEASE
;	GENTRP	IOOI,IOOI00			;LOAD MODULE OUTPUT INIT
;	GENTRP	IOOP,IOOP00			;LOAD MODULE OUTPUT PUT.
	GENTRP	GGSD,GSD00			;GET GSD
;	GENTRP	GNGSD,GNGS00			;GET NON-GSD BLOCK.
	GENTRP	PRLD,PRLD00			;PROCESS RLD
	GENTRP	SRGLOB,SRGL00			;GET VALUE OF GLOBAL
	GENTRP	PTGLOB,PTGL00			;GET PTR TO GLOBAL
	GENTRP	INSYME,INSY00			;INSERT AT SYME
	GENTRP	SRMODN,SRMO00			;SEARCH FOR MODULE NAME
	GENTRP	INUSYM,INUS00			;INSERT UNDEFINED SYMBOL
	GENTRP	SYMOVF,SYMO00			;CHECK FOR SYMBOL OVERFLOW (FATAL)
	GENTRP	GETSEC,GETS00			;GET SECTION NAME POINTER
	GENTRP	IOT,IOT00		;IOT SIMULATION
	GENTRP	SWSR,SWSR00		;SWITCH SEARCH
	GENTRP	INPTRH,INPT00	;INSERT AT PTRH
;	GENTRP	DIRSR,DIRS00		;DIRECTORY SEARCH
;	GENTRP	MOVTAB,MOVT00
	GENTRP	NOVAL,NOV00
	GENTRP	ONEVAL,ONEV00
;	GENTRP	ERCODE,ERCO00
;	GENTRP	READER,READ00
;	DATA AREA

	IFNDEF	NONREN,	<RELOC 0>

BZCOR:				;START OF CORE TO BE ZAPPED

PTRH:	.BLKW	1		;POINTER TO CURRENT SECTION
SYMB:	.BLKW	1		;SYMBOLS BEGINNING
SYME:	.BLKW	1		;SYMBOLS END
;USYME:	.BLKW	1		;SYMBOLS END OF UNDEFINES
SSYME:	.BLKW	1		;SAVED SYME FOR PMAP
PASS:	.BLKB	1		;PASS FLAG
MAPF:	.BLKB	1		;MAP LIST FLAG
				;MAP DEVICE CODE
CONCAT:	.BLKB	1		;CONCATENATION FLAG
PTRG:	.BLKW	1		;PTR TO MODULE NAME
CURPC:	.BLKW	1		;CURRENT PC
PRSIZE:	.BLKW	1		;PROGRAM SIZE IN BYTES
PTSECT:	.BLKW	1		;PTR TO CURRENT SECTION LEADER
LOWADR:	.BLKW	1		;LOWEST ADDRESS LOADED.

OFFSET:	.BLKW	1		;OFFSET FOR RLD TXT COMMAND.
TMP1:	.BLKW	1
				;LOAD MODULE DEVICE
IDENT:	.BLKW	2		;IDENT
TRAF:	.BLKB	1		;TRA FLAG (0=NONE SEEN YET)
TOPMEM:	.BLKW	1		;TOP OF MEMORY
BOTMEM:	.BLKW	1		;BOTTOM OF MEMOTY
TOPF:	.BLKB	1		;TOP SPECIFIED FLAG
BOTF:	.BLKB	1		;BOTTOM FLAG
DDTF:	.BLKB	1		;D SWITCH
SDDTRA:	.BLKB	1		;DDT TRA SEEN FLAG
UTRA:	.BLKB	1		;USE THIS FILE FOR TRA
FTRA:	.BLKB	1		;FORCED TRA
STRA:	.BLKB	1		;SYMBOLIC TRA
MONLIB:	.BLKB	1		;MON LIB SEARCH FLAG
SECTIM:	.BLKB	1		;CHANGE "   " TO ".  "
LIBF:	.BLKB	1		;LIBRARY FLAG
BELOW0:	.BLKB	1		;PROGRAM TO BE LINKED BELOW 0
ODTF:	.BLKB	1		;TRY TO OPEN ODT FILE
MONTOP:	.BLKW	1		;TOP OF MONITOR
INA:
	BLOCK	<INBLN>/2+INA-.

INB:
	BLOCK	<INBLN>/2+INB-.
LSTMOD:	BLOCK	1		;LISTING MODE (1-TTY/2-LPT)
LSTPNT:	BLOCK	1		;START OF CURRENT LISTING BUFFER
LSTBUF:	BLOCK	^D72/5+2	;LISTING BUFFER
SYMSAV:	BLOCK	2		;TEMP STORAGE
UNDFLG:	BLOCK	1		;/U FLAG

TRABLK:	BLOCK	^D10/2		;SAVE AREA FOR XFER ADDRESS
TRA=	.-1

DDTTRA:	BLOCK	^D10/2
TRADDT=	.-1
SPBLK:	BLOCK	SPLEN		;SP BUFFER
ENDFLG:	BLOCK	1		;/E SEEN
GSDFLG:	BLOCK	1		;ERROR FLAG FOR GSD
LIBMOD:	BLOCK	1		;LIBRARY MODE:
				;+1  ENTERING VALUES IN LSYMB
				;-1  TAKING VALUES OUT OF LSYMB
LSYMB:	BLOCK	1		;START OF LIBRARY STORAGE
LSYME:	BLOCK	1		;END OF LIBRARY STORAGE
OBJDEV:	BLOCK	1		;DEVICE NAME
OBJNAM:	BLOCK	1		;FILE    "
OBJEXT:	BLOCK	1		;EXTENSION

EZCOR:

	IFNDEF	NONREN,	<RELOC>


	END