## 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;
.
|