;
; sigast.mac defines the routine(s) that catch signals.
;
; These routines are put in as AST servers and determine what AST called
; them. They then call the appropriate routine, telling it which signal.
;
; Assuming the signal number is in which, the C code would look like:
;
;	if (~(which & 1))
;	    (*$$sigs[which])(which);
;
; The int and quit signals are both assumed to by CTRL/C, and undo the
; implied CTRL/O.
;
;****************************************************************
;*								*
;*			W A R N I N G ! ! !			*
;*								*
;* The way we tell which interupt we're catching, is with a	*
;* bunch of entry points pointed into a series of INC WHICHs.	*
;* Ghu help you if you should be interupted during the INCs,	*
;* or before which is saved into R1! In general, don't get	*
;* interupted during an interupt handler. You were warned.	*
;*								*
;****************************************************************
.RCTRLO = 104355	; RT11 Cancel CTRL-O
.TTRST	= 104026	; RSTS Cancel CTRL-O

	.psect	.data.
which:	.word	0
	.psect	.prog.

	inc	which	; 16
	inc	which	; SIG_TERM
	inc	which	; SIG_ALRM
	inc	which	; SIG_PIPE
	inc	which	; SIG_SYS
	inc	which	; SIG_SEGV
	inc	which	; SIG_BUS
	inc	which	; SIG_KILL
	inc	which	; SIG_FPE
	inc	which	; SIG_EMT
	inc	which	; SIG_IOT
	inc	which	; SIG_TRAP
	inc	which	; SIG_ILL
	inc	which	; SIG_QUIT
	inc	which	; SIG_INT
	inc	which	; SIG_HUP
$$sig0:
	mov	r0, -(sp)	; Save R0
	mov	r1, -(sp)	;  and R1
	mov	which, r1	; Get the signal number
	clr	which		;  and make sure the next one works
				;
				; Breath a sigh of relief here - we've
				; closed the interupt window.
				;

	cmp	#2, r1		; If signal is quit or interupt
	bgt	get.sig		;  we want to undo any CTRL/Os
	cmp	#3, r1
	blt	get.sig
	jsr	pc, no.ctrlo
get.sig:
	mov	r1, -(sp)	; Signal number is the argument
	asl	r1		; Use it as a word index
	mov	$$sigs(r1), r1	;  into the signal table
	bit	#1, r1		; If the entry is odd, then ignore the signal
	bne	nocall		; Otherwise it is the routine to call
	jsr	pc, (r1)	; So call it.
nocall:
	tst	(sp)+		; Get the arg (the signal no) off the stack
	mov	(sp)+, r1	; Restore R1
	mov	(sp)+, r0	;  and R0
	rti	

no.ctrlo:			; We need to re-enadle ouput.
	tst	$$rsts		; On RSTS?
	beq	no.rsts
	cmp	$$opsy, #7	;  and RT11.RTS?
	bne	no.rt11		;   do rtemt(.RCTRLO, 0)
	clr	-(sp)		; Push the zero
	mov	#.RCTRLO, -(sp)	;  and the EMT
	jsr	pc, rtemt	;   and call the routine
	cmp	(sp)+,(sp)+	; Get the args off the stack
	br	done		;  and call it a day.
no.rt11:
	mov	#.TTRST,-(sp)	; Then we can do RSTS EMTs
	jsr	pc, rstsys	;  via rstsys(.TTRST)
	tst	(sp)+		; Get the arg off the stack.
no.rsts:
done:	rts	pc

	.globl	$$rsts
	.globl	$$opsy
	.globl	rtemt
	.globl	rstsys

	.globl	$$sigs

	.globl	$$sig0
	.end
