~kris/9p

9hist

dddced867518bc3d3ab9bbb0b9d728e35d495f12 — David du Colombier 36 years ago 70fd5bf
Plan 9 from Bell Labs 1990-03-29
6 files changed, 257 insertions(+), 32 deletions(-)

M gnot/dev.c
M gnot/errno.h
M gnot/fns.h
M gnot/screen.c
M port/dev.c
M port/devbit.c
M gnot/dev.c => gnot/dev.c +2 -0
@@ 67,6 67,8 @@ devattach(int tc, char *spec)
Chan *
devclone(Chan *c, Chan *nc)
{
	if(c->flag & COPEN)
		panic("clone of open file type %c\n", devchar[c->type]);
	if(nc == 0)
		nc = newchan();
	nc->type = c->type;

M gnot/errno.h => gnot/errno.h +1 -0
@@ 49,5 49,6 @@ enum{
	Ebadblt,	/* bad bitblt or bitmap request */
	Enobitmap,	/* out of bitmap descriptors */
	Enobitstore,	/* out of bitmap storage */
	Ebadbitmap,	/* unallocated bitmap */
	Egreg,		/* it's all greg's fault */
};

M gnot/fns.h => gnot/fns.h +1 -0
@@ 69,6 69,7 @@ void	machinit(void);
void	mapstack(Proc*);
void	mmuinit(void);
int	mount(Chan*, Chan*, int);
void	mousebuttons(int);
Chan	*namec(char*, int, int, ulong);
void	nexterror(void);
Alarm	*newalarm(void);

M gnot/screen.c => gnot/screen.c +75 -7
@@ 16,6 16,8 @@ struct{
	int	bwid;
}out;

void	duartinit(void);

Bitmap	screen =
{
	(ulong*)((4*1024*1024-256*1024)|KZERO),	/* BUG */


@@ 29,7 31,8 @@ Bitmap	screen =
void
screeninit(void)
{
	bitblt(&screen, Pt(0, 0), &screen, screen.rect, 0);
	duartinit();
	bitblt(&screen, Pt(0, 0), &screen, screen.r, 0);
	out.pos.x = MINX;
	out.pos.y = 0;
	out.bwid = defont0.info[' '].width;


@@ 44,14 47,14 @@ screenputc(int c)
	if(c == '\n'){
		out.pos.x = MINX;
		out.pos.y += defont0.height;
		if(out.pos.y > screen.rect.max.y-defont0.height)
			out.pos.y = screen.rect.min.y;
		if(out.pos.y > screen.r.max.y-defont0.height)
			out.pos.y = screen.r.min.y;
		bitblt(&screen, Pt(0, out.pos.y), &screen,
		    Rect(0, out.pos.y, screen.rect.max.x, out.pos.y+2*defont0.height), 0);
		    Rect(0, out.pos.y, screen.r.max.x, out.pos.y+2*defont0.height), 0);
	}else if(c == '\t'){
		nx = out.pos.x + (8-(out.pos.x/out.bwid&7))*out.bwid;
		out.pos.x = nx;
		if(out.pos.x >= screen.rect.max.x)
		if(out.pos.x >= screen.r.max.x)
			screenputc('\n');
	}else if(c == '\b'){
		if(out.pos.x >= out.bwid+MINX){


@@ 60,7 63,7 @@ screenputc(int c)
			out.pos.x -= out.bwid;
		}
	}else{
		if(out.pos.x >= screen.rect.max.x-out.bwid)
		if(out.pos.x >= screen.r.max.x-out.bwid)
			screenputc('\n');
		buf[0] = c&0x7F;
		buf[1] = 0;


@@ 77,13 80,18 @@ struct Duart{
	uchar	cmnd;		/* Command Register */
	uchar	data;		/* RX Holding / TX Holding Register */
	uchar	ipc_acr;	/* Input Port Change/Aux. Control Register */
#define	ivr	ivr		/* Interrupt Vector Register */
	uchar	is_imr;		/* Interrupt Status/Interrupt Mask Register */
#define	ip_opcr	is_imr		/* Input Port/Output Port Configuration Register */
	uchar	ctur;		/* Counter/Timer Upper Register */
#define	scc_sopbc ctur		/* Start Counter Command/Set Output Port Bits Command */
	uchar	ctlr;		/* Counter/Timer Lower Register */
#define	scc_ropbc ctlr		/* Stop Counter Command/Reset Output Port Bits Command */
};

enum{
	CHAR_ERR	=0x00,	/* MR1x - Mode Register 1 */
	PAR_ENB		=0x00,
	EVEN_PAR	=0x00,
	ODD_PAR		=0x04,
	NO_PAR		=0x10,


@@ 113,6 121,9 @@ enum{
	PAR_ERR		=0x20,
	FRM_ERR		=0x40,
	RCVD_BRK	=0x80,
	BD9600		=0xBB,
	BD4800		=0x99,
	BD2400		=0x88,
	IM_IPC		=0x80,	/* IMRx/ISRx - Interrupt Mask/Interrupt Status */
	IM_DBB		=0x40,
	IM_RRDYB	=0x20,


@@ 143,6 154,54 @@ uchar keymap[]={
};

void
duartinit(void)
{
	Duart *duart;

	duart  =  DUARTREG;

	/*
	 * Keyboard
	 */
	duart[0].cmnd = RESET_RCV|DIS_TX|DIS_RX;
	duart[0].cmnd = RESET_TRANS;
	duart[0].cmnd = RESET_ERR;
	duart[0].cmnd = RESET_MR;
	duart[0].mr1_2 = CHAR_ERR|PAR_ENB|EVEN_PAR|CBITS8;
	duart[0].mr1_2 = NORM_OP|ONESTOPB;
	duart[0].sr_csr = BD4800;

	/*
	 * Pen
	 */
	duart[1].cmnd = RESET_RCV|DIS_TX|DIS_RX;
	duart[1].cmnd = RESET_TRANS;
	duart[1].cmnd = RESET_ERR;
	duart[1].cmnd = RESET_MR;
	duart[1].mr1_2 = CHAR_ERR|NO_PAR|CBITS8;
	duart[1].mr1_2 = NORM_OP|ONESTOPB;
	duart[1].sr_csr = BD2400;

	/*
	 * Output port
	 */
	duart[0].ipc_acr = 0xBF;	/* allow change	of state interrupt */
	duart[1].ip_opcr = 0x00;
	duart[1].scc_ropbc = 0xFF;	/* make sure the port is reset first */
	duart[1].scc_sopbc = 0x04;	/* dtr = 1, pp = 01 */
	duart[0].is_imr = IM_IPC|IM_RRDYB|IM_XRDYB|IM_RRDYA;
	duart[0].cmnd = ENB_TX|ENB_RX;	/* enable TX and RX last */
	duart[1].cmnd = ENB_TX|ENB_RX;

	/*
	 * Initialize keyboard
	 */
	while (!(duart[0].sr_csr & (XMT_EMT|XMT_RDY)))
		;
	duart[0].data = 0x02;
}

void
duartintr(void)
{
	int cause, status, c;


@@ 176,5 235,14 @@ duartintr(void)
	 */
	if(cause & IM_RRDYB)		/* pen input */
		c = duart[1].data;
	/*
	 * Is it 4?
	 */
	if(cause & IM_XRDYB)
		duart[1].cmnd = DIS_TX;
	/*
	 * Is it 3?
	 */
	if(cause & IM_IPC)
		mousebuttons((~duart[0].ipc_acr) & 7);
}


M port/dev.c => port/dev.c +2 -0
@@ 67,6 67,8 @@ devattach(int tc, char *spec)
Chan *
devclone(Chan *c, Chan *nc)
{
	if(c->flag & COPEN)
		panic("clone of open file type %c\n", devchar[c->type]);
	if(nc == 0)
		nc = newchan();
	nc->type = c->type;

M port/devbit.c => port/devbit.c +176 -25
@@ 9,6 9,13 @@

#include	"gnot.h"

extern Font	defont0;	/* BUG */

/*
 * Device (#b/bitblt) is exclusive use on open, so no locks are necessary
 * for i/o
 */

/*
 * Some fields in Bitmaps are overloaded:
 *	ldepth = -1 means free.


@@ 20,27 27,30 @@
struct{
	Ref;
	int	bltuse;
	QLock	blt;		/* a group of bitblts in a single write is atomic */
	Bitmap	*map;		/* arena */
	Bitmap	*free;		/* free list */
	ulong	*words;		/* storage */
	ulong	nwords;		/* total in arena */
	ulong	*wfree;		/* pointer to next free word */
	int	lastid;		/* last allocated bitmap id */
	int	init;		/* freshly opened; init message pending */
}bit;

#define	FREE	0x80000000
void	bitcompact(void);
void	bitfree(Bitmap*);
extern	Bitmap	screen;
Mouse	mouse;

enum{
	Qdir,
	Qbitblt,
	Qmouse,
};

Dirtab bitdir[]={
	"bitblt",	Qbitblt,	0,			0600,
	"mouse",	Qmouse,		0,			0600,
};

#define	NBIT	(sizeof bitdir/sizeof(Dirtab))


@@ 113,6 123,7 @@ bitopen(Chan *c, int omode)
			error(0, Einuse);
		}
		bit.lastid = -1;
		bit.init = 1;
		unlock(&bit);
		incref(&bit);
	}


@@ 147,7 158,7 @@ bitclose(Chan *c)
	Bitmap *bp;

	if(c->qid != CHDIR){
		lock(&bit);			/* FREE ALL THE BITMAPS: BUG */
		lock(&bit);
		if(--bit.ref == 0){
			for(i=1,bp=&bit.map[1]; i<conf.nbitmap; i++,bp++)
				if(bp->ldepth >= 0)


@@ 160,6 171,15 @@ bitclose(Chan *c)

#define	GSHORT(p)		(((p)[0]<<0) | ((p)[1]<<8))
#define	GLONG(p)		((GSHORT(p)<<0) | (GSHORT(p+2)<<16))
#define	PSHORT(p, v)		((p)[0]=(v), (p)[1]=((v)>>8))
#define	PLONG(p, v)		(PSHORT(p, (v)), PSHORT(p+2, (v)>>16))

/*
 * These macros turn user-level (high bit at left) into internal (whatever)
 * bit order.  On the gnot they're trivial.
 */
#define	U2K(x)	(x)
#define	K2U(x)	(x)

long
bitread(Chan *c, void *va, long n)


@@ 172,20 192,37 @@ bitread(Chan *c, void *va, long n)
	if(c->qid != Qbitblt)
		error(0, Egreg);
	p = va;
	qlock(&bit.blt);
	if(waserror()){
		qunlock(&bit.blt);
		nexterror();
	}
	/*
	 * Fuss about and figure out what to say.
	 */
	if(bit.init){
		/*
		 * init:
		 *	'I'		1
		 *	ldepth		2
		 * 	rectangle	16
		 */
		if(n < 19)
			error(0, Ebadblt);
		p[0] = 'I';
		PSHORT(p+1, screen.ldepth);
		PLONG(p+3, screen.r.min.x);
		PLONG(p+7, screen.r.min.y);
		PLONG(p+11, screen.r.max.x);
		PLONG(p+15, screen.r.max.y);
		bit.init = 0;
		goto done;
	}
	if(bit.lastid > 0){
		/*
		 * allocate:
		 *	'A'		1
		 *	bitmap id	2
		 */
		if(n < 3)
			error(0, Ebadblt);
		p[0] = 'A';
		p[1] = bit.lastid;
		p[2] = bit.lastid>>8;
		PSHORT(p+1, bit.lastid);
		bit.lastid = -1;
		n = 3;
		goto done;


@@ 193,7 230,6 @@ bitread(Chan *c, void *va, long n)
	error(0, Ebadblt);

    done:
	qunlock(&bit.blt);
	return n;
}



@@ 201,9 237,8 @@ bitread(Chan *c, void *va, long n)
long
bitwrite(Chan *c, void *va, long n)
{
	uchar *p;
	long m;
	long v;
	uchar *p, *q;
	long m, v, miny, maxy, t, x, y;
	ulong l, nw, ws;
	Point pt;
	Rectangle rect;


@@ 217,13 252,12 @@ bitwrite(Chan *c, void *va, long n)

	p = va;
	m = n;
	qlock(&bit.blt);
	if(waserror()){
		qunlock(&bit.blt);
		nexterror();
	}
	while(m > 0)
		switch(*p){
		default:
			pprint("bitblt request 0x%x\n", *p);
			error(0, Ebadblt);

		case 'a':
			/*
			 * allocate:


@@ 247,7 281,6 @@ bitwrite(Chan *c, void *va, long n)
			if(rect.min.x >= 0)
				l = (rect.max.x+ws-1)/ws - rect.min.x/ws;
			else{	/* make positive before divide */
				long t;
				t = (-rect.min.x)+ws-1;
				t = (t/ws)*ws;
				l = (t+rect.max.x+ws-1)/ws;


@@ 273,7 306,7 @@ bitwrite(Chan *c, void *va, long n)
			bp->zero = -bp->zero;
			bp->width = l;
			bp->ldepth = v;
			bp->rect = rect;
			bp->r = rect;
			bp->cache = 0;
			bit.lastid = bp-bit.map;
			m -= 18;


@@ 295,13 328,13 @@ bitwrite(Chan *c, void *va, long n)
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || dst->ldepth < 0)
				error(0, Ebadblt);
				error(0, Ebadbitmap);
			pt.x = GLONG(p+3);
			pt.y = GLONG(p+7);
			v = GSHORT(p+11);
			src = &bit.map[v];
			if(v<0 || v>=conf.nbitmap || src->ldepth < 0)
				error(0, Ebadblt);
				error(0, Ebadbitmap);
			rect.min.x = GLONG(p+13);
			rect.min.y = GLONG(p+17);
			rect.max.x = GLONG(p+21);


@@ 322,15 355,124 @@ bitwrite(Chan *c, void *va, long n)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v >= conf.nbitmap || dst->ldepth<0)
				error(0, Ebadblt);
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			bitfree(dst);
			m -= 3;
			p += 3;
			break;

		case 's':
			/*
			 * string
			 *	's'		1
			 *	id		2
			 *	pt		8
			 *	font id		2
			 *	fcode		2
			 * 	string		n (null terminated)
			 */
			if(m < 16)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			pt.x = GLONG(p+3);
			pt.y = GLONG(p+7);
			v = GSHORT(p+11);
			if(v != 0)	/* BUG */
				error(0, Ebadblt);
			v = GSHORT(p+13);
			p += 15;
			m -= 15;
			q = memchr(p, 0, m);
			if(q == 0)
				error(0, Ebadblt);
			string(dst, pt, &defont0/*BUG*/, (char*)p, v);
			q++;
			m -= q-p;
			p = q;
			break;

		case 't':
			/*
			 * texture
			 *	't'		1
			 *	dst id		2
			 *	Rectangle	16
			 *	src id		2
			 *	fcode		2
			 */
			if(m < 23)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			rect.min.x = GLONG(p+3);
			rect.min.y = GLONG(p+7);
			rect.max.x = GLONG(p+11);
			rect.max.y = GLONG(p+15);
			v = GSHORT(p+19);
			src = &bit.map[v];
			if(v>=conf.nbitmap || src->ldepth<0)
				error(0, Ebadbitmap);
			if(src->r.min.x!=0 || src->r.min.y!=0 || src->r.max.x!=16 || src->r.max.y!=16)
				error(0, Ebadblt);
			v = GSHORT(p+21);
			{
				int i;
				Texture t;

				for(i=0; i<16; i++)
					t.bits[i] = src->base[i]>>16;
				texture(dst, rect, &t, v);
			}
			m -= 23;
			p += 23;
			break;

		case 'w':
			/*
			 * write
			 *	'w'		1
			 *	dst id		2
			 *	miny		4
			 *	maxy		4
			 *	data		bytewidth*(maxy-miny)
			 */
			if(m < 11)
				error(0, Ebadblt);
			v = GSHORT(p+1);
			dst = &bit.map[v];
			if(v>=conf.nbitmap || dst->ldepth<0)
				error(0, Ebadbitmap);
			miny = GLONG(p+3);
			maxy = GLONG(p+7);
			ws = 1<<(3-dst->ldepth);	/* pixels per byte */
			/* set l to number of bytes of incoming data per scan line */
			if(dst->r.min.x >= 0)
				l = (dst->r.max.x+ws-1)/ws - dst->r.min.x/ws;
			else{	/* make positive before divide */
				t = (-dst->r.min.x)+ws-1;
				t = (t/ws)*ws;
				l = (t+dst->r.max.x+ws-1)/ws;
			}
			p += 11;
			m -= 11;
			if(m < l*(maxy-miny))
				error(0, Ebadblt);
			for(y=miny; y<maxy; y++){
				q = (uchar*)addr(dst, Pt(dst->r.min.x, y));
				q += (dst->r.min.x&((sizeof(ulong))*ws-1))/8;
				for(x=0; x<l; x++)
					*q++ = U2K(*p++);
				m -= l;
			}
			break;
		}

	qunlock(&bit.blt);
	return n;
}



@@ 377,3 519,12 @@ print("bitcompact\n");
	bit.wfree = p1;
print("bitcompact done\n");
}

void
mousebuttons(int b)
{
	if(mouse.buttons != b){
		print("buttons %x\n", b);
		mouse.buttons = b;
	}
}