Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/pc/vgas3.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname pc/vgas3.c 1994/0803
## diff -e /dev/null /n/fornaxdump/1994/0803/sys/src/brazil/pc/vgas3.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"

#include <libg.h>
#include "screen.h"
#include "vga.h"

/*
 * Hardware graphics cursor support for
 * generic S3 chipset.
 * Assume we're in enhanced mode.
 */
static Lock s3pagelock;
static ulong storage;

extern Bitmap gscreen;

static void
sets3page(int page)
{
	uchar crt51;

	/*
	 * I don't understand why these are different.
	 */
	if(gscreen.ldepth == 3){
		/*
		 * The S3 registers need to be unlocked for this.
		 * Let's hope they are already:
		 *	vgaxo(Crtx, 0x38, 0x48);
		 *	vgaxo(Crtx, 0x39, 0xA0);
		 *
		 * The page is 6 bits, the lower 4 bits in Crt35<3:0>,
		 * the upper 2 in Crt51<3:2>.
		 */
		vgaxo(Crtx, 0x35, page & 0x0F);
		crt51 = vgaxi(Crtx, 0x51) & 0xF3;
		vgaxo(Crtx, 0x51, crt51|((page & 0x30)>>2));
	}
	else
		vgaxo(Crtx, 0x35, (page<<2) & 0x0C);
}

static void
vsyncactive(void)
{
	/*
	 * Hardware cursor information is fetched from display memory
	 * during the horizontal blank active time. The 80x chips may hang
	 * if the cursor is turned on or off during this period.
	 */
	while((vgai(Status1) & 0x08) == 0)
		;
}

static void
disable(void)
{
	uchar crt45;

	/*
	 * Turn cursor off.
	 */
	crt45 = vgaxi(Crtx, 0x45) & 0xFE;
	vsyncactive();
	vgaxo(Crtx, 0x45, crt45);
}

static void
enable(void)
{
	int i;

	disable();

	/*
	 * Cursor colours. Set both the CR0[EF] and the colour
	 * stack in case we are using a 16-bit RAMDAC.
	 */
	vgaxo(Crtx, 0x0E, 0x00);
	vgaxo(Crtx, 0x0F, 0xFF);
	vgaxi(Crtx, 0x45);
	for(i = 0; i < 4; i++)
		vgaxo(Crtx, 0x4A, 0x00);
	vgaxi(Crtx, 0x45);
	for(i = 0; i < 4; i++)
		vgaxo(Crtx, 0x4B, 0xFF);

	/*
	 * Find a place for the cursor data in display memory.
	 * Must be on a 1024-byte boundary.
	 */
	storage = (gscreen.width*BY2WD*gscreen.r.max.y+1023)/1024;
	vgaxo(Crtx, 0x4C, (storage>>8) & 0x0F);
	vgaxo(Crtx, 0x4D, storage & 0xFF);
	storage *= 1024;

	/*
	 * Enable the cursor in X11 mode.
	 */
	vgaxo(Crtx, 0x55, vgaxi(Crtx, 0x55)|0x10);
	vsyncactive();
	vgaxo(Crtx, 0x45, 0x01);
}

static void
load(Cursor *c)
{
	uchar *and, *xor;
	int x, y;

	/*
	 * Disable the cursor and lock the display
	 * memory so we can update the cursor bitmap.
	 * Set the display page (do we need to restore
	 * the current contents when done?) and the
	 * pointers to the two planes.
	 */
	disable();
	lock(&s3pagelock);

	sets3page(storage>>16);
	and = ((uchar*)gscreen.base) + (storage & 0xFFFF);
	xor = and + 512;

	/*
	 * The cursor is set in X11 mode which gives the following
	 * truth table:
	 *	and xor	colour
	 *	 0   0	underlying pixel colour
	 *	 0   1	underlying pixel colour
	 *	 1   0	background colour
	 *	 1   1	foreground colour
	 * Put the cursor into the top-left of the 64x64 array.
	 */
	for(y = 0; y < 64; y++){
		for(x = 0; x < 8; x++){
			if(y < 16 && x < 2){
				and[8*y + x] = c->clr[2*y + x]^c->set[2*y + x];
				xor[8*y + x] = c->set[2*y + x];
			}
			else {
				and[8*y + x] = 0;
				xor[8*y + x] = 0;
			}
		}
	}
	unlock(&s3pagelock);

	/*
	 * Set the cursor offset and enable the cursor.
	 */
	vgaxo(Crtx, 0x4E, -c->offset.x);
	vgaxo(Crtx, 0x4F, -c->offset.y);
	vsyncactive();
	vgaxo(Crtx, 0x45, 0x01);
}

static int
move(Point p)
{
	vgaxo(Crtx, 0x46, (p.x>>8) & 0x07);
	vgaxo(Crtx, 0x47, p.x & 0xFF);
	vgaxo(Crtx, 0x49, p.y & 0xFF);
	vgaxo(Crtx, 0x48, (p.y>>8) & 0x07);

	return 0;
}

Hwgc s3hwgc = {
	"s3hwgc",
	enable,
	load,
	move,
	disable,
};

void
s3page(int page)
{
	if(hwgc == &s3hwgc){
		lock(&s3pagelock);
		sets3page(page);
		unlock(&s3pagelock);
	}
	else
		sets3page(page);
}
.
## diffname pc/vgas3.c 1994/0804
## diff -e /n/fornaxdump/1994/0803/sys/src/brazil/pc/vgas3.c /n/fornaxdump/1994/0804/sys/src/brazil/pc/vgas3.c
166,169c
	int x, xo, y, yo;

	/*
	 * Mustn't position the cursor offscreen even partially,
	 * or it disappears. Therefore, if x or y is -ve, adjust the
	 * cursor offset instead.
	 */
	if((x = p.x+hotpoint.x) < 0){
		xo = -x;
		xo = ((xo+1)/2)*2;
		x = 0;
	}
	else
		xo = 0;
	if((y = p.y+hotpoint.y) < 0){
		yo = -y;
		y = 0;
	}
	else
		yo = 0;

	vgaxo(Crtx, 0x46, (x>>8) & 0x07);
	vgaxo(Crtx, 0x47, x & 0xFF);
	vgaxo(Crtx, 0x49, y & 0xFF);
	vgaxo(Crtx, 0x4E, xo);
	vgaxo(Crtx, 0x4F, yo);
	vgaxo(Crtx, 0x48, (y>>8) & 0x07);
.
157,158c
	hotpoint = c->offset;
.
155c
	 * Set the cursor hotpoint and enable the cursor.
.
147,148c
				*p++ = 0x00;
				*p++ = 0x00;
				*p++ = 0x00;
				*p++ = 0x00;
.
141,144c
		for(x = 0; x < 64/8; x += 2){
			if(x < 16/8 && y < 16){
				*p++ = c->clr[2*y + x]|c->set[2*y + x];
				*p++ = c->clr[2*y + x+1]|c->set[2*y + x+1];
				*p++ = c->set[2*y + x];
				*p++ = c->set[2*y + x+1];
.
127,128c
	p = ((uchar*)gscreen.base) + (storage & 0xFFFF);
.
121c
	 * pointer to the two planes. What if this crosses
	 * into a new page?
.
113c
	uchar *p;
.
91c
		vgaxo(Crtx, 0x4B, 0x00);
.
88c
		vgaxo(Crtx, 0x4A, 0xFF);
.
84,85c
	vgaxo(Crtx, 0x0E, 0xFF);
	vgaxo(Crtx, 0x0F, 0x00);
.
82a
	 * Why are these colours reversed?
.
18a
static Point hotpoint;
.
## diffname pc/vgas3.c 1994/0809
## diff -e /n/fornaxdump/1994/0804/sys/src/brazil/pc/vgas3.c /n/fornaxdump/1994/0809/sys/src/brazil/pc/vgas3.c
198a
	unlock(&s3pagelock);
.
176a
	 * There seems to be a bug in that if the offset is 1, the
	 * cursor doesn't disappear off the left edge properly, so
	 * round it up to be even.
.
172a
	if(canlock(&s3pagelock) == 0)
		return -1;

.
165a

	unlock(&s3pagelock);
.
158d
140a
	 *
	 * The cursor pattern in memory is interleaved words of
	 * AND and XOR patterns.
.
127d
119,120c
	 * Lock the display memory so we can update the
	 * cursor bitmap if necessary.
	 * If it's the same as the last cursor we loaded,
	 * just make sure it's enabled.
	 */
	lock(&s3pagelock);
	if(memcmp(c, &loaded, sizeof(Cursor)) == 0){
		vsyncactive();
		vgaxo(Crtx, 0x45, 0x01);
		unlock(&s3pagelock);
		return;
	}
	memmove(&loaded, c, sizeof(Cursor));

	/*
	 * Disable the cursor.
.
19a
static Cursor loaded;
.
## diffname pc/vgas3.c 1994/0810
## diff -e /n/fornaxdump/1994/0809/sys/src/brazil/pc/vgas3.c /n/fornaxdump/1994/0810/sys/src/brazil/pc/vgas3.c
192c
		return 1;
.
132c
	memmove(&curcursor, c, sizeof(Cursor));
.
126c
	if(memcmp(c, &curcursor, sizeof(Cursor)) == 0){
.
22a
extern Cursor curcursor;
.
20d
## diffname pc/vgas3.c 1995/0126
## diff -e /n/fornaxdump/1994/0810/sys/src/brazil/pc/vgas3.c /n/fornaxdump/1995/0126/sys/src/brazil/pc/vgas3.c
244a
}

static Vgac s3 = {
	"s3",
	s3page,

	0,
};

void
vgas3link(void)
{
	addvgaclink(&s3);
	addhwgclink(&s3hwgc);
.
232a

	0,
.
94c
		vgaxo(Crtx, 0x4B, Pblack);
.
91c
		vgaxo(Crtx, 0x4A, Pwhite);
.
87,88c
	vgaxo(Crtx, 0x0E, Pwhite);
	vgaxo(Crtx, 0x0F, Pblack);
.
29,31d
## diffname pc/vgas3.c 1995/02021
## diff -e /n/fornaxdump/1995/0126/sys/src/brazil/pc/vgas3.c /n/fornaxdump/1995/02021/sys/src/brazil/pc/vgas3.c
234c
static void
.
## diffname pc/vgas3.c 1997/0327
## diff -e /n/fornaxdump/1995/02021/sys/src/brazil/pc/vgas3.c /n/emeliedump/1997/0327/sys/src/brazil/pc/vgas3.c
237,243c
	lock(&s3lock);
	sets3page(page);
	unlock(&s3lock);
.
220c
	unlock(&s3lock);
.
188c
	if(canlock(&s3lock) == 0)
.
180c
	unlock(&s3lock);
.
138c
	_disable();
.
126c
		unlock(&s3lock);
.
122c
	lock(&s3lock);
.
107a

	unlock(&s3lock);
.
78a
	_disable();

.
77c
	lock(&s3lock);
.
72a
disable(void)
{
	lock(&s3lock);
	_disable();
	unlock(&s3lock);
}

static void
.
60c
_disable(void)
.
17c
static Lock s3lock;
.
## diffname pc/vgas3.c 1997/1101
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/vgas3.c /n/emeliedump/1997/1101/sys/src/brazil/pc/vgas3.c
260,266d
254,258c
	s3enable,
	s3disable,
	s3load,
	s3move,
.
246,252c
VGAcur vgas3cur = {
	"s3hwgc",
.
243a
	0,
	s3page,
	s3linear,
.
236,241c
VGAdev vgas3dev = {
	"s3",
.
232d
218c
	if((y = p.y+scr->offset.y) < 0){
.
211c
	if((x = p.x+scr->offset.x) < 0){
.
200,202d
196c
s3move(VGAscr* scr, Point p)
.
191,192d
188,189c
	scr->offset = curs->offset;
	s3vsyncactive();
.
186c
	 * Save the cursor hotpoint and enable the cursor.
.
184a
	s3pageset(scr, opage);
	unlock(&scr->devlock);

.
171,174c
				*p++ = curs->clr[2*y + x]|curs->set[2*y + x];
				*p++ = curs->clr[2*y + x+1]|curs->set[2*y + x+1];
				*p++ = curs->set[2*y + x];
				*p++ = curs->set[2*y + x+1];
.
152,154d
143,150c
	p = KADDR(scr->aperture);
	lock(&scr->devlock);
	opage = s3pageset(scr, scr->storage>>16);
	p += (scr->storage & 0xFFFF);
.
134,141c
	s3disable(scr);
.
129,132c
	 * Disable the cursor and
	 * set the pointer to the two planes.
	 * Is linear addressing turned on? This will determine
	 * how we access the cursor storage.
.
126c
	int opage, x, y;
.
123c
s3load(VGAscr* scr, Cursor* curs)
.
118,119d
116c
	s3vsyncactive();
.
110a
	scr->storage = storage;
.
107c
	storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024;
.
87,88d
85c
	s3disable(scr);
.
83a
	ulong storage;
.
75,82d
73c
s3enable(VGAscr* scr)
.
68c
	s3vsyncactive();
.
60c
s3disable(VGAscr*)
.
49a
	lock(&scr->devlock);
	s3pageset(scr, page);
	unlock(&scr->devlock);
}

static ulong
s3linear(VGAscr* scr, int* size, int* align)
{
	ulong aperture, oaperture;
	int oapsize, wasupamem;
	Pcidev *p;

	oaperture = scr->aperture;
	oapsize = scr->apsize;
	wasupamem = scr->isupamem;
	if(wasupamem)
		upafree(oaperture, oapsize);
	scr->isupamem = 0;

	if(p = pcimatch(nil, 0x5333, 0)){
		aperture = p->mem[0].bar & ~0x0F;
		*size = p->mem[0].size;
	}
	else
		aperture = 0;

	aperture = upamalloc(aperture, *size, *align);
	if(aperture == 0){
		if(wasupamem && upamalloc(oaperture, oapsize, 0))
			scr->isupamem = 1;
	}
	else
		scr->isupamem = 1;

	return aperture;
}

static void
s3vsyncactive(void)
{
.
48c
s3page(VGAscr* scr, int page)
.
44a
		opage = (crt35>>2) & 0x03;
	}

	return opage;
.
43c
	else{
.
40,41c
		crt51 = vgaxi(Crtx, 0x51);
		vgaxo(Crtx, 0x51, (crt51 & ~0x0C)|((page & 0x30)>>2));
		opage = ((crt51 & 0x0C)<<2)|(crt35 & 0x0F);
.
29c
	crt35 = vgaxi(Crtx, 0x35);
	if(scr->gscreen->ldepth == 3){
.
27c
	uchar crt35, crt51;
	int opage;
.
12,25c
static int
s3pageset(VGAscr* scr, int page)
.
10d
8c
#define	Image	IMAGE
#include <draw.h>
#include <memdraw.h>
.
5a
#include "io.h"
.
## diffname pc/vgas3.c 1998/0116
## diff -e /n/emeliedump/1997/1101/sys/src/brazil/pc/vgas3.c /n/emeliedump/1998/0116/sys/src/brazil/pc/vgas3.c
198,199c
	switch(id){

	case 0xE110:				/* ViRGE/GX2 */
		break;

	default:
		s3pageset(scr, opage);
		unlock(&scr->devlock);
		break;
	}
.
192,193d
189a
				*p++ = 0xFF;
				*p++ = 0xFF;
.
184,185c
				*p++ = ~(curs->clr[2*y + x]|curs->set[2*y + x]);
				*p++ = ~(curs->clr[2*y + x+1]|curs->set[2*y + x+1]);
.
172,175c
	 *	 0   0	background colour
	 *	 0   1	foreground colour
	 *	 1   0	current screen pixel
	 *	 1   1	NOT current screen pixel
.
169,170c
	 * The cursor is set in Microsoft Windows format (the ViRGE/GX2 no
	 * longer supports the X11 format) which gives the following truth table:
.
167a
	case 0xE110:				/* ViRGE/GX2 */
		p += scr->storage;
		break;

	default:
		lock(&scr->devlock);
		opage = s3pageset(scr, scr->storage>>16);
		p += (scr->storage & 0xFFFF);
		break;
	}

.
164,166c
	id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E);
	switch(id){
.
162a
	opage = 0;
.
158,159d
153c
	int id, opage, x, y;
.
144c
	vgaxo(Crtx, 0x55, vgaxi(Crtx, 0x55) & ~0x10);
.
142c
	 * Enable the cursor in Microsoft Windows format.
.
130a
	case 0xE110:				/* ViRGE/GX2 */
		for(i = 0; i < 3; i++)
			vgaxo(Crtx, 0x4A, Pblack);
		vgaxi(Crtx, 0x45);
		for(i = 0; i < 3; i++)
			vgaxo(Crtx, 0x4B, Pwhite);
		break;

	default:
		for(i = 0; i < 3; i++)
			vgaxo(Crtx, 0x4A, Pwhite);
		vgaxi(Crtx, 0x45);
		for(i = 0; i < 3; i++)
			vgaxo(Crtx, 0x4B, Pblack);
		break;
	}

.
125,129c
	id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E);
	switch(id){
.
120c
	 * This stuff is just a mystery for the ViRGE/GX2.
.
112c
	int i, id;
.
47,49c
	int id;

	id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E);
	switch(id){

	case 0xE110:				/* ViRGE/GX2 */
		break;

	default:
		lock(&scr->devlock);
		s3pageset(scr, page);
		unlock(&scr->devlock);
		break;
	}
.
## diffname pc/vgas3.c 1999/0119
## diff -e /n/emeliedump/1998/0116/sys/src/brazil/pc/vgas3.c /n/emeliedump/1999/0119/sys/src/brazil/pc/vgas3.c
11a
#include <cursor.h>
.
## diffname pc/vgas3.c 1999/0716
## diff -e /n/emeliedump/1999/0119/sys/src/brazil/pc/vgas3.c /n/emeliedump/1999/0716/sys/src/brazil/pc/vgas3.c
92a
	memset(&seg, 0, sizeof(seg));
	seg.attr = SG_PHYSICAL;
	seg.name = smalloc(NAMELEN);
	snprint(seg.name, NAMELEN, "s3screen");
	seg.pa = aperture;
	seg.size = osize;
	addphysseg(&seg);
.
72a
	osize = *size;
.
69a
	Physseg seg;
.
67c
	ulong aperture, oaperture, osize;
.
## diffname pc/vgas3.c 1999/0821
## diff -e /n/emeliedump/1999/0716/sys/src/brazil/pc/vgas3.c /n/emeliedump/1999/0821/sys/src/brazil/pc/vgas3.c
244a
	case 0xE131:				/* ViRGE */
.
201a
	case 0xE131:				/* ViRGE */
.
## diffname pc/vgas3.c 1999/1005
## diff -e /n/emeliedump/1999/0821/sys/src/brazil/pc/vgas3.c /n/emeliedump/1999/1005/sys/src/brazil/pc/vgas3.c
306a
	s3drawinit,
.
299a
/*
 * 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;
}

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->aperture+0x1000000);
		scr->fill = hwfill;
		scr->scroll = hwscroll;
	}
}

.
246a
	case 0xE18A:				/* ViRGE/[DG]X */
	case 0xE110:				/* ViRGE/GX2 */
	case 0xE13D:				/* ViRGE/VX */
.
245d
202a
	case 0xE18A:				/* ViRGE/[DG]X */
	case 0xE110:				/* ViRGE/GX2 */
	case 0xE13D:				/* ViRGE/VX */
.
201d
157,165d
149,155c
	for(i = 0; i < 3; i++)
		vgaxo(Crtx, 0x4A, Pblack);
	vgaxi(Crtx, 0x45);
	for(i = 0; i < 3; i++)
		vgaxo(Crtx, 0x4B, Pwhite);
.
146,147d
141d
133c
	int i;
.
101a

.
94a
	if(oaperture)
		print("warning (BUG): redefinition of aperture does not change s3screen segment\n");
.
74d
71a
	osize = *size;
.
67,68c
	ulong aperture, oaperture;
	int osize, oapsize, wasupamem;
.
22c
	if(scr->gscreen->depth >= 8){
.
## diffname pc/vgas3.c 2000/0326
## diff -e /n/emeliedump/1999/1005/sys/src/brazil/pc/vgas3.c /n/emeliedump/2000/0326/sys/src/9/pc/vgas3.c
465a
		/* scr->blank = hwblank; */
.
444a
s3blank(int blank)
{
	uchar x;

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

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

.
## diffname pc/vgas3.c 2000/0611
## diff -e /n/emeliedump/2000/0326/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0611/sys/src/9/pc/vgas3.c
239a
	case 0xE122:				/* Savage4 */
.
193a
	case 0xE122:				/* Savage4 */
.
86a
	if(wasupamem)
		upafree(oaperture, oapsize);
	scr->isupamem = 0;

.
81,84c
		for(i=0; i<nelem(p->mem); i++){
			if(p->mem[i].size >= *size
			&& ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0)
				break;
		}
		if(i >= nelem(p->mem)){
			print("vgas3: aperture not found\n");
			return 0;
		}
		aperture = p->mem[i].bar & ~0x0F;
		*size = p->mem[i].size;
	}else
.
76,78d
68c
	int i, osize, oapsize, wasupamem;
.
## diffname pc/vgas3.c 2000/0612
## diff -e /n/emeliedump/2000/0611/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0612/sys/src/9/pc/vgas3.c
379a
	if(x >= Maxloop)
		waitcount.idletimeout++;
.
367a
	if(x >= Maxloop)
		waitcount.fifotimeout++;
.
354a
	if(x >= Maxloop)
		waitcount.lineartimeout++;
.
327a
	ulong lineartimeout;
	ulong fifotimeout;
	ulong idletimeout;
.
169c
	vgaxo(Crtx, 0x4C, storage>>8);
.
113a
	if(mmiosize){
		memset(&seg, 0, sizeof(seg));
		seg.attr = SG_PHYSICAL;
		seg.name = smalloc(NAMELEN);
		snprint(seg.name, NAMELEN, mmioname);
		seg.pa = mmiobase;
		seg.size = mmiosize;
		addphysseg(&seg);
	}
.
88a

		id = (vgaxi(Crtx, 0x30)<<8)|vgaxi(Crtx, 0x2E);
		if(id == 0xE122){		/* find Savage4 mmio */
			/*
			 * We could assume that the MMIO registers
			 * will be in the screen segment and just use
			 * that, but PCI software is allowed to move them
			 * if it feels like it, so we look for an aperture of
			 * the right size; only the first 512k actually means
			 * anything.  The S3 engineers overestimated how
			 * much space they would need in the first design.
			 */
			for(j=0; j<nelem(p->mem); j++){
				if(i == j)
					continue;
				if(p->mem[j].size==512*1024 || p->mem[j].size==16*1024*1024){
					mmiobase = p->mem[j].bar & ~0x0F;
					mmiosize = 512*1024;
					mmioname = "savage4mmio";
					break;
				}
			}
			if(mmiosize == 0){
				print("savage4: mmio not found\n");
				return 0;
			}
		}
.
76a
	mmiosize = 0;
	mmiobase = 0;
	mmioname = nil;
.
67,68c
	char *mmioname;
	ulong aperture, oaperture, mmiobase, mmiosize;
	int i, id, j, osize, oapsize, wasupamem;
.
## diffname pc/vgas3.c 2000/0701
## diff -e /n/emeliedump/2000/0612/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0701/sys/src/9/pc/vgas3.c
289a
	case 0xE112:				/* Savage4/MX */
.
242a
	case 0xE112:				/* Savage4/MX */
.
## diffname pc/vgas3.c 2000/0708
## diff -e /n/emeliedump/2000/0701/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0708/sys/src/9/pc/vgas3.c
343a
}

static void
s3enable(VGAscr* scr)
{
	int i;
	ulong storage;

	s3disable(scr);

	/*
	 * Cursor colours. Set both the CR0[EF] and the colour
	 * stack in case we are using a 16-bit RAMDAC.
	 */
	vgaxo(Crtx, 0x0E, Pwhite);
	vgaxo(Crtx, 0x0F, Pblack);
	vgaxi(Crtx, 0x45);

	for(i = 0; i < 3; i++)
		vgaxo(Crtx, 0x4A, Pblack);
	vgaxi(Crtx, 0x45);
	for(i = 0; i < 3; i++)
		vgaxo(Crtx, 0x4B, Pwhite);

	/*
	 * Find a place for the cursor data in display memory.
	 * Must be on a 1024-byte boundary.
	 */
	storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024;
	vgaxo(Crtx, 0x4C, storage>>8);
	vgaxo(Crtx, 0x4D, storage & 0xFF);
	storage *= 1024;
	scr->storage = storage;

	/*
	 * Load, locate and enable the cursor
	 * in Microsoft Windows format.
	 */
	s3load(scr, &arrow);
	s3move(scr, ZP);
	vgaxo(Crtx, 0x55, vgaxi(Crtx, 0x55) & ~0x10);
	s3vsyncactive();
	vgaxo(Crtx, 0x45, 0x01);
.
291c
	case 0xE112:				/* Savage4/IX-MV */
.
243c
	case 0xE112:				/* Savage4/IX-MV */
.
183,222d
## diffname pc/vgas3.c 2000/0721
## diff -e /n/emeliedump/2000/0708/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0721/sys/src/9/pc/vgas3.c
248c
	case 0xE101:				/* ViRGE/[DG]X */
.
216,217c
	 * The cursor is set in Microsoft Windows format (the ViRGE/GX2 doesn't
	 * support the X11 format) which gives the following truth table:
.
200c
	case 0xE101:				/* ViRGE/[DG]X */
.
## diffname pc/vgas3.c 2000/0803
## diff -e /n/emeliedump/2000/0721/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0803/sys/src/9/pc/vgas3.c
545,547c
	case 0x5631:				/* ViRGE */
	case 0x883D:				/* ViRGE/VX */
	case 0x8A10:				/* ViRGE/GX2 */
.
394c
	case 0x8A10:	/* ViRGE/GX2 */
.
389,390c
	case 0x5631:	/* ViRGE */
	case 0x883D:	/* ViRGE/VX */
.
247,252c
	case 0x5631:				/* ViRGE */
	case 0x8A01:				/* ViRGE/[DG]X */
	case 0x8A10:				/* ViRGE/GX2 */
	case 0x883D:				/* ViRGE/VX */
	case 0x8A12:				/* Savage4/IX-MV */
	case 0x8A22:				/* Savage4 */
.
199,204c
	case 0x5631:				/* ViRGE */
	case 0x8A01:				/* ViRGE/[DG]X */
	case 0x8A10:				/* ViRGE/GX2 */
	case 0x883D:				/* ViRGE/VX */
	case 0x8A12:				/* Savage4/IX-MV */
	case 0x8A22:				/* Savage4 */
.
94,95c
		id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
		if(id == 0x8A22){		/* find Savage4 mmio */
.
53c
	case 0x8A10:				/* ViRGE/GX2 */
.
50c
	id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
.
## diffname pc/vgas3.c 2000/0809
## diff -e /n/emeliedump/2000/0803/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0809/sys/src/9/pc/vgas3.c
534c
	id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
.
196c
	id = (vgaxi(Crtx, 0x2D)<<8)|vgaxi(Crtx, 0x2E);
.
## diffname pc/vgas3.c 2000/0820
## diff -e /n/emeliedump/2000/0809/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0820/sys/src/9/pc/vgas3.c
251c
	case 0x8C12:				/* Savage4/IX-MV */
.
203c
	case 0x8C12:				/* Savage4/IX-MV */
.
## diffname pc/vgas3.c 2000/0903
## diff -e /n/emeliedump/2000/0820/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0903/sys/src/9/pc/vgas3.c
551a
		break;
	case SAVAGE4:
		savageinit(scr);
		break;
.
545,547c
	case VIRGE:				/* ViRGE */
	case VIRGEVX:				/* ViRGE/VX */
	case VIRGEGX2:				/* ViRGE/GX2 */
.
531a
	extern void savageinit(VGAscr*);	/* vgasavage.c */
.
528a

.
247,252c
	case VIRGE:
	case VIRGEDXGX:
	case VIRGEGX2:
	case VIRGEVX:	
	case SAVAGEIXMV:
	case SAVAGE4:
.
199,204c
	case VIRGE:
	case VIRGEDXGX:
	case VIRGEGX2:
	case VIRGEVX:	
	case SAVAGEIXMV:
	case SAVAGE4:
.
110a
					scr->mmio = (ulong*)upamalloc(mmiobase, mmiosize, 16*1024*1024);
.
95c
		if(id == SAVAGE4){		/* find Savage4 mmio */
.
81c
	if(p = pcimatch(nil, PCIS3, 0)){
.
53c
	case VIRGEGX2:
.
14a
enum {
	PCIS3		= 0x5333,		/* PCI VID */

	SAVAGE3D	= 0x8A20,	/* PCI DID */
	SAVAGE3DMV	= 0x8A21,
	SAVAGE4		= 0x8A22,
	SAVAGEMXMV	= 0x8C10,
	SAVAGEMX	= 0x8C11,
	SAVAGEIXMV	= 0x8C12,
	SAVAGEIX	= 0x8C13,
	SAVAGE2000	= 0x9102,

	VIRGE		= 0x5631,
	VIRGEGX2	= 0x8A10,
	VIRGEDXGX	= 0x8A01,
	VIRGEVX		= 0x883D,
	VIRGEMX		= 0x8C01,
	VIRGEMXP	= 0x8C03,

	AURORA64VPLUS	= 0x8812,
};

.
## diffname pc/vgas3.c 2000/0904
## diff -e /n/emeliedump/2000/0903/sys/src/9/pc/vgas3.c /n/emeliedump/2000/0904/sys/src/9/pc/vgas3.c
578a
		/* scr->mmio is set by s3linear */
.
577a
	case SAVAGEIXMV:
		scr->mmio = (ulong*)(scr->aperture+0x1000000);
		savageinit(scr);	
		break;
.
570,572c
	case VIRGE:
	case VIRGEVX:
	case VIRGEGX2:
.
## diffname pc/vgas3.c 2001/0405
## diff -e /n/emeliedump/2000/0904/sys/src/9/pc/vgas3.c /n/emeliedump/2001/0405/sys/src/9/pc/vgas3.c
103c

	/*
	 * S3 makes cards other than display controllers, so
	 * look for the first S3 display controller (device class 3)
	 * and not one of their sound cards.
	 */
	p = nil;
	while(p = pcimatch(p, PCIS3, 0)){
		if(p->ccrb == 0x03)
			break;
	}
	if(p != nil){
.
## diffname pc/vgas3.c 2001/0527
## diff -e /n/emeliedump/2001/0405/sys/src/9/pc/vgas3.c /n/emeliedump/2001/0527/sys/src/9/pc/vgas3.c
182,183c
		kstrdup(&seg.name, mmioname);
.
173,174c
	kstrdup(&seg.name, "s3screen");
.
103,114c
	if(p = pcimatch(nil, PCIS3, 0)){
.
## diffname pc/vgas3.c 2001/0704
## diff -e /n/emeliedump/2001/0527/sys/src/9/pc/vgas3.c /n/emeliedump/2001/0704/sys/src/9/pc/vgas3.c
158c
	if(oaperture && oaperture != aperture)
.
## diffname pc/vgas3.c 2001/0908
## diff -e /n/emeliedump/2001/0704/sys/src/9/pc/vgas3.c /n/emeliedump/2001/0908/sys/src/9/pc/vgas3.c
167,174c
	if(mmiosize)
		addvgaseg(mmioname, mmiobase, mmiosize);

.
160,165c
	addvgaseg("s3screen", aperture, osize);
.
103c

	/*
	 * S3 makes cards other than display controllers, so
	 * look for the first S3 display controller (device class 3)
	 * and not one of their sound cards.
	 */
	p = nil;
	while(p = pcimatch(p, PCIS3, 0)){
		if(p->ccrb == 0x03)
			break;
	}
	if(p != nil){
.
93d
## diffname pc/vgas3.c 2001/1014
## diff -e /n/emeliedump/2001/0908/sys/src/9/pc/vgas3.c /n/emeliedump/2001/1014/sys/src/9/pc/vgas3.c
579a
	case SUPERSAVAGEIXC16:
.
514c
	stride = round16(Dx(scr->gscreen->r))*d/8;
.
469c
	stride = round16(Dx(scr->gscreen->r))*d/8;
.
279d
266,276c
	if(dolock){
.
229a
		dolock = 1;
.
225a
	case SUPERSAVAGEIXC16:
		dolock = 0;
.
207c
	int id, dolock, opage, x, y;
.
143,144c
					scr->mmio = (ulong*)upamalloc(mmiobase, mmiosize, 0);
					mmioname = "savagemmio";
.
127c
		switch(id){			/* find mmio */
		case SAVAGE4:
		case SUPERSAVAGEIXC16:
.
24a
	SUPERSAVAGEIXC16 = 0x8C2E,
.
14a
#define	round16(x)	(((x)+15)&~15)

.
## diffname pc/vgas3.c 2001/1015
## diff -e /n/emeliedump/2001/1014/sys/src/9/pc/vgas3.c /n/emeliedump/2001/1015/sys/src/9/pc/vgas3.c
571d
563a
	scr->blank = s3blank;
	/* hwblank = 1;		not known to work well */

.
547d
536c
s3blank(VGAscr*, int blank)
.
511c
	stride = Dx(scr->gscreen->r)*d/8;
.
466c
	stride = Dx(scr->gscreen->r)*d/8;
.
15,16d
## diffname pc/vgas3.c 2001/1030
## diff -e /n/emeliedump/2001/1015/sys/src/9/pc/vgas3.c /n/emeliedump/2001/1030/sys/src/9/pc/vgas3.c
571a
	case SAVAGEMXMV:
.
226a
	case SAVAGEMXMV:
.
## diffname pc/vgas3.c 2003/0226
## diff -e /n/emeliedump/2001/1030/sys/src/9/pc/vgas3.c /n/emeliedump/2003/0226/sys/src/9/pc/vgas3.c
579a
	case PROSAVAGEP:
	case PROSAVAGEK:
.
229a
	case PROSAVAGEP:
	case PROSAVAGEK:
.
129a
		case PROSAVAGEP:
		case PROSAVAGEK:
.
20a
	PROSAVAGEP	= 0x8A25,
	PROSAVAGEK	= 0x8A26,
.
## diffname pc/vgas3.c 2003/0326
## diff -e /n/emeliedump/2003/0226/sys/src/9/pc/vgas3.c /n/emeliedump/2003/0326/sys/src/9/pc/vgas3.c
411a
	case 0x8A01:	/* ViRGE/[DG]X.  XFree86 says no waiting necessary */
		return;
.

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].