~kris/9p

9hist

7beaef922774bae5a96a3dd2518b895473ed19a5 — David du Colombier 34 years ago 71e175c
Plan 9 from Bell Labs 1992-08-24
8 files changed, 259 insertions(+), 239 deletions(-)

M port/devmnt.c
M port/devproc.c
M port/error.h
M port/pgrp.c
M port/portdat.h
M port/segment.c
D ss/malloc.h
M ss/screen.c
M port/devmnt.c => port/devmnt.c +1 -1
@@ 250,7 250,7 @@ mntclone(Chan *c, Chan *nc)
		nc = newchan();
		alloc = 1;
	}
	if(waserror()){
	if(waserror()) {
		mntfree(r);
		if(alloc)
			close(nc);

M port/devproc.c => port/devproc.c +21 -16
@@ 21,7 21,8 @@ enum{
};

#define	STATSIZE	(2*NAMELEN+12+7*12)
Dirtab procdir[]={
Dirtab procdir[] =
{
	"ctl",		{Qctl},		0,			0000,
	"mem",		{Qmem},		0,			0000,
	"note",		{Qnote},	0,			0000,


@@ 53,13 54,14 @@ char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Shdata" };

void	procctlreq(Proc*, char*, int);
int	procctlmemio(Proc*, ulong, int, void*, int);
Chan   *proctext(Chan*, Proc*);
Segment *txt2data(Proc*, Segment*);
Chan*	proctext(Chan*, Proc*);
Segment* txt2data(Proc*, Segment*);
int	procstopped(void*);

int
procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
{
	Qid qid;
	Proc *p;
	char buf[NAMELEN];
	ulong pid, path, perm;


@@ 73,13 75,15 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
		if(pid == 0)
			return 0;
		sprint(buf, "%d", pid);
		devdir(c, (Qid){CHDIR|((s+1)<<QSHIFT), pid}, buf, 0, p->user, CHDIR|0555, dp);
		qid = (Qid){CHDIR|((s+1)<<QSHIFT), pid};
		devdir(c, qid, buf, 0, p->user, CHDIR|0555, dp);
		return 1;
	}
	if(s >= NPROC)
		return -1;
	if(tab)
		panic("procgen");

	tab = &procdir[s];
	path = c->qid.path&~(CHDIR|((1<<QSHIFT)-1));	/* slot component */



@@ 88,7 92,8 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
	if(perm == 0)
		perm = p->procmode;

	devdir(c, (Qid){path|tab->qid.path, c->qid.vers}, tab->name, tab->length, p->user, perm, dp);
	qid = (Qid){path|tab->qid.path, c->qid.vers};
	devdir(c, qid, tab->name, tab->length, p->user, perm, dp);
	return 1;
}



@@ 156,7 161,6 @@ procopen(Chan *c, int omode)
			error(Eperm);
		tc = proctext(c, p);
		tc->offset = 0;

		return tc;

	case Qctl:


@@ 168,11 172,12 @@ procopen(Chan *c, int omode)
		break;

	case Qnotepg:
		if(omode!=OWRITE || pg->pgrpid==1)	/* easy to do by mistake */
		if(omode!=OWRITE || pg->pgrpid == 1)
			error(Eperm);
		c->pgrpid.path = pg->index+1;
		c->pgrpid.path = pg->pgrpid+1;
		c->pgrpid.vers = p->noteid;
		break;

	default:
		pprint("procopen %lux\n", c->qid);
		error(Egreg);


@@ 263,6 268,10 @@ procread(Chan *c, void *va, long n, ulong offset)
		}

		if(offset >= KZERO) {
			/* Protect crypt key memory */
			if(offset >= palloc.cmembase && offset < palloc.cmemtop)
				error(Eperm);

			/* validate physical kernel addresses */
			if(offset < (ulong)end) {
				if(offset+n > (ulong)end)


@@ 332,11 341,6 @@ procread(Chan *c, void *va, long n, ulong offset)
		if(offset+n > STATSIZE)
			n = STATSIZE - offset;

/* Assertion for deref of psstate which causes faults */
if((p->state < Dead) || (p->state > Rendezvous))
	panic("p->state=#%lux, p->psstate=#%lux\n", p->state, p->psstate);


		j = sprint(statbuf, "%-27s %-27s %-11s ",
			p->text, p->user, p->psstate ? p->psstate : statename[p->state]);
		for(i=0; i<6; i++){


@@ 424,7 428,8 @@ procwrite(Chan *c, void *va, long n, ulong offset)
			pxu = (User*)b;
			hi = offset+n;
			/* Check for floating point registers */
			if(offset >= (ulong)&u->fpsave && hi <= (ulong)&u->fpsave+sizeof(FPsave)){
			if(offset >= (ulong)&u->fpsave &&
			   hi <= (ulong)&u->fpsave+sizeof(FPsave)){
				memmove(b+(offset-USERADDR), a, n);
				break;
			}


@@ 598,9 603,9 @@ procstopped(void *a)
int
procctlmemio(Proc *p, ulong offset, int n, void *va, int read)
{
	KMap *k;
	Pte *pte;
	Page *pg;
	KMap *k;
	Segment *s;
	ulong soff, l;
	char *a = va, *b;


@@ 660,8 665,8 @@ procctlmemio(Proc *p, ulong offset, int n, void *va, int read)
Segment *
txt2data(Proc *p, Segment *s)
{
	Segment *ps;
	int i;
	Segment *ps;

	ps = newseg(SG_DATA, s->base, s->size);
	ps->image = s->image;

M port/error.h => port/error.h +1 -0
@@ 53,3 53,4 @@ extern char Eneedservice[];	/* service required for tcp/udp/il calls */
extern char Enomem[];		/* kernel allocate failed */
extern char Esfnotcached[];	/* subfont not cached */
extern char Egreg[];		/* it's a thermal problem */
extern char Esoverlap[];	/* segments overlap */

M port/pgrp.c => port/pgrp.c +120 -73
@@ 8,6 8,52 @@
static Ref pgrpid;
static Ref mountid;

struct
{
	Lock;
	Crypt	*free;
} cryptalloc;

/*
 * crypt entries are allocated from a pool rather than allocated using malloc so
 * the memory can be protected from reading by devproc. The base and top of the
 * crypt arena is stored in palloc for devproc.
 */
Crypt*
newcrypt(void)
{
	Crypt *c;

	lock(&cryptalloc);
	if(cryptalloc.free) {
		c = cryptalloc.free;
		cryptalloc.free = c->next;
		unlock(&cryptalloc);
		return c;
	}

	cryptalloc.free = malloc(sizeof(Crypt)*conf.nproc);
	if(cryptalloc.free == 0)
		panic("newcrypt");

	for(c = cryptalloc.free+1; c < cryptalloc.free+conf.nproc-1; c++)
		c->next = c+1;

	palloc.cmembase = (ulong)cryptalloc.free;
	palloc.cmembase = palloc.cmembase+(sizeof(Crypt)*conf.nproc);
	unlock(&cryptalloc);
	return newcrypt();
}

void
freecrypt(Crypt *c)
{
	lock(&cryptalloc);
	c->next = cryptalloc.free;
	cryptalloc.free = c;
	unlock(&cryptalloc);
}

void
pgrpnote(ulong noteid, char *a, long n, int flag)
{


@@ 26,11 72,11 @@ pgrpnote(ulong noteid, char *a, long n, int flag)
			continue;
		if(p->noteid == noteid && p->kp == 0) {
			qlock(&p->debug);
			if(p->pid==0 || p->noteid != noteid){
			if(p->pid == 0 || p->noteid != noteid){
				qunlock(&p->debug);
				continue;
			}
			if(!waserror()){
			if(!waserror()) {
				postnote(p, 0, buf, flag);
				poperror();
			}


@@ 44,53 90,13 @@ newpgrp(void)
{
	Pgrp *p;

	p = smalloc(sizeof(Pgrp)+sizeof(Crypt));
	p = smalloc(sizeof(Pgrp));
	p->ref = 1;
	/* This needs to have its own arena for protection */
	p->crypt = (Crypt*)((uchar*)p+sizeof(Pgrp));
	p->crypt = newcrypt();
	p->pgrpid = incref(&pgrpid);
	return p;
}

Fgrp*
dupfgrp(Fgrp *f)
{
	Fgrp *new;
	Chan *c;
	int i;

	new = smalloc(sizeof(Fgrp));
	new->ref = 1;

	lock(f);
	new->maxfd = f->maxfd;
	for(i = 0; i <= f->maxfd; i++)
		if(c = f->fd[i]){
			incref(c);
			new->fd[i] = c;
		}
	unlock(f);

	return new;
}

void
resrcwait(char *reason)
{
	char *p;

	p = u->p->psstate;
	if(reason) {
		u->p->psstate = reason;
		print("%s\n", reason);
	}
	if(u == 0)
		panic("resrcwait");

	tsleep(&u->p->sleep, return0, 0, 1000);
	u->p->psstate = p;
}

void
closepgrp(Pgrp *p)
{


@@ 110,40 116,12 @@ closepgrp(Pgrp *p)
			}
		}
		qunlock(&p->debug);
		freecrypt(p->crypt);
		free(p);
	}
}

void
closefgrp(Fgrp *f)
{
	int i;
	Chan *c;

	if(decref(f) == 0) {
		for(i = 0; i <= f->maxfd; i++)
			if(c = f->fd[i])
				close(c);

		free(f);
	}
}


Mount*
newmount(Mhead *mh, Chan *to)
{
	Mount *m;

	m = smalloc(sizeof(Mount));
	m->to = to;
	m->head = mh;
	incref(to);
	m->mountid = incref(&mountid);
	return m;
}

void
pgrpcpy(Pgrp *to, Pgrp *from)
{
	Mhead **h, **e, *f, **tom, **l, *mh;


@@ 173,6 151,58 @@ pgrpcpy(Pgrp *to, Pgrp *from)
	runlock(&from->ns);
}

Fgrp*
dupfgrp(Fgrp *f)
{
	Fgrp *new;
	Chan *c;
	int i;

	new = smalloc(sizeof(Fgrp));
	new->ref = 1;

	lock(f);
	new->maxfd = f->maxfd;
	for(i = 0; i <= f->maxfd; i++) {
		if(c = f->fd[i]){
			incref(c);
			new->fd[i] = c;
		}
	}
	unlock(f);

	return new;
}

void
closefgrp(Fgrp *f)
{
	int i;
	Chan *c;

	if(decref(f) == 0) {
		for(i = 0; i <= f->maxfd; i++)
			if(c = f->fd[i])
				close(c);

		free(f);
	}
}


Mount*
newmount(Mhead *mh, Chan *to)
{
	Mount *m;

	m = smalloc(sizeof(Mount));
	m->to = to;
	m->head = mh;
	incref(to);
	m->mountid = incref(&mountid);
	return m;
}

void
mountfree(Mount *m)
{


@@ 185,3 215,20 @@ mountfree(Mount *m)
		m = f;
	}
}

void
resrcwait(char *reason)
{
	char *p;

	p = u->p->psstate;
	if(reason) {
		u->p->psstate = reason;
		print("%s\n", reason);
	}
	if(u == 0)
		panic("resrcwait");

	tsleep(&u->p->sleep, return0, 0, 1000);
	u->p->psstate = p;
}

M port/portdat.h => port/portdat.h +86 -86
@@ 179,23 179,24 @@ struct Crypt
{
	char	key[DESKEYLEN];		/* des encryption key */
	char	chal[8];		/* challenge for setting user name */
	Crypt	*next;
};

struct Dev
{
	void	 (*reset)(void);
	void	 (*init)(void);
	Chan	*(*attach)(char*);
	Chan	*(*clone)(Chan*, Chan*);
	int	 (*walk)(Chan*, char*);
	void	 (*stat)(Chan*, char*);
	Chan	*(*open)(Chan*, int);
	void	 (*create)(Chan*, char*, int, ulong);
	void	 (*close)(Chan*);
	long	 (*read)(Chan*, void*, long, ulong);
	long	 (*write)(Chan*, void*, long, ulong);
	void	 (*remove)(Chan*);
	void	 (*wstat)(Chan*, char*);
	void	(*reset)(void);
	void	(*init)(void);
	Chan*	(*attach)(char*);
	Chan*	(*clone)(Chan*, Chan*);
	int	(*walk)(Chan*, char*);
	void	(*stat)(Chan*, char*);
	Chan*	(*open)(Chan*, int);
	void	(*create)(Chan*, char*, int, ulong);
	void	(*close)(Chan*);
	long	(*read)(Chan*, void*, long, ulong);
	long	(*write)(Chan*, void*, long, ulong);
	void	(*remove)(Chan*);
	void	(*wstat)(Chan*, char*);
};

struct Dirtab


@@ 211,19 212,21 @@ struct Dirtab
 */
struct Etherpkt
{
	uchar d[6];
	uchar s[6];
	uchar type[2];
	uchar data[1500];
	uchar crc[4];
	uchar	d[6];
	uchar	s[6];
	uchar	type[2];
	uchar	data[1500];
	uchar	crc[4];
};
#define	ETHERMINTU	60		/* minimum transmit size */
#define	ETHERMAXTU	1514		/* maximum transmit size */
#define ETHERHDRSIZE	14		/* size of an ethernet header */

/*
 *  SCSI devices.
 */
enum
{
	ETHERMINTU =	60,		/* minimum transmit size */
	ETHERMAXTU =	1514,		/* maximum transmit size */
	ETHERHDRSIZE =	14,		/* size of an ethernet header */
};

/* SCSI devices. */
enum
{
	ScsiTestunit	= 0x00,


@@ 233,44 236,41 @@ enum
	ScsiRead	= 0x08,
	ScsiWrite	= 0x0a,

	/*
	 * data direction
	 */
	/* data direction */
	ScsiIn		= 1,
	ScsiOut		= 0,
};

struct Scsibuf
{
	void *	virt;
	void *	phys;
	Scsibuf *next;
	void*		virt;
	void*		phys;
	Scsibuf*	next;
};

struct Scsidata
{
	uchar *	base;
	uchar *	lim;
	uchar *	ptr;
	uchar*		base;
	uchar*		lim;
	uchar*		ptr;
};

struct Scsi
{
	QLock;
	ulong	pid;
	ushort	target;
	ushort	lun;
	ushort	rflag;
	ushort	status;
	Scsidata cmd;
	Scsidata data;
	Scsibuf	*b;
	uchar	*save;
	uchar	cmdblk[16];
};
/*
 *  character based IO (mouse, keyboard, console screen)
 */
	ulong		pid;
	ushort		target;
	ushort		lun;
	ushort		rflag;
	ushort		status;
	Scsidata 	cmd;
	Scsidata 	data;
	Scsibuf*	b;
	uchar*		save;
	uchar		cmdblk[16];
};

/* character based IO (mouse, keyboard, console screen) */
#define NQ	4096
struct IOQ
{


@@ 362,7 362,7 @@ struct Swapalloc
	char	*top;			/* Top of swap map */
	Rendez	r;			/* Pager kproc idle sleep */
	ulong	highwater;		/* Threshold beyond which we must page */
	ulong	headroom;		/* Space pager attempts to clear below highwater */
	ulong	headroom;		/* Space pager keeps free under highwater */
}swapalloc;

struct Image


@@ 373,7 373,7 @@ struct Image
	Qid	mqid;
	Chan	*mchan;
	ushort	type;			/* Device type of owning channel */
	Segment *s;			/* TEXT segment for image if running, may be null */
	Segment *s;			/* TEXT segment for image if running */
	Image	*hash;			/* Qid hash chains */
	Image	*next;			/* Free list */
};


@@ 421,22 421,26 @@ struct Segment
	ulong	fstart;			/* start address in file for demand load */
	ulong	flen;			/* length of segment in file */
	int	flushme;		/* maintain consistent icache for this segment */
	Image	*image;			/* image in file system attached to this segment */
	Image	*image;			/* text in file attached to this segment */
	Page	*(*pgalloc)(ulong addr);/* SG_PHYSICAL page allocator */
	void	(*pgfree)(Page *);	/* SG_PHYSICAL page free */
	Pte	*map[SEGMAPSIZE];	/* segment pte map */
};

#define RENDHASH	32
enum
{
	RENDHASH =	32,		/* Hash to lookup rendezvous tags */
	MNTHASH	=	32,		/* Hash to walk mount table */
	NFD =		100,		/* Number of per process file descriptors */
	PGHSIZE	=	512,		/* Page hash for image lookup */
};
#define REND(p,s)	((p)->rendhash[(s)%RENDHASH])
#define MNTHASH		32
#define MOUNTH(p,s)	((p)->mnthash[(s)->qid.path%MNTHASH])

struct Pgrp
{
	Ref;				/* also used as a lock when mounting */
	Pgrp	*next;			/* free list */
	int	index;			/* index in pgrp table */
	ulong	pgrpid;
	Crypt	*crypt;			/* encryption key and challenge */
	QLock	debug;			/* single access via devproc.c */


@@ 462,7 466,6 @@ struct Evalue
	Evalue	*link;
};

#define	NFD	100
struct Fgrp
{
	Ref;


@@ 470,7 473,6 @@ struct Fgrp
	int	maxfd;			/* highest fd in use */
};

#define PGHSIZE	512
struct Palloc
{
	Lock;


@@ 485,16 487,8 @@ struct Palloc
	Rendez	r;			/* Sleep for free mem */
	QLock	pwait;			/* Queue of procs waiting for memory */
	int	wanted;			/* Do the wakeup at free */
};

struct Pgrps
{
	Lock;
	Pgrp	*arena;
	Pgrp	*free;
	ulong	pgrpid;
	ulong	cryptbase;
	ulong	crypttop;
	ulong	cmembase;		/* Key memory protected from read by devproc */
	ulong	cmemtop;
};

struct Waitq


@@ 609,7 603,7 @@ struct Proc
	int	(*tfn)(void*);

	/*
	 *  machine specific MMU goo
	 *  machine specific MMU
	 */
	PMMU;
};


@@ 629,13 623,14 @@ struct Qinfo
	Qinfo		*next;
};

/*
 *  Queue.flag
 */
#define QHUNGUP	0x1			/* flag bit meaning the stream has been hung up */
#define QINUSE	0x2
#define QHIWAT	0x4			/* queue has gone past the high water mark */	
#define QDEBUG	0x8
/* Queue.flag */
enum
{
	QHUNGUP	=	0x1,	/* stream has been hung up */
	QINUSE =	0x2,	/* allocation check */
	QHIWAT =	0x4,	/* queue has gone past the high water mark */	
	QDEBUG =	0x8,
};

struct Queue
{


@@ 686,12 681,12 @@ struct Stream
 */
enum
{
	Shighqid = STREAMQID(1,0) - 1,
	Sdataqid = Shighqid,
	Sctlqid = Sdataqid-1,
	Slowqid = Sctlqid,
	Streamhi= (32*1024),		/* byte count high water mark */
	Streambhi= 128,			/* block count high water mark */
	Shighqid	= STREAMQID(1,0) - 1,
	Sdataqid	= Shighqid,
	Sctlqid		= Sdataqid-1,
	Slowqid		= Sctlqid,
	Streamhi	= (32*1024),	/* byte count high water mark */
	Streambhi	= 128,		/* block count high water mark */
};

/*


@@ 725,9 720,12 @@ struct Network
	Netprot	*prot;			/* linked list of protections */
};

#define	PRINTSIZE	256
#define	NUMSIZE		12		/* size of formatted number */
#define MB		(1024*1024)
enum
{
	PRINTSIZE =	256,
	NUMSIZE	=	12,		/* size of formatted number */
	MB =		(1024*1024),
};

extern	Conf	conf;
extern	char*	conffile;


@@ 748,12 746,14 @@ extern  Image	swapimage;
extern	char	sysname[NAMELEN];
extern	Talarm	talarm;
extern	Palloc 	palloc;
extern	Pgrps 	pgrpalloc;
extern	int	cpuserver;

#define	CHDIR		0x80000000L
#define	CHAPPEND 	0x40000000L
#define	CHEXCL		0x20000000L
enum
{
	CHDIR =		0x80000000L,
	CHAPPEND = 	0x40000000L,
	CHEXCL =	0x20000000L,
};

/*
 * auth messages

M port/segment.c => port/segment.c +23 -29
@@ 62,9 62,7 @@ putseg(Segment *s)
		return;

	i = s->image;
	if(i)
	if(i->s == s)
	if(s->ref == 1) {
	if(i && i->s == s && s->ref == 1) {
		lock(i);
		if(s->ref == 1)
			i->s = 0;


@@ 94,22 92,24 @@ relocateseg(Segment *s, ulong offset)
	Page **pg, **endpages;

	endpte = &s->map[SEGMAPSIZE];
	for(p = s->map; p < endpte; p++)
	for(p = s->map; p < endpte; p++) {
		if(*p) {
			endpages = &((*p)->pages[PTEPERTAB]);
			for(pg = (*p)->pages; pg < endpages; pg++)
				if(*pg)
					(*pg)->va += offset;
		}
	}
}

Segment*
dupseg(Segment *s, int share)
{
	int i;
	Pte *pte;
	Segment *n;
	int i;

	SET(n);
	switch(s->type&SG_TYPE) {
	case SG_TEXT:			/* New segment shares pte set */
	case SG_SHARED:


@@ 121,7 121,7 @@ dupseg(Segment *s, int share)
	case SG_STACK:
		qlock(&s->lk);
		n = newseg(s->type, s->base, s->size);
		goto copypte;
		break;

	case SG_BSS:			/* Just copy on write */
		qlock(&s->lk);


@@ 132,7 132,7 @@ dupseg(Segment *s, int share)
			return s;
		}
		n = newseg(s->type, s->base, s->size);
		goto copypte;
		break;

	case SG_DATA:			/* Copy on write plus demand load info */
		qlock(&s->lk);


@@ 148,19 148,15 @@ dupseg(Segment *s, int share)
		n->image = s->image;
		n->fstart = s->fstart;
		n->flen = s->flen;

	copypte:
		for(i = 0; i < SEGMAPSIZE; i++)
			if(pte = s->map[i])
				n->map[i] = ptecpy(pte);

		n->flushme = s->flushme;
		qunlock(&s->lk);
		return n;	
		break;
	}
	for(i = 0; i < SEGMAPSIZE; i++)
		if(pte = s->map[i])
			n->map[i] = ptecpy(pte);

	panic("dupseg");
	return 0;		/* not reached */
	n->flushme = s->flushme;
	qunlock(&s->lk);
	return n;	
}

void


@@ 320,8 316,8 @@ ibrk(ulong addr, int seg)

	qlock(&s->lk);

	/* We may start with the bss overlapping the data */
	if(addr < s->base) {
		/* We may start with the bss overlapping the data */
		if(seg != BSEG || u->p->seg[DSEG] == 0 || addr < u->p->seg[DSEG]->base) {
			qunlock(&s->lk);
			error(Enovmem);


@@ 337,23 333,21 @@ ibrk(ulong addr, int seg)
		return 0;
	}

	if(newsize > (PTEMAPMEM*SEGMAPSIZE)/BY2PG) {
		qunlock(&s->lk);
		return -1;
	}

	for(i = 0; i < NSEG; i++) {
		ns = u->p->seg[i];
		if(ns == 0 || ns == s)
			continue;
		if(newtop >= ns->base)
		if(newtop < ns->top) {
		if(newtop >= ns->base && newtop < ns->top) {
			qunlock(&s->lk);
			pprint("segments overlap\n");
			error(Enovmem);
			error(Esoverlap);
		}
	}

	if(newsize > (PTEMAPMEM*SEGMAPSIZE)/BY2PG) {
		qunlock(&s->lk);
		return -1;
	}

	s->top = newtop;
	s->size = newsize;
	qunlock(&s->lk);


@@ 424,7 418,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
			continue;	
		if((newtop > ns->base && newtop <= ns->top) ||
		   (va >= ns->base && va < ns->top))
			error(Enovmem);
			error(Esoverlap);
	}

	for(ps = physseg; ps->name; ps++)

D ss/malloc.h => ss/malloc.h +0 -15
@@ 1,15 0,0 @@
struct tbl_entry {
	struct tbl_entry *next;		/* free list */
	int *data;			/* data */
};

struct table {
	int size;			/* # entries */
	struct tbl_entry *entries;	/* the entries */
	struct tbl_entry *free;		/* the free list */
};

void *tbl_alloc(struct table *, int);
void tbl_free(struct table *, void *);
int tbl_index(struct table *, void *);
void *tbl_data(struct table *, int);

M ss/screen.c => ss/screen.c +7 -19
@@ 100,13 100,13 @@ screeninit(char *str)
		dac->cntrl = 0x00;	/* no tests */
		havecol = 0;	
		if(havecol) {
			/*
			 * For now, just use a fixed colormap, where pixel i is
			 * regarded as 3 bits of red, 3 bits of green, and 2 bits of blue.
			 * Intensities are inverted so that 0 means white, 255 means black.
			 * Exception: pixels 85 and 170 are set to intermediate grey values
			 * so that 2-bit grey scale images will look ok on this screen.
			 */
		/*
		 * For now, just use a fixed colormap, where pixel i is
		 * regarded as 3 bits of red, 3 bits of green, and 2 bits of blue.
		 * Intensities are inverted so that 0 means white, 255 means black.
		 * Exception: pixels 85 and 170 are set to intermediate grey values
		 * so that 2-bit grey scale images will look ok on this screen.
		 */
			for(i = 0; i<256; i++) {
				r = ~rep((i>>5) & 7, 3);
				g = ~rep((i>>2) & 7, 3);


@@ 126,18 126,6 @@ screeninit(char *str)
	}
}

mapdump(void)
{
	dac->addr = 4;
	print("cntrl4 %.2ux\n", dac->cntrl);
	dac->addr = 5;
	print("cntrl5 %.2ux\n", dac->cntrl);
	dac->addr = 6;
	print("cntrl6 %.2ux\n", dac->cntrl);
	dac->addr = 7;
	print("cntrl7 %.2ux\n", dac->cntrl);
}

void
screenputnl(void)
{