[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Working Psigintr call...
Ok, life is much happier with MiNT 1.10. Here's my working version of the
stuff I sent out for comment before. Psigintr takes two arguments, an
exception vector number, and a signal number. It uses setexc to point the
exception handler for the given vector at a routine which just calls
post_sig. So, the requested signal is sent to the process that originally
called Psigintr... If you would care to see my double-buffered direct-to-disk
sound play/record program that uses this, drop me a line.
-- Howard
*** 1.1 1994/02/17 16:16:26
--- dos.c 1994/02/17 16:17:52
***************
*** 603,605 ****
--- 603,606 ----
dos_tab[0x13c] = s_alert;
dos_tab[0x13d] = t_malarm;
+ dos_tab[0x13e] = p_sigintr;
}
*** 1.1 1994/02/17 20:17:08
--- dosmem.c 1994/02/17 20:19:58
***************
*** 736,739 ****
--- 736,741 ----
}
+ /* cancel all user-specified interrupt signals */
+ cancelsigintrs();
/* cancel all pending timeouts for this process */
cancelalltimeouts();
*** 1.1 1994/02/17 16:16:26
--- dossig.c 1994/02/17 23:35:26
***************
*** 211,212 ****
--- 211,319 ----
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 */
+ vec2 |= vec << 24; /* byte of vector address */
+ #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;
+ short s = spl7();
+
+ for (old=NULL, ptr=usiglst; ptr; old=ptr, ptr=ptr->next)
+ if (ptr->proc == curproc) {
+ setexc(ptr->vec, ptr->oldv);
+ if (old)
+ old->next = ptr->next;
+ else
+ usiglst = ptr->next;
+ kfree(ptr);
+ }
+ spl(s);
+ }
*** 1.1 1994/02/17 16:16:26
--- intr.spp 1994/02/17 23:27:04
***************
*** 71,75 ****
clr.w -(sp) ; yes, long frames: push a frame word
L_short1:
! pea L_comeback ; push fake PC
move.w sr,-(sp) ; push status register
move.l _old_vbl+8,-(sp) ; go service the interrupt
--- 71,75 ----
clr.w -(sp) ; yes, long frames: push a frame word
L_short1:
! pea L_comeback(pc) ; push fake PC
move.w sr,-(sp) ; push status register
move.l _old_vbl+8,-(sp) ; go service the interrupt
***************
*** 235,238 ****
--- 235,268 ----
;
+ ; 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
+
+ ;
; New bus error handler for memory protection: get the ssp and
; put it in the proc structure before calling
*** 1.1 1994/02/17 16:33:50
--- proto.h 1994/02/17 20:30:28
***************
*** 167,170 ****
--- 167,172 ----
long ARGS_ON_STACK p_sigpending P_((void));
long ARGS_ON_STACK p_sigpause P_((ulong mask));
+ long ARGS_ON_STACK p_sigintr P_((int vec, int sig));
+ void cancelsigintrs P_((void));
/* filesys.c */