plan 9 kernel history: overview | file list | diff list

2000/0401/alphapc/devvga.c (diff list | history)

2000/0330/sys/src/9/alphapc/devvga.c:14,372000/0401/sys/src/9/alphapc/devvga.c:14,40 (short | long | prev | next)
1999/0415    
#include <cursor.h> 
#include "screen.h" 
 
2000/0401    
extern uchar	*vgabios; 
 
1999/0415    
enum { 
	Qdir, 
	Qvgaiob, 
	Qvgaiow, 
	Qvgaiol, 
	Qvgactl, 
2000/0401    
	Qvgabios, 
1999/0415    
}; 
 
static Dirtab vgadir[] = { 
	"vgaiob",	{ Qvgaiob, 0 },		0,	0660, 
	"vgaiow",	{ Qvgaiow, 0 },		0,	0660, 
	"vgaiol",	{ Qvgaiol, 0 },		0,	0660, 
	"vgactl",	{ Qvgactl, 0 },		0,	0660, 
2000/0401    
	"vgabios",	{ Qvgabios, 0 },		0x10000,	0440, 
1999/0415    
}; 
 
static void 
vgareset(void) 
{ 
2000/0401    
	/* reserve the 'standard' vga registers */ 
	if(ioalloc(0x2b0, 0x2df-0x2b0+1, 0, "vga") < 0) 
		panic("vga ports already allocated");  
	if(ioalloc(0x3c0, 0x3da-0x3c0+1, 0, "vga") < 0) 
		panic("vga ports already allocated");  
1999/0415    
	conf.monitor = 1; 
} 
 
2000/0330/sys/src/9/alphapc/devvga.c:69,782000/0401/sys/src/9/alphapc/devvga.c:72,79
1999/0415    
static long 
vgaread(Chan* c, void* a, long n, vlong off) 
{ 
	int len, port; 
2000/0401    
	int len; 
1999/0415    
	char *p, *s; 
	ushort *sp; 
	ulong *lp; 
	VGAscr *scr; 
	ulong offset = off; 
 
2000/0330/sys/src/9/alphapc/devvga.c:93,1132000/0401/sys/src/9/alphapc/devvga.c:94,114
1999/0415    
			s = scr->dev->name; 
		else 
			s = "cga"; 
2000/0330    
		len = snprint(p, READSTR, "type %s\n", s); 
2000/0401    
		len = snprint(p, READSTR, "type: %s\n", s); 
1999/0415    
		if(scr->gscreen) 
2000/0330    
			len += snprint(p+len, READSTR-len, "size %dx%dx%d\n", 
2000/0401    
			len += snprint(p+len, READSTR-len, "size: %dx%dx%d\n", 
1999/0415    
				scr->gscreen->r.max.x, scr->gscreen->r.max.y, 
				1<<scr->gscreen->ldepth); 
2000/0401    
				scr->gscreen->depth); 
1999/0415    
		if(scr->cur) 
			s = scr->cur->name; 
		else 
			s = "off"; 
2000/0330    
		len += snprint(p+len, READSTR-len, "hwgc %s\n", s); 
2000/0401    
		len += snprint(p+len, READSTR-len, "hwgc: %s\n", s); 
1999/0512    
		if(scr->pciaddr) 
2000/0330    
			snprint(p+len, READSTR-len, "addr 0x%lux\n", 
2000/0401    
			snprint(p+len, READSTR-len, "addr: 0x%lux\n", 
1999/0512    
				scr->pciaddr); 
		else 
2000/0330    
			snprint(p+len, READSTR-len, "addr 0x%lux\n", 
2000/0401    
			snprint(p+len, READSTR-len, "addr: 0x%lux\n", 
1999/0512    
				scr->aperture); 
1999/0415    
 
		n = readstr(offset, a, n, p); 
2000/0330/sys/src/9/alphapc/devvga.c:116,1452000/0401/sys/src/9/alphapc/devvga.c:117,134
1999/0415    
 
		return n; 
 
	case Qvgaiob: 
		port = offset; 
		for(p = a; port < offset+n; port++) 
			*p++ = inb(port); 
2000/0401    
	case Qvgabios: 
		if(vgabios == nil) 
			error(Egreg); 
		if(offset&0x80000000) 
			offset &= ~0x800E0000; 
		if(offset+n > 0x10000) 
			n = 0x10000-offset; 
		if(n < 0) 
			return 0; 
		memmove(a, vgabios+offset, n); 
1999/0415    
		return n; 
 
	case Qvgaiow: 
		if((n & 0x01) || (offset & 0x01)) 
			error(Ebadarg); 
		n /= 2; 
		sp = a; 
		for(port = offset; port < offset+n; port += 2) 
			*sp++ = ins(port); 
		return n*2; 
                 
	case Qvgaiol: 
		if((n & 0x03) || (offset & 0x03)) 
			error(Ebadarg); 
		n /= 4; 
		lp = a; 
		for(port = offset; port < offset+n; port += 4) 
			*lp++ = inl(port); 
		return n*4; 
                 
	default: 
		error(Egreg); 
		break; 
2000/0330/sys/src/9/alphapc/devvga.c:148,1642000/0401/sys/src/9/alphapc/devvga.c:137,157
1999/0415    
	return 0; 
} 
 
2000/0401    
static char Ebusy[] = "vga already configured"; 
 
1999/0415    
static void 
vgactl(char* a) 
{ 
	int align, i, n, size, x, y, z; 
	char *field[4], *p; 
2000/0401    
	char *chanstr, *field[6], *p; 
	ulong chan; 
1999/0415    
	VGAscr *scr; 
	extern VGAdev *vgadev[]; 
	extern VGAcur *vgacur[]; 
2000/0401    
	Rectangle r; 
1999/0415    
 
2000/0308    
	n = getfields(a, field, 4, 1, " "); 
1999/0415    
	if(n < 2) 
2000/0401    
	n = getfields(a, field, nelem(field), 1, " "); 
	if(n < 1) 
1999/0415    
		error(Ebadarg); 
 
	scr = &vgascreen[0]; 
2000/0330/sys/src/9/alphapc/devvga.c:165,1702000/0401/sys/src/9/alphapc/devvga.c:158,168
1999/0415    
	if(strcmp(field[0], "hwgc") == 0){ 
		if(n < 2) 
			error(Ebadarg); 
2000/0401    
 
		/* BUG: drawinit should become a different message rather than piggybacking */ 
		if(scr && scr->dev && scr->dev->drawinit) 
			scr->dev->drawinit(scr); 
 
1999/0415    
		if(strcmp(field[1], "off") == 0){ 
			lock(&cursor); 
			if(scr->cur){ 
2000/0330/sys/src/9/alphapc/devvga.c:205,2122000/0401/sys/src/9/alphapc/devvga.c:203,213
1999/0415    
		} 
	} 
	else if(strcmp(field[0], "size") == 0){ 
		if(n < 2) 
2000/0401    
		if(n < 3) 
1999/0415    
			error(Ebadarg); 
2000/0401    
		if(drawhasclients()) 
			error(Ebusy); 
 
1999/0415    
		x = strtoul(field[1], &p, 0); 
		if(x == 0 || x > 2048) 
			error(Ebadarg); 
2000/0330/sys/src/9/alphapc/devvga.c:219,2412000/0401/sys/src/9/alphapc/devvga.c:220,295
1999/0415    
		if(*p) 
			p++; 
 
		switch(strtoul(p, &p, 0)){ 
		case 8: 
			z = 3; 
			break; 
2000/0401    
		z = strtoul(p, &p, 0); 
1999/0415    
 
		default: 
			z = 0; 
			error(Ebadarg); 
		} 
2000/0401    
		chanstr = field[2]; 
		if((chan = strtochan(chanstr)) == 0) 
			error("bad channel"); 
1999/0415    
 
2000/0401    
		if(chantodepth(chan) != z) 
			error("depth, channel do not match"); 
 
1999/0415    
		cursoroff(1); 
		if(screensize(x, y, z)) 
2000/0401    
		deletescreenimage(); 
		if(screensize(x, y, z, chan)) 
1999/0415    
			error(Egreg); 
		vgascreenwin(scr); 
		cursoron(1); 
		return; 
	} 
2000/0401    
	else if(strcmp(field[0], "actualsize") == 0){ 
		if(scr->gscreen == nil) 
			error("set the screen size first"); 
 
		if(n < 2) 
			error(Ebadarg); 
		x = strtoul(field[1], &p, 0); 
		if(x == 0 || x > 2048) 
			error(Ebadarg); 
		if(*p) 
			p++; 
 
		y = strtoul(p, nil, 0); 
		if(y == 0 || y > 2048) 
			error(Ebadarg); 
 
		if(x > scr->gscreen->r.max.x || y > scr->gscreen->r.max.y) 
			error("physical screen bigger than virtual"); 
 
		r = Rect(0,0,x,y); 
		if(!eqrect(r, scr->gscreen->r)){ 
			if(scr->cur == nil || scr->cur->doespanning == 0) 
				error("virtual screen not supported"); 
		} 
 
		physgscreenr = r; 
		return; 
	} 
	else if(strcmp(field[0], "palettedepth") == 0){ 
		if(n < 2) 
			error(Ebadarg); 
 
		x = strtoul(field[1], &p, 0); 
		if(x != 8 && x != 6) 
			error(Ebadarg); 
 
		scr->palettedepth = x; 
		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; 
	} 
1999/0415    
	else if(strcmp(field[0], "linear") == 0){ 
		if(n < 2) 
			error(Ebadarg); 
2000/0330/sys/src/9/alphapc/devvga.c:249,2542000/0401/sys/src/9/alphapc/devvga.c:303,330
1999/0415    
			error("not enough free address space"); 
		return; 
	} 
2000/0401    
/*	else if(strcmp(field[0], "memset") == 0){ 
		if(n < 4) 
			error(Ebadarg); 
		memset((void*)strtoul(field[1], 0, 0), atoi(field[2]), atoi(field[3])); 
		return; 
	} 
*/ 
	else if(strcmp(field[0], "blank") == 0){ 
		if(n < 2) 
			error(Ebadarg); 
		drawblankscreen(atoi(field[1])); 
		return; 
	} 
	else if(strcmp(field[0], "hwaccel") == 0){ 
		if(n < 2) 
			error(Ebadarg); 
		if(strcmp(field[1], "on") == 0) 
			hwaccel = 1; 
		else if(strcmp(field[1], "off") == 0) 
			hwaccel = 0; 
		return; 
	} 
1999/0415    
 
	error(Ebadarg); 
} 
2000/0330/sys/src/9/alphapc/devvga.c:256,2652000/0401/sys/src/9/alphapc/devvga.c:332,338
1999/0415    
static long 
vgawrite(Chan* c, void* a, long n, vlong off) 
{ 
	int port; 
	char *p; 
	ushort *sp; 
	ulong *lp; 
	ulong offset = off; 
 
	switch(c->qid.path & ~CHDIR){ 
2000/0330/sys/src/9/alphapc/devvga.c:281,3102000/0401/sys/src/9/alphapc/devvga.c:354,359
1999/0415    
		poperror(); 
		free(p); 
		return n; 
                 
	case Qvgaiob: 
		p = a; 
		for(port = offset; port < offset+n; port++) 
			outb(port, *p++); 
		return n; 
                 
	case Qvgaiow: 
		if((n & 01) || (offset & 01)) 
			error(Ebadarg); 
		n /= 2; 
		sp = a; 
		for(port = offset; port < offset+n; port += 2) 
			outs(port, *sp++); 
		return n*2; 
                 
	case Qvgaiol: 
		if((n & 0x03) || (offset & 0x03)) 
			error(Ebadarg); 
		n /= 4; 
		lp = a; 
		for(port = offset; port < offset+n; port += 4) 
			outl(port, *lp++); 
		return n*4; 
 
	default: 
		error(Egreg); 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)