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

1997/0718/pc/vgaclgd542x.c (diff list | history)

pc/vgaclgd542x.c on 1995/02021
1995/02021    
#include "u.h" 
#include "../port/lib.h" 
#include "mem.h" 
#include "dat.h" 
#include "fns.h" 
1997/0717    
#include "io.h" 
1995/02021    
#include "../port/error.h" 
 
#include <libg.h> 
#include "screen.h" 
#include "vga.h" 
 
1997/0716    
extern Bitmap gscreen; 
extern Cursor curcursor; 
 
1997/0327    
static Lock clgd542xlock; 
1997/0716    
static ulong storage; 
1997/0327    
 
1995/02021    
static void 
1997/0718    
setclgd542xpage(int page) 
{ 
	if(vgaxi(Seqx, 0x07) & 0xF0) 
		page = 0; 
	if(vgaxi(Seqx, 0x0B) & 0x20) 
		vgaxo(Grx, 0x09, page<<2); 
	else 
		vgaxo(Grx, 0x09, page<<4); 
} 
 
static void 
1995/02021    
clgd542xpage(int page) 
{ 
1997/0327    
	lock(&clgd542xlock); 
1997/0718    
	setclgd542xpage(page); 
1997/0327    
	unlock(&clgd542xlock); 
1995/02021    
} 
 
1997/0717    
static int 
clgd542xlinear(ulong* mem, ulong* size, ulong* align) 
{ 
	ulong baseaddr; 
	static Pcidev *p; 
 
1997/0718    
	if(*size != 16*MB) 
1997/0717    
		return 0; 
1997/0718    
	if(*align == 0) 
		*align = 16*MB; 
	else if(*align & (16*MB-1)) 
		return 0; 
1997/0717    
 
	*mem = 0; 
 
	/* 
	 * This obviously isn't good enough on a system with 
	 * more than one PCI card from Cirrus. 
	 */ 
	if(p == 0 && (p = pcimatch(p, 0x1013, 0)) == 0) 
		return 0; 
 
	switch(p->did){ 
 
	case 0xA0: 
	case 0xA8: 
	case 0xAC: 
		break; 
 
	default: 
		return 0; 
	} 
 
1997/0718    
	/* 
	 * This doesn't work if the card is on the other side of a 
	 * a bridge. Need to coordinate with PCI support. 
	 */ 
1997/0717    
	if((baseaddr = upamalloc(0, *size, *align)) == 0) 
		return 0; 
	*mem = baseaddr; 
	baseaddr = PADDR(baseaddr); 
	pcicfgw32(p, PciBAR0, baseaddr); 
 
	return *mem; 
} 
 
1997/0716    
static void 
disable(void) 
{ 
	uchar sr12; 
 
	lock(&clgd542xlock); 
	sr12 = vgaxi(Seqx, 0x12); 
	vgaxo(Seqx, 0x12, sr12 & ~0x01); 
	unlock(&clgd542xlock); 
} 
 
static void 
enable(void) 
{ 
	uchar sr12; 
1997/0717    
	int mem, x; 
1997/0716    
  
	/* 
	 * Disable the cursor. 
	 */ 
	lock(&clgd542xlock); 
	sr12 = vgaxi(Seqx, 0x12); 
	vgaxo(Seqx, 0x12, sr12 & ~0x01); 
 
	/* 
	 * Cursor colours.   
	 */ 
	vgaxo(Seqx, 0x12, sr12|0x02); 
	setcolor(0x00, Pwhite<<(32-6), Pwhite<<(32-6), Pwhite<<(32-6)); 
	setcolor(0x0F, Pblack<<(32-6), Pblack<<(32-6), Pblack<<(32-6)); 
	vgaxo(Seqx, 0x12, sr12); 
 
1997/0717    
	mem = 0; 
	switch(vgaxi(Crtx, 0x27) & ~0x03){ 
1997/0716    
 
1997/0717    
	case 0x88:				/* CL-GD5420 */ 
	case 0x8C:				/* CL-GD5422 */ 
	case 0x94:				/* CL-GD5424 */ 
	case 0x80:				/* CL-GD5425 */ 
	case 0x90:				/* CL-GD5426 */ 
	case 0x98:				/* CL-GD5427 */ 
	case 0x9C:				/* CL-GD5429 */ 
		/* 
		 * The BIOS leaves the memory size in Seq0A, bits 4 and 3. 
		 * See Technical Reference Manual Appendix E1, Section 1.3.2. 
		 * 
		 * The storage area for the 64x64 cursors is the last 16Kb of 
		 * display memory. 
		 */ 
		mem = (vgaxi(Seqx, 0x0A)>>3) & 0x03; 
1997/0716    
		break; 
 
1997/0717    
	case 0xA0:				/* CL-GD5430 */ 
	case 0xA8:				/* CL-GD5434 */ 
	case 0xAC:				/* CL-GD5436 */ 
		/* 
		 * Attempt to intuit the memory size from the DRAM control 
		 * register. Minimum is 512KB. 
		 * If DRAM bank switching is on then there's double. 
		 */ 
		x = vgaxi(Seqx, 0x0F); 
		mem = (x>>3) & 0x03; 
		if(x & 0x80) 
			mem++; 
1997/0716    
		break; 
 
1997/0717    
	default:				/* uh, ah dunno */ 
1997/0716    
		break; 
	} 
1997/0717    
	storage = ((256<<mem)-16)*1024; 
 
1997/0716    
	/* 
	 * Set the current cursor to index 0 
	 * and turn the 64x64 cursor on. 
	 */ 
	vgaxo(Seqx, 0x13, 0); 
	vgaxo(Seqx, 0x12, sr12|0x05); 
 
	unlock(&clgd542xlock); 
} 
 
static void 
initcursor(Cursor* c, int xo, int yo, int index) 
{ 
	uchar *p; 
	uint p0, p1; 
	int x, y; 
 
	/* 
	 * Is linear addressing turned on? This will determine 
	 * how we access the cursor storage. 
	 */ 
	if(vgaxi(Seqx, 0x07) & 0xF0) 
		p = ((uchar*)gscreen.base) + storage; 
	else { 
1997/0718    
		setclgd542xpage(storage>>16); 
1997/0716    
		p = ((uchar*)gscreen.base) + (storage & 0xFFFF); 
	} 
1997/0718    
	p += index*1024; 
1997/0716    
 
	for(y = yo; y < 16; y++){ 
		p0 = c->clr[2*y]; 
		p1 = c->clr[2*y+1]; 
		if(xo){ 
			p0 = (p0<<xo)|(p1>>(8-xo)); 
			p1 <<= xo; 
		} 
		*p++ = p0; 
		*p++ = p1; 
 
		for(x = 16; x < 64; x += 8) 
			*p++ = 0x00; 
 
		p0 = c->clr[2*y]|c->set[2*y]; 
		p1 = c->clr[2*y+1]|c->set[2*y+1]; 
		if(xo){ 
			p0 = (p0<<xo)|(p1>>(8-xo)); 
			p1 <<= xo; 
		} 
		*p++ = p0; 
		*p++ = p1; 
 
		for(x = 16; x < 64; x += 8) 
			*p++ = 0x00; 
	} 
	while(y < 64+yo){ 
		for(x = 0; x < 64; x += 8){ 
			*p++ = 0x00; 
			*p++ = 0x00; 
		} 
		y++; 
	} 
} 
 
static void 
load(Cursor* c) 
{ 
	uchar sr12; 
 
	/* 
	 * Lock the display memory so we can update the 
	 * cursor bitmap if necessary. 
	 * Disable the cursor. 
	 * If it's the same as the last cursor loaded, 
	 * just make sure it's enabled and index 0. 
	 */ 
	lock(&clgd542xlock); 
	sr12 = vgaxi(Seqx, 0x12); 
	vgaxo(Seqx, 0x12, sr12 & ~0x01); 
 
	if(memcmp(c, &curcursor, sizeof(Cursor)) == 0){ 
		vgaxo(Seqx, 0x13, 0); 
		vgaxo(Seqx, 0x12, sr12|0x05); 
		unlock(&clgd542xlock); 
		return; 
	} 
	memmove(&curcursor, c, sizeof(Cursor)); 
	initcursor(c, 0, 0, 0); 
 
	/* 
	 * Enable the cursor. 
	 */ 
	vgaxo(Seqx, 0x13, 0); 
	vgaxo(Seqx, 0x12, sr12|0x05); 
1997/0718    
{ 
for(storage = 0; storage < (2048-32)*1024; storage += 16*1024) 
    initcursor(c, 0, 0, 0); 
} 
1997/0716    
 
	unlock(&clgd542xlock); 
} 
 
static int 
move(Point p) 
{ 
	int index, x, xo, y, yo; 
 
	if(canlock(&clgd542xlock) == 0) 
		return 1; 
 
	index = 0; 
	if((x = p.x+curcursor.offset.x) < 0){ 
		xo = -x; 
		x = 0; 
	} 
	else 
		xo = 0; 
	if((y = p.y+curcursor.offset.y) < 0){ 
		yo = -y; 
		y = 0; 
	} 
	else 
		yo = 0; 
 
	if(xo || yo){ 
		initcursor(&curcursor, xo, yo, 1); 
		index = 1; 
	} 
	vgaxo(Seqx, 0x13, index<<2); 
	 
	vgaxo(Seqx, 0x10|((x & 0x07)<<5), (x>>3) & 0xFF); 
	vgaxo(Seqx, 0x11|((y & 0x07)<<5), (y>>3) & 0xFF); 
 
	unlock(&clgd542xlock); 
	return 0; 
} 
 
static Hwgc clgd542xhwgc = { 
	"clgd542xhwgc", 
	enable, 
	load, 
	move, 
	disable, 
 
	0, 
}; 
 
1995/02021    
static Vgac clgd542x = { 
	"clgd542x", 
	clgd542xpage, 
1997/0717    
	clgd542xlinear, 
1995/02021    
 
	0, 
}; 
 
void 
vgaclgd542xlink(void) 
{ 
	addvgaclink(&clgd542x); 
1997/0716    
	addhwgclink(&clgd542xhwgc); 
1995/02021    
} 


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