173 lines
3.8 KiB
C
173 lines
3.8 KiB
C
/*
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
* in the LICENSE file.
|
|
*/
|
|
|
|
#include <u.h>
|
|
#include <lib9.h>
|
|
#include <bio.h>
|
|
|
|
#include "pci.h"
|
|
#include "vga.h"
|
|
|
|
/*
|
|
* S3 Vision964 GUI Accelerator.
|
|
*/
|
|
static void
|
|
snarf(Vga* vga, Ctlr* ctlr)
|
|
{
|
|
s3generic.snarf(vga, ctlr);
|
|
vga->crt[0x22] = vgaxi(Crtx, 0x22);
|
|
vga->crt[0x24] = vgaxi(Crtx, 0x24);
|
|
vga->crt[0x26] = vgaxi(Crtx, 0x26);
|
|
}
|
|
|
|
static void
|
|
options(Vga* vga, Ctlr* ctlr)
|
|
{
|
|
ctlr->flag |= Hlinear|Henhanced|Foptions;
|
|
}
|
|
|
|
static void
|
|
init(Vga* vga, Ctlr* ctlr)
|
|
{
|
|
Mode *mode;
|
|
uint32_t x;
|
|
int sid, dbl, bpp, divide;
|
|
char *val;
|
|
|
|
if(vga->mode->z > 8)
|
|
error("depth %d not supported\n", vga->mode->z);
|
|
|
|
mode = vga->mode;
|
|
if(vga->ramdac && (vga->ramdac->flag & Uclk2)){
|
|
resyncinit(vga, ctlr, Uenhanced, 0);
|
|
vga->crt[0x00] = ((mode->ht/2)>>3)-5;
|
|
vga->crt[0x01] = ((mode->x/2)>>3)-1;
|
|
vga->crt[0x02] = ((mode->shb/2)>>3)-1;
|
|
|
|
x = (mode->ehb/2)>>3;
|
|
vga->crt[0x03] = 0x80|(x & 0x1F);
|
|
vga->crt[0x04] = (mode->shs/2)>>3;
|
|
vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
|
|
if(x & 0x20)
|
|
vga->crt[0x05] |= 0x80;
|
|
vga->crt[0x13] = mode->x/8;
|
|
}
|
|
else if(mode->z == 8)
|
|
resyncinit(vga, ctlr, Uenhanced, 0);
|
|
s3generic.init(vga, ctlr);
|
|
/*
|
|
if((ctlr->flag & Uenhanced) == 0)
|
|
vga->crt[0x33] &= ~0x20;
|
|
*/
|
|
vga->crt[0x3B] = (vga->crt[0]+vga->crt[4]+1)/2;
|
|
if(vga->crt[0x3B] & 0x100)
|
|
vga->crt[0x5D] |= 0x40;
|
|
vga->crt[0x55] = 0x00;
|
|
|
|
vga->crt[0x40] &= ~0x10;
|
|
vga->crt[0x53] &= ~0x20;
|
|
vga->crt[0x58] &= ~0x48;
|
|
if(dbattr(vga->attr, "sam512") == 0)
|
|
vga->crt[0x58] |= 0x40; /* set 256 word SAM, always works */
|
|
vga->crt[0x65] = 0x00;
|
|
vga->crt[0x66] &= ~0x07;
|
|
vga->crt[0x6D] = 0x00;
|
|
if(ctlr->flag & Uenhanced){
|
|
if(vga->ramdac && (vga->ramdac->flag & Hsid32))
|
|
sid = 32;
|
|
else
|
|
sid = 64;
|
|
if(vga->ramdac && (vga->ramdac->flag & Uclk2))
|
|
dbl = 2;
|
|
else
|
|
dbl = 1;
|
|
if(mode->z < 4)
|
|
bpp = 4;
|
|
else
|
|
bpp = mode->z;
|
|
divide = sid/(dbl*bpp);
|
|
switch(divide){
|
|
case 2:
|
|
vga->crt[0x66] |= 0x01;
|
|
break;
|
|
case 4:
|
|
vga->crt[0x66] |= 0x02;
|
|
break;
|
|
case 8:
|
|
vga->crt[0x66] |= 0x03;
|
|
break;
|
|
case 16:
|
|
vga->crt[0x66] |= 0x04;
|
|
break;
|
|
case 32:
|
|
vga->crt[0x66] |= 0x05;
|
|
break;
|
|
}
|
|
|
|
vga->crt[0x40] |= 0x10;
|
|
vga->crt[0x65] |= 0x02;
|
|
if(vga->ramdac && (vga->ramdac->flag & Hsid32))
|
|
vga->crt[0x66] |= 0x10;
|
|
|
|
/*
|
|
* Some heuristics (what part of aux/vga isn't?)
|
|
* to prevent some of the right border appearing
|
|
* on the left edge of the screen.
|
|
*/
|
|
if(dbattr(vga->attr, "vclkphs"))
|
|
vga->crt[0x67] |= 0x01;
|
|
if(val = dbattr(vga->attr, "delaybl"))
|
|
vga->crt[0x6D] |= strtoul(val, 0, 0) & 0x07;
|
|
else if(mode->x > 1024)
|
|
vga->crt[0x6D] |= 0x01;
|
|
else
|
|
vga->crt[0x6D] |= 0x03;
|
|
|
|
if(val = dbattr(vga->attr, "delaysc"))
|
|
vga->crt[0x6D] |= (strtoul(val, 0, 0) & 0x07)<<4;
|
|
}
|
|
}
|
|
|
|
static void
|
|
load(Vga* vga, Ctlr* ctlr)
|
|
{
|
|
uint16_t advfunc;
|
|
|
|
s3generic.load(vga, ctlr);
|
|
vgaxo(Crtx, 0x65, vga->crt[0x65]);
|
|
vgaxo(Crtx, 0x66, vga->crt[0x66]);
|
|
vgaxo(Crtx, 0x6D, vga->crt[0x6D]);
|
|
|
|
advfunc = 0x0000;
|
|
if(ctlr->flag & Uenhanced)
|
|
advfunc = 0x0001;
|
|
outportw(0x4AE8, advfunc);
|
|
}
|
|
|
|
static void
|
|
dump(Vga* vga, Ctlr* ctlr)
|
|
{
|
|
s3generic.dump(vga, ctlr);
|
|
printitem(ctlr->name, "Crt22");
|
|
printreg(vga->crt[0x22]);
|
|
printitem(ctlr->name, "Crt24");
|
|
printreg(vga->crt[0x24]);
|
|
printitem(ctlr->name, "Crt26");
|
|
printreg(vga->crt[0x26]);
|
|
}
|
|
|
|
Ctlr vision964 = {
|
|
"vision964", /* name */
|
|
snarf, /* snarf */
|
|
options, /* options */
|
|
init, /* init */
|
|
load, /* load */
|
|
dump, /* dump */
|
|
};
|