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