[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Psigintr, sorry for the delay



Sorry it took so long to get this tiny patch re-sent. This is relative to the
h7 patch just sent out.

--- dos.c.O	Fri Jul 22 15:15:40 1994
+++ dos.c	Fri Jul 22 15:24:44 1994
@@ -707,6 +707,7 @@
 	dos_tab[0x13b] = d_getcwd;
 	dos_tab[0x13c] = s_alert;
 	dos_tab[0x13d] = t_malarm;
+	dos_tab[0x13e] = p_sigintr;
 	dos_tab[0x13f] = s_uptime;
 	dos_tab[0x142] = d_xreaddir;
 	dos_tab[0x143] = p_seteuid;
--- dosmem.c.O	Fri Jul 22 15:15:52 1994
+++ dosmem.c	Fri Jul 22 15:27:22 1994
@@ -770,6 +770,8 @@
 		FATAL("attempt to terminate MiNT");
 	}
 
+/* cancel all user-specified interrupt signals */
+	cancelsigintrs();
 /* cancel all pending timeouts for this process */
 	cancelalltimeouts();
 /* cancel alarm clock */
--- dossig.c.O	Tue Aug 17 01:30:28 1993
+++ dossig.c	Fri Jul 22 15:19:02 1994
@@ -210,3 +210,113 @@
 	TRACE(("Psigpause: returning OK"));
 	return 0;
 }
+
+/*
+ * p_sigintr: Set an exception vector to send us the specified signal.
+ */
+
+typedef struct usig {
+	int vec;		/* exception vector number */
+	int sig;		/* signal to send */
+	PROC *proc;		/* process to get signal */
+	long oldv;		/* old exception vector value */
+	struct usig *next;	/* next entry ... */
+} usig;
+
+static usig *usiglst;
+extern long mcpu;
+
+long ARGS_ON_STACK
+p_sigintr(vec, sig)
+	int vec;
+	int sig;
+{
+	extern void new_intr();	/* in intr.spp */
+	long vec2;
+	usig *new;
+
+	if (!sig)		/* ignore signal 0 */
+		return 0;
+
+	vec2 = (long) new_intr;
+
+#ifndef ONLY030
+	if (mcpu == 0)			
+		/* put vector number in high byte of vector address */
+		vec2 |= ((long) vec) << 24;
+#endif
+	new = kmalloc(sizeof(usig));
+	if (!new)			/* hope this never happens...! */
+		return ENSMEM;
+	new->vec = vec;
+	new->sig = sig;
+	new->proc = curproc;
+	new->next = usiglst;		/* simple unsorted list... */
+	usiglst = new;
+
+	new->oldv = setexc(vec, vec2);
+	return new->oldv;
+}
+
+/*
+ * Find the process that requested this interrupt, and send it a signal.
+ * Called at interrupt time by new_intr() from intr.spp, with interrupt
+ * vector number on the stack.
+ */
+
+void ARGS_ON_STACK
+sig_user(vec)
+	int vec;
+{
+	usig *ptr;
+
+	for (ptr = usiglst; ptr; ptr=ptr->next)
+		if (vec == ptr->vec) {
+			if (ptr->proc->wait_q != ZOMBIE_Q &&
+			    ptr->proc->wait_q != TSR_Q) {
+				post_sig(ptr->proc, ptr->sig);
+			}
+#if 0	/* Search entire list, to allow multiple processes to respond to
+	   the same interrupt. (Why/when would you want that?) */
+			break;
+#endif
+		}
+	/*
+	 * Clear in-service bit for ST MFP interrupts
+	 */
+	if (vec >= 64 && vec < 80) {
+		char *mfp, c;
+
+		if (vec < 72)		/* Register B */
+			mfp = (char *)0xfffffa11L;
+		else			/* Register A */
+			mfp = (char *)0xfffffa0fL;
+		c = 1 << (vec & 7);
+
+		*mfp = ~c;
+	}
+}
+
+/*
+ * cancelsigintrs: remove any interrupts requested by this process, called
+ * at process termination.
+ */
+void ARGS_ON_STACK
+cancelsigintrs()
+{
+	usig *ptr, **old, *nxt;
+	short s = spl7();
+
+	for (old=&usiglst, ptr=usiglst; ptr; ) {
+		nxt = ptr->next;
+		if (ptr->proc == curproc) {
+			setexc(ptr->vec, ptr->oldv);
+			*old = nxt;
+			kfree(ptr);
+		} else {
+			old = &(ptr->next);
+		}
+		ptr = nxt;
+	}
+	spl(s);
+}
--- intr.spp.O	Fri Jul 22 15:16:02 1994
+++ intr.spp	Fri Jul 22 15:32:40 1994
@@ -76,7 +76,7 @@
 %endif
 	clr.w	-(sp)			; yes, long frames: push a frame word
 L_short1:
-	pea	L_comeback		; push fake PC
+	pea	L_comeback(pc)		; push fake PC
 	move.w	sr,-(sp)		; push status register
 	move.l	_old_vbl+8,-(sp)	; go service the interrupt
 	rts
@@ -231,7 +231,37 @@
 	move.l	_old_ikbd+8,-(sp)
 	rts			; jump to system interrupt routine
 
+; Generic routine for handling any user-specified interrupts. On 68000, the
+; vector number is stored in the high byte of the program counter.
 ;
+	XDEF	_new_intr
+
+_new_intr:
+	movem.l	d0-d2/a0-a2,-(sp)	; save regs
+
+%ifndef ONLY030
+	tst.w	($59e.w)	; is frame format on stack?
+	bne.s	nvec		; yes, go use it
+	bsr.s	ndummy		; push PC to stack
+	nop
+ndummy:	
+	move.w	(sp)+,d0	; pop hi(PC) to d0
+	addq.w	#2,sp		; pop lo(PC) off stack
+	lsr.w	#8,d0		; move hi byte to vector number
+	bra.s	ngot		; continue
+nvec:
+%endif
+	move.w	30(sp),d0	; get frame word
+	lsr.w	#2,d0		; move vector offset to vector number
+ngot:
+	move.w	d0,-(sp)	; push vector offset
+	jsr	_sig_user	; send signal
+	addq.w	#2,sp			; pop vector offset
+	movem.l	(sp)+,d0-d2/a0-a2	; restore regs
+	rte
+
+
+;
 ; simple signal handlers
 ; global variables referenced:
 ; in_kernel: (main.c): flag to indicate that we're in the MiNT kernel
--- proto.h.O	Fri Jul 22 15:16:42 1994
+++ proto.h	Fri Jul 22 15:19:04 1994
@@ -166,6 +166,8 @@
 long ARGS_ON_STACK p_vfork P_((void));
 long ARGS_ON_STACK p_fork P_((void));
 
+long ARGS_ON_STACK p_sigintr P_((int vec, int sig));
+void cancelsigintrs P_((void));
 /* dossig.c */
 long ARGS_ON_STACK p_kill P_((int pid, int sig));
 long ARGS_ON_STACK p_sigaction P_((int sig, const struct sigaction *act,