1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4 
5 #include <unistd.h>
6 
7 #include "misc.h"
8 #include "xf86.h"
9 #include "xf86_OSproc.h"
10 #include "vgaHW.h"
11 #include "compiler.h"
12 #include "xf86cmap.h"
13 #include "mga.h"
14 #include "mga_reg.h"
15 
16 #define TEXT_AMOUNT 16384
17 #define FONT_AMOUNT (8*8192)
18 
19 void
MGAG200SERestoreFonts(ScrnInfoPtr scrninfp,vgaRegPtr restore)20 MGAG200SERestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
21 {
22     vgaHWPtr hwp = VGAHWPTR(scrninfp);
23     MGAPtr pMga = MGAPTR(scrninfp);
24     int savedIOBase;
25     unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
26     Bool doMap = FALSE;
27     unsigned char scrn;
28 
29     /* If nothing to do, return now */
30     if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
31 	return;
32 
33     if (hwp->Base == NULL) {
34 	doMap = TRUE;
35 	if (!vgaHWMapMem(scrninfp)) {
36 	    xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
37 		    "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
38 	    return;
39 	}
40     }
41 
42     /* save the registers that are needed here */
43     miscOut = hwp->readMiscOut(hwp);
44     attr10 = hwp->readAttr(hwp, 0x10);
45     gr1 = hwp->readGr(hwp, 0x01);
46     gr3 = hwp->readGr(hwp, 0x03);
47     gr4 = hwp->readGr(hwp, 0x04);
48     gr5 = hwp->readGr(hwp, 0x05);
49     gr6 = hwp->readGr(hwp, 0x06);
50     gr8 = hwp->readGr(hwp, 0x08);
51     seq2 = hwp->readSeq(hwp, 0x02);
52     seq4 = hwp->readSeq(hwp, 0x04);
53 
54     /* save hwp->IOBase and temporarily set it for colour mode */
55     savedIOBase = hwp->IOBase;
56     hwp->IOBase = VGA_IOBASE_COLOR;
57 
58     /* Force into colour mode */
59     hwp->writeMiscOut(hwp, miscOut | 0x01);
60 
61     scrn = hwp->readSeq(hwp, 0x01);
62     scrn |= 0x20;/* blank screen */
63     vgaHWSeqReset(hwp, TRUE);
64     MGAWAITVSYNC();
65     MGAWAITBUSY();
66     hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
67     usleep(20000);
68     vgaHWSeqReset(hwp, FALSE);
69 
70     /*
71      * here we temporarily switch to 16 colour planar mode, to simply
72      * copy the font-info and saved text.
73      *
74      * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
75      */
76 #if 0
77     hwp->writeAttr(hwp, 0x10, 0x01);   /* graphics mode */
78 #endif
79     if (scrninfp->depth == 4) {
80 	/* GJA */
81 	hwp->writeGr(hwp, 0x03, 0x00);  /* don't rotate, write unmodified */
82 	hwp->writeGr(hwp, 0x08, 0xFF);  /* write all bits in a byte */
83 	hwp->writeGr(hwp, 0x01, 0x00);  /* all planes come from CPU */
84     }
85 
86     hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
87     hwp->writeGr(hwp, 0x05, 0x00);  /* write mode 0, read mode 0 */
88     hwp->writeGr(hwp, 0x06, 0x05);  /* set graphics */
89 
90     if (hwp->FontInfo1) {
91 	hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
92 	hwp->writeGr(hwp, 0x04, 0x02);  /* read plane 2 */
93 	slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT);
94     }
95 
96     if (hwp->FontInfo2) {
97 	hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
98 	hwp->writeGr(hwp, 0x04, 0x03);  /* read plane 3 */
99 	slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT);
100     }
101 
102     if (hwp->TextInfo) {
103 	hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
104 	hwp->writeGr(hwp, 0x04, 0x00);  /* read plane 0 */
105 	slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT);
106 	hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
107 	hwp->writeGr(hwp, 0x04, 0x01);  /* read plane 1 */
108 	slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
109 		hwp->Base, TEXT_AMOUNT);
110     }
111 
112     /* restore the registers that were changed */
113     hwp->writeMiscOut(hwp, miscOut);
114     hwp->writeAttr(hwp, 0x10, attr10);
115     hwp->writeGr(hwp, 0x01, gr1);
116     hwp->writeGr(hwp, 0x03, gr3);
117     hwp->writeGr(hwp, 0x04, gr4);
118     hwp->writeGr(hwp, 0x05, gr5);
119     hwp->writeGr(hwp, 0x06, gr6);
120     hwp->writeGr(hwp, 0x08, gr8);
121     hwp->writeSeq(hwp, 0x02, seq2);
122     hwp->writeSeq(hwp, 0x04, seq4);
123     hwp->IOBase = savedIOBase;
124 
125     scrn = hwp->readSeq(hwp, 0x01);
126     scrn &= ~0x20;/* enable screen */
127     vgaHWSeqReset(hwp, TRUE);
128     MGAWAITVSYNC();
129     MGAWAITBUSY();
130     hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
131     usleep(20000);
132     vgaHWSeqReset(hwp, FALSE);
133 
134     if (doMap)
135 	vgaHWUnmapMem(scrninfp);
136 }
137 
138 
139 void
MGAG200SESaveFonts(ScrnInfoPtr scrninfp,vgaRegPtr save)140 MGAG200SESaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
141 {
142     vgaHWPtr hwp = VGAHWPTR(scrninfp);
143     MGAPtr pMga = MGAPTR(scrninfp);
144     int savedIOBase;
145     unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
146     Bool doMap = FALSE;
147     unsigned char scrn;
148 
149     if (hwp->Base == NULL) {
150 	doMap = TRUE;
151 	if (!vgaHWMapMem(scrninfp)) {
152 	    xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
153 		    "vgaHWSaveFonts: vgaHWMapMem() failed\n");
154 	    return;
155 	}
156     }
157 
158     /* If in graphics mode, don't save anything */
159     attr10 = hwp->readAttr(hwp, 0x10);
160     if (attr10 & 0x01)
161 	return;
162 
163     /* save the registers that are needed here */
164     miscOut = hwp->readMiscOut(hwp);
165     gr4 = hwp->readGr(hwp, 0x04);
166     gr5 = hwp->readGr(hwp, 0x05);
167     gr6 = hwp->readGr(hwp, 0x06);
168     seq2 = hwp->readSeq(hwp, 0x02);
169     seq4 = hwp->readSeq(hwp, 0x04);
170 
171     /* save hwp->IOBase and temporarily set it for colour mode */
172     savedIOBase = hwp->IOBase;
173     hwp->IOBase = VGA_IOBASE_COLOR;
174 
175     /* Force into colour mode */
176     hwp->writeMiscOut(hwp, miscOut | 0x01);
177 
178     scrn = hwp->readSeq(hwp, 0x01);
179     scrn |= 0x20;/* blank screen */
180     vgaHWSeqReset(hwp, TRUE);
181     MGAWAITVSYNC();
182     MGAWAITBUSY();
183     hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
184     usleep(20000);
185     vgaHWSeqReset(hwp, FALSE);
186 
187     /*
188      * get the character sets, and text screen if required
189      */
190     /*
191      * Here we temporarily switch to 16 colour planar mode, to simply
192      * copy the font-info
193      *
194      * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
195      */
196 #if 0
197     hwp->writeAttr(hwp, 0x10, 0x01);   /* graphics mode */
198 #endif
199     hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
200     hwp->writeGr(hwp, 0x05, 0x00);  /* write mode 0, read mode 0 */
201     hwp->writeGr(hwp, 0x06, 0x05);  /* set graphics */
202     if (hwp->FontInfo1 || (hwp->FontInfo1 = malloc(FONT_AMOUNT))) {
203 	hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
204 	hwp->writeGr(hwp, 0x04, 0x02);  /* read plane 2 */
205 	slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT);
206     }
207     if (hwp->FontInfo2 || (hwp->FontInfo2 = malloc(FONT_AMOUNT))) {
208 	hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
209 	hwp->writeGr(hwp, 0x04, 0x03);  /* read plane 3 */
210 	slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT);
211     }
212     if (hwp->TextInfo || (hwp->TextInfo = malloc(2 * TEXT_AMOUNT))) {
213 	hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
214 	hwp->writeGr(hwp, 0x04, 0x00);  /* read plane 0 */
215 	slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT);
216 	hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
217 	hwp->writeGr(hwp, 0x04, 0x01);  /* read plane 1 */
218 	slowbcopy_frombus(hwp->Base,
219 		(unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
220     }
221 
222     /* Restore clobbered registers */
223     hwp->writeAttr(hwp, 0x10, attr10);
224     hwp->writeGr(hwp, 0x04, gr4);
225     hwp->writeGr(hwp, 0x05, gr5);
226     hwp->writeGr(hwp, 0x06, gr6);
227     hwp->writeSeq(hwp, 0x02, seq2);
228     hwp->writeSeq(hwp, 0x04, seq4);
229     hwp->writeMiscOut(hwp, miscOut);
230     hwp->IOBase = savedIOBase;
231 
232     scrn = hwp->readSeq(hwp, 0x01);
233     scrn &= ~0x20;/* enable screen */
234     vgaHWSeqReset(hwp, TRUE);
235     MGAWAITVSYNC();
236     MGAWAITBUSY();
237     hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
238     usleep(20000);
239     vgaHWSeqReset(hwp, FALSE);
240 
241     if (doMap)
242 	vgaHWUnmapMem(scrninfp);
243 }
244 
245 void
MGAG200SERestoreMode(ScrnInfoPtr scrninfp,vgaRegPtr restore)246 MGAG200SERestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
247 {
248     vgaHWPtr hwp = VGAHWPTR(scrninfp);
249     MGAPtr pMga = MGAPTR(scrninfp);
250     int i;
251     unsigned char scrn;
252 
253     if (restore->MiscOutReg & 0x01)
254     hwp->IOBase = VGA_IOBASE_COLOR;
255     else
256     hwp->IOBase = VGA_IOBASE_MONO;
257 
258     hwp->writeMiscOut(hwp, restore->MiscOutReg);
259 
260 
261     for (i = 1; i < restore->numSequencer; i++)
262     {
263     MGAWAITVSYNC();
264     MGAWAITBUSY();
265 	hwp->writeSeq(hwp, i, restore->Sequencer[i]);
266 	usleep(20000);
267     }
268 
269     scrn = hwp->readSeq(hwp, 0x01);
270     scrn |= 0x20;/* blank screen */
271     vgaHWSeqReset(hwp, TRUE);
272     MGAWAITVSYNC();
273     MGAWAITBUSY();
274     hwp->writeSeq(hwp, 0x01, scrn);/* change mode */
275     usleep(20000);
276 
277     /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
278     hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
279 
280     for (i = 0; i < restore->numCRTC; i++)
281 	hwp->writeCrtc(hwp, i, restore->CRTC[i]);
282 
283     for (i = 0; i < restore->numGraphics; i++)
284     hwp->writeGr(hwp, i, restore->Graphics[i]);
285 
286     hwp->enablePalette(hwp);
287     for (i = 0; i < restore->numAttribute; i++)
288     hwp->writeAttr(hwp, i, restore->Attribute[i]);
289     hwp->disablePalette(hwp);
290 
291     MGAWAITVSYNC();
292     MGAWAITBUSY();
293 	hwp->writeSeq(hwp, 1, restore->Sequencer[1]);
294     usleep(20000);
295 }
296 
297 void
MGAG200SESaveMode(ScrnInfoPtr scrninfp,vgaRegPtr save)298 MGAG200SESaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
299 {
300     vgaHWPtr hwp = VGAHWPTR(scrninfp);
301     int i;
302 
303     save->MiscOutReg = hwp->readMiscOut(hwp);
304     if (save->MiscOutReg & 0x01)
305     hwp->IOBase = VGA_IOBASE_COLOR;
306     else
307     hwp->IOBase = VGA_IOBASE_MONO;
308 
309     for (i = 0; i < save->numCRTC; i++) {
310     save->CRTC[i] = hwp->readCrtc(hwp, i);
311 #ifdef DEBUG
312     ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
313 #endif
314     }
315 
316     hwp->enablePalette(hwp);
317     for (i = 0; i < save->numAttribute; i++) {
318     save->Attribute[i] = hwp->readAttr(hwp, i);
319 #ifdef DEBUG
320     ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
321 #endif
322     }
323     hwp->disablePalette(hwp);
324 
325     for (i = 0; i < save->numGraphics; i++) {
326     save->Graphics[i] = hwp->readGr(hwp, i);
327 #ifdef DEBUG
328     ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
329 #endif
330     }
331 
332     for (i = 1; i < save->numSequencer; i++) {
333     save->Sequencer[i] = hwp->readSeq(hwp, i);
334 #ifdef DEBUG
335     ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
336 #endif
337     }
338 }
339 
340 void
MGAG200SEHWProtect(ScrnInfoPtr pScrn,Bool on)341 MGAG200SEHWProtect(ScrnInfoPtr pScrn, Bool on)
342 {
343   vgaHWPtr hwp = VGAHWPTR(pScrn);
344   MGAPtr pMga = MGAPTR(pScrn);
345 
346   unsigned char tmp;
347 
348   if (pScrn->vtSema) {
349     if (on) {
350       /*
351        * Turn off screen and disable sequencer.
352        */
353       tmp = hwp->readSeq(hwp, 0x01);
354 
355       vgaHWSeqReset(hwp, TRUE);         /* start synchronous reset */
356       MGAWAITVSYNC();
357       MGAWAITBUSY();
358       hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
359       usleep(20000);
360       hwp->enablePalette(hwp);
361     } else {
362       /*
363        * Reenable sequencer, then turn on screen.
364        */
365 
366       tmp = hwp->readSeq(hwp, 0x01);
367 
368       MGAWAITVSYNC();
369       MGAWAITBUSY();
370       hwp->writeSeq(hwp, 0x01, tmp & ~0x20);    /* reenable display */
371       usleep(20000);
372       vgaHWSeqReset(hwp, FALSE);        /* clear synchronousreset */
373 
374       hwp->disablePalette(hwp);
375     }
376   }
377 }
378