xref: /plan9/sys/src/cmd/aux/vga/vision964.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 
5 #include "pci.h"
6 #include "vga.h"
7 
8 /*
9  * S3 Vision964 GUI Accelerator.
10  */
11 static void
snarf(Vga * vga,Ctlr * ctlr)12 snarf(Vga* vga, Ctlr* ctlr)
13 {
14 	s3generic.snarf(vga, ctlr);
15 	vga->crt[0x22] = vgaxi(Crtx, 0x22);
16 	vga->crt[0x24] = vgaxi(Crtx, 0x24);
17 	vga->crt[0x26] = vgaxi(Crtx, 0x26);
18 }
19 
20 static void
options(Vga *,Ctlr * ctlr)21 options(Vga*, Ctlr* ctlr)
22 {
23 	ctlr->flag |= Hlinear|Henhanced|Foptions;
24 }
25 
26 static void
init(Vga * vga,Ctlr * ctlr)27 init(Vga* vga, Ctlr* ctlr)
28 {
29 	Mode *mode;
30 	ulong x;
31 	int sid, dbl, bpp, divide;
32 	char *val;
33 
34 	if(vga->mode->z > 8)
35 		error("depth %d not supported\n", vga->mode->z);
36 
37 	mode = vga->mode;
38 	if(vga->ramdac && (vga->ramdac->flag & Uclk2)){
39 		resyncinit(vga, ctlr, Uenhanced, 0);
40 		vga->crt[0x00] = ((mode->ht/2)>>3)-5;
41 		vga->crt[0x01] = ((mode->x/2)>>3)-1;
42 		vga->crt[0x02] = ((mode->shb/2)>>3)-1;
43 
44 		x = (mode->ehb/2)>>3;
45 		vga->crt[0x03] = 0x80|(x & 0x1F);
46 		vga->crt[0x04] = (mode->shs/2)>>3;
47 		vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
48 		if(x & 0x20)
49 			vga->crt[0x05] |= 0x80;
50 		vga->crt[0x13] = mode->x/8;
51 	}
52 	else if(mode->z == 8)
53 		resyncinit(vga, ctlr, Uenhanced, 0);
54 	s3generic.init(vga, ctlr);
55 	/*
56 	if((ctlr->flag & Uenhanced) == 0)
57 		vga->crt[0x33] &= ~0x20;
58 	 */
59 	vga->crt[0x3B] = (vga->crt[0]+vga->crt[4]+1)/2;
60 	if(vga->crt[0x3B] & 0x100)
61 		vga->crt[0x5D] |= 0x40;
62 	vga->crt[0x55] = 0x00;
63 
64 	vga->crt[0x40] &= ~0x10;
65 	vga->crt[0x53] &= ~0x20;
66 	vga->crt[0x58] &= ~0x48;
67 	if(dbattr(vga->attr, "sam512") == 0)
68 		vga->crt[0x58] |= 0x40;		/* set 256 word SAM, always works */
69 	vga->crt[0x65] = 0x00;
70 	vga->crt[0x66] &= ~0x07;
71 	vga->crt[0x6D] = 0x00;
72 	if(ctlr->flag & Uenhanced){
73 		if(vga->ramdac && (vga->ramdac->flag & Hsid32))
74 			sid = 32;
75 		else
76 			sid = 64;
77 		if(vga->ramdac && (vga->ramdac->flag & Uclk2))
78 			dbl = 2;
79 		else
80 			dbl = 1;
81 		if(mode->z < 4)
82 			bpp = 4;
83 		else
84 			bpp = mode->z;
85 		divide = sid/(dbl*bpp);
86 		switch(divide){
87 		case 2:
88 			vga->crt[0x66] |= 0x01;
89 			break;
90 		case 4:
91 			vga->crt[0x66] |= 0x02;
92 			break;
93 		case 8:
94 			vga->crt[0x66] |= 0x03;
95 			break;
96 		case 16:
97 			vga->crt[0x66] |= 0x04;
98 			break;
99 		case 32:
100 			vga->crt[0x66] |= 0x05;
101 			break;
102 		}
103 
104 		vga->crt[0x40] |= 0x10;
105 		vga->crt[0x65] |= 0x02;
106 		if(vga->ramdac && (vga->ramdac->flag & Hsid32))
107 			vga->crt[0x66] |= 0x10;
108 
109 		/*
110 		 * Some heuristics (what part of aux/vga isn't?)
111 		 * to prevent some of the right border appearing
112 		 * on the left edge of the screen.
113 		 */
114 		if(dbattr(vga->attr, "vclkphs"))
115 			vga->crt[0x67] |= 0x01;
116 		if(val = dbattr(vga->attr, "delaybl"))
117 			vga->crt[0x6D] |= strtoul(val, 0, 0) & 0x07;
118 		else if(mode->x > 1024)
119 			vga->crt[0x6D] |= 0x01;
120 		else
121 			vga->crt[0x6D] |= 0x03;
122 
123 		if(val = dbattr(vga->attr, "delaysc"))
124 			vga->crt[0x6D] |= (strtoul(val, 0, 0) & 0x07)<<4;
125 	}
126 }
127 
128 static void
load(Vga * vga,Ctlr * ctlr)129 load(Vga* vga, Ctlr* ctlr)
130 {
131 	ushort advfunc;
132 
133 	s3generic.load(vga, ctlr);
134 	vgaxo(Crtx, 0x65, vga->crt[0x65]);
135 	vgaxo(Crtx, 0x66, vga->crt[0x66]);
136 	vgaxo(Crtx, 0x6D, vga->crt[0x6D]);
137 
138 	advfunc = 0x0000;
139 	if(ctlr->flag & Uenhanced)
140 		advfunc = 0x0001;
141 	outportw(0x4AE8, advfunc);
142 }
143 
144 static void
dump(Vga * vga,Ctlr * ctlr)145 dump(Vga* vga, Ctlr* ctlr)
146 {
147 	s3generic.dump(vga, ctlr);
148 	printitem(ctlr->name, "Crt22");
149 	printreg(vga->crt[0x22]);
150 	printitem(ctlr->name, "Crt24");
151 	printreg(vga->crt[0x24]);
152 	printitem(ctlr->name, "Crt26");
153 	printreg(vga->crt[0x26]);
154 }
155 
156 Ctlr vision964 = {
157 	"vision964",			/* name */
158 	snarf,				/* snarf */
159 	options,			/* options */
160 	init,				/* init */
161 	load,				/* load */
162 	dump,				/* dump */
163 };
164