PROCEDURE	<RNOERR - RUNOFF ERROR PROCESSING>,010101

;+
; ABSTRACT:	This module displays the RUNOFF error messages
;		for non-IAS systems. It contains one FDB which
;		is used to access LB:[1,2]RNOERR.MSG and
;		LB:[1,2]QIOSYM.MSG. If RUNOFF is unable to access
;		these message files, then an appropriate error
;		message is generated.
;
; WRITTEN: 05-MAY-80,-1.0.0-, HENRY R. TUMBLIN
;
; MODIFIED: 17-May-80,-1.1.0-, Henry R. Tumblin
;	Removed dependance on MO....
;
; Modified: 05-Dec-80, -1.1.1-, John D. Leonard
;	Globalized PLIST and fixed bug on reading error message when
;	record is even multilple of 8. (incorrect rounding after division).
; VERIFIED:
;-

	.SBTTL	MCALLS AND RUNOFF DEFINITIONS

	.MCALL	DIR$,SAVE,UNSAVE,WTSE$S,EXIT$S,OPNS$R
	.MCALL	FCSMC$,QIOW$,READ$,WRITE$,PRINT,WAIT$
	FCSMC$

	.GLOBL	ALLOC			; Memory allocator
	.GLOBL	APNDN			; current appendix number
	.GLOBL	CHPTN			; current chapter number
	.GLOBL	CMBF			; Command buffer
	.GLOBL	ERRFDB			; Error message FDB
	.GLOBL	LOBUF			; Line output buffer
	.GLOBL	QISFDB			; qiosym fdb
	.GLOBL	PAGCNT			; total page count
	.GLOBL	PAGENO			; current page number
	.GLOBL	RNOERR			; module entry point
	.GLOBL	RUNOFF			; Runoff restart point
	.GLOBL	$CBDMG			; Convert binary to decimal
	.GLOBL	$EDMSG			; Edit message
	.GLOBL	$NUMLW			; Number pages low flag


	.sbttl	Other messages

	PDATA	RNOERP

ER01:	.ASCIZ	"Error opening LB:[1,2]%X, FCS %D"

ER02:	.ASCIZ	"Error reading error message file, FCS %D"

ERS:	.ASCIZ	"Command reads as [.%VE]"

JST:	.ASCIZ	"Line contains '%VE'"

	.IF	NDF	V$$MS
	.IF	DF	R$$11M
SYSTM:	.ASCII	"RSX-11M"
SYSTMS=.-SYSTM
	.ENDC	; R$$11M

	.IF	DF	I$$AS
SYSTM:	.ASCII	"IAS"
SYSTMS=.-SYSTM
	.ENDC	; I$$AS

	.IF	DF	R$$STS
SYSTM:	.ASCII	"RSTS/E"
SYSTMS=.-SYSTM
	.ENDC	; R$$STS

	.IF	DF	R$$11D
SYSTM:	.ASCII	"RSX-11D"
SYSTMS=.-SYSTM
	.ENDC	; R$$11D
	.ENDC

	.IF	DF	V$$MS
SYSTM:	.ASCII	"VMS"
SYSTMS=.-SYSTM
	.ENDC	; V$$MS

	.EVEN

	.SBTTL	DATA AREA

	DATA	RNOERD

BLKNO:	.BLKW	2			; Block number in file to read

PLIST::	.BLKW	12.			; parameter list

PCANO:	.BLKB	14.			; chapter/appendix-page number

ERRBUF:	.BLKB	512.			; Error input buffer

LINBF:	.BLKB	132.			; Message output buffer

	.SBTTL	START MAINLINE

;	All error dispatch is accomplished via the trap
;	instruction. On entry, the trap code * 2 is
;	the first word on the stack. followed by the PS and PC
;
	CODE	RNOERR

RNOERR:	SAVE	R0,R1,R2		; save our registers
	MOV	6(SP),R2		; get trap code
	ASR	R2			; Get message number

	CMP	#EXIT,R2		; exit ?
	BNE	3$			; NE - skip exit code
	MOV	PAGCNT,PLIST		;
	INC	R2			; Increment message number.
	MOV	#ERRFDB,R0		; Point to file string.
	CALL	OUTMO			; send to mo....
	EXIT$S				; exit gracefully(always)

3$:	CMP	#TPAGES,R2		; page numbers ?
	BNE	4$			; NE - no
	MOV	PAGCNT,PLIST		;
	INC	R2			; Get message number
	MOV	#ERRFDB,R0		; point to rno error file
	CALL	OUTMO			; send to mo....
	JMP	RTNERR			; and return

4$:	CMP	#USRMSG,R2		; User message (.MSG )
	BNE	51$			; NE - no
	MOV	BF.LEN(R4),PLIST	; Get buffer length
	MOV	BF.ADR(R4),PLIST+2	; Get buffer address
	MOV	#ERRFDB,R0		; Point to file string
	INC	R2			; Bump up counter
	CALL	OUTMO			; Output the string
	JMP	RTNERR			; Return to caller

51$:	CMP	#VERSN,R2		; Identify ourselves ?
	BNE	5$			; NE - no
	MOV	#SYSTMS,PLIST		; Set string length
	MOV	#SYSTM,PLIST+2		; Point to string
	MOV	#ERRFDB,R0		; Point to error file
	INC	R2			; Output the string
	CALL	OUTMO			;  ...
	JMP	RTNERR			; Return to caller

	.SBTTL	PROCESS MESSAGE

5$:	BIT	#FCSERR,R2		; fcs error ?
	BNE	40$			; NE - yes, set up plist different

;	display the current page number

	MOV	#PCANO,R0		; point to buffer
	MOV	R0,PLIST		;   ...
	MOV	R0,PLIST+2		;   ...
	MOV	APNDN,R2		; get appendix #
	BEQ	10$			; EQ - then check chapter
	ADD	#100,R2			; convert to ascii character
	MOVB	R2,(R0)+		; move into position
	BR	20$			; go to common code

10$:	CLR	R1			; clear trash
	MOVB	CHPTN,R1		; get chapter -> R1
	BEQ	25$			; EQ - then just page #
	CLR	R2			; zero suppress
	CALL	$CBDMG			; get chapter #
20$:	MOVB	#'-,(R0)+		; insert a dash
25$:	MOV	PAGENO,R1		; get page #
	TSTEQ	$NUMLW,26$		; numbers on bottom of page ?
	INC	R1			; add one to it
26$:	CLR	R2			; set zero suppress
	CALL	$CBDMG			; convert to decimal
	SUB	#PCANO,R0		; get length
	MOV	R0,PLIST		; set length
	BR	50$			; go to common code

40$:	MOV	14(SP),R0		; get fdb address
	CLR	R1			; for sign extend
	MOVB	F.ERR(R0),R1		; get error, sign extended
	MOV	R1,PLIST		; move into parameter list

50$:	MOV	6(SP),R2		; get trap code again
	ASR	R2			; get message number
	BIC	#FTLERR!FCSERR,R2	; clear any indicators

	INC	R2			; get message number
	MOV	#ERRFDB,R0		; point to rno error file
	CALL	OUTMO			; send to mo....

	BIT	#FCSERR*2,6(SP)		; fcs error ?
	BEQ	60$			; EQ - no
	MOV	14(SP),R0		; Point to error FDB
	MOVB	F.ERR(R0),R2		; Get FCS error code.
	NEG	R2			; make error code positive
	TSTB	F.ERR+1(R0)		; fcs or dsw ?
	BEQ	55$			; EQ - then it's fcs
	ADD	#128.,R2		; set up for a dsw error
55$:	MOV	#QISFDB,R0		; Point to correct FDB
	CALL	OUTMO			; send to mo....
	CALL	CRLF			; Clear to next line

60$:	MOV	6(SP),R1		; get the trap code.
	ASR	R1			; shift back
	BIC	#FCSERR!FTLERR,R1	; clear error bits

;	Special processing -- Invalid command

	CLR	R2			; Indicate format string
	CMP	#ILCMM,R1		; Illegal command ?
	BNE	65$			; NE - no
	MOV	#ERS,R1			; Point to format string
	MOV	CMBF+BF.ADR,PLIST+2	; Point to error string
	MOV	CMBF+BF.LEN,PLIST	; Set up for
;	DEC	PLIST			; Minus the CR
	BR	70$			; Go to common code

;	Special processing -- Unable to justify line

65$:	CMP	R1,#JUSRM1		; Justify error ?
	BNE	RTNERR			; NE - then skip it
	MOV	#JST,R1			; Set format string
	MOV	LOBUF+BF.ADR,PLIST+2	; Point to error string
	MOV	LOBUF+BF.LEN,PLIST	; Set up for

;	Output the string to the user

70$:	CALL	OUTMO			; send to mo....
	MOV	CMBF+BF.ADR,CMBF+BF.PTR	; Reset command pointers

RTNERR:	UNSAVE	R0,R1,R2		; restore registers
	BIT	#FTLERR*2,(SP)		; fatal error ?
	BEQ	90$			; EQ - no
	JMP	RUNOFF			; and restart

90$:	BIT	#FCSERR*2,(SP)+		; fcs error ?
	BEQ	95$			; EQ - no, return
	MOV	2(SP),4(SP)		; pop stack
	MOV	(SP)+,(SP)		; for fcs argument
95$:	RTI				; return from trap


	.SBTTL	INTERR -- SEVERE ERROR HANDLER

INTERR:: DIAG	SEVERR			; Severe error

	BPT				; obtain a crash dump


	.SBTTL	OUTMO -- COMMON OUTPUT ROUTINE
;+
; OUTMO -- Output an error message for RUNOFF. This procedure
;	was designed for MO.... under IAS, but will work with
;	RSX-11M and RSTS by emulating the execution of MO....
;	with $EDMSG and FCS.
;
; On entry:
;
;	R0 = Address of FDB to use
;	R1 = Address of format string
;	R2 = record number in file to print, or 0 if R1 points to
;	     a format string.
;	
;	All registers are preserved
;
OUTMO:	SAVE	R0,R1,R2,R3,R4,R5	; Save registers
	TST	R2			; Is it a format string ?
	BEQ	40$			; EQ - yes, process format string
	OPNS$R	R0			; Open the error msessage file
	BCC	10$			; CC - then opened OK
	MOV	#PLIST,R1		; Point to the parameter list.
	MOV	F.FNB+N.FNAM(R0),(R1)+	; File name
	MOV	F.FNB+N.FNAM+2(R0),(R1)+ ; ...
	MOV	F.FNB+N.FNAM+4(R0),(R1)+ ; ...
	MOV	F.FNB+N.FTYP(R0),(R1)+	; File type
	MOV	F.FNB+N.FVER(R0),(R1)+	; File version
	MOVB	F.ERR(R0),R2		; Get error code.
	MOV	R2,(R1)+		; Put error code in argument block
	MOV	#ER01,R1		; Point to the error string.
	BR	40$			; And print the error code.
10$:	MOV	#ERRBUF,R1		; Get length of record to allocate
	MOV	R2,R3			; Get record # into R3
	.IF	DF	A$$RAP
	ADD	#7.,R3			; Round up
	.ENDC
	CLR	R2			; Clear upper 16 bits for division
	.IF	NDF	R$$EIS
	MOV	R3,R2			; Save in R3
	.REPT	3
	ASR	R2			; Divide by 8
	.ENDR
	BIC	#^C7,R3			; Clear off upper bits	
	.IFF
	DIV	#8.,R2			; Divide by 8
	.ENDC
	.IF	NDF	A$$RAP
	INC	R2			; Get block # to read
	.ENDC
	CLR	BLKNO			; Reset block to read
	MOV	R2,BLKNO+2		; And set up for read
	READ$	R0,R1,#512.,#BLKNO	; Read the block in
	BCC	20$			; CC - then read was successfull
	MOV	#ER02,R1		; Get the error message.
	MOVB	F.ERR(R0),R2		; Sign extend the error number.
	MOV	R2,PLIST		; Set into parameter list.
	CLOSE$	R0			; Close the opened file
	BR	40$			; And print it.

20$:	WAIT$	R0			; Wait for block
	CLOSE$	R0			; Close file
	.IF	NDF	A$$RAP
	DEC	R3			; One less for my calculations
	.ENDC
	.IF	NDF	R$$EIS
	.REPT	6
	ASL	R3			; Multiply by 64
	.ENDR
	.IFF
	MUL	#64.,R3			; Get offset into buffer
	.ENDC
	ADD	R3,R1			; Point to record in question
40$:	MOV	#LINBF,R0		; Point to output area
	MOV	#PLIST,R2		; Point to parameter list
	CALL	$EDMSG			; And process the error
	PRINT	#LINBF,R1,#40		; And output the error message
90$:	UNSAVE	R0,R1,R2,R3,R4,R5	; Restore registers

	RETURN				; And return

	.END
