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