2 |
- |
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 |
};
|