~kris/9p

9hist

8dc1fbbb7ddae6d8701470ffad426ad7173603be — David du Colombier 26 years ago 14003b6
Plan 9 from Bell Labs 2000-04-07
M alphapc/devvga.c => alphapc/devvga.c +46 -29
@@ 1,4 1,5 @@
/*
 * VGA controller
 */
#include "u.h"
#include "../port/lib.h"


@@ 69,6 70,20 @@ vgaclose(Chan*)
{
}

static void
checkport(int start, int end)
{
	/* standard vga regs are OK */
	if(start >= 0x2b0 && end <= 0x2df+1)
		return;
	if(start >= 0x3c0 && end <= 0x3da+1)
		return;

	if(iounused(start, end))
		return;
	error(Eperm);
}

static long
vgaread(Chan* c, void* a, long n, vlong off)
{


@@ 76,6 91,7 @@ vgaread(Chan* c, void* a, long n, vlong off)
	char *p, *s;
	VGAscr *scr;
	ulong offset = off;
	char chbuf[30];

	switch(c->qid.path & ~CHDIR){



@@ 90,27 106,32 @@ vgaread(Chan* c, void* a, long n, vlong off)
			free(p);
			nexterror();
		}

		len = 0;

		if(scr->dev)
			s = scr->dev->name;
		else
			s = "cga";
		len = snprint(p, READSTR, "type: %s\n", s);
		if(scr->gscreen)
			len += snprint(p+len, READSTR-len, "size: %dx%dx%d\n",
		len += snprint(p+len, READSTR-len, "type %s\n", s);

		if(scr->gscreen) {
			len += snprint(p+len, READSTR-len, "size %dx%dx%d %s\n",
				scr->gscreen->r.max.x, scr->gscreen->r.max.y,
				scr->gscreen->depth);
		if(scr->cur)
			s = scr->cur->name;
		else
			s = "off";
		len += snprint(p+len, READSTR-len, "hwgc: %s\n", s);
				scr->gscreen->depth, chantostr(chbuf, scr->gscreen->chan));

			if(Dx(scr->gscreen->r) != Dx(physgscreenr) 
			|| Dy(scr->gscreen->r) != Dy(physgscreenr))
				len += snprint(p+len, READSTR-len, "actualsize %dx%d\n",
					physgscreenr.max.x, physgscreenr.max.y);
		}

		len += snprint(p+len, READSTR-len, "hwaccel %s\n", hwaccel ? "on" : "off");
		len += snprint(p+len, READSTR-len, "hwblank %s\n", hwblank ? "on" : "off");
		if(scr->pciaddr)
			snprint(p+len, READSTR-len, "addr: 0x%lux\n",
				scr->pciaddr);
			snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->pciaddr);
		else
			snprint(p+len, READSTR-len, "addr: 0x%lux\n",
				scr->aperture);

			snprint(p+len, READSTR-len, "addr 0x%lux\n", scr->aperture);
		n = readstr(offset, a, n, p);
		poperror();
		free(p);


@@ 159,10 180,6 @@ vgactl(char* a)
		if(n < 2)
			error(Ebadarg);

		/* BUG: drawinit should become a different message rather than piggybacking */
		if(scr && scr->dev && scr->dev->drawinit)
			scr->dev->drawinit(scr);

		if(strcmp(field[1], "off") == 0){
			lock(&cursor);
			if(scr->cur){


@@ 277,17 294,8 @@ vgactl(char* a)
		return;
	}
	else if(strcmp(field[0], "drawinit") == 0){
		/*
		 * This is a separate message, but first we need to make
		 * aux/vga send it; once everyone has the new vga, we
		 * can take the drawinit stuff out of hwgc.
		 */

		/*
		if(scr && scr->dev && scr->dev->drawinit)
			scr->dev->drawinit(scr);
		*/

		return;
	}
	else if(strcmp(field[0], "linear") == 0){


@@ 311,9 319,9 @@ vgactl(char* a)
	}
*/
	else if(strcmp(field[0], "blank") == 0){
		if(n < 2)
		if(n < 1)
			error(Ebadarg);
		drawblankscreen(atoi(field[1]));
		drawblankscreen(1);
		return;
	}
	else if(strcmp(field[0], "hwaccel") == 0){


@@ 325,6 333,15 @@ vgactl(char* a)
			hwaccel = 0;
		return;
	}
	else if(strcmp(field[0], "hwblank") == 0){
		if(n < 2)
			error(Ebadarg);
		if(strcmp(field[1], "on") == 0)
			hwblank = 1;
		else if(strcmp(field[1], "off") == 0)
			hwblank = 0;
		return;
	}

	error(Ebadarg);
}

M alphapc/fns.h => alphapc/fns.h +1 -0
@@ 44,6 44,7 @@ void		intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
int		ioalloc(int, int, int, char*);
void		iofree(int);
void		ioinit(void);
int		iounused(int, int);
int		iprint(char*, ...);
int		irqallocread(char*, long, vlong);
int		isaconfig(char*, int, ISAConf*);

M alphapc/io.h => alphapc/io.h +1 -0
@@ 16,6 16,7 @@ enum {
	IrqAUX		= 12,		/* PS/2 port */
	IrqIRQ13	= 13,		/* coprocessor on 386 */
	IrqATA0		= 14,
	IrqATA1		= 15,
	MaxIrqPIC	= 15,

	VectorPIC	= 64,

M alphapc/screen.c => alphapc/screen.c +18 -3
@@ 51,7 51,7 @@ screensize(int x, int y, int z, ulong chan)
	 * be given back if aperture is set.
	 */
	if(scr->aperture == 0){
		int width = (x*(1<<z))/BI2WD;
		int width = (x*z)/BI2WD;

		gscreendata.bdata = xalloc(width*BY2WD*y);
		if(gscreendata.bdata == 0)


@@ 73,11 73,16 @@ screensize(int x, int y, int z, ulong chan)
	if(gscreen == nil)
		return -1;

/*	memset(gscreen->data->bdata, 0x15, (x*y*z+7)/8);	/* RSC BUG */
	memfillcolor(gscreen, DRed);

	scr->palettedepth = 6;	/* default */
	scr->gscreendata = &gscreendata;
	scr->memdefont = getmemdefont();
	scr->gscreen = gscreen;

	physgscreenr = gscreen->r;

	drawcmap();
	return 0;
}


@@ 101,8 106,7 @@ screenaperture(int size, int align)
		aperture = scr->dev->linear(scr, &size, &align);
		if(aperture == 0)
			return 1;
	}
	else{
	}else{
		aperture = upamalloc(0, size, align);
		if(aperture == 0)
			return 1;


@@ 460,6 464,7 @@ Memimage *lastbadi;
Memdata *lastbad;
Memimage *lastbadsrc, *lastbaddst;
int hwaccel = 1;
int hwblank = 1;

int
hwdraw(Memdrawparam *par)


@@ 513,3 518,13 @@ hwdraw(Memdrawparam *par)

	return 0;	
}

void
blankscreen(int blank)
{
	VGAscr *scr;

	scr = &vgascreen[0];
	if(hwblank && scr->blank)
		scr->blank(scr, blank);
}

M alphapc/screen.h => alphapc/screen.h +7 -0
@@ 104,14 104,17 @@ struct VGAscr {
	ulong	colormap[Pcolours][3];
	int	palettedepth;

	ulong	*mmio;
	Memimage* gscreen;
	Memdata* gscreendata;
	Memsubfont* memdefont;

	int	(*fill)(VGAscr*, Rectangle, ulong);
	int	(*scroll)(VGAscr*, Rectangle, Rectangle);
	void	(*blank)(VGAscr*, int);
	ulong	id;	/* internal identifier for driver use */
};

extern VGAscr vgascreen[];

enum {


@@ 123,6 126,7 @@ extern void mousectl(char*[], int);

/* screen.c */
extern int		hwaccel;	/* use hw acceleration; default on */
extern int		hwblank;	/* use hw blanking; default on */
extern void	flushmemscreen(Rectangle);
extern int	cursoron(int);
extern void	cursoroff(int);


@@ 130,6 134,7 @@ extern void	setcursor(Cursor*);
extern int	screensize(int, int, int, ulong);
extern int	screenaperture(int, int);
extern Rectangle physgscreenr;	/* actual monitor size */
extern void	blankscreen(int);

/* devdraw.c */
extern void	deletescreenimage(void);


@@ 138,5 143,7 @@ extern int		drawhasclients(void);
/* vga.c */
extern void	vgascreenwin(VGAscr*);
extern void	vgaimageinit(ulong);
extern ulong	vgapcilinear(VGAscr*, int*, int*, int, int);

extern void	drawblankscreen(int);
extern void	vgablank(VGAscr*, int);

M alphapc/vga.c => alphapc/vga.c +28 -0
@@ 189,3 189,31 @@ vgascreenwin(VGAscr* scr)

	screenputs = vgascreenputs;
}

/*
 * Supposedly this is the way to turn DPMS
 * monitors off using just the VGA registers.
 * Unfortunately, it seems to mess up the video mode
 * on the cards I've tried.
 */
void
vgablank(VGAscr*, int blank)
{
	uchar seq1, crtc17;

	if(blank) {
		seq1 = 0x00;
		crtc17 = 0x80;
	} else {
		seq1 = 0x20;
		crtc17 = 0x00;
	}

	outs(Seqx, 0x0100);			/* synchronous reset */
	seq1 |= vgaxi(Seqx, 1) & ~0x20;
	vgaxo(Seqx, 1, seq1);
	crtc17 |= vgaxi(Crtx, 0x17) & ~0x80;
	delay(10);
	vgaxo(Crtx, 0x17, crtc17);
	outs(Crtx, 0x0300);				/* end synchronous reset */
}

M alphapc/vgas3.c => alphapc/vgas3.c +203 -0
@@ 284,6 284,208 @@ s3move(VGAscr* scr, Point p)
	return 0;
}

/*
 * The manual gives byte offsets, but we want ulong offsets, hence /4.
 */
enum {
	SrcBase = 0xA4D4/4,
	DstBase = 0xA4D8/4,
	Stride = 0xA4E4/4,
	FgrdData = 0xA4F4/4,
	WidthHeight = 0xA504/4,
	SrcXY = 0xA508/4,
	DestXY = 0xA50C/4,
	Command = 0xA500/4,
	SubStat = 0x8504/4,
	FifoStat = 0x850C/4,
};

/*
 * Wait for writes to VGA memory via linear aperture to flush.
 */
enum {Maxloop = 1<<24};
struct {
	ulong linear;
	ulong fifo;
	ulong idle;
} waitcount;

static void
waitforlinearfifo(VGAscr *scr)
{
	ulong *mmio;
	long x;
	static ulong nwaitforlinearfifo;
	ulong mask, val;

	switch(scr->id){
	default:
		panic("unknown scr->id in s3 waitforlinearfifo");
	case 0xE131:	/* ViRGE */
	case 0xE13D:	/* ViRGE/VX */
		mask = 0x0F<<6;
		val = 0x08<<6;
		break;
	case 0xE110:	/* ViRGE/GX2 */
		mask = 0x1F<<6;
		val = 0x10<<6;
		break;
	}
	mmio = scr->mmio;
	x = 0;
	while((mmio[FifoStat]&mask) != val && x++ < Maxloop)
		waitcount.linear++;
}

static void
waitforfifo(VGAscr *scr, int entries)
{
	ulong *mmio;
	long x;
	static ulong nwaitforfifo;

	mmio = scr->mmio;
	x = 0;
	while((mmio[SubStat]&0x1F00) < ((entries+2)<<8) && x++ < Maxloop)
		waitcount.fifo++;
}

static void
waitforidle(VGAscr *scr)
{
	ulong *mmio;
	long x;

	mmio = scr->mmio;
	x = 0;
	while((mmio[SubStat]&0x3F00) != 0x3000 && x++ < Maxloop)
		waitcount.idle++;
}

static int
hwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
{
	enum { Bitbltop = 0xCC };	/* copy source */
	ulong *mmio;
	ulong cmd, stride;
	Point dp, sp;
	int did, d;

	d = scr->gscreen->depth;
	did = (d-8)/8;
	cmd = 0x00000020|(Bitbltop<<17)|(did<<2);
	stride = Dx(scr->gscreen->r)*d/8;

	if(r.min.x <= sr.min.x){
		cmd |= 1<<25;
		dp.x = r.min.x;
		sp.x = sr.min.x;
	}else{
		dp.x = r.max.x-1;
		sp.x = sr.max.x-1;
	}

	if(r.min.y <= sr.min.y){
		cmd |= 1<<26;
		dp.y = r.min.y;
		sp.y = sr.min.y;
	}else{
		dp.y = r.max.y-1;
		sp.y = sr.max.y-1;
	}

	mmio = scr->mmio;
	waitforlinearfifo(scr);
	waitforfifo(scr, 7);
	mmio[SrcBase] = scr->aperture;
	mmio[DstBase] = scr->aperture;
	mmio[Stride] = (stride<<16)|stride;
	mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
	mmio[SrcXY] = (sp.x<<16)|sp.y;
	mmio[DestXY] = (dp.x<<16)|dp.y;
	mmio[Command] = cmd;
	waitforidle(scr);
	return 1;
}

static int
hwfill(VGAscr *scr, Rectangle r, ulong sval)
{
	enum { Bitbltop = 0xCC };	/* copy source */
	ulong *mmio;
	ulong cmd, stride;
	int did, d;

	d = scr->gscreen->depth;
	did = (d-8)/8;
	cmd = 0x16000120|(Bitbltop<<17)|(did<<2);
	stride = Dx(scr->gscreen->r)*d/8;
	mmio = scr->mmio;
	waitforlinearfifo(scr);
	waitforfifo(scr, 8);
	mmio[SrcBase] = scr->aperture;
	mmio[DstBase] = scr->aperture;
	mmio[DstBase] = scr->aperture;
	mmio[Stride] = (stride<<16)|stride;
	mmio[FgrdData] = sval;
	mmio[WidthHeight] = ((Dx(r)-1)<<16)|Dy(r);
	mmio[DestXY] = (r.min.x<<16)|r.min.y;
	mmio[Command] = cmd;
	waitforidle(scr);
	return 1;
}

enum {
	CursorSyncCtl = 0x0D,	/* in Seqx */
	VsyncHi = 0x80,
	VsyncLo = 0x40,
	HsyncHi = 0x20,
	HsyncLo = 0x10,
};

static void
s3blank(int blank)
{
	uchar x;

	x = vgaxi(Seqx, CursorSyncCtl);
	x &= ~0xF0;
	if(blank)
		x |= VsyncLo | HsyncLo;
	vgaxo(Seqx, CursorSyncCtl, x);
}

static void
s3drawinit(VGAscr *scr)
{
	ulong id;

	id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E);
	scr->id = id;

	/*
	 * It's highly likely that other ViRGEs will work without
	 * change to the driver, with the exception of the size of
	 * the linear aperture memory write FIFO.  Since we don't
	 * know that size, I'm not turning them on.  See waitforlinearfifo
	 * above.
	 */
	switch(id){
	case 0xE131:				/* ViRGE */
	case 0xE13D:				/* ViRGE/VX */
	case 0xE110:				/* ViRGE/GX2 */
		scr->mmio = (ulong*)(scr->pciaddr+0x1000000);
/*
 * Untested on the Alpha.
 */
/*
		scr->fill = hwfill;
		scr->scroll = hwscroll;
*/
		/* scr->blank = hwblank; */
	}
}

VGAdev vgas3dev = {
	"s3",



@@ 291,6 493,7 @@ VGAdev vgas3dev = {
	0,
	s3page,
	s3linear,
	s3drawinit,
};

VGAcur vgas3cur = {

M boot/bootip.c => boot/bootip.c +2 -1
@@ 42,7 42,8 @@ configip(void)
	case 'b':
	case 'h':
	case 'm':
		ARGF();
		p = ARGF();
		USED(p);
		break;
	} ARGEND;


M port/alloc.c => port/alloc.c +0 -1
@@ 76,7 76,6 @@ static void
ppanic(Pool *p, char *fmt, ...)
{
	va_list v;
	int n;
	Private *pv;
	char msg[sizeof pv->msg];


M port/devaudio.c => port/devaudio.c +3 -1
@@ 1188,8 1188,10 @@ swab(uchar *a)
{
	ulong *p, *ep, b;

	if(!SBswab)
	if(!SBswab){
		USED(a);
		return;
	}
	p = (ulong*)a;
	ep = p + (Bufsize>>2);
	while(p < ep) {