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 Vision968 GUI Accelerator.
10 */
11 static void
snarf(Vga * vga,Ctlr * ctlr)12 snarf(Vga* vga, Ctlr* ctlr)
13 {
14 s3generic.snarf(vga, ctlr);
15
16 vga->sequencer[0x09] = vgaxi(Seqx, 0x09);
17 vga->sequencer[0x0A] = vgaxi(Seqx, 0x0A);
18
19 vga->crt[0x22] = vgaxi(Crtx, 0x22);
20 vga->crt[0x24] = vgaxi(Crtx, 0x24);
21 vga->crt[0x26] = vgaxi(Crtx, 0x26);
22 vga->crt[0x2D] = vgaxi(Crtx, 0x2D);
23 vga->crt[0x2E] = vgaxi(Crtx, 0x2E);
24 vga->crt[0x2F] = vgaxi(Crtx, 0x2F);
25 }
26
27 static void
options(Vga *,Ctlr * ctlr)28 options(Vga*, Ctlr* ctlr)
29 {
30 ctlr->flag |= Hlinear|Henhanced|Foptions;
31 }
32
33 static void
init(Vga * vga,Ctlr * ctlr)34 init(Vga* vga, Ctlr* ctlr)
35 {
36 Mode *mode;
37 ulong x;
38 int sid, dbl, bpp, divide;
39 char *val;
40
41 if(vga->mode->z > 8)
42 error("depth %d not supported\n", vga->mode->z);
43
44 mode = vga->mode;
45 if(vga->ramdac && (vga->ramdac->flag & Uclk2)){
46 resyncinit(vga, ctlr, Uenhanced, 0);
47 vga->crt[0x00] = ((mode->ht/2)>>3)-5;
48 vga->crt[0x01] = ((mode->x/2)>>3)-1;
49 vga->crt[0x02] = ((mode->shb/2)>>3)-1;
50
51 x = (mode->ehb/2)>>3;
52 vga->crt[0x03] = 0x80|(x & 0x1F);
53 vga->crt[0x04] = (mode->shs/2)>>3;
54 vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
55 if(x & 0x20)
56 vga->crt[0x05] |= 0x80;
57 vga->crt[0x13] = mode->x/8;
58 }
59 else if(mode->z == 8)
60 resyncinit(vga, ctlr, Uenhanced, 0);
61 s3generic.init(vga, ctlr);
62 /*
63 if((ctlr->flag & Uenhanced) == 0)
64 vga->crt[0x33] &= ~0x20;
65 */
66 vga->crt[0x3B] = (vga->crt[0]+vga->crt[4]+1)/2;
67 if(vga->crt[0x3B] & 0x100)
68 vga->crt[0x5D] |= 0x40;
69 vga->crt[0x55] = 0x00;
70
71 vga->crt[0x40] &= ~0x10;
72 vga->crt[0x53] &= ~0x20;
73 vga->crt[0x58] &= ~0x48;
74 vga->crt[0x65] = 0x00;
75 vga->crt[0x66] &= ~0x07;
76 vga->crt[0x67] = 0x00;
77 vga->crt[0x6D] = 0x00;
78 if(ctlr->flag & Uenhanced){
79 if(vga->ramdac && (vga->ramdac->flag & Hextsid)){
80 if(vga->ramdac->flag & Hsid32)
81 sid = 32;
82 else
83 sid = 64;
84 if(vga->ramdac->flag & Uclk2)
85 dbl = 2;
86 else
87 dbl = 1;
88 if(mode->z < 4)
89 bpp = 4;
90 else
91 bpp = mode->z;
92 divide = sid/(dbl*bpp);
93 switch(divide){
94 case 2:
95 vga->crt[0x66] |= 0x01;
96 break;
97 case 4:
98 vga->crt[0x66] |= 0x02;
99 break;
100 case 8:
101 vga->crt[0x66] |= 0x03;
102 break;
103 case 16:
104 vga->crt[0x66] |= 0x04;
105 break;
106 case 32:
107 vga->crt[0x66] |= 0x05;
108 break;
109 }
110 }
111
112 vga->crt[0x40] |= 0x10;
113 vga->crt[0x58] |= 0x40;
114
115 /*
116 * The test against 1376 is necessary for the STB
117 * Velocity 64 Video, no idea if it's relevant to other
118 * cards.
119 * Although not mentioned in the databook, bit 4 of Crt67
120 * needs to be set on the STB Velocity 64 Video too. Gak.
121 */
122 if(dbattr(vga->attr, "disa1sc") && mode->x <= 1376)
123 vga->crt[0x65] |= 0x02;
124 if(vga->ramdac && strncmp(vga->ramdac->name, "tvp3026", 7))
125 vga->crt[0x67] |= 0x10;
126
127 if(dbattr(vga->attr, "vclkphs"))
128 vga->crt[0x67] |= 0x01;
129 if(val = dbattr(vga->attr, "delaybl"))
130 vga->crt[0x6D] |= strtoul(val, 0, 0) & 0x07;
131 if(val = dbattr(vga->attr, "delaysc"))
132 vga->crt[0x6D] |= (strtoul(val, 0, 0) & 0x07)<<4;
133 }
134 }
135
136 static void
load(Vga * vga,Ctlr * ctlr)137 load(Vga* vga, Ctlr* ctlr)
138 {
139 ushort advfunc;
140
141 s3generic.load(vga, ctlr);
142 vgaxo(Crtx, 0x65, vga->crt[0x65]);
143 vgaxo(Crtx, 0x66, vga->crt[0x66]);
144 vgaxo(Crtx, 0x67, vga->crt[0x67]);
145 vgaxo(Crtx, 0x6D, vga->crt[0x6D]);
146
147 advfunc = 0x0000;
148 if(ctlr->flag & Uenhanced)
149 advfunc = 0x0001;
150 outportw(0x4AE8, advfunc);
151 }
152
153 static void
dump(Vga * vga,Ctlr * ctlr)154 dump(Vga* vga, Ctlr* ctlr)
155 {
156 s3generic.dump(vga, ctlr);
157
158 printitem(ctlr->name, "Seq09");
159 printreg(vga->sequencer[0x09]);
160 printreg(vga->sequencer[0x0A]);
161
162 printitem(ctlr->name, "Crt22");
163 printreg(vga->crt[0x22]);
164 printitem(ctlr->name, "Crt24");
165 printreg(vga->crt[0x24]);
166 printitem(ctlr->name, "Crt26");
167 printreg(vga->crt[0x26]);
168 printitem(ctlr->name, "Crt2D");
169 printreg(vga->crt[0x2D]);
170 printreg(vga->crt[0x2E]);
171 printreg(vga->crt[0x2F]);
172 }
173
174 Ctlr vision968 = {
175 "vision968", /* name */
176 snarf, /* snarf */
177 options, /* options */
178 init, /* init */
179 load, /* load */
180 dump, /* dump */
181 };
182