summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/68020/notetramp.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/lib/ap/68020/notetramp.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/lib/ap/68020/notetramp.c')
-rwxr-xr-xsys/src/ape/lib/ap/68020/notetramp.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/sys/src/ape/lib/ap/68020/notetramp.c b/sys/src/ape/lib/ap/68020/notetramp.c
new file mode 100755
index 000000000..7803a35c7
--- /dev/null
+++ b/sys/src/ape/lib/ap/68020/notetramp.c
@@ -0,0 +1,72 @@
+#include "../plan9/lib.h"
+#include "../plan9/sys9.h"
+#include <signal.h>
+#include <setjmp.h>
+
+/* A stack to hold pcs when signals nest */
+#define MAXSIGSTACK 20
+typedef struct Pcstack Pcstack;
+static struct Pcstack {
+ int sig;
+ void (*hdlr)(int, char*, Ureg*);
+ unsigned long restorepc;
+ Ureg *u;
+} pcstack[MAXSIGSTACK];
+static int nstack = 0;
+
+static void notecont(Ureg*, char*);
+
+void
+_notetramp(int sig, void (*hdlr)(int, char*, Ureg*), Ureg *u)
+{
+ Pcstack *p;
+
+ if(nstack >= MAXSIGSTACK)
+ _NOTED(1); /* nesting too deep; just do system default */
+ p = &pcstack[nstack];
+ p->restorepc = u->pc;
+ p->sig = sig;
+ p->hdlr = hdlr;
+ p->u = u;
+ nstack++;
+ u->pc = (unsigned long) notecont;
+ _NOTED(2); /* NSAVE: clear note but hold state */
+}
+
+static void
+notecont(Ureg *u, char *s)
+{
+ Pcstack *p;
+ void(*f)(int, char*, Ureg*);
+
+ p = &pcstack[nstack-1];
+ f = p->hdlr;
+ u->pc = p->restorepc;
+ nstack--;
+ (*f)(p->sig, s, u);
+ _NOTED(3); /* NRSTR */
+}
+
+#define JMPBUFPC 1
+#define JMPBUFSP 0
+
+extern sigset_t _psigblocked;
+
+void
+siglongjmp(sigjmp_buf j, int ret)
+{
+ struct Ureg *u;
+
+ if(j[0])
+ _psigblocked = j[1];
+ if(nstack == 0 || pcstack[nstack-1].u->sp > j[2+JMPBUFSP])
+ longjmp(j+2, ret);
+ u = pcstack[nstack-1].u;
+ nstack--;
+ u->r0 = ret;
+ if(ret == 0)
+ u->r0 = 1;
+ u->pc = j[2+JMPBUFPC];
+ u->sp = j[2+JMPBUFSP] + 4;
+ _NOTED(3); /* NRSTR */
+}