xref: /plan9-contrib/sys/src/cmd/aux/vga/vision964.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier 
5*9a747e4fSDavid du Colombier #include "pci.h"
67dd7cddfSDavid du Colombier #include "vga.h"
77dd7cddfSDavid du Colombier 
87dd7cddfSDavid du Colombier /*
97dd7cddfSDavid du Colombier  * S3 Vision964 GUI Accelerator.
107dd7cddfSDavid du Colombier  */
117dd7cddfSDavid du Colombier static void
snarf(Vga * vga,Ctlr * ctlr)127dd7cddfSDavid du Colombier snarf(Vga* vga, Ctlr* ctlr)
137dd7cddfSDavid du Colombier {
147dd7cddfSDavid du Colombier 	s3generic.snarf(vga, ctlr);
157dd7cddfSDavid du Colombier 	vga->crt[0x22] = vgaxi(Crtx, 0x22);
167dd7cddfSDavid du Colombier 	vga->crt[0x24] = vgaxi(Crtx, 0x24);
177dd7cddfSDavid du Colombier 	vga->crt[0x26] = vgaxi(Crtx, 0x26);
187dd7cddfSDavid du Colombier }
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier static void
options(Vga *,Ctlr * ctlr)217dd7cddfSDavid du Colombier options(Vga*, Ctlr* ctlr)
227dd7cddfSDavid du Colombier {
237dd7cddfSDavid du Colombier 	ctlr->flag |= Hlinear|Henhanced|Foptions;
247dd7cddfSDavid du Colombier }
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier static void
init(Vga * vga,Ctlr * ctlr)277dd7cddfSDavid du Colombier init(Vga* vga, Ctlr* ctlr)
287dd7cddfSDavid du Colombier {
297dd7cddfSDavid du Colombier 	Mode *mode;
307dd7cddfSDavid du Colombier 	ulong x;
317dd7cddfSDavid du Colombier 	int sid, dbl, bpp, divide;
327dd7cddfSDavid du Colombier 	char *val;
337dd7cddfSDavid du Colombier 
347dd7cddfSDavid du Colombier 	if(vga->mode->z > 8)
357dd7cddfSDavid du Colombier 		error("depth %d not supported\n", vga->mode->z);
367dd7cddfSDavid du Colombier 
377dd7cddfSDavid du Colombier 	mode = vga->mode;
387dd7cddfSDavid du Colombier 	if(vga->ramdac && (vga->ramdac->flag & Uclk2)){
397dd7cddfSDavid du Colombier 		resyncinit(vga, ctlr, Uenhanced, 0);
407dd7cddfSDavid du Colombier 		vga->crt[0x00] = ((mode->ht/2)>>3)-5;
417dd7cddfSDavid du Colombier 		vga->crt[0x01] = ((mode->x/2)>>3)-1;
427dd7cddfSDavid du Colombier 		vga->crt[0x02] = ((mode->shb/2)>>3)-1;
437dd7cddfSDavid du Colombier 
447dd7cddfSDavid du Colombier 		x = (mode->ehb/2)>>3;
457dd7cddfSDavid du Colombier 		vga->crt[0x03] = 0x80|(x & 0x1F);
467dd7cddfSDavid du Colombier 		vga->crt[0x04] = (mode->shs/2)>>3;
477dd7cddfSDavid du Colombier 		vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
487dd7cddfSDavid du Colombier 		if(x & 0x20)
497dd7cddfSDavid du Colombier 			vga->crt[0x05] |= 0x80;
507dd7cddfSDavid du Colombier 		vga->crt[0x13] = mode->x/8;
517dd7cddfSDavid du Colombier 	}
527dd7cddfSDavid du Colombier 	else if(mode->z == 8)
537dd7cddfSDavid du Colombier 		resyncinit(vga, ctlr, Uenhanced, 0);
547dd7cddfSDavid du Colombier 	s3generic.init(vga, ctlr);
557dd7cddfSDavid du Colombier 	/*
567dd7cddfSDavid du Colombier 	if((ctlr->flag & Uenhanced) == 0)
577dd7cddfSDavid du Colombier 		vga->crt[0x33] &= ~0x20;
587dd7cddfSDavid du Colombier 	 */
597dd7cddfSDavid du Colombier 	vga->crt[0x3B] = (vga->crt[0]+vga->crt[4]+1)/2;
607dd7cddfSDavid du Colombier 	if(vga->crt[0x3B] & 0x100)
617dd7cddfSDavid du Colombier 		vga->crt[0x5D] |= 0x40;
627dd7cddfSDavid du Colombier 	vga->crt[0x55] = 0x00;
637dd7cddfSDavid du Colombier 
647dd7cddfSDavid du Colombier 	vga->crt[0x40] &= ~0x10;
657dd7cddfSDavid du Colombier 	vga->crt[0x53] &= ~0x20;
667dd7cddfSDavid du Colombier 	vga->crt[0x58] &= ~0x48;
677dd7cddfSDavid du Colombier 	if(dbattr(vga->attr, "sam512") == 0)
687dd7cddfSDavid du Colombier 		vga->crt[0x58] |= 0x40;		/* set 256 word SAM, always works */
697dd7cddfSDavid du Colombier 	vga->crt[0x65] = 0x00;
707dd7cddfSDavid du Colombier 	vga->crt[0x66] &= ~0x07;
717dd7cddfSDavid du Colombier 	vga->crt[0x6D] = 0x00;
727dd7cddfSDavid du Colombier 	if(ctlr->flag & Uenhanced){
737dd7cddfSDavid du Colombier 		if(vga->ramdac && (vga->ramdac->flag & Hsid32))
747dd7cddfSDavid du Colombier 			sid = 32;
757dd7cddfSDavid du Colombier 		else
767dd7cddfSDavid du Colombier 			sid = 64;
777dd7cddfSDavid du Colombier 		if(vga->ramdac && (vga->ramdac->flag & Uclk2))
787dd7cddfSDavid du Colombier 			dbl = 2;
797dd7cddfSDavid du Colombier 		else
807dd7cddfSDavid du Colombier 			dbl = 1;
817dd7cddfSDavid du Colombier 		if(mode->z < 4)
827dd7cddfSDavid du Colombier 			bpp = 4;
837dd7cddfSDavid du Colombier 		else
847dd7cddfSDavid du Colombier 			bpp = mode->z;
857dd7cddfSDavid du Colombier 		divide = sid/(dbl*bpp);
867dd7cddfSDavid du Colombier 		switch(divide){
877dd7cddfSDavid du Colombier 		case 2:
887dd7cddfSDavid du Colombier 			vga->crt[0x66] |= 0x01;
897dd7cddfSDavid du Colombier 			break;
907dd7cddfSDavid du Colombier 		case 4:
917dd7cddfSDavid du Colombier 			vga->crt[0x66] |= 0x02;
927dd7cddfSDavid du Colombier 			break;
937dd7cddfSDavid du Colombier 		case 8:
947dd7cddfSDavid du Colombier 			vga->crt[0x66] |= 0x03;
957dd7cddfSDavid du Colombier 			break;
967dd7cddfSDavid du Colombier 		case 16:
977dd7cddfSDavid du Colombier 			vga->crt[0x66] |= 0x04;
987dd7cddfSDavid du Colombier 			break;
997dd7cddfSDavid du Colombier 		case 32:
1007dd7cddfSDavid du Colombier 			vga->crt[0x66] |= 0x05;
1017dd7cddfSDavid du Colombier 			break;
1027dd7cddfSDavid du Colombier 		}
1037dd7cddfSDavid du Colombier 
1047dd7cddfSDavid du Colombier 		vga->crt[0x40] |= 0x10;
1057dd7cddfSDavid du Colombier 		vga->crt[0x65] |= 0x02;
1067dd7cddfSDavid du Colombier 		if(vga->ramdac && (vga->ramdac->flag & Hsid32))
1077dd7cddfSDavid du Colombier 			vga->crt[0x66] |= 0x10;
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier 		/*
1107dd7cddfSDavid du Colombier 		 * Some heuristics (what part of aux/vga isn't?)
1117dd7cddfSDavid du Colombier 		 * to prevent some of the right border appearing
1127dd7cddfSDavid du Colombier 		 * on the left edge of the screen.
1137dd7cddfSDavid du Colombier 		 */
1147dd7cddfSDavid du Colombier 		if(dbattr(vga->attr, "vclkphs"))
1157dd7cddfSDavid du Colombier 			vga->crt[0x67] |= 0x01;
1167dd7cddfSDavid du Colombier 		if(val = dbattr(vga->attr, "delaybl"))
1177dd7cddfSDavid du Colombier 			vga->crt[0x6D] |= strtoul(val, 0, 0) & 0x07;
1187dd7cddfSDavid du Colombier 		else if(mode->x > 1024)
1197dd7cddfSDavid du Colombier 			vga->crt[0x6D] |= 0x01;
1207dd7cddfSDavid du Colombier 		else
1217dd7cddfSDavid du Colombier 			vga->crt[0x6D] |= 0x03;
1227dd7cddfSDavid du Colombier 
1237dd7cddfSDavid du Colombier 		if(val = dbattr(vga->attr, "delaysc"))
1247dd7cddfSDavid du Colombier 			vga->crt[0x6D] |= (strtoul(val, 0, 0) & 0x07)<<4;
1257dd7cddfSDavid du Colombier 	}
1267dd7cddfSDavid du Colombier }
1277dd7cddfSDavid du Colombier 
1287dd7cddfSDavid du Colombier static void
load(Vga * vga,Ctlr * ctlr)1297dd7cddfSDavid du Colombier load(Vga* vga, Ctlr* ctlr)
1307dd7cddfSDavid du Colombier {
1317dd7cddfSDavid du Colombier 	ushort advfunc;
1327dd7cddfSDavid du Colombier 
1337dd7cddfSDavid du Colombier 	s3generic.load(vga, ctlr);
1347dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x65, vga->crt[0x65]);
1357dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x66, vga->crt[0x66]);
1367dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x6D, vga->crt[0x6D]);
1377dd7cddfSDavid du Colombier 
1387dd7cddfSDavid du Colombier 	advfunc = 0x0000;
1397dd7cddfSDavid du Colombier 	if(ctlr->flag & Uenhanced)
1407dd7cddfSDavid du Colombier 		advfunc = 0x0001;
1417dd7cddfSDavid du Colombier 	outportw(0x4AE8, advfunc);
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier 
1447dd7cddfSDavid du Colombier static void
dump(Vga * vga,Ctlr * ctlr)1457dd7cddfSDavid du Colombier dump(Vga* vga, Ctlr* ctlr)
1467dd7cddfSDavid du Colombier {
1477dd7cddfSDavid du Colombier 	s3generic.dump(vga, ctlr);
1487dd7cddfSDavid du Colombier 	printitem(ctlr->name, "Crt22");
1497dd7cddfSDavid du Colombier 	printreg(vga->crt[0x22]);
1507dd7cddfSDavid du Colombier 	printitem(ctlr->name, "Crt24");
1517dd7cddfSDavid du Colombier 	printreg(vga->crt[0x24]);
1527dd7cddfSDavid du Colombier 	printitem(ctlr->name, "Crt26");
1537dd7cddfSDavid du Colombier 	printreg(vga->crt[0x26]);
1547dd7cddfSDavid du Colombier }
1557dd7cddfSDavid du Colombier 
1567dd7cddfSDavid du Colombier Ctlr vision964 = {
1577dd7cddfSDavid du Colombier 	"vision964",			/* name */
1587dd7cddfSDavid du Colombier 	snarf,				/* snarf */
1597dd7cddfSDavid du Colombier 	options,			/* options */
1607dd7cddfSDavid du Colombier 	init,				/* init */
1617dd7cddfSDavid du Colombier 	load,				/* load */
1627dd7cddfSDavid du Colombier 	dump,				/* dump */
1637dd7cddfSDavid du Colombier };
164