]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/vga/et4000.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / aux / vga / et4000.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 #include "pci.h"
6 #include "vga.h"
7
8 /*
9  * Tseng Labs Inc. ET4000 Video Controller.
10  */
11 enum {
12         Crtcbx          = 0x217A,       /* Secondary CRT controller */
13
14         Sprite          = 0xE0,
15         NSprite         = 0x10,
16
17         Ima             = 0xF0,
18         NIma            = 0x08,
19 };
20
21 static void
22 setkey(void)
23 {
24         outportb(0x3BF, 0x03);
25         outportb(0x3D8, 0xA0);
26         outportb(0x3CD, 0x00);
27 }
28
29 static void
30 snarf(Vga* vga, Ctlr* ctlr)
31 {
32         int i;
33
34         setkey();
35
36         vga->sequencer[0x06] = vgaxi(Seqx, 0x06);
37         vga->sequencer[0x07] = vgaxi(Seqx, 0x07);
38
39         for(i = 0x30; i < 0x38; i++)
40                 vga->crt[i] = vgaxi(Crtx, i);
41         vga->crt[0x3F] = vgaxi(Crtx, 0x3F);
42
43         vga->attribute[0x16] = vgaxi(Attrx, 0x16);
44         vga->attribute[0x17] = vgaxi(Attrx, 0x17);
45
46         /*
47          * Memory size.
48          */
49         switch(vga->crt[0x37] & 0x03){
50
51         case 1:
52                 vga->vmz = 256*1024;
53                 break;
54
55         case 2:
56                 vga->vmz = 512*1024;
57                 break;
58
59         case 3:
60                 vga->vmz = 1024*1024;
61                 break;
62         }
63         if(strncmp(ctlr->name, "et4000-w32", 10) == 0){
64                 if(vga->crt[0x32] & 0x80)
65                         vga->vmz *= 2;
66         }
67         else if(vga->crt[0x37] & 0x80)
68                 vga->vmz *= 2;
69
70         ctlr->flag |= Fsnarf;
71 }
72
73 static void
74 options(Vga* vga, Ctlr* ctlr)
75 {
76         /*
77          * The ET4000 does not need to have the vertical
78          * timing values divided by 2 for interlace mode.
79          */
80         if(vga->mode->interlace == 'v')
81                 vga->mode->interlace = 'V';
82
83         if(strncmp(ctlr->name, "et4000-w32", 10) == 0)
84                 ctlr->flag |= Hpclk2x8;
85         
86         ctlr->flag |= Hclkdiv|Foptions;
87 }
88
89 static void
90 init(Vga* vga, Ctlr* ctlr)
91 {
92         Mode *mode;
93         ulong x;
94
95         if(vga->mode->z > 8)
96                 error("depth %d not supported\n", vga->mode->z);
97
98         if(ctlr->flag & Upclk2x8){
99                 mode = vga->mode;
100                 vga->crt[0x00] = ((mode->ht/2)>>3)-5;
101                 vga->crt[0x01] = ((mode->x/2)>>3)-1;
102                 vga->crt[0x02] = ((mode->shb/2)>>3)-1;
103         
104                 x = (mode->ehb/2)>>3;
105                 vga->crt[0x03] = 0x80|(x & 0x1F);
106                 vga->crt[0x04] = (mode->shs/2)>>3;
107                 vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
108                 if(x & 0x20)
109                         vga->crt[0x05] |= 0x80;
110         }
111         /*
112          * Itth a mythtawee.
113          */
114         if(vga->crt[0x14] & 0x20)
115                 vga->crt[0x17] |= 0x08;
116         vga->crt[0x17] &= ~0x20;
117
118         vga->crt[0x30] = 0x00;
119         vga->crt[0x33] = 0x00;
120
121         /*
122          * Overflow High.
123          */
124         vga->crt[0x35] = 0x00;
125         if(vga->crt[0x15] & 0x400)
126                 vga->crt[0x35] |= 0x01;
127         if(vga->crt[0x06] & 0x400)
128                 vga->crt[0x35] |= 0x02;
129         if(vga->crt[0x12] & 0x400)
130                 vga->crt[0x35] |= 0x04;
131         if(vga->crt[0x10] & 0x400)
132                 vga->crt[0x35] |= 0x08;
133         if(vga->crt[0x18] & 0x400)
134                 vga->crt[0x35] |= 0x10;
135         if(vga->mode->interlace == 'V')
136                 vga->crt[0x35] |= 0x80;
137
138         /*
139          * Horizontal Overflow.
140          */
141         vga->crt[0x3F] = 0x00;
142         if(vga->crt[0x00] & 0x100)
143                 vga->crt[0x3F] |= 0x01;
144         if(vga->crt[0x02] & 0x100)
145                 vga->crt[0x3F] |= 0x04;
146         if(vga->crt[0x04] & 0x100)
147                 vga->crt[0x3F] |= 0x10;
148         if(vga->crt[0x13] & 0x100)
149                 vga->crt[0x3F] |= 0x80;
150
151         /*
152          * Turn off MMU buffers, linear map
153          * and memory-mapped registers.
154          */
155         vga->crt[0x36] &= ~0x38;
156
157         if(strncmp(ctlr->name, "et4000-w32", 10) == 0)
158                 vga->crt[0x37] |= 0x80;
159
160         vga->sequencer[0x06] = 0x00;
161
162         /*
163          * Clock select.
164          */
165         if(vga->f[0] > 86000000)
166                 error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
167         vga->misc &= ~0x0C;
168         vga->misc |= (vga->i[0] & 0x03)<<2;
169         if(vga->i[0] & 0x04)
170                 vga->crt[0x34] |= 0x02;
171         else
172                 vga->crt[0x34] &= ~0x02;
173         vga->crt[0x31] &= ~0xC0;
174         vga->crt[0x31] |= (vga->i[0] & 0x18)<<3;
175
176         vga->sequencer[0x07] &= ~0x41;
177         if(vga->d[0] == 4)
178                 vga->sequencer[0x07] |= 0x01;
179         else if(vga->d[0] == 2)
180                 vga->sequencer[0x07] |= 0x40;
181
182         vga->attribute[0x10] &= ~0x40;
183         vga->attribute[0x11] = Pblack;
184         vga->attribute[0x16] = 0x80;
185
186         if(ctlr->flag & Upclk2x8)
187                 vga->attribute[0x16] |= 0x20;
188
189         ctlr->flag |= Finit;
190 }
191
192 static void
193 load(Vga* vga, Ctlr* ctlr)
194 {
195         vgaxo(Crtx, 0x30, vga->crt[0x30]);
196         vgaxo(Crtx, 0x31, vga->crt[0x31]);
197         vgaxo(Crtx, 0x33, vga->crt[0x33]);
198         vgaxo(Crtx, 0x34, vga->crt[0x34]);
199         vgaxo(Crtx, 0x35, vga->crt[0x35]);
200         vgaxo(Crtx, 0x36, vga->crt[0x36]);
201         vgaxo(Crtx, 0x37, vga->crt[0x37]);
202         vgaxo(Crtx, 0x3F, vga->crt[0x3F]);
203
204         vgaxo(Seqx, 0x06, vga->sequencer[0x06]);
205         vgaxo(Seqx, 0x07, vga->sequencer[0x07]);
206
207         vgaxo(Attrx, 0x16, vga->attribute[0x16]);
208
209         ctlr->flag |= Fload;
210 }
211
212 static void
213 dump(Vga* vga, Ctlr* ctlr)
214 {
215         int i;
216         char *name;
217         ushort shb, vrs, x;
218
219         name = ctlr->name;
220
221         printitem(name, "Seq06");
222         printreg(vga->sequencer[0x06]);
223         printreg(vga->sequencer[0x07]);
224
225         printitem(name, "Crt30");
226         for(i = 0x30; i < 0x38; i++)
227                 printreg(vga->crt[i]);
228         printitem(name, "Crt3F");
229         printreg(vga->crt[0x3F]);
230
231         printitem(name, "Attr16");
232         printreg(vga->attribute[0x16]);
233         printreg(vga->attribute[0x17]);
234
235         if(strncmp(name, "et4000-w32", 10) == 0){
236                 printitem(name, "SpriteE0");
237                 for(i = Sprite; i < Sprite+NSprite; i++){
238                         outportb(Crtcbx, i);
239                         printreg(inportb(Crtcbx+1));
240                 }
241                 printitem(name, "ImaF0");
242                 for(i = Ima; i < Ima+NIma; i++){
243                         outportb(Crtcbx, i);
244                         printreg(inportb(Crtcbx+1));
245                 }
246         }
247
248         /*
249          * Try to disassemble the snarfed values into
250          * understandable numbers.
251          * Only do this if we weren't called after Finit.
252          */
253         if(ctlr->flag & Finit)
254                 return;
255
256         x = (vga->crt[0x01]+1)<<3;
257         printitem(name, "hde");
258         printreg(x);
259         Bprint(&stdout, "%6ud", x);
260
261         shb = ((((vga->crt[0x3F] & 0x04)<<6)|vga->crt[0x02])+1)<<3;
262         printitem(name, "shb");
263         printreg(shb);
264         Bprint(&stdout, "%6ud", shb);
265
266         x = (((vga->crt[0x05] & 0x80)>>2)|(vga->crt[0x03] & 0x1F))<<3;
267         printitem(name, "ehb");
268         printreg(x);
269         for(i = 0; x < shb; i++)
270                 x |= 0x200<<i;
271         Bprint(&stdout, "%6ud", x);
272
273         x = ((((vga->crt[0x3F] & 0x01)<<8)|vga->crt[0x00])+5)<<3;
274         printitem(name, "ht");
275         printreg(x);
276         Bprint(&stdout, "%6ud", x);
277
278         x = vga->crt[0x12];
279         if(vga->crt[0x07] & 0x02)
280                 x |= 0x100;
281         if(vga->crt[0x07] & 0x40)
282                 x |= 0x200;
283         if(vga->crt[0x35] & 0x04)
284                 x |= 0x400;
285         x += 1;
286         printitem(name, "vde");
287         printreg(x);
288         Bprint(&stdout, "%6ud", x);
289
290         vrs = vga->crt[0x10];
291         if(vga->crt[0x07] & 0x04)
292                 vrs |= 0x100;
293         if(vga->crt[0x07] & 0x80)
294                 vrs |= 0x200;
295         if(vga->crt[0x35] & 0x08)
296                 vrs |= 0x400;
297         printitem(name, "vrs");
298         printreg(vrs);
299         Bprint(&stdout, "%6ud", vrs);
300
301         x = (vrs & ~0x0F)|(vga->crt[0x11] & 0x0F);
302         printitem(name, "vre");
303         printreg(x);
304         Bprint(&stdout, "%6ud", x);
305
306         x = vga->crt[0x06];
307         if(vga->crt[0x07] & 0x01)
308                 x |= 0x100;
309         if(vga->crt[0x07] & 0x20)
310                 x |= 0x200;
311         if(vga->crt[0x35] & 0x02)
312                 x |= 0x400;
313         x += 2;
314         printitem(name, "vt");
315         printreg(x);
316         Bprint(&stdout, "%6ud", x);
317
318         printitem(name, "d i");
319         if(vga->sequencer[0x07] & 0x01)
320                 x = 4;
321         else if(vga->sequencer[0x07] & 0x40)
322                 x = 2;
323         else
324                 x = 0;
325         Bprint(&stdout, "%9ud", x);
326         x = (vga->misc & 0x0C)>>2;
327         if(vga->crt[0x34] & 0x02)
328                 x |= 0x04;
329         x |= (vga->crt[0x31] & 0xC0)>>3;
330         Bprint(&stdout, "%8ud\n", x);
331 }
332
333 Ctlr et4000 = {
334         "et4000",                       /* name */
335         snarf,                          /* snarf */
336         options,                        /* options */
337         init,                           /* init */
338         load,                           /* load */
339         dump,                           /* dump */
340 };