	.TITLE	DISOP3
	.IDENT	/hah010/
	.PSECT	CODE,RO
 
;
; VERSION 01
;
; TOM GETZINGER  22-OCT-80
;
; Modified:	07-Nov-83	hah003
;		Print numbers > 170000(8) as negative numbers
; 		27-Jul-85	hah010
;		Convert SELECT subroutine to support DOB as a I&D space task.
;
;
; THIS ROUTINE DISASSEMBLES AN OPERAND
;
; INPUTS:
;	R4 POINTS TO THE CURRENT TEXT ENTRY
;	R5 POINTS TO THE OUTPUT AREA
;	R1 IS THE OPERAND TYPE
;
; OUTPUTS:
;	IF THERE IS NOT ENOUGH TEXT FOR THE OPERAND:
;		CARRY IS SET
;		R4 -> FIRST TEXT ENTRY
;	IF THE OPERAND IS NOT LEGAL:
;		OVERFLOW IS SET
;		R4 -> FIRST TEXT ENTRY
;	OTHERWISE
;		THE OPERAND IS APPENDED TO THE OUTPUT BUFFER
;
;
; MACROs								;hah010
;									;hah010
	.macro	select	table						;hah010
	mov	r0,-(sp)	;Save R0 (restored by SELECT)		;hah010
	mov	table,	r0						;hah010
	call	select							;hah010
	.endm								;hah010

;
; LOCAL DATA
;
 
	.NLIST	BEX
	.PSECT	RODATA,RO,D
REGSTR:	.ASCII	"R0R1R2R3R4R5SPPC"

	.even								;hah010
table:
									;hah010
	.BYTE	1,11.							;hah010
	.WORD	done		; ILLEGAL				;hah010
	.WORD	addrss		; ADDRESS MODE				;hah010
	.WORD	add100		; ADDRESS MODE*100			;hah010
	.WORD	reg100		; REG*100				;hah010
	.WORD	brnch		; BRANCH				;hah010
	.WORD	mrk		; MARK					;hah010
	.WORD	regs		; REG					;hah010
	.WORD	subone		; SOB					;hah010
	.WORD	ac100		; AC*100				;hah010
	.WORD	fppadd		; FPP ADDRESS MODE			;hah010
	.WORD	setpri		; SPL					;hah010
	.WORD	trp		; TRAP					;hah010

	.PSECT	CODE
	.enabl	lsb

DISOP3::
	MOV	FRSTXT,R0	; R0 -> FIRST TEXT ENTRY
	MOV	T.VAL(R0),R2	; R2 = INSTRUCTION
	select	#table							;hah010
 
fppadd:	MOV	R2,R1		; GET THE REGISTER
	BIC	#^C7,R1		; CLEAR GARBAGE
	ASH	#-3,R2		; GET THE MODE
	BIC	#^C7,R2		; CLEAR GARBAGE
	BNE	40$		; IT ISN'T REG MODE
	CMP	R1,#3		; IS IT A LEGAL FP REG?
	BLE	40$		; YES
15$:	MOV	FRSTXT,R4	; NO, THE OPERAND IS NOT LEGAL
	SEV			; INDICATE THAT
	RETURN			; AND WE'RE DONE
 
add100:	ASH	#-6,R2		; SHIFT ADDRESS MODE DOWN
addrss:	MOV	R2,R1		; GET THE REGISTER
	BIC	#^C7,R1		; CLEAR GARBAGE
	ASH	#-3,R2		; GET THE MODE
	BIC	#^C7,R2		; CLEAR GARBAGE
40$:	BIT	#1,R2		; DEFERRED MODE?
	BEQ	50$		; NO
	CMP	R2,#1		; REGISTER DEFERRED?
	BEQ	50$		; YES
	MOVB	#'@,(R5)+	; NO, SO START WITH AN '@'
	DEC	R2		; CLEAR DEFERRED BIT
50$:	CMP	R1,#7		; IS THE REGISTER PC?
	BNE	90$		; NO
	BIT	#2,R2		; IMMEDIATE OR RELATIVE MODE?
	BEQ	90$		; NO
	MOV	(R4),R0		; POINT TO NEXT TEXT ENTRY
	BEQ	95$		; WE RAN OUT OF TEXT
	BIT	#TF.BYT!TF.LMT,T.FLAG(R0) ; IS THIS A WORD?
	BNE	55$		; NO, SO IT'S NO GOOD
	MOV	R0,R4		; YES, SO SKIP TO IT
	MOV	INSTLN,R3	; GET THE INSTRUCTION LENGTH
	ADD	#2,INSTLN	; THE INSTRUCTION IS NOW A WORD LONGER
	BIT	#4,R2		; IMMEDIATE?
	BNE	70$		; NO
	MOVB	#'#,(R5)+	; YES, SO OUTPUT A '#'
	BIT	#TF.REL,T.FLAG(R4) ; IS THE TEXT RELOCATED?
	BEQ	60$		; NO
	CLR	INST(R3)	; YES, USE A VALUE OF ZERO FOR THE INSTRUCTION
	MOV	T.STR(R4),R0	; ADD THE STRING
	CALL	ADDSTR
	BR	85$		; AND WE'RE DONE
55$:	BIT	#4,R2		; RELATIVE MODE?
	BNE	15$		; YES, SO THE OPERAND IS NOT LEGAL
	BR	125$		; NO, SO IT'S OKAY
 
60$:	MOV	T.VAL(R4),R0	; NO, SO GET THE VALUE
	MOV	R0,INST(R3)	; PUT IT IN THE INSTRUCTION BUFFER
	cmp	#170000,r0	;Negative number?			;hah003
	bhi	65$		;Probably not				;hah003
	neg	r0		;Get absolute value			;hah003
	movb	#'-,(r5)+	;Put in a minus sign			;hah003
65$:									;hah003
	CALL	ADDOCT		; OUTPUT IT IN OCTAL
	BR	85$		; AND WE'RE DONE
 
70$:
	BIT	#TF.REL,T.FLAG(R4) ; IS THE TEXT RELOCATED?
	BEQ	80$		; NO
	CLR	INST(R3)	; YES, USE A VALUE OF ZERO
	MOV	T.STR(R4),R0	; ADD THE STRING
	CALL	ADDSTR
	BIT	#TF.DSP,T.FLAG(R4) ; IS THE OPERAND DISPLACED?
	BNE	85$		; YES
	MOV	#PPCP,R0	; NO, SO ADD '(PC)'
	CALL	APPEND
	BR	85$		; AND WE'RE DONE
 
80$:	MOV	T.VAL(R4),R1	; ADDRESS REFERENCED = VALUE
	MOV	R1,INST(R3)
	ADD	T.ADDR(R4),R1	;			+ CURRENT ADDRESS
	ADD	#2,R1		;			+ 2
	MOV	CRNPSN,R0
	CALL	ADDSYM		; ADD THE SYMBOL
85$:	JMP	done		; AND WE'RE DONE
 
90$:	CMP	R2,#6		; INDEXED MODE?
	BNE	110$		; NO
	MOV	(R4),R4		; YES, POINT TO NEXT TEXT ENTRY
	BEQ	95$		; WE RAN OUT OF TEXT
	BIT	#TF.BYT!TF.LMT,T.FLAG(R4) ; IS THIS A WORD?
	BNE	15$		; NO, SO IT'S NO GOOD
	MOV	INSTLN,R3	; GET THE INSTRUCTION LENGTH
	ADD	#2,INSTLN	; INCREMENT IT BY TWO
	BIT	#TF.REL,T.FLAG(R4) ; YES, IS THE TEXT RELOCATED?
	BEQ	100$		; NO
	CLR	INST(R3)	; YES, USE A VALUE OF ZERO
	MOV	T.STR(R4),R0	; ADD THE STRING
	CALL	ADDSTR
	BR	110$
 
95$:	MOV	FRSTXT,R4	; BACKUP TEXT POINTER TO START
	SEC			; SET ERROR FLAG
	BR	280$		; AND RETURN
 
100$:	MOV	T.VAL(R4),R0	; NO, SO GET THE VALUE
	MOV	R0,INST(R3)	; ADD TO THE INSTRUCTION VALUE TABLE
	cmp	#170000,r0	;Negative number?			;hah003
	bhi	105$		;Probably not				;hah003
	neg	r0		;Make it positive			;hah003
	movb	#'-,(r5)+	;Say it is negative			;hah003
105$:									;hah003
	CALL	ADDOCT		; OUTPUT IT IN OCTAL
 
110$:	CMP	R2,#4		; REGISTER DECREMENTAL?
	BNE	120$		; NO
	MOVB	#'-,(R5)+	; YES, SO ADD A '-'
120$:	TST	R2		; REGISTER MODE?
	BEQ	130$		; YES
125$:	MOVB	#'(,(R5)+	; NO, SO ADD A '('

130$:	ASL	R1
	ADD	#REGSTR,R1
	MOVB	(R1)+,(R5)+	; ADD THE REGISTER NAME
	MOVB	(R1)+,(R5)+
	TST	R2		; REGISTER MODE?
	BEQ	140$		; YES
	MOVB	#'),(R5)+	; NO, SO ADD A ')'
140$:	CMP	R2,#2		; REGISTER INCREMENTAL?
	BNE	done		; NO, SO WE'RE DONE
	MOVB	#'+,(R5)+	; YES, SO ADD A '+'
	BR	done		; AND THEN WE'RE DONE
 
brnch:	MOVB	R2,R1		; SIGN EXTEND BRANCH DISPLACEMENT
	BR	170$
subone:	BIC	#^C77,R2	; CLEAR GARBAGE
	NEG	R2		; COMPLEMENT SOB DISPLACEMENT
	MOV	R2,R1
170$:	INC	R1		; OFFSET IS FROM WORD AFTER THE BRANCH
	ASL	R1		; CONVERT TO BYTE OFFSET
	ADD	T.ADDR(R4),R1	; CONVERT TO ADDRESS
	MOV	CRNPSN,R0
	CALL	ADDSYM		; ADD THE SYMBOL
	BR	done		; AND WE'RE DONE
 
ac100:	ASH	#-6,R2		; SHIFT REGISTER DOWN
	BIC	#^C3,R2		; CLEAR GARBAGE
	BR	210$
reg100:	ASH	#-6,R2		; SHIFT REGISTER DOWN
regs:	BIC	#^C7,R2		; CLEAR GARBAGE
210$:	ASL	R2
	ADD	#REGSTR,R2
	MOVB	(R2)+,(R5)+	; ADD THE REGISTER NAME
	MOVB	(R2)+,(R5)+
	BR	done		; AND WE'RE DONE
 
trp:	BIC	#^C377,R2	; CLEAR GARBAGE
	BR	250$
mrk:	BIC	#^C77,R2	; CLEAR GARBAGE
	BR	250$
setpri:	BIC	#^C7,R2		; CLEAR GARBAGE
250$:	MOV	R2,R0
	CALL	ADDOCT		; ADD OCTAL OPERAND
	BR	done
 
done:	.WORD	CLC!CLV		; CLEAR ERROR FLAGS
280$:	RETURN			; AND WE'RE DONE
 
	.END
