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