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 19void 20MGAG200SERestoreFonts(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 139void 140MGAG200SESaveFonts(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 245void 246MGAG200SERestoreMode(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 297void 298MGAG200SESaveMode(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 340void 341MGAG200SEHWProtect(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 * Re-enable 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); /* re-enable display */ 371 usleep(20000); 372 vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */ 373 374 hwp->disablePalette(hwp); 375 } 376 } 377} 378