#include #include #include #include "pci.h" #include "vga.h" /* * S3 Vision968 GUI Accelerator. */ static void snarf(Vga* vga, Ctlr* ctlr) { s3generic.snarf(vga, ctlr); vga->sequencer[0x09] = vgaxi(Seqx, 0x09); vga->sequencer[0x0A] = vgaxi(Seqx, 0x0A); vga->crt[0x22] = vgaxi(Crtx, 0x22); vga->crt[0x24] = vgaxi(Crtx, 0x24); vga->crt[0x26] = vgaxi(Crtx, 0x26); vga->crt[0x2D] = vgaxi(Crtx, 0x2D); vga->crt[0x2E] = vgaxi(Crtx, 0x2E); vga->crt[0x2F] = vgaxi(Crtx, 0x2F); } static void options(Vga*, Ctlr* ctlr) { ctlr->flag |= Hlinear|Henhanced|Foptions; } static void init(Vga* vga, Ctlr* ctlr) { Mode *mode; ulong 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; vga->crt[0x65] = 0x00; vga->crt[0x66] &= ~0x07; vga->crt[0x67] = 0x00; vga->crt[0x6D] = 0x00; if(ctlr->flag & Uenhanced){ if(vga->ramdac && (vga->ramdac->flag & Hextsid)){ if(vga->ramdac->flag & Hsid32) sid = 32; else sid = 64; if(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[0x58] |= 0x40; /* * The test against 1376 is necessary for the STB * Velocity 64 Video, no idea if it's relevant to other * cards. * Although not mentioned in the databook, bit 4 of Crt67 * needs to be set on the STB Velocity 64 Video too. Gak. */ if(dbattr(vga->attr, "disa1sc") && mode->x <= 1376) vga->crt[0x65] |= 0x02; if(vga->ramdac && strncmp(vga->ramdac->name, "tvp3026", 7)) vga->crt[0x67] |= 0x10; if(dbattr(vga->attr, "vclkphs")) vga->crt[0x67] |= 0x01; if(val = dbattr(vga->attr, "delaybl")) vga->crt[0x6D] |= strtoul(val, 0, 0) & 0x07; if(val = dbattr(vga->attr, "delaysc")) vga->crt[0x6D] |= (strtoul(val, 0, 0) & 0x07)<<4; } } static void load(Vga* vga, Ctlr* ctlr) { ushort advfunc; s3generic.load(vga, ctlr); vgaxo(Crtx, 0x65, vga->crt[0x65]); vgaxo(Crtx, 0x66, vga->crt[0x66]); vgaxo(Crtx, 0x67, vga->crt[0x67]); 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, "Seq09"); printreg(vga->sequencer[0x09]); printreg(vga->sequencer[0x0A]); printitem(ctlr->name, "Crt22"); printreg(vga->crt[0x22]); printitem(ctlr->name, "Crt24"); printreg(vga->crt[0x24]); printitem(ctlr->name, "Crt26"); printreg(vga->crt[0x26]); printitem(ctlr->name, "Crt2D"); printreg(vga->crt[0x2D]); printreg(vga->crt[0x2E]); printreg(vga->crt[0x2F]); } Ctlr vision968 = { "vision968", /* name */ snarf, /* snarf */ options, /* options */ init, /* init */ load, /* load */ dump, /* dump */ };