]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/vga/ark2000pv.c
abaco: cleanup, handle image/x-icon, don't use backspace as a hotkey, and remove...
[plan9front.git] / sys / src / cmd / aux / vga / ark2000pv.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  * ARK Logic ARK2000PV GUI accelerator.
10  */
11 static void
12 snarf(Vga* vga, Ctlr* ctlr)
13 {
14         int i;
15
16         /*
17          * Unlock access to the extended I/O registers.
18          */
19         vgaxo(Seqx, 0x1D, 0x01);
20
21         for(i = 0x10; i < 0x2E; i++)
22                 vga->sequencer[i] = vgaxi(Seqx, i);
23         for(i = 0x40; i < 0x47; i++)
24                 vga->crt[i] = vgaxi(Crtx, i);
25         vga->crt[0x50] = vgaxi(Crtx, 0x50);
26
27         /*
28          * A hidey-hole for the coprocessor status register.
29          */
30         vga->crt[0xFF] = inportb(0x3CB);
31
32         /*
33          * Memory size.
34          */
35         switch((vga->sequencer[0x10]>>6) & 0x03){
36
37         case 0x00:
38                 vga->vma = vga->vmz = 1*1024*1024;
39                 break;
40
41         case 0x01:
42                 vga->vma = vga->vmz = 2*1024*1024;
43                 break;
44
45         case 0x02:
46                 vga->vma = vga->vmz = 4*1024*1024;
47                 break;
48         }
49
50         ctlr->flag |= Fsnarf;
51 }
52
53 static void
54 options(Vga*, Ctlr* ctlr)
55 {
56         ctlr->flag |= Hlinear|Hpclk2x8|Foptions;
57 }
58
59 static void
60 init(Vga* vga, Ctlr* ctlr)
61 {
62         Mode *mode;
63         ulong x;
64
65         mode = vga->mode;
66
67         vga->crt[0x46] = 0x00;
68         if(ctlr->flag & Upclk2x8){
69                 vga->crt[0x00] = ((mode->ht/2)>>3)-5;
70                 vga->crt[0x01] = ((mode->x/2)>>3)-1;
71                 vga->crt[0x02] = ((mode->shb/2)>>3)-1;
72         
73                 x = (mode->ehb/2)>>3;
74                 vga->crt[0x03] = 0x80|(x & 0x1F);
75                 vga->crt[0x04] = (mode->shs/2)>>3;
76                 vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
77                 if(x & 0x20)
78                         vga->crt[0x05] |= 0x80;
79                 vga->crt[0x13] = mode->x/8;
80
81                 vga->crt[0x46] |= 0x04;
82         }
83
84         /*
85          * Overflow bits.
86          */
87         vga->crt[0x40] = 0x00;
88         if(vga->crt[0x18] & 0x400)
89                 vga->crt[0x40] |= 0x08;
90         if(vga->crt[0x10] & 0x400)
91                 vga->crt[0x40] |= 0x10;
92         if(vga->crt[0x15] & 0x400)
93                 vga->crt[0x40] |= 0x20;
94         if(vga->crt[0x12] & 0x400)
95                 vga->crt[0x40] |= 0x40;
96         if(vga->crt[0x06] & 0x400)
97                 vga->crt[0x40] |= 0x80;
98
99         vga->crt[0x41] = 0x00;
100         if(vga->crt[0x13] & 0x100)
101                 vga->crt[0x41] |= 0x08;
102         if(vga->crt[0x04] & 0x100)
103                 vga->crt[0x41] |= 0x10;
104         if(vga->crt[0x02] & 0x100)
105                 vga->crt[0x41] |= 0x20;
106         if(vga->crt[0x01] & 0x100)
107                 vga->crt[0x41] |= 0x40;
108         if(vga->crt[0x00] & 0x100)
109                 vga->crt[0x41] |= 0x80;
110
111         /*
112          * Interlace.
113          */
114         vga->crt[0x42] = 0x00;
115         vga->crt[0x44] = 0x00;
116         if(mode->interlace){
117                 vga->crt[0x42] = vga->crt[0]/2;
118                 vga->crt[0x44] |= 0x04;
119         }
120         vga->crt[0x45] = 0x00;
121
122         /*
123          * Memory configuration:
124          * enable linear|coprocessor|VESA modes;
125          * set aperture to 64Kb, 0xA0000;
126          * set aperture index 0.
127          * Bugs: 1024x768x1 doesn't work (aperture not set correctly?);
128          *       hwgc doesn't work in 1-bit modes (hardware?).
129          */
130         vga->sequencer[0x10] &= ~0x3F;
131         vga->sequencer[0x11] &= ~0x0F;
132         switch(mode->z){
133
134         case 1:
135                 vga->sequencer[0x10] |= 0x03;
136                 vga->sequencer[0x11] |= 0x01;
137                 cflag = 1;
138                 break;
139
140         case 8:
141                 vga->sequencer[0x10] |= 0x0F;
142                 vga->sequencer[0x11] |= 0x06;
143                 if(vga->linear && (ctlr->flag & Hlinear) && vga->vmz)
144                         ctlr->flag |= Ulinear;
145                 break;
146
147         default:
148                 error("depth %d not supported\n", mode->z);
149         }
150         vga->sequencer[0x12] &= ~0x03;
151         vga->sequencer[0x13] = 0x0A;
152         vga->sequencer[0x14] = 0x00;
153         vga->sequencer[0x15] = 0x00;
154         vga->sequencer[0x16] = 0x00;
155
156         /*
157          * Frame Buffer Pitch and FIFO control.
158          * Set the FIFO to 32 deep and refill trigger when
159          * 6 slots empty.
160          */
161         vga->sequencer[0x17] = 0x00;
162         vga->sequencer[0x18] = 0x13;
163         if(mode->x <= 640)
164                 vga->sequencer[0x17] = 0x00;
165         else if(mode->x <= 800)
166                 vga->sequencer[0x17] |= 0x01;
167         else if(mode->x <= 1024)
168                 vga->sequencer[0x17] |= 0x02;
169         else if(mode->x <= 1280)
170                 vga->sequencer[0x17] |= 0x04;
171         else if(mode->x <= 1600)
172                 vga->sequencer[0x17] |= 0x05;
173         else if(mode->x <= 2048)
174                 vga->sequencer[0x17] |= 0x06;
175
176         /*
177          * Clock select.
178          */
179         vga->misc &= ~0x0C;
180         vga->misc |= (vga->i[0] & 0x03)<<2;
181         vga->sequencer[0x11] &= ~0xC0;
182         vga->sequencer[0x11] |= (vga->i[0] & 0x0C)<<4;
183
184         vga->attribute[0x11] = 0x00;    /* color map entry for black */
185
186         ctlr->flag |= Finit;
187 }
188
189 static void
190 load(Vga* vga, Ctlr* ctlr)
191 {
192         ulong l;
193
194         /*
195          * Ensure there are no glitches when selecting a new
196          * clock frequency.
197          * The sequencer toggle seems to matter on the Hercules
198          * Stingray 64/Video at 1280x1024x8. Without it the screen
199          * is fuzzy; a second load clears it up and there's no
200          * difference between the two register sets. A mystery.
201          */
202         vgao(MiscW, vga->misc & ~0x0C);
203         vgaxo(Seqx, 0x11, vga->sequencer[0x11]);
204         vgao(MiscW, vga->misc);
205         if(vga->ramdac && strncmp(vga->ramdac->name, "w30c516", 7) == 0){
206                 sequencer(vga, 1);
207                 sleep(500);
208                 sequencer(vga, 0);
209         }
210
211         if(ctlr->flag & Ulinear){
212                 vga->sequencer[0x10] |= 0x10;
213                 if(vga->vmz <= 1024*1024)
214                         vga->sequencer[0x12] |= 0x01;
215                 else if(vga->vmz <= 2*1024*1024)
216                         vga->sequencer[0x12] |= 0x02;
217                 else
218                         vga->sequencer[0x12] |= 0x03;
219                 l = vga->vmb>>16;
220                 vga->sequencer[0x13] = l & 0xFF;
221                 vga->sequencer[0x14] = (l>>8) & 0xFF;
222         }
223
224         vgaxo(Seqx, 0x10, vga->sequencer[0x10]);
225         vgaxo(Seqx, 0x12, vga->sequencer[0x12]);
226         vgaxo(Seqx, 0x13, vga->sequencer[0x13]);
227         vgaxo(Seqx, 0x14, vga->sequencer[0x14]);
228         vgaxo(Seqx, 0x15, vga->sequencer[0x15]);
229         vgaxo(Seqx, 0x16, vga->sequencer[0x16]);
230         vgaxo(Seqx, 0x17, vga->sequencer[0x17]);
231         vgaxo(Seqx, 0x18, vga->sequencer[0x18]);
232
233         vgaxo(Crtx, 0x40, vga->crt[0x40]);
234         vgaxo(Crtx, 0x41, vga->crt[0x41]);
235         vgaxo(Crtx, 0x42, vga->crt[0x42]);
236         vgaxo(Crtx, 0x44, vga->crt[0x44]);
237         vgaxo(Crtx, 0x45, vga->crt[0x45]);
238         vgaxo(Crtx, 0x46, vga->crt[0x46]);
239
240         ctlr->flag |= Fload;
241 }
242
243 static void
244 dump(Vga* vga, Ctlr* ctlr)
245 {
246         int i;
247
248         printitem(ctlr->name, "Seq10");
249         for(i = 0x10; i < 0x2E; i++)
250                 printreg(vga->sequencer[i]);
251         printitem(ctlr->name, "Crt40");
252         for(i = 0x40; i < 0x47; i++)
253                 printreg(vga->crt[i]);
254         printitem(ctlr->name, "Crt50");
255         printreg(vga->crt[0x50]);
256         printitem(ctlr->name, "Cop status");
257         printreg(vga->crt[0xFF]);
258 }
259
260 Ctlr ark2000pv = {
261         "ark2000pv",                    /* name */
262         snarf,                          /* snarf */
263         options,                        /* options */
264         init,                           /* init */
265         load,                           /* load */
266         dump,                           /* dump */
267 };
268
269 Ctlr ark2000pvhwgc = {
270         "ark2000pvhwgc",                /* name */
271         0,                              /* snarf */
272         0,                              /* options */
273         0,                              /* init */
274         0,                              /* load */
275         0,                              /* dump */
276 };