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

1995/0531/carrera/screen.c (diff list | history)

carrera/screen.c on 1993/0906
1993/0906    
#include	"u.h" 
#include	"../port/lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"io.h" 
#include	"ureg.h" 
#include	"../port/error.h" 
 
#include	<libg.h> 
1994/0210    
#include	"screen.h" 
1993/0906    
 
1994/0210    
#define	MINX	8 
1993/0906    
 
1994/0210    
#define DAC	((Dac*)BTDac) 
typedef struct Dac Dac; 
struct Dac 
1993/0906    
{ 
1994/0210    
	uchar	pad0[7]; 
	uchar	cr0; 
	uchar	pad1[7]; 
	uchar	cr1; 
	uchar	pad2[7]; 
	uchar	cr2; 
	uchar	pad3[7]; 
	uchar	cr3; 
1993/0906    
}; 
 
1994/0211    
char s1[] = { 0x00, 0x00, 0xC0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
1993/0906    
 
1994/0413    
extern	Subfont	defont0; 
1994/0210    
static	ulong		rep(ulong, int); 
1993/0906    
 
1994/0210    
struct{ 
	Point	pos; 
	int	bwid; 
}out; 
 
Lock	screenlock; 
 
1994/0413    
Bitmap	gscreen = 
1993/0906    
{ 
1994/0525    
	{ 0, 0, 1597, 1234 }, 
	{ 0, 0, 1597, 1234 }, 
1994/0413    
	3, 
1994/0525    
	Screenvirt+0x000178D0, 
1993/0918    
	0, 
1994/0210    
	512, 
1993/0918    
	0 
}; 
 
1994/0413    
static Bitmap hwcursor= 
1993/0918    
{ 
1994/0413    
	{0, 0, 64, 64}, 
	{0, 0, 64, 64}, 
	1, 
1994/0210    
	0,		/* base filled in by malloc when needed */ 
1993/0906    
	0, 
1994/0210    
	4, 
1994/0413    
	0, 
1994/0210    
}; 
 
uchar bdata[] = 
{ 
	0xC0, 
}; 
 
1994/0413    
Bitmap bgrnd = 
1994/0210    
{ 
1994/0413    
	{ 0, 0, 1, 1 }, 
	{ 0, 0, 1, 1 }, 
	3, 
1994/0210    
	(ulong*)bdata, 
1993/1221    
	0, 
1994/0210    
	4, 
1993/0906    
	0 
}; 
 
static Rectangle window; 
1994/0414    
static Point curpos; 
1993/0906    
static int h, w; 
 
void 
screenwin(void) 
{ 
1994/0210    
	Dac *d; 
1994/0216    
	Point p; 
	int i, y; 
1994/0520    
	Cursor zero; 
1993/1222    
 
1994/0216    
	memset((void*)Screenvirt, 0xff, 3*1024*1024); 
1994/0215    
 
1994/0413    
	texture(&gscreen, gscreen.r, &bgrnd, S); 
1993/0906    
	w = defont0.info[' '].width; 
	h = defont0.height; 
 
1994/0210    
	window.min = Pt(100, 100); 
1994/0227    
	window.max = add(window.min, Pt(10+w*120, 10+h*60)); 
1993/0906    
 
1994/0413    
	bitblt(&gscreen, add(window.min, Pt(5, 5)), &gscreen, window, F); 
	bitblt(&gscreen, window.min, &gscreen, window, Zero); 
	border(&gscreen, window, 4, F); 
1993/0906    
	window = inset(window, 5); 
1994/0216    
	for(i = 0; i < h+6; i += 2) { 
		y = window.min.y+i; 
1994/0413    
		bitblt(&gscreen, Pt(window.min.x, y), 
			&gscreen, Rect(window.min.x, y, window.max.x, y+1), F); 
1994/0216    
	} 
	p = add(window.min, Pt(10, 2)); 
1994/0413    
	subfstring(&gscreen, p, &defont0, "Brazil Console ", S); 
1994/0216    
	window.min.y += h+6; 
1994/0414    
	curpos = window.min; 
1993/0906    
	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; 
1993/0918    
 
1994/0210    
	d = DAC; 
	/* cursor color 1: white */ 
	d->cr1 = 0x01; 
	d->cr0 = 0x81; 
	d->cr2 = 0xFF; 
	d->cr2 = 0xFF; 
	d->cr2 = 0xFF; 
	/* cursor color 2: noir */ 
	d->cr1 = 0x01; 
	d->cr0 = 0x82; 
	d->cr2 = 0; 
	d->cr2 = 0; 
	d->cr2 = 0; 
	/* cursor color 3: schwarz */ 
	d->cr1 = 0x01; 
	d->cr0 = 0x83; 
	d->cr2 = 0; 
	d->cr2 = 0; 
	d->cr2 = 0; 
	/* initialize with all-transparent cursor */ 
1994/0520    
	memset(&zero, 0, sizeof zero); 
	setcursor(&zero); 
1994/0210    
	/* enable both planes of cursor */ 
	d->cr1 = 0x03; 
	d->cr0 = 0x00; 
	d->cr2 = 0xc0; 
1993/0906    
} 
 
1994/0210    
void 
dacinit(void) 
1993/0918    
{ 
1994/0210    
	Dac *d; 
	int i; 
	ulong r, g, b; 
1993/0908    
 
1994/0210    
	d = DAC; 
1993/1228    
 
1994/0210    
	/* Control registers */ 
	d->cr0 = 0x01; 
	d->cr1 = 0x02; 
	for(i = 0; i < sizeof s1; i++) 
		d->cr2 = s1[i]; 
1993/0918    
 
1994/0210    
	/* Cursor programming */ 
	d->cr0 = 0x00; 
	d->cr1 = 0x03; 
	d->cr2 = 0xC0; 
	for(i = 0; i < 12; i++) 
		d->cr2 = 0; 
 
	/* Load Cursor Ram */ 
	d->cr0 = 0x00; 
	d->cr1 = 0x04; 
	for(i = 0; i < 0x400; i++) 
		d->cr2 = 0xff; 
 
	for(i = 0; i<256; i++) { 
1994/0909    
		r = rep((i>>5) & 7, 3); 
		g = rep((i>>2) & 7, 3); 
		b = rep(i & 3, 2); 
1994/0210    
		setcolor(i, r, g, b); 
	} 
1994/0909    
	setcolor(170, 0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA); 
	setcolor(85, 0x55555555, 0x55555555, 0x55555555); 
1994/0210    
 
	/* Overlay Palette Ram */ 
	d->cr0 = 0x00; 
	d->cr1 = 0x01; 
	for(i = 0; i < 0x10; i++) { 
		d->cr2 = 0xff; 
		d->cr2 = 0xff; 
		d->cr2 = 0xff; 
	} 
 
	/* Overlay Palette Ram */ 
	d->cr0 = 0x81; 
	d->cr1 = 0x01; 
	for(i = 0; i < 3; i++) { 
		d->cr2 = 0xff; 
		d->cr2 = 0xff; 
		d->cr2 = 0xff; 
	} 
1993/1222    
} 
 
1993/0906    
void 
screeninit(void) 
{ 
1994/0210    
	dacinit(); 
1993/0906    
 
1994/0413    
	bitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); 
1994/0210    
	out.pos.x = MINX; 
	out.pos.y = 0; 
	out.bwid = defont0.info[' '].width; 
1993/0906    
 
	screenwin(); 
} 
 
static void 
scroll(void) 
{ 
	int o; 
	Rectangle r; 
 
	o = 5*h; 
	r = Rpt(Pt(window.min.x, window.min.y+o), window.max); 
1994/0413    
	bitblt(&gscreen, window.min, &gscreen, r, S); 
1993/0906    
	r = Rpt(Pt(window.min.x, window.max.y-o), window.max); 
1994/0413    
	bitblt(&gscreen, r.min, &gscreen, r, Zero); 
1994/0414    
	curpos.y -= o; 
1993/0906    
} 
 
static void 
screenputc(char *buf) 
{ 
	int pos; 
1994/0401    
	Rectangle r; 
1993/0906    
 
	switch(buf[0]) { 
	case '\n': 
1994/0414    
		if(curpos.y+h >= window.max.y) 
1993/0906    
			scroll(); 
1994/0414    
		curpos.y += h; 
1993/0906    
		screenputc("\r"); 
		break; 
	case '\r': 
1994/0414    
		curpos.x = window.min.x; 
1993/0906    
		break; 
	case '\t': 
1994/0414    
		pos = (curpos.x-window.min.x)/w; 
1993/0906    
		pos = 8-(pos%8); 
1994/0414    
		curpos.x += pos*w; 
1993/0906    
		break; 
	case '\b': 
1994/0414    
		if(curpos.x-w >= 0){ 
			r.min.x = curpos.x-w; 
			r.max.x = curpos.x; 
			r.min.y = curpos.y; 
			r.max.y = curpos.y+defont0.height; 
1994/0413    
			bitblt(&gscreen, r.min, &gscreen, r, Zero); 
1994/0414    
			curpos.x -= w; 
1994/0401    
		} 
1993/0906    
		break; 
	default: 
1994/0414    
		if(curpos.x >= window.max.x-w) 
1993/0906    
			screenputc("\n"); 
1994/0414    
		curpos = subfstring(&gscreen, curpos, &defont0, buf, S); 
1993/0906    
	} 
} 
 
void 
screenputs(char *s, int n) 
{ 
	int i; 
	Rune r; 
	char buf[4]; 
 
1993/0918    
	if((getstatus() & IE) == 0) { 
1993/0906    
		/* don't deadlock trying to print in interrupt */ 
		if(!canlock(&screenlock)) 
			return;	 
	} 
	else 
		lock(&screenlock); 
 
1994/0210    
	while(n > 0){ 
1993/0906    
		i = chartorune(&r, s); 
		if(i == 0){ 
			s++; 
			--n; 
			continue; 
		} 
		memmove(buf, s, i); 
		buf[i] = 0; 
		n -= i; 
		s += i; 
		screenputc(buf); 
	} 
	unlock(&screenlock); 
} 
 
1994/0210    
uchar revtab0[] = { 
 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 
 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 
 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 
 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 
 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 
 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 
 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 
 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 
 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 
 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 
 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 
 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 
 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 
 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 
 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 
 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 
 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 
 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 
 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 
 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 
 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 
 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 
 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 
 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 
 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 
 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 
 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 
 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 
 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 
 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 
 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 
 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 
}; 
 
1993/0906    
void 
getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) 
{ 
1994/0210    
	Dac *d; 
	uchar r, g, b; 
	extern uchar revtab0[]; 
1993/1230    
 
1994/0210    
	d = DAC; 
 
1995/0531    
	/* to protect DAC from mouse movement */ 
	lock(&cursor); 
 
1994/0909    
	d->cr0 = revtab0[255 - (p & 0xFF)]; 
1994/0210    
	d->cr1 = 0; 
	r = d->cr3; 
	g = d->cr3; 
	b = d->cr3; 
	*pr = (r<<24) | (r<<16) | (r<<8) | r; 
	*pg = (g<<24) | (g<<16) | (g<<8) | g; 
	*pb = (b<<24) | (b<<16) | (b<<8) | b; 
1995/0531    
 
	unlock(&cursor); 
1993/0906    
} 
 
int 
setcolor(ulong p, ulong r, ulong g, ulong b) 
{ 
1994/0210    
	Dac *d; 
	extern uchar revtab0[]; 
1993/1230    
 
1994/0210    
	d = DAC; 
1993/0906    
 
1995/0531    
	/* to protect DAC from mouse movement */ 
	lock(&cursor); 
 
1994/0909    
	d->cr0 = revtab0[255 - (p & 0xFF)]; 
1994/0210    
	d->cr1 = 0; 
	d->cr3 = r >> 24; 
	d->cr3 = g >> 24; 
	d->cr3 = b >> 24; 
1995/0531    
 
	unlock(&cursor); 
 
1994/0210    
	return 1; 
1993/0906    
} 
 
1994/0210    
/* replicate (from top) value in v (n bits) until it fills a ulong */ 
static ulong 
rep(ulong v, int n) 
1993/0906    
{ 
1994/0210    
	int o; 
	ulong rv; 
1993/0906    
 
1994/0210    
	rv = 0; 
	for(o = 32 - n; o >= 0; o -= n) 
		rv |= (v << o); 
	return rv; 
1993/0906    
} 
 
void 
1994/0520    
setcursor(Cursor *curs) 
1993/0906    
{ 
1994/0210    
	Dac *d; 
1994/0520    
	int x, y, i; 
1994/0210    
	Point org; 
1994/0520    
	uchar ylow, yhigh, *p; 
1994/0210    
	ulong spix, cpix, dpix; 
1994/0520    
	ulong s[16], c[16]; 
1993/0906    
 
1994/0520    
	for(i=0; i<16; i++){ 
		p = (uchar*)&s[i]; 
		*p = curs->set[2*i]; 
		*(p+1) = curs->set[2*i+1]; 
		p = (uchar*)&c[i]; 
		*p = curs->clr[2*i]; 
		*(p+1) = curs->clr[2*i+1]; 
	} 
1994/0210    
	hwcursor.base = (ulong *)malloc(1024); 
	if(hwcursor.base == 0) 
		error(Enomem); 
	/* hw cursor is 64x64 with hot point at (32,32) */ 
1994/0520    
	org = add(Pt(32,32), curs->offset);  
1994/0210    
	for(x = 0; x < 16; x++) 
		for(y = 0; y < 16; y++) { 
			spix = (s[y]>>(31-(x&0x1F)))&1; 
			cpix = (c[y]>>(31-(x&0x1F)))&1; 
			dpix = (spix<<1) | cpix; 
1994/0413    
			point(&hwcursor, add(Pt(x,y), org), dpix, S); 
1994/0210    
		} 
1993/0907    
 
1994/0210    
	d = DAC; 
1995/0531    
 
1994/0210    
	/* have to set y offscreen before writing cursor bits */ 
	d->cr1 = 0x03; 
	d->cr0 = 0x03; 
	ylow = d->cr2; 
	yhigh = d->cr2; 
	d->cr1 = 0x03; 
	d->cr0 = 0x03; 
	d->cr2 = 0xFF; 
	d->cr2 = 0xFF; 
	/* now set the bits */ 
	d->cr1 = 0x04; 
	d->cr0 = 0x00; 
	for(x = 0; x < 1024; x++) 
		d->cr2 = ((uchar *)hwcursor.base)[x]; 
	/* set y back */ 
	d->cr1 = 0x03; 
	d->cr0 = 0x03; 
	d->cr2 = ylow; 
	d->cr2 = yhigh; 
1995/0531    
	 
1994/0210    
	free(hwcursor.base); 
1993/0906    
} 
 
1994/0624    
int 
1994/0414    
cursoron(int dolock) 
1993/0906    
{ 
1994/0210    
	Dac *d; 
1994/0414    
	Point p; 
1993/0906    
 
1994/0414    
	p = mousexy(); 
 
1994/0210    
	d = DAC; 
1993/0906    
 
1994/0414    
	if(dolock) 
		lock(&cursor); 
 
1994/0525    
	p.x += 296;		/* adjusted by experiment */ 
1994/0414    
	p.y += 11;		/* adjusted by experiment */ 
1994/0210    
	d->cr1 = 03; 
	d->cr0 = 01; 
1994/0414    
	d->cr2 = p.x&0xFF; 
	d->cr2 = (p.x>>8)&0xF; 
	d->cr2 = p.y&0xFF; 
	d->cr2 = (p.y>>8)&0xF; 
 
	if(dolock) 
		unlock(&cursor); 
1994/0624    
	return 0; 
1993/0906    
} 
 
1994/0210    
int 
screenbits(void) 
1993/0906    
{ 
1994/0210    
	return 1<<gscreen.ldepth; 
1993/0906    
} 
 
1993/1026    
extern	cursorlock(Rectangle); 
extern	cursorunlock(void); 
1994/0210    
 
1993/0930    
/* 
1993/1026    
 * paste tile into screen. 
1993/1228    
 * tile is at location r, first pixel in *data.  
 * tl is length of scan line to insert, 
1993/1026    
 * l is amount to advance data after each scan line. 
1994/0407    
 * gscreen.ldepth is known to be >= 3 
1993/0930    
 */ 
void 
1994/0412    
screenload(Rectangle r, uchar *data, int tl, int l, int dolock) 
1993/0930    
{ 
	uchar *q; 
1994/0407    
	int y; 
1993/0930    
 
1994/0412    
	USED(dolock); 
 
1993/1026    
	if(!rectclip(&r, gscreen.r) || tl<=0) 
1993/0930    
		return; 
1994/0210    
 
1993/0930    
	lock(&screenlock); 
1994/0413    
	q = byteaddr(&gscreen, r.min); 
1994/0407    
	for(y=r.min.y; y<r.max.y; y++){ 
		memmove(q, data, tl); 
1994/0412    
		q += gscreen.width*sizeof(ulong); 
		data += l; 
	} 
	unlock(&screenlock); 
} 
 
/* 
 * get a tile from screen memory. 
 * tile is at location r, first pixel in *data.  
 * tl is length of scan line to insert, 
 * l is amount to advance data after each scan line. 
1994/0413    
 * gscreen.ldepth is known to be >= 3. 
 * screenunload() doesn't clip, so must be 
 * called correctly. 
1994/0412    
 */ 
void 
screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) 
{ 
	uchar *q; 
	int y; 
 
	USED(dolock); 
 
	lock(&screenlock); 
1994/0413    
	q = byteaddr(&gscreen, r.min); 
1994/0412    
	for(y=r.min.y; y<r.max.y; y++){ 
		memmove(data, q, tl); 
1994/0407    
		q += gscreen.width*sizeof(ulong); 
		data += l; 
	} 
1993/0930    
	unlock(&screenlock); 
1993/0906    
} 


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