]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/aux/vga/neomagic.c
abaco: cleanup, handle image/x-icon, don't use backspace as a hotkey, and remove...
[plan9front.git] / sys / src / cmd / aux / vga / neomagic.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 #include "pci.h"
6 #include "vga.h"
7
8 typedef struct {
9         Pcidev* pci;
10
11         int     x;
12         int     y;
13 } Neomagic;
14
15 enum {
16         ExtCrtx = 0x19,
17         MaxCRT=0x85,
18         MaxGR=0xc7,
19 };
20
21 enum {
22         GeneralLockReg = 0x0A,
23         ExtCRTDispAddr = 0x0E,
24         ExtCRTOffset = 0x0F,
25         SysIfaceCntl1 = 0x10,
26         SysIfaceCntl2 = 0x11,
27         SingleAddrPage = 0x15,          /* not changed? */
28         DualAddrPage = 0x16,            /* not changed? */
29         PanelDispCntlReg1 = 0x20,
30         PanelDispCntlReg2 = 0x25,
31         PanelDispCntlReg3 = 0x30,
32         PanelVertCenterReg1 = 0x28,
33         PanelVertCenterReg2 = 0x29,
34         PanelVertCenterReg3 = 0x2A,
35         PanelVertCenterReg4 = 0x32,     /* not 2070 */
36         PanelHorizCenterReg1 = 0x33,
37         PanelHorizCenterReg2 = 0x34,
38         PanelHorizCenterReg3 = 0x35,
39         PanelHorizCenterReg4 = 0x36,    /* 2160, 2200, 2360 */
40         PanelVertCenterReg5 = 0x37,     /* 2200, 2360 */
41         PanelHorizCenterReg5 = 0x38,    /* 2200, 2360 */
42
43         ExtColorModeSelect = 0x90,
44
45         VerticalExt = 0x70,             /* 2200; iobase+4 */
46 };
47
48 static int crts[] = {
49         0x1D, 0x1F, 0x21, 0x23, 0x25, 0x2F,
50         /* also 40-59, 60-69, 70-MaxCRT */
51         -1
52 };
53
54 /*
55  * Neomagic driver (fake)
56  */
57 static void
58 snarf(Vga* vga, Ctlr* ctlr)
59 {
60         int i;
61         Pcidev *p;
62         Neomagic *nm;
63
64         generic.snarf(vga, ctlr);
65
66         outportw(Grx, 0x2609);  /* unlock neo registers */
67         outportw(Grx, 0x0015);  /* reset bank */
68
69         for(i=0; crts[i] >= 0; i++)
70                 vga->crt[crts[i]] = vgaxi(Crtx, crts[i]);
71         for(i=0x40; i <= MaxCRT; i++)
72                 vga->crt[i] = vgaxi(Crtx, i);
73
74         for(i=0x08; i<=0x3F; i++)
75                 vga->graphics[i] = vgaxi(Grx, i);
76         for(i=0x70; i<=MaxGR; i++)
77                 vga->graphics[i] = vgaxi(Grx, i);
78
79         if(vga->private == nil){
80                 vga->private = alloc(sizeof(Neomagic));
81                 nm = vga->private;
82                 if((p = pcimatch(0, 0x10C8, 0)) == nil)
83                         error("%s: not found\n", ctlr->name);
84                 switch(p->did){
85                 case 0x0003:                    /* MagicGraph 128 ZV */
86                         vga->f[1] = 80000000;
87                         vga->vmz = 2048*1024;
88                         vga->apz = 4*1024*1024;
89                         break;
90                 case 0x0083:                    /* MagicGraph 128 ZV+ */
91                         vga->f[1] = 80000000;
92                         vga->vmz = 2048*1024;
93                         vga->apz = 4*1024*1024;
94                         break;
95                 case 0x0004:                    /* MagicGraph 128 XD */
96                         vga->f[1] = 90000000;
97                         vga->vmz = 2048*1024;
98                         vga->apz = 16*1024*1024;
99                         break;
100                 case 0x0005:                    /* MagicMedia 256 AV */
101                         vga->f[1] = 110000000;
102                         vga->vmz = 2560*1024;
103                         vga->apz = 16*1024*1024;
104                         break;
105                 case 0x0006:                    /* MagicMedia 256 ZX */
106                         vga->f[1] = 110000000;
107                         vga->vmz = 4096*1024;
108                         vga->apz = 16*1024*1024;
109                         break;
110                 case 0x0016:                    /* MagicMedia 256 XL+ */
111                         vga->f[1] = 110000000;
112                         /* Vaio VESA BIOS says 6080, but then hwgc doesn't work */
113                         vga->vmz = 4096*1024;
114                         vga->apz = 32*1024*1024;
115                         break;
116                 case 0x0001:                    /* MagicGraph 128 */
117                 case 0x0002:                    /* MagicGraph 128 V */
118                 default:
119                         error("%s: DID %4.4uX unsupported\n",
120                                 ctlr->name, p->did);
121                 }
122                 nm->pci = p;
123         }
124
125         ctlr->flag |= Fsnarf;
126 }
127
128 static void
129 options(Vga*, Ctlr* ctlr)
130 {
131         ctlr->flag |= Ulinear|Hlinear|Foptions;
132 }
133
134 static void
135 init(Vga* vga, Ctlr* ctlr)
136 {
137         Neomagic *nm;
138         int i, h, v, t;
139
140         generic.init(vga, ctlr);
141
142         nm = vga->private;
143         switch((vga->graphics[0x20]>>3)&3){
144         case 0:
145                 nm->x = 640;
146                 nm->y = 480;
147                 break;
148         case 1:
149                 nm->x = 800;
150                 nm->y = 600;
151                 break;
152         case 2:
153                 nm->x = 1024;
154                 nm->y = 768;
155         case 3:
156                 nm->x = 1280;
157                 nm->y = 1024;
158                 break;
159         }
160
161         vga->crt[0x0C] = 0;     /* vga starting address (offset) */
162         vga->crt[0x0D] = 0;
163         vga->graphics[GeneralLockReg] = 0x01;   /* (internal or simultaneous) */
164         vga->attribute[0x10] &= ~0x40;  /* 2x4 mode not right for neomagic */
165
166         t = 2;          /* LCD only (0x01 for external) */
167         switch(vga->mode->x){
168         case 1280:
169                 t |= 0x60;
170                 break;
171         case 1024:
172                 t |= 0x40;
173                 break;
174         case 800:
175                 t |= 0x20;
176                 break;
177         }
178         if(0 && (nm->pci->did == 0x0005) || (nm->pci->did == 0x0006)){
179                 vga->graphics[PanelDispCntlReg1] &= 0x98;
180                 vga->graphics[PanelDispCntlReg1] |= (t & ~0x98);
181         }
182         else{
183                 vga->graphics[PanelDispCntlReg1] &= 0xDC;       /* save bits 7:6, 4:2 */
184                 vga->graphics[PanelDispCntlReg1] |= (t & ~0xDC);
185         }
186
187         vga->graphics[PanelDispCntlReg2] &= 0x38;
188         vga->graphics[PanelDispCntlReg3] &= 0xEF;
189         vga->graphics[PanelVertCenterReg1] = 0x00;
190         vga->graphics[PanelVertCenterReg2] = 0x00;
191         vga->graphics[PanelVertCenterReg3] = 0x00;
192         vga->graphics[PanelVertCenterReg4] = 0x00;
193         vga->graphics[PanelVertCenterReg5] = 0x00;
194         vga->graphics[PanelHorizCenterReg1] = 0x00;
195         vga->graphics[PanelHorizCenterReg2] = 0x00;
196         vga->graphics[PanelHorizCenterReg3] = 0x00;
197         vga->graphics[PanelHorizCenterReg4] = 0x00;
198         vga->graphics[PanelHorizCenterReg5] = 0x00;
199         if(vga->mode->x < nm->x){
200                 vga->graphics[PanelDispCntlReg2] |= 0x01;
201                 vga->graphics[PanelDispCntlReg3] |= 0x10;
202                 h = ((nm->x - vga->mode->x) >> 4) - 1;
203                 v = ((nm->y - vga->mode->y) >> 1) - 2;
204                 switch(vga->mode->x){
205                 case 640:
206                         vga->graphics[PanelHorizCenterReg1] = h;
207                         vga->graphics[PanelVertCenterReg3] = v;
208                         break;
209                 case 800:
210                         vga->graphics[PanelHorizCenterReg2] = h;
211                         vga->graphics[PanelVertCenterReg4] = v;
212                         break;
213                 case 1024:
214                         vga->graphics[PanelHorizCenterReg5] = h;
215                         vga->graphics[PanelVertCenterReg5] = v;
216                         break;
217                 }
218         }
219
220         vga->graphics[ExtCRTDispAddr] = 0x10;
221         vga->graphics[SysIfaceCntl1] &= 0x0F;
222         vga->graphics[SysIfaceCntl1] |= 0x30;
223         vga->graphics[SysIfaceCntl2] = 0x40;    /* make sure MMIO is enabled */
224         vga->graphics[SingleAddrPage] = 0x00;
225         vga->graphics[DualAddrPage] = 0x00;
226         vga->graphics[ExtCRTOffset] = 0x00;
227         t = vga->graphics[ExtColorModeSelect] & 0x70;   /* colour mode extension */
228         if(vga->mode->z == 8){
229                 t |= 0x11;
230                 vga->crt[0x13] = vga->mode->x/8;
231                 vga->graphics[ExtCRTOffset] = vga->mode->x>>11;
232                 vga->graphics[0x05] = 0x00;     /* linear addressing? */
233                 vga->crt[0x14] = 0x40;  /* double word mode but don't count by 4 */
234         }
235         else if(vga->mode->z == 16){
236                 t |= 0x13;
237                 vga->crt[0x13] = vga->mode->x/4;
238                 vga->graphics[0x05] = 0x00;     /* linear addressing? */
239                 vga->crt[0x14] = 0x40;  /* double word mode but don't count by 4 */
240                 vga->graphics[ExtCRTOffset] = vga->mode->x>>10;
241                 for(i = 0; i < Pcolours; i++){
242                         vga->palette[i][Red] = i<<1;
243                         vga->palette[i][Green] = i;
244                         vga->palette[i][Blue] = i<<1;
245                 }
246         }
247         else if(vga->mode->z == 24){
248                 t |= 0x14;
249                 vga->crt[0x13] = (vga->mode->x*3)/8;
250 //              vga->graphics[0x05] = 0x00;     /* linear addressing? */
251                 vga->crt[0x14] = 0x40;  /* double word mode but don't count by 4 */
252                 vga->graphics[ExtCRTOffset] = (vga->mode->x*3)>>11;
253                 for(i = 0; i < Pcolours; i++){
254                         vga->palette[i][Red] = i;
255                         vga->palette[i][Green] = i;
256                         vga->palette[i][Blue] = i;
257                 }
258         }
259         else
260                 error("depth %d not supported\n", vga->mode->z);
261         vga->graphics[ExtColorModeSelect] = t;
262
263         vga->misc |= 0x0C;
264
265         ctlr->flag |= Finit;
266 }
267
268 static void
269 load(Vga* vga, Ctlr* ctlr)
270 {
271         vgaxo(Grx, GeneralLockReg, vga->graphics[GeneralLockReg]);
272         vgaxo(Grx, ExtColorModeSelect, vga->graphics[ExtColorModeSelect]);
273         vgaxo(Grx, PanelDispCntlReg2, vga->graphics[PanelDispCntlReg2] & 0x39);
274         sleep(200);
275
276         generic.load(vga, ctlr);
277
278         vgaxo(Grx, ExtCRTDispAddr, vga->graphics[ExtCRTDispAddr]);
279         vgaxo(Grx, ExtCRTOffset, vga->graphics[ExtCRTOffset] & 0x39);
280         vgaxo(Grx, SysIfaceCntl1, vga->graphics[SysIfaceCntl1]);
281         if(ctlr->flag & Ulinear)
282                 vga->graphics[SysIfaceCntl2] |= 0x80;
283         vgaxo(Grx, SysIfaceCntl2, vga->graphics[SysIfaceCntl2]);
284         vgaxo(Grx, SingleAddrPage, vga->graphics[SingleAddrPage]);
285         vgaxo(Grx, DualAddrPage, vga->graphics[DualAddrPage]);
286         vgaxo(Grx, PanelDispCntlReg1, vga->graphics[PanelDispCntlReg1]);
287         vgaxo(Grx, PanelDispCntlReg2, vga->graphics[PanelDispCntlReg2]);
288         vgaxo(Grx, PanelDispCntlReg3, vga->graphics[PanelDispCntlReg3]);
289         vgaxo(Grx, PanelVertCenterReg1, vga->graphics[PanelVertCenterReg1]);
290         vgaxo(Grx, PanelVertCenterReg2, vga->graphics[PanelVertCenterReg2]);
291         vgaxo(Grx, PanelVertCenterReg3, vga->graphics[PanelVertCenterReg3]);
292         vgaxo(Grx, PanelVertCenterReg4, vga->graphics[PanelVertCenterReg4]);
293         vgaxo(Grx, PanelHorizCenterReg1, vga->graphics[PanelHorizCenterReg1]);
294         vgaxo(Grx, PanelHorizCenterReg2, vga->graphics[PanelHorizCenterReg2]);
295         vgaxo(Grx, PanelHorizCenterReg3, vga->graphics[PanelHorizCenterReg3]);
296         vgaxo(Grx, PanelHorizCenterReg4, vga->graphics[PanelHorizCenterReg4]);
297         vgaxo(Grx, PanelVertCenterReg5, vga->graphics[PanelVertCenterReg5]);
298         vgaxo(Grx, PanelHorizCenterReg5, vga->graphics[PanelHorizCenterReg5]);
299
300         if(vga->mode->z != 8)
301                 palette.load(vga, ctlr);
302 }
303
304 static void
305 dump(Vga* vga, Ctlr* ctlr)
306 {
307         int i;
308         char buf[100];
309
310         generic.dump(vga, ctlr);
311
312         for(i = 0; crts[i] >= 0; i++){
313                 sprint(buf, "Crt%2.2uX", crts[i]);
314                 printitem(ctlr->name, buf);
315                 printreg(vga->crt[crts[i]]);
316         }
317         printitem(ctlr->name, "Crt40");
318         for(i=0x40; i<=0x59; i++)
319                 printreg(vga->crt[i]);
320         printitem(ctlr->name, "Crt60");
321         for(i=0x60; i<=0x69; i++)
322                 printreg(vga->crt[i]);
323         printitem(ctlr->name, "Crt70");
324         for (i = 0x70; i <= MaxCRT; i++)
325                 printreg(vga->crt[i]);
326
327         printitem(ctlr->name, "Gr08");
328         for(i=0x08; i<=0x3F; i++)
329                 printreg(vga->graphics[i]);
330         printitem(ctlr->name, "Gr70");
331         for(i=0x70; i<=MaxGR; i++)
332                 printreg(vga->graphics[i]);
333 }
334
335 Ctlr neomagic = {
336         "neomagic",                     /* name */
337         snarf,                          /* snarf */
338         options,                        /* options */
339         init,                           /* init */
340         load,                           /* load */
341         dump,                           /* dump */
342 };
343
344 Ctlr neomagichwgc = {
345         "neomagichwgc",                 /* name */
346         0,                              /* snarf */
347         0,                              /* options */
348         0,                              /* init */
349         0,                              /* load */
350         0,                              /* dump */
351 };