	.title	traps	Operating system trap handling routine
	.ident	"V02.00"
;+
; Index		Operating system trap handling routine
;
; Description
;
;	This module contains code which is executed after a synchronous
;	trap is detected by the operating system.  All such traps are
;	regarded as fatal errors and the program will exit with "severe
;	error" status.
;
;	The following traps are processed:
;
;		Illegal memory reference (trap through vector 4)
;		Illegal instruction (trap through vector 10)
;		BPT (assuming a debugging aid is not present)
;		IOT
;		Illegal TRAP (this may be a Fortran error)
;		Illegal EMT
;		Floating point exception
;		Memory management violation
;
;	Before exiting to the operating system, the contents of
;	the registers prior to the trap along with a stack dump
;	will be written, in octal, to the terminal.
;
;	Note that some errors, such as stack overflow or random jumps
;	into the operating system, may cause the C program to be
;	terminated without the C library regaining control.
;
;	The SVTK$ executive service is called at initialization time.
;
; Bugs
;
;	The code may loop if a trap occurrs within the trap handler.
;-
; Edit history:
; V02.00 19-Oct-82 TTC		Rework of CS library
;

	.psect	c$strn

line:
	.ascii	"%06o/%06o %06o %06o %06o %06o %06o %06o %06o"
	.byte	15,12,0

stkmsg:
	.byte	15,12
	.ascii	"Pre-trap stack dump:"
	.byte	15,12,0

$$regs:
	.byte	15,12,15,12
	.ascii	"Pre-trap register dump:"
	.byte	15,12
	.ascii	"R0 = %06o  R1 = %06o  R2 = %06o  R3 = %06o  R4 = %06o"
	.byte	15,12
	.asciz	"R5 = %06o  "
$$pcsp:
	.ascii	"SP = %06o  PC = %06o  PS = %06o"
	.byte	15,12,0

errfmt:	.asciz	<15><12>"%s - %s"<15><12>	; Format for error()
NXMmsg:	.asciz	"Odd or nonexistent address trap"
MMUmsg:	.asciz	"Memory protect violation"
BPTmsg:	.asciz	"BPT trap or C run-time library error"
IOTmsg:	.asciz	"Illegal IOT"
ILImsg:	.asciz	"Illegal Instruction"
TRPmsg:	.asciz	"TRAP trap or FORTRAN error signal"
EMTmsg:	.asciz	"Illegal EMT"
FPUmsg:	.asciz	"FPP/FIS exception"
	.even

	.psect	c$data
;
; SST trap table for RSX11-M
;
$$sstt::
	.word	NXMtrp
	.word	MMUtrp
	.word	BPTtrp
	.word	IOTtrp
	.word	ILItrp
	.word	EMTtrp
	.word	TRPtrp
	.word	FPUtrp

	.psect	c$code
;
; Set up for the particular trap. The PC is needed for the register
; dump but not thereafter.
;
NXMtrp:
	mov	#NXMmsg,-(sp)	; Message pointer
	clr	-(sp)		; Push number of trap dependent parameters
	br	traps

MMUtrp:
	mov	#MMUmsg,-(sp)	; Message pointer
	mov	#6,-(sp)	; Push number of trap dependent parameters
	br	traps

BPTtrp:
	mov	#BPTmsg,-(sp)	; Message pointer
	clr	-(sp)		; Push number of trap dependent parameters
	br	traps

IOTtrp:
	mov	#IOTmsg,-(sp)	; Message pointer
	clr	-(sp)		; Push number of trap dependent parameters
	br	traps

ILItrp:
	mov	#ILImsg,-(sp)	; Message pointer
	clr	-(sp)		; Push number of trap dependent parameters
	br	traps

TRPtrp:
	mov	#TRPmsg,-(sp)	; Message pointer
	mov	#2,-(sp)	; Push number of trap dependent parameters
	br	traps

EMTtrp:
	mov	#EMTmsg,-(sp)	; Message pointer
	mov	#2,-(sp)	; Push number of trap dependent parameters
	br	traps

FPUtrp:
	mov	#FPUmsg,-(sp)	; Message pointer
	clr	-(sp)		; Push number of trap dependent parameters
				; Fall through to traps

;
; Common trap handling completion. Register dump which shows the correct
; pre-trap PC and SP.
;
traps:
	mov	r5,-(sp)	; Stack 'em for output
	mov	r4,-(sp)
	mov	r3,-(sp)
	mov	r2,-(sp)
	mov	r1,-(sp)
	mov	r0,-(sp)
	mov	#$$regs,-(sp)	; Push message address
	call	printnf		; Print register dump
	add	#16,sp		; Cleanup the stack
	mov	(sp)+,r0	; r0 = number of trap dependent paramters
	mov	(sp)+,r4	; r4 --> error message
	add	r0,sp		; remove trap dependent parameters
	mov	sp,r0		; r0 = SP
	add	#4,r0		; r0 = pre-trap SP (current SP - PC and PS)
	mov	r0,-(sp)	; Push pre-trap SP value
	mov	#$$pcsp,-(sp)	; Push message address
	call	printnf		; Print pre-trap SP, PC and PS
	tst	(sp)+		; Pop message address
	mov	(sp)+,r2	; r2 = pre-trap SP value
	cmp	(sp)+,(sp)+	; Pop pre-trap PC and PS
;
; Do a stack dump.
; R2 = start of stack
;
	mov	#stkmsg,-(sp)	; Put message on stack
	call	ttosnf		; Print message
	mov	$$stnd,(sp)	; stack end value (initial sp)

	bic	#17,r2		; Round start down
	add	#17,(sp)	; Round end
	bic	#17,(sp)	; Up

10$:	cmp	r2,(sp)		; Far enough?
	bhi	40$		; If so, branch around
	add	#16,r2		; Get to last word for this line
	mov	#8.,r3		; Push 8 words from stack
20$:	mov	(r2),-(sp)
	dec	r3
	beq	30$
	sub	#2,r2
	br	20$
30$:	mov	r2,-(sp)	; Push the start address
	mov	#line,-(sp)	; Push line buffer
	call	printnf		; Output to terminal
	add	#24,sp		; Cleanup the stack
	add	#20,r2		; r2 --> after last word in last line
	br	10$

40$:	mov	r4,(sp)		; Replace stack end value on stack with err msg
	mov	#$$task,-(sp)	; Push task name for error message.
	mov	#errfmt,-(sp)	; Error message format goes on top.
	call	printf		; Print the error message
	bis	#4,$$exst	; Set severe error bit in exit status word
	jmp	$$exit		; Exit the task

	.end
