	.TITLE	RLD3
	.IDENT	/hah003/
	.PSECT	CODE,RO
 
;
; VERSION 01
;
; TOM GETZINGER  26-OCT-80
;
; Modified:	07-Nov-83	hah002
;		Add support for library base additive RLD
;		07-Nov-83	hah003
;		Print numbers > 170000(8) as negative numbers
;
; THIS MODULE PROCESSES "RLD" RECORDS IN PASS 3
;
; LOCAL DATA
;
 
	.PSECT	RWDATA,RW,D
BYTMOD:	.BLKB	1		; SET IF BYTE MODIFICATION
CMD:	.BLKB	1		; CURRENT RELOCATION COMMAND
VAL:				; CURRENT RELOCATION VALUE
MODADR:	.BLKW	1		; CURRENT MODIFICATION ADDRESS
NAME:	.BLKW	2		; CURRENT RELOCATION NAME

	.even								;hah002
 
	.PSECT	RODATA,RO,D
CMDLEN:	.BYTE	0		; ILLEGAL
	.BYTE	10		; INTERNAL
	.BYTE	10		; GLOBAL
	.BYTE	10		; INTERNAL DISPLACED
	.BYTE	10		; GLOBAL DISPLACED
	.BYTE	17		; GLOBAL ADDITIVE
	.BYTE	17		; GLOBAL ADDITIVE DISPLACED
	.BYTE	0		; LOCATION COUNTER DEFINITION
	.BYTE	0		; LOCATION COUNTER MODIFICATION
	.BYTE	0		; .LIMIT
	.BYTE	10		; PSECT
	.BYTE	0		; ILLEGAL
	.BYTE	10		; PSECT DISPLACED
	.BYTE	10		; PSECT ADDITIVE
	.BYTE	10		; PSECT ADDITIVE DISPLACED
	.BYTE	0		; COMPLEX
	.byte	17		;Library base additive			;hah002

	.even								;hah002

	.PSECT	CODE
 
	.MCALL	PUT$S
 
RLD3::	MOV	R2,-(SP)	; SAVE R2
 
10$:	SUB	#2,R4		; ANY MORE RELOCATION ENTRIES?
	BMI	45$		; NO
	CLRB	BYTMOD		; ASSUME WORD MODIFICATION
	MOVB	(R3)+,CMD	; GET RELOCATION COMMAND
	BPL	20$		; OUR ASSUMPTION WAS CORRECT
	INCB	BYTMOD		; NO IT WASN'T, SO SET BYTE MOD FLAG
	BICB	#200,CMD	; CLEAR MODIFICATION FLAG
20$:	MOVB	(R3)+,R0	; GET DISPLACEMENT
	ADD	LSTADR,R0	; CONVERT TO ADDRESS
	MOV	R0,MODADR	; AND SAVE IT
	CMPB	CMD,#RT.LCD	; LOCATION COUNTER DEFINITION?
	BEQ	30$		; YES
	CMPB	CMD,#RT.LCM	; NO, LOCATION COUNTER MODIFICATION?
	BNE	50$		; NO
 
30$:	CALL	DASM3		; DISASSEMBLE ANY PREVIOUS TEXT
	CALL	DMPTXT		; DUMP REMAINING TEXT
	CMPB	CMD,#RT.LCD	; LOCATION COUNTER DEFINITION?
	BNE	40$		; NO
	MOV	#CRNPSC,R0
	CALL	GETR50		; GET CURRENT PSECT NAME
	CALL	PSCNUM		; GET CURRENT PSECT NUMBER
	CMP	R0,CRNPSN	; IS IT THE SAME AS THE OLD CURRENT?
	BEQ	40$		; YES, SO IT DIDN'T CHANGE
	MOV	CRNPSN,R1	; NO
	BMI	35$		; THERE IS NO CURRENT PSECT
	ASH	#3,R1
	ADD	PSCTBL,R1	; POINT INTO THE PSECT TABLE
	MOV	CRNADR,4(R1)	; SAVE OLD "CURRENT ADDRESS"
	CMP	CRNADR,6(R1)	; DID WE HIT THE MAX ADDRESS?
	BNE	35$		; NO
	CLR	6(R1)		; YES, SO CLEAR MAX ADDRESS
35$:	MOV	R0,CRNPSN	; SAVE NEW PSECT NUMBER
	ASH	#3,R0
	ADD	PSCTBL,R0	; POINT INTO THE PSECT TABLE
	MOV	4(R0),CRNADR	; SET NEW "CURRENT ADDRESS"
	MOV	F.NRBD+2+FDBOUT,R5 ; POINT TO OUTPUT BUFFER
	MOV	#PSECT,R0	; OUTPUT "	.PSECT	"
	CALL	APPEND
	MOV	#CRNPSC,R0	; FOLLOWED BY THE PSECT NAME
	CALL	ADDR50
	SUB	F.NRBD+2+FDBOUT,R5 ; CALCULATE RECORD LENGTH
	PUT$S	#FDBOUT,,R5	; OUTPUT THE RECORD
40$:	CALL	GETWRD		; GET CURRENT ADDRESS
	CMP	R0,CRNADR	; DID THE CURRENT ADDRESS CHANGE?
	BEQ	42$		; NO
	MOV	R0,R1		; YES, COPY ADDRESS
	SUB	CRNADR,R1	; CALCULATE DIFFERENCE
	MOV	R0,CRNADR	; SAVE NEW CURRENT ADDRESS
	MOV	F.NRBD+2+FDBOUT,R5 ; POINT TO OUTPUT BUFFER
	MOV	#.EQ.P,R0	; OUTPUT "	.=.+"
	cmp	#170000,r1	;Negative number?			;hah003
	bhi	41$		;Probably not				;hah003
	neg	r1		;Make it positive			;hah003
	mov	#.eq.m,r0	;Change message				;hah003
41$:									;hah003
	CALL	APPEND
	MOV	R1,R0
	CALL	ADDOCT		; FOLLOWED BY THE DIFFERENCE
	SUB	F.NRBD+2+FDBOUT,R5 ; CALCULATE THE RECORD LENGTH
	PUT$S	#FDBOUT,,R5	; OUTPUT THE RECORD
42$:	TST	R4		; ANY RLD ENTRIES LEFT?
	BNE	75$		; YES, SOMETHING'S WRONG
45$:	JMP	240$		; NO, SO WE'RE DONE
 
50$:	BIC	#1,R0		; CALCULATE WORD MOD ADDR
	MOV	#FRSTXT,R2	; GET FIRST LINK
 
60$:	MOV	(R2),R2		; LINK TO NEXT TEXT
	BEQ	75$		; THERE IS NONE
	CMP	T.ADDR(R2),MODADR ; DO THE ADDRESSES MATCH?
	BNE	70$		; NO
	CMPB	T.FLAG(R2),BYTMOD ; ARE THEY THE SAME LENGTH?
	BEQ	90$		; YES
	TST	BYTMOD		; NO, ARE WE MODIFYING A WORD?
	BEQ	75$		; YES, SO SOMETHING'S WRONG
	BR	80$		; NO, SO SPLIT THE TEXT WORD
 
70$:	CMP	R0,T.ADDR(R2)	; DO WORD ADDRESSES MATCH?
	BNE	60$		; NO, KEEP LOOKING
	TSTB	T.FLAG(R2)	; IS TEXT A WORD?
	BNE	60$		; NO, SO KEEP LOOKING
	TSTB	BYTMOD		; BYTE MODIFICATION?
	BNE	80$		; YES, SO SPLIT THE TEXT WORD
75$:	JMP	230$		; NO, SOMETHING'S WRONG
 
80$:	MOV	#FREEHD,R0	; ALLOCATE A MEMORY BLOCK
	MOV	#-T.LEN,R1	; FOR THE TEXT BYTE
	MOV	R2,-(SP)	; SAVE POINTER
	CALL	$RQCB		; ALLOCATE A TEXT BLOCK
	BCC	85$		; WE GOT IT OKAY
	TRAP	NOMEM		; "NO DYNAMIC MEMORY"
85$:	MOV	(SP)+,R2	; RESTORE POINTER
	CLR	T.STR(R0)	; THERE IS NO STRING
	MOV	T.NEXT(R2),T.NEXT(R0) ; LINK NEW TEXT IN
	MOV	R0,T.NEXT(R2)
	MOVB	#TF.BYT,T.FLAG(R2) ; CHANGE WORD TO BYTE
	MOV	#TF.BYT,T.FLAG(R0) ; AND MAKE NEW TEXT A BYTE
	MOVB	T.VAL+1(R2),T.VAL(R0) ; SET VALUE
	CLRB	T.VAL+1(R2)	; REMOVE UPPER BYTE FROM OLD TEXT
	CLRB	T.VAL+1(R0)	; AND ENSURE IT'S CLEARED ON NEW TEXT
	MOV	T.ADDR(R2),T.ADDR(R0) ; GET ADDRESS
	INC	T.ADDR(R0)
	BIT	#1,MODADR	; ARE WE POINTING TO THE RIGHT BYTE
	BEQ	90$		; YES
	MOV	(R2),R2		; NO, SO GO TO IT
 
90$:
;	BIT	#TF.REL!TF.LMT,T.FLAG(R2) ; HAS TXT BEEN RELOCATED?	;hah002
;	BIT	#TF.REL!TF.LMT!tf.lib,T.FLAG(R2) ; HAS TXT BEEN REL?	;hah002
;	BNE	230$		; YES, SO SOMETHING'S WRONG		;hah002
	beq	95$		;No, everyting is OK			;hah002
	jmp	230$		;Error, cannot relocate twice		;hah002
95$:									;hah002
	BIS	#TF.REL,T.FLAG(R2) ; NO, BUT IT IS NOW
	MOVB	CMD,R1		; GET RELOCATION COMMAND
;	CMP	R1,#RT.COM	; IS THE COMMAND TOO BIG?		;hah002
	CMP	R1,#RT.max	; IS THE COMMAND TOO BIG?		;hah002
	BHI	230$		; YES
	MOVB	CMDFLG(R1),R1	; GET THE FLAGS
	BIT	#CF.NAM,R1	; DOES CMD NEED A NAME?
	BEQ	100$		; NO
	MOV	#NAME,R0	; YES, SO GET IT
	CALL	GETR50
100$:	BIT	#CF.VAL,R1	; DOES CMD NEED A VALUE?
	BEQ	105$		; NO
	CALL	GETWRD		; YES, SO GET IT
	MOV	R0,VAL		; AND SAVE IT
105$:	BIT	#CF.DSP,R1	; IS THE TEXT DISPLACED?
	BEQ	110$		; NO
	BIS	#TF.DSP,T.FLAG(R2) ; YES, SO INDICATE IT
110$:	MOVB	CMD,R1		; GET CMD
	MOVB	CMDLEN(R1),R1	; GET THE COMMAND TEXT LENGTH
	BEQ	130$		; IT HAS NONE
	MOV	#FREEHD,R0	; POINT TO FREE MEMORY LISTHEAD
	MOV	R2,-(SP)	; SAVE TEXT POINTER
	CALL	$RQCB		; GET A STRING BLOCK
	BCC	120$
	TRAP	NOMEM		; WE RAN OUT OF MEMORY
120$:	MOV	(SP)+,R2	; RESTORE THE TEXT POINTER
	MOV	R0,T.STR(R2)	; SAVE THE TEXT POINTER
	MOV	R0,R5		; PUT IT INTO R5
	MOVB	R1,(R5)+	; STORE THE STRING LENGTH
130$:	MOVB	CMD,R1		; GET THE COMMAND
	CALL	SELECT		; GO PROCESS IT
;	.BYTE	RT.I,RT.COM						;hah002
	.BYTE	RT.I,RT.max						;hah002
	.WORD	230$		; ILLEGAL
	.WORD	150$		; INTERNAL
	.WORD	170$		; GLOBAL
	.WORD	190$		; INTERNAL DISPLACED
	.WORD	170$		; GLOBAL DISPLACED
	.WORD	180$		; GLOBAL ADDITIVE
	.WORD	180$		; GLOBAL ADDITIVE DISPLACED
	.WORD	230$		; LOCATION COUNTER DEFINITION
	.WORD	230$		; LOCATION COUNTER MODIFICATION
	.WORD	210$		; .LIMIT
	.WORD	135$		; PSECT
	.WORD	230$		; ILLEGAL
	.WORD	135$		; PSECT DISPLACED
	.WORD	140$		; PSECT ADDITIVE
	.WORD	140$		; PSECT ADDITIVE DISPLACED
	.WORD	220$		; COMPLEX
	.word	300$		;Library base additive			;hah002
 
135$:	CLR	VAL		; PSECT AND PSECT DISP HAVE NO VALUE
140$:	MOV	#NAME,R0	; GET THE PSECT NUMBER
	CALL	PSCNUM
	BR	160$		; AND GO ADD THE LABEL
150$:	MOV	CRNPSN,R0	; GET THE CURRENT PSECT NUMBER
160$:	MOV	VAL,R1		; GET THE OFFSET
	CALL	ADDSYM		; AND ADD THE SYMBOL
	BR	200$		; AND THAT'S IT
 
170$:	MOV	#NAME,R0	; ADD THE NAME
	CALL	ADDR50
	BR	200$		; AND THAT'S ALL
 
180$:	MOV	#NAME,R0	; ADD THE GLOBAL SYMBOL
	CALL	ADDR50
	MOVB	#'+,(R5)+	; FOLLOWED BY A PLUS
	cmp	#170000,val	;Negative number?			;hah003
	bhi	190$		;Probably not				;hah003
	neg	val		;Make it positive			;hah003
	movb	#'-,-1(r5)	;Put minus sign over plus sign		;hah003
 
190$:	MOV	VAL,R0		; ADD THE VALUE
	CALL	ADDOCT
 
200$:	CLRB	(R5)		; SET STRING END INDICATOR
	JMP	10$		; AND WE'RE DONE WITH THIS COMMAND
 
210$:	BIS	#TF.LMT,T.FLAG(R2) ; SET THE ".LIMIT" BIT
	BIC	#TF.REL,T.FLAG(R2) ; CLEAR THE "RELOCATED" FLAG
	MOV	(R2),R0		; GET ADDRESS OF NEXT TEXT WORD
	BEQ	230$		; THERE IS NONE
	MOV	(R0),(R2)	; REMOVE TEXT WORD FROM THE LINKED LIST
	MOV	R0,R2
	TST	T.FLAG(R2)	; IS THE TEXT A NORMAL WORD?
	BNE	230$		; NO, SO SOMETHING'S WRONG
	MOV	#FREEHD,R0
	MOV	#T.LEN,R1
	CALL	$RLCB		; RELEASE THE TEXT WORD
	JMP	10$		; AND WE'RE DONE WITH THIS COMMAND
 
220$:	CALL	DCOM		; DISASSEMBLE A COMPLEX RELOCATION
	JMP	10$		; AND WE'RE DONE
 
230$:	TRAP	OBJFMT		; OBJECT FORMAT ERROR
 
240$:	CLC			; CLEAR ERROR FLAG
 
250$:	MOV	(SP)+,R2	; RESTORE R2
	RETURN			; AND WE'RE DONE

300$:									;hah002
	bis	#tf.lib,t.flag(r2) ;Say we have a libr. base		;hah002
	bic	#tf.rel,t.flag(r2) ;This is not a normal rel. record	;hah002
	mov	#base,r0	;Start of library base message		;hah002
	call	append		;Store it				;hah002
	mov	val,r0		;Get the offset				;hah002
	cmp	#170000,r0	;Negative number?			;hah003
	bhi	310$		;Probably not				;hah003
	neg	r0		;Make it positive			;hah003
	movb	#'-,(r5)+	;Store it				;hah003
	br	320$		;Continue				;hah003
310$:									;hah003
	movb	#'+,(r5)+	;Store it				;hah003
320$:									;hah003
	call	addoct		;Convert the offset to ASCII		;hah002
	jmp	10$		;Continue				;hah002
 
	.END
