shithub: drawcpu

Download patch

ref: 82dc85253c9ab0f7b9925c69e4b065ca4347ab04
parent: f26dd3371d96047be87a41d745dbc73040531a6c
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Jul 31 18:42:45 EDT 2025

More pieces to get it working

--- a/include/lib.h
+++ b/include/lib.h
@@ -28,6 +28,7 @@
 
 typedef unsigned char	p9_uchar;
 typedef unsigned int	p9_uint;
+typedef uint8_t         p9_u8int;
 typedef unsigned int	p9_ulong;
 typedef int		p9_long;
 typedef signed char	p9_schar;
@@ -42,6 +43,7 @@
 #define uchar	p9_uchar
 #define ushort	p9_ushort
 #define uint	p9_uint
+#define u8int   p9_u8int
 #define u32int	p9_u32int
 #define u64int	p9_u64int
 
--- a/kern/arm.c
+++ b/kern/arm.c
@@ -34,7 +34,7 @@
 }
 
 static u32int
-doshift(u32int instr, uint *carry)
+doshift(u32int instr, u8int *carry)
 {
     ulong amount, val;
     val = up->R[instr & 15];
@@ -100,7 +100,7 @@
 	Segment *seg;
 
 	if(instr & fI) {
-		uint carry = 0;
+		u8int carry = 0;
 		if(instr & (1<<4))
 			invalid(instr);
 		offset = doshift(instr, &carry);
@@ -111,7 +111,7 @@
 	Rn = up->R + ((instr >> 16) & 15);
 	Rd = up->R + ((instr >> 12) & 15);
     if (debug)
-        print("single: Rn=%d Rd=%d offset=%d\n",  ((instr >> 16) & 15), ((instr >> 12) & 15), offset);
+        print("single: Rn=%d Rd=%d offset=%.8ux\n",  ((instr >> 16) & 15), ((instr >> 12) & 15), offset);
 	if((instr & (fW | fP)) == fW)
 		invalid(instr);
 	if(Rn == up->R + 15) {
@@ -130,18 +130,18 @@
 		*(u32int*) targ = *Rd;
 		break;
 	case fB:
-		*(uint*) targ = *Rd;
+		*(u8int*) targ = *Rd;
 		break;
 	case fL:
 		*Rd = *(u32int*) targ;
 		break;
 	case fB | fL:
-		*Rd = *(uint*) targ;
+		*Rd = *(u8int*) targ;
 		break;
 	}
 	if(Rd == up->R + 15 && !(instr & fL)) {
 		if(instr & fB)
-			*(uint*) targ += 8;
+			*(u8int*) targ += 8;
 		else
 			*(u32int*) targ += 8;
 	}
@@ -186,7 +186,7 @@
 }
 
 static u32int
-add(u32int a, u32int b, uint type, uint *carry, uint *overflow)
+add(u32int a, u32int b, u8int type, u8int *carry, u8int *overflow)
 {
     u32int res1;
     u64int res2;
@@ -212,7 +212,7 @@
 alu(u32int instr)
 {
     u32int Rn, *Rd, operand, shift, result, op;
-    uint carry, overflow;
+    u8int carry, overflow;
     Rn = up->R[(instr >> 16) & 15];
     Rd = up->R + ((instr >> 12) & 15);
 	if(((instr >> 16) & 15) == 15) {
@@ -279,6 +279,8 @@
     if(offset & (1<<23))
         offset |= ~((1 << 24) - 1);
     offset *= 4;
+    if(debug)
+        print("branch: offset=%.8ux\n", offset);
     if(instr & fLi)
         up->R[14] = up->R[15];
     up->R[15] += offset + 4;
@@ -311,7 +313,7 @@
     if(instr & fH)
         target = evenaddr(target, 1);
     switch(instr & (fSg | fH | fL)) {
-    case fSg: *(uint*) vaddr(target, 1, &seg) = *Rd; break;
+    case fSg: *(u8int*) vaddr(target, 1, &seg) = *Rd; break;
     case fSg | fL: *Rd = (long) *(char*) vaddr(target, 1, &seg); break;
     case fH: case fSg | fH: *(uint16_t*) vaddr(target, 2, &seg) = *Rd; break;
     case fH | fL: *Rd = *(uint16_t*) vaddr(target, 2, &seg); break;
@@ -486,7 +488,6 @@
 
     instr = *(u32int*) vaddr(up->R[15], 4, &seg);
     segunlock(seg);
-
     up->R[15] += 4;
 
     // CPSR testing for conditional execution
--- a/kern/dat.h
+++ b/kern/dat.h
@@ -10,6 +10,7 @@
 typedef struct Dirtab	Dirtab;
 typedef struct Egrp	Egrp;
 typedef struct Evalue	Evalue;
+typedef struct Fd Fd;
 typedef struct Fgrp	Fgrp;
 typedef struct DevConf	DevConf;
 typedef struct Label	Label;
@@ -366,6 +367,14 @@
 	Dead,
 };
 
+struct Fd
+{
+	RWlock rw;
+	Ref ref;
+	uint *fds;
+	int nfds;
+};
+
 struct Proc
 {
 	uint	state;
@@ -397,8 +406,9 @@
 	char	errbuf1[ERRMAX];
 	char	genbuf[128];	/* buffer used e.g. for last name element from namec */
 	char	text[KNAMELEN];
+	char 	name[NAMEMAX+1];
+	Ref 	*path;
 
-
 	u32int lladdr;		/* LL/SC emulation */
 	u32int llval;
 
@@ -406,7 +416,7 @@
 
 	u32int FPSR;
 	double F[Nfpregs];
-	int		fd; 		/* fd for syscall emulation */
+	Fd	   *fd; 		/* fd for syscall emulation */
 
 	/* Notes */
 	u32int notehandler;
--- a/kern/devssl.c
+++ b/kern/devssl.c
@@ -111,13 +111,13 @@
 static long	sslput(Dstate *s, Block * volatile b);
 
 char *sslnames[] = {
-[Qclonus]	"clone",
-[Qdata]		"data",
-[Qctl]		"ctl",
-[Qsecretin]	"secretin",
-[Qsecretout]	"secretout",
-[Qencalgs]	"encalgs",
-[Qhashalgs]	"hashalgs",
+[Qclonus]		= "clone",
+[Qdata]			= "data",
+[Qctl]			= "ctl",
+[Qsecretin]		= "secretin",
+[Qsecretout]	= "secretout",
+[Qencalgs]		= "encalgs",
+[Qhashalgs]		= "hashalgs",
 };
 
 static int
--- a/kern/devtls.c
+++ b/kern/devtls.c
@@ -258,14 +258,14 @@
 static void	pdump(int, void*, char*);
 
 static char *tlsnames[] = {
-[Qclonus]		"clone",
-[Qencalgs]	"encalgs",
-[Qhashalgs]	"hashalgs",
-[Qdata]		"data",
-[Qctl]		"ctl",
-[Qhand]		"hand",
-[Qstatus]		"status",
-[Qstats]		"stats",
+[Qclonus]	= "clone",
+[Qencalgs]	= "encalgs",
+[Qhashalgs]	= "hashalgs",
+[Qdata]		= "data",
+[Qctl]		= "ctl",
+[Qhand]		= "hand",
+[Qstatus]	= "status",
+[Qstats]	= "stats",
 };
 
 static int convdir[] = { Qctl, Qdata, Qhand, Qstatus, Qstats };
--- a/kern/fns.h
+++ b/kern/fns.h
@@ -214,6 +214,7 @@
 int 		setlabel(Label*);
 void		setmalloctag(void*, uintptr);
 void		setrealloctag(void*, uintptr);
+void        setcexec(Fd *, int, int);
 long		showfilewrite(char*, int);
 char*		skipslash(char*);
 void		sleep(Rendez*, int(*)(void*), void*);
--- a/kern/procinit.c
+++ b/kern/procinit.c
@@ -31,6 +31,8 @@
 
 	p = mallocz(sizeof(Proc), 1);
 	p->pid = incref(&pidref);
+	p->fd = mallocz(sizeof(Fd), 1);
+	incref(&p->fd->ref);
 	strcpy(p->user, eve);
 	p->syserrstr = p->errbuf0;
 	p->errstr = p->errbuf1;
--- a/kern/seg.c
+++ b/kern/seg.c
@@ -7,6 +7,7 @@
 newseg(u32int start, u32int size, int idx)
 {
 	Segment *s;
+
 	if(debug)	
 		print("newseg: size=%.8ux start=%.8ux idx=%d\n", size, start, idx);
 	s = malloc(sizeof *s);
@@ -17,8 +18,6 @@
 	s->start = start;
 	s->size = size;
 	s->dref = malloc(size + sizeof(Ref));
-	if(s->dref == nil)
-		panic("%r");
 	memset(s->dref, 0, sizeof(Ref));
 	incref(s->dref);
 	s->data = s->dref + 1;
@@ -49,8 +48,10 @@
 vaddr(u32int addr, u32int len, Segment **seg)
 {
     Segment **ss, *s;
+	int count = 0;
 
     for (ss = up->S; ss < up->S + SEGNUM; ss++) {
+		count++;
         if (*ss == nil)
             continue;
         s = *ss;
@@ -60,12 +61,12 @@
             if (s->flags & SEGFLLOCK)
                 rlock(&s->rw);
             *seg = s;
-//			if(debug)
-//				print("vaddr addr=%.8ux, (%d), PC=%.8ux index=%.8ux\n", addr, len, up->R[15], s->start);
+			if(debug)
+				print("vaddr addr=%.8ux, (%d), PC=%.8ux index=%.8ux segment=%d\n", addr, len, up->R[15], s->start, count);
             return (char *)s->data + (addr - s->start);
         }
     }
-    panic("fault addr=%.8ux, (%d), PC=%.8ux", addr, len, up->R[15]);
+    panic("segfault addr=%.8ux, (%d), PC=%.8ux", addr, len, up->R[15]);
     return nil;
 }
 
@@ -74,6 +75,7 @@
 {
     Segment *seg;
 	void *ret;
+	
     ret = vaddr(addr, len, &seg);
 	segunlock(seg);
 	return ret;
@@ -100,7 +102,7 @@
 	}
 	if(len < 0)
 		len = strlen(targ) + 1;
-	ret = malloc(len);
+	ret = mallocz(len, 1);
 	if (ret == nil)
 		panic("%r");
 	setmalloctag(ret, getcallerpc(&addr));
@@ -115,7 +117,7 @@
 {
 	void *targ, *v;
 	Segment *seg;
-	
+
 	targ = vaddr(addr, len, &seg);
 	if((seg->flags & SEGFLLOCK) == 0) {
 		*buffered = 0;
@@ -123,7 +125,7 @@
 	}
 	segunlock(seg);
 	*buffered = 1;
-	v = malloc(len);
+	v = mallocz(len, 1);
 	if (v == nil)
 		panic("%r");
 	setmalloctag(v, getcallerpc(&addr));
--- a/kern/syscall.c
+++ b/kern/syscall.c
@@ -76,7 +76,7 @@
 	namet = copyifnec(name, -1, &copied);
 	fd = open(namet, flags);
 	if(debug)
-		print("sysopen: fd=%.8ux name=%s flags=%.8ux\n", fd, namet, flags);
+		print("sysopen: fd=%lux name=%s flags=%lux\n", fd, namet, flags);
 	if(copied)
 		free(namet);
 	if(fd < 0) {
@@ -84,6 +84,7 @@
 		up->R[0] = fd;
 		return;
 	}
+	setcexec(up->fd, fd, flags & OCEXEC);
 	up->R[0] = fd;
 }
 
@@ -100,7 +101,7 @@
 	namet = copyifnec(name, -1, &copied);
 	fd = create(namet, flags, perm);
 	if(debug)
-		print("syscreate\n");
+		print("syscreate: name=%s\n", namet);
 	if(copied)
 		free(namet);
 	if(fd < 0) {
@@ -108,6 +109,7 @@
 		up->R[0] = fd;
 		return;
 	}
+	setcexec(up->fd, fd, flags & OCEXEC);
 	up->R[0] = fd;
 }
 
@@ -118,8 +120,10 @@
 	
 	fd = arg(0);
 	if(debug)
-		print("sysclose: fd=%.8ux\n", fd);
+		print("sysclose: fd=%lux\n", fd);
 	up->R[0] = noteerr(close(fd), 0);
+	if((fd & (1<<31)) == 0)
+		setcexec(up->fd, fd, 0);
 }
 
 static void
@@ -135,7 +139,7 @@
 	size = arg(2);
 	off = argv(3);
 	if(debug)
-		print("syspread: size=0x%.8ux off=0x%.8ux\n", size, off);
+		print("syspread: size=0x%lux off=0x%lux\n", size, off);
 	targ = bufifnec(buf, size, &buffered);
 	up->R[0] = noteerr(pread(fd, targ, size, off), size);
 	if(buffered)
@@ -156,7 +160,7 @@
 	off = argv(3);
 	buft = copyifnec(buf, size, &copied);
 	if(debug)
-		print("syspwrite: buf=%s size=%.8ux off=%.8ux\n", buft, size, off);
+		print("syspwrite: fd=%ux buf=%s size=%lux off=%lux\n", fd, buft, size, off);
 	up->R[0] = noteerr(pwrite(fd, buft, size, off), size);
 	if(copied)
 		free(buft);
@@ -174,7 +178,7 @@
 	n = argv(2);
 	type = arg(4);
 	if(debug)
-		print("sysseek: to=%d whence=%.4ux\n", n, type);
+		print("sysseek: to=%d whence=%lux\n", n, type);
 	*ret = seek(fd, n, type);
 	if(*ret < 0) noteerr(0, 1);
 	segunlock(seg);
@@ -205,31 +209,14 @@
     char *namet;
     void *edirt;
     int copied, buffered;
-    Segment *seg;
 
-    name = arg(0); // R0
-	if(debug)
-	    print("sysstat: name=%.8ux, R13=%.8ux\n", name, up->R[13]);
-    if (!vaddr(name, 1, &seg)) {
-        print("sysstat: invalid name pointer %.8ux\n", name);
-        cherrstr("invalid name pointer");
-        up->R[0] = -1;
-        return;
-    }
+    name = arg(0);
     namet = copyifnec(name, -1, &copied);
-    edir = arg(1); // R1
-    nedir = arg(2); // R2
+    edir = arg(1); 
+    nedir = arg(2);
+	    edirt = bufifnec(edir, nedir, &buffered);
 	if(debug)
-	    print("sysstat: edir=%.8ux, nedir=%d\n", edir, nedir);
-    if (nedir > 0 && !vaddr(edir, nedir, &seg)) {
-        print("sysstat: invalid edir pointer %.8ux\n", edir);
-        cherrstr("invalid edir pointer");
-        if (copied)
-            free(namet);
-        up->R[0] = -1;
-        return;
-    }
-    edirt = bufifnec(edir, nedir, &buffered);
+	    print("sysstat: edir=%s, nedir=%d\n", edirt, nedir);
     up->R[0] = noteerr(stat(namet, edirt, nedir), nedir);
     if (copied)
         free(namet);
@@ -243,12 +230,12 @@
 	u32int fd, edir, nedir;
 	void *edirt;
 	int buffered;
-	if(debug)
-		print("sysfstat\n");
 	fd = arg(0);
 	edir = arg(1);
 	nedir = arg(2);
 	edirt = bufifnec(edir, nedir, &buffered);
+	if(debug)
+		print("sysfstat: edir=%s, nedir=%d\n", edirt, nedir);
 	up->R[0] = noteerr(sysfstat(fd, edirt, nedir), nedir);
 	if(buffered)
 		copyback(edir, up->R[0], edirt);
@@ -266,9 +253,9 @@
 	namet = copyifnec(name, -1, &copied);
 	edir = arg(1);
 	nedir = arg(2);
-	if(debug)
-		print("syswstat\n");
 	edirt = copyifnec(edir, nedir, &copied2);
+	if(debug)
+		print("syswstate dir=%s, name=%s\n", edirt, namet);
 	up->R[0] = noteerr(syswstat(namet, edirt, nedir), nedir);
 	if(copied)
 		free(namet);
@@ -286,9 +273,9 @@
 	fd = arg(0);
 	edir = arg(1);
 	nedir = arg(2);
-	if(debug)
-		print("sysfwstat\n");
 	edirt = copyifnec(edir, nedir, &copied);
+	if(debug)
+		print("sysfwstat: %d, %#ux, %d\n",fd, edir, nedir);
 	up->R[0] = noteerr(sysfwstat(fd, edirt, nedir), nedir);
 	if(copied)
 		free(edirt);
@@ -312,16 +299,16 @@
 	v = arg(0);
 	v = v + 7 & -8;
 	if(debug)
-		print("sysbrk v=%.8ux\n", v);
+		print("sysbrk v=%#lux\n", v);
 	if(v >= up->S[SEGSTACK]->start)
-		fprint(2, "bss > stack, wtf?");
+		panic("bss > stack, wtf?");
 	if(v < up->S[SEGBSS]->start)
-		fprint(2, "bss length < 0, wtf?");
+		panic("bss length < 0, wtf?");
 	s = up->S[SEGBSS];
 	wlock(&s->rw);
 	s->dref = realloc(s->dref, v - s->start + sizeof(Ref));
 	if(s->dref == nil)
-		fprint(2, "error reallocating");
+		panic("error reallocating");
 	s->data = s->dref + 1;
 	if(s->size < v - s->start)
 		memset((char*)s->data + s->size, 0, v - s->start - s->size);
@@ -396,7 +383,8 @@
 	int rc, i;
 	Segment *s, *t;
 	Proc *p;
-	
+	if(debug)
+		print("sysrfork\n");
 	flags = arg(0);
 	if((flags & (RFFDG | RFCFDG)) == (RFFDG | RFCFDG) ||
 	   (flags & (RFNAMEG | RFCNAMEG)) == (RFNAMEG | RFCNAMEG) ||
@@ -494,13 +482,13 @@
 	char *namet;
 	char **argvv;
 	int i, argc, rc;
-	Segment *seg1, *seg2;
+	Segment *seg;
 	u32int *argvt;
-	
+
 	name = arg(0);
 	argv = arg(1);
 	namet = estrdup((char*)vaddrnol(name, 0));
-	argvt = vaddr(argv, 0, &seg1);
+	argvt = vaddr(argv, 0, &seg);
 	if(debug)
 		print("sysexec: name=%s", namet);
 	for(argc = 0; argvt[argc]; argc++)
@@ -517,7 +505,7 @@
 		argvv[i] = estrdup((char*)vaddrnol(argvt[i], 0));
 	}
 	argvv[argc] = nil;
-	segunlock(seg1);
+	segunlock(seg);
 	rc = loadtext(namet, argc, argvv);
 	for(i = 0; i < argc; i++)
 		free(argvv[i]);
@@ -764,11 +752,11 @@
         [MOUNT]     = _sysmount,
         [REMOVE]    = _sysremove,
         [ALARM]     = _sysalarm,
+		[AWAIT]     = _sysawait,
         [SEMACQUIRE]= _syssemacquire,
         [SEMRELEASE]= _syssemrelease,
     };
 
     n = up->R[0];
-
     calls[n]();
 }
\ No newline at end of file
--- a/kern/sysproc.c
+++ b/kern/sysproc.c
@@ -14,10 +14,16 @@
 
 #undef rfork
 #undef read
-
 jmp_buf exec_jmp;
 #define pgsize  0x1000
 
+/* Use sizes from arm32 */
+#undef USTKTOP
+#undef USTKSIZE
+#define USTKTOP 0x3FFFFFFFULL
+#define USTKSIZE 0x100000
+
+
 static void
 nop(int x)
 {
@@ -32,6 +38,27 @@
 	return *(u32int*) vaddrnol(up->R[13] + 4 + 4 * n, 4);
 }
 
+
+static void
+copyname(char *file)
+{
+	char *p;
+	
+	p = strrchr(file, '/');
+	if(p == nil)
+		p = file;
+	else
+		p++;
+	strncpy(up->name, p, NAMEMAX);
+
+	if(up->path != nil && decref(up->path) == 0)
+		free(up->path);
+	up->path = malloc(sizeof(Ref) + strlen(file)+1);
+    memset(up->path, 0, sizeof(Ref) + strlen(file)+1);
+	incref(up->path);
+	strcpy((char*)(up->path + 1), file);
+}
+
 static uvlong
 _round(uvlong a, ulong b)
 {
@@ -43,7 +70,100 @@
 	return(w);
 }
 
+Fd *
+newfid(void)
+{
+	Fd *fd;
+	
+	fd = mallocz(sizeof(*fd), 1);
+	incref(&fd->ref);
+	return fd;
+}
+
+Fd *
+copyfd(Fd *old)
+{
+	Fd *new;
+	
+	rlock(&old->rw);
+	new = newfid();
+	if(old->nfds > 0) {
+		new->nfds = old->nfds;
+		new->fds = mallocz(old->nfds, 1);
+		memcpy(new->fds, old->fds, old->nfds);
+	}
+	runlock(&old->rw);
+	return new;
+}
+
+void
+fddecref(Fd *fd)
+{
+	if(decref(&fd->ref) == 0) {
+		free(fd->fds);
+		free(fd);
+	}
+}
+
 int
+iscexec(Fd *fd, int n)
+{
+	int r;
+
+	r = 0;
+	rlock(&fd->rw);
+	if(n / 8 < fd->nfds)
+		r = (fd->fds[n / 8] & (1 << (n % 8))) != 0;
+	runlock(&fd->rw);
+	return r;
+}
+
+void
+setcexec(Fd *fd, int n, int status)
+{
+	int old;
+
+	wlock(&fd->rw);
+	if(n / 8 >= fd->nfds) {
+		if(status == 0) {
+			wunlock(&fd->rw);
+			return;
+		}
+		old = fd->nfds;
+		fd->nfds = (n / 8) + 1;
+		fd->fds = realloc(fd->fds, fd->nfds);
+		memset(fd->fds + old, 0, fd->nfds - old);
+	}
+	if(status == 0)
+		fd->fds[n / 8] &= ~(1 << (n % 8));
+	else
+		fd->fds[n / 8] |= (1 << (n % 8));
+	wunlock(&fd->rw);
+}
+
+void
+fdclear(Fd *fd)
+{
+	int i, j, k;
+
+	wlock(&fd->rw);
+	if(fd->nfds == 0) {
+		wunlock(&fd->rw);
+		return;
+	}
+	for(i = 0; i < fd->nfds; i++) {
+		j = fd->fds[i];
+		for(k = 0; k < 8; k++)
+			if(j & (1<<k))
+				close(8 * i + k);
+	}
+	free(fd->fds);
+	fd->nfds = 0;
+	fd->fds = nil;
+	wunlock(&fd->rw);
+}
+
+int
 sysrfork(int flags)
 {
     int pid, status;
@@ -241,7 +361,7 @@
     case NCONT:
         break;
     default:
-        sysfatal("unhandled noted argument %d", rc);
+        panic("unhandled noted argument %d", rc);
     }
     up->innote = 0;
     ureg = vaddrnol(uregp, 18 * 4); /* just to be sure */
@@ -367,9 +487,6 @@
     if(beswal(hdr.magic) != E_MAGIC)
         panic("bad magic number in exec header: got 0x%lux, want 0x%lux", beswal(hdr.magic), E_MAGIC);
 
-    freesegs();
-    up->CPSR = 0;
-    
     hdrsz = sizeof(Exec);
     txtaddr = pgsize + hdrsz;
     txtsz = beswal(hdr.text);
@@ -379,7 +496,11 @@
     datoff = txtsz + hdrsz;
     bsssz = beswal(hdr.bss);
 
-    /* Create segments: text, data, bss, stack */
+    copyname(file);
+    up->notehandler = up->innote = up->notein = up->noteout = 0;
+    freesegs();
+    memset(up->R, 0, sizeof(up->R));
+    up->CPSR = 0;
     text = newseg(txtaddr - hdrsz, txtsz + hdrsz, SEGTEXT);
     data = newseg(dataddr, datsz, SEGDATA);
     bss = newseg(dataddr + datsz, bsssz, SEGBSS);
@@ -394,6 +515,7 @@
     memset(bss->data, 0, bss->size);
     up->R[15] = beswal(hdr.entry);
     close(fd);
+    fdclear(up->fd);
     initstack(argc, argv);
 
     if(debug)
--- a/main.c
+++ b/main.c
@@ -78,7 +78,7 @@
 main(int argc, char **argv)
 {
 	extern ulong kerndate;
-	char *path, *file;
+	char *path, *file, *rc;
 
 	debug = 0;
 	path = nil;
@@ -88,6 +88,9 @@
 		eve = "drawcpu";
 
 	ARGBEGIN {
+	case 'r':
+		rc = EARGF(usage());
+		break;
 	case 'p':
 		path = EARGF(usage());
 		break;
@@ -124,6 +127,10 @@
 	if(bind("/root", "/", MAFTER) < 0)
 		panic("bind /root: %r");
 
+	/* RC Main */
+	if(rc != nil)
+		bind(rc, "/rc", MAFTER);
+
 	if(path != nil)
 		bind(path, "/bin", MAFTER);
 
@@ -146,8 +153,8 @@
 
 	notify(notehandler);
 	for(;;) {
-//		if(debug)
-//			dump();
+		if(debug)
+			dump();
 		step();
 		while((up->notein - up->noteout) % NNOTE) {
 			donote(up->notes[up->noteout % NNOTE], 0);
--