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