📄 vgahw.c
字号:
crtc17 |= inb(vgaIOBase+5) & ~0x80; usleep(10000); outb(vgaIOBase+5, crtc17); outw(0x3C4, 0x0300); /* End Reset */#endif}/* * vgaHWSaveScreen * perform a sequencer reset. */voidvgaHWSaveScreen(start) Bool start;{#if !defined(PC98_NEC480) && !defined(PC98_EGC) if (start == SS_START) outw(0x3C4, 0x0100); /* synchronous reset */ else outw(0x3C4, 0x0300); /* end reset */#endif}/* * setExternClock * call the external clock program * */static BoolsetExternClock(clock2) int clock2; /* the Clock index */{ int i;#ifdef MACH386 union wait exit_status;#else int exit_status;#endif if (clock2 == currentExternClock) return(TRUE);#ifndef OSKIT switch(fork()) { case -1:#endif ErrorF("Fork failed for ClockProg (%s)\n", strerror(errno)); return(FALSE);#ifndef OSKIT case 0: /* child */ /* * Make sure that the child doesn't inherit any I/O permissions it * shouldn't have. It's better to put constraints on the development * of a clock program than to give I/O permissions to a bogus program * in someone's XF86Config file */ for (i = 0; i < MAXSCREENS; i++) xf86DisableIOPorts(i); setuid(getuid());#if !defined(AMOEBA) && !defined(MINIX) /* set stdin, stdout to the consoleFD, and leave stderr alone */ for (i = 0; i < 2; i++) { if (xf86Info.consoleFd != i) { close(i); dup(xf86Info.consoleFd); } }#endif { char *progname, clockarg[8], clockindex[4]; if ((progname = strrchr(vga256InfoRec.clockprog, '/'))) progname++; else progname = vga256InfoRec.clockprog; if(clock2 < MAXCLOCKS){ sprintf(clockarg, "%.3f", vga256InfoRec.clock[clock2] / 1000.0); sprintf(clockindex, "%d", clock2 ); } else { sprintf(clockarg, "%.3f", clock2 / 1000.0); sprintf(clockindex, "%d",255 ); } execl(vga256InfoRec.clockprog, progname, clockarg, clockindex, NULL); ErrorF("Exec failed for ClockProg command \"%s\" (%s)\n", vga256InfoRec.clockprog, strerror(errno)); exit(255); } break; default: /* parent */ wait(&exit_status); if (WIFEXITED(exit_status)) { switch (WEXITSTATUS(exit_status)) { case 0: /* OK */ break; case 255: /* exec() failed */ return(FALSE); default: /* bad exit status */ ErrorF("ClockProg \"%s\" had bad exit status %d\n", vga256InfoRec.clockprog, WEXITSTATUS(exit_status)); return(FALSE); } } else if (WIFSIGNALED(exit_status)) { ErrorF("ClockProg \"%s\" died on signal %d\n", vga256InfoRec.clockprog, WTERMSIG(exit_status)); return(FALSE); }#ifdef WIFSTOPPED else if (WIFSTOPPED(exit_status)) { ErrorF("ClockProg \"%s\" stopped by signal %d\n", vga256InfoRec.clockprog, WSTOPSIG(exit_status)); return(FALSE); }#endif else /* should never get to this point */ { ErrorF("ClockProg \"%s\" has unknown exit condition\n", vga256InfoRec.clockprog); return(FALSE); } } currentExternClock = clock2; return(TRUE);#endif}/* * vgaHWRestore -- * restore a video mode */voidvgaHWRestore(restore) vgaHWPtr restore;{ int i,tmp;#if !defined(PC98_NEC480) && !defined(PC98_EGC) tmp = inb(vgaIOBase + 0x0A); /* Reset flip-flop */ outb(0x3C0, 0x00); /* Enables pallete access */#endif /* * This here is a workaround a bug in the kd-driver. We MUST explicitely * restore the font we got, when we entered graphics mode. * The bug was seen on ESIX, and ISC 2.0.2 when using a monochrome * monitor. * * BTW, also GIO_FONT seems to have a bug, so we cannot use it, to get * a font. */ vgaSaveScreen(NULL, FALSE);#if defined(SAVE_TEXT) || defined(SAVE_FONT1) || defined(SAVE_FONT2) if(restore->FontInfo1 || restore->FontInfo2 || restore->TextInfo) { /* * here we switch temporary to 16 color-plane-mode, to simply * copy the font-info and saved text * * BUGALLERT: The vga's segment-select register MUST be set appropriate ! */ tmp = inb(vgaIOBase + 0x0A); /* reset flip-flop */ outb(0x3C0,0x30); outb(0x3C0, 0x01); /* graphics mode */#ifdef XF86VGA16 outw(0x3CE,0x0003); /* GJA - don't rotate, write unmodified */ outw(0x3CE,0xFF08); /* GJA - write all bits in a byte */ outw(0x3CE,0x0001); /* GJA - all planes come from CPU */#endif#ifdef SAVE_FONT1 if (restore->FontInfo1) { outw(0x3C4, 0x0402); /* write to plane 2 */ outw(0x3C4, 0x0604); /* enable plane graphics */ outw(0x3CE, 0x0204); /* read plane 2 */ outw(0x3CE, 0x0005); /* write mode 0, read mode 0 */ outw(0x3CE, 0x0506); /* set graphics */ slowbcopy_tobus(restore->FontInfo1, vgaBase, FONT_AMOUNT); }#endif#ifdef SAVE_FONT2 if (restore->FontInfo2) { outw(0x3C4, 0x0802); /* write to plane 3 */ outw(0x3C4, 0x0604); /* enable plane graphics */ outw(0x3CE, 0x0304); /* read plane 3 */ outw(0x3CE, 0x0005); /* write mode 0, read mode 0 */ outw(0x3CE, 0x0506); /* set graphics */ slowbcopy_tobus(restore->FontInfo2, vgaBase, FONT_AMOUNT); }#endif#ifdef SAVE_TEXT if (restore->TextInfo) { outw(0x3C4, 0x0102); /* write to plane 0 */ outw(0x3C4, 0x0604); /* enable plane graphics */ outw(0x3CE, 0x0004); /* read plane 0 */ outw(0x3CE, 0x0005); /* write mode 0, read mode 0 */ outw(0x3CE, 0x0506); /* set graphics */ slowbcopy_tobus(restore->TextInfo, vgaBase, TEXT_AMOUNT); outw(0x3C4, 0x0202); /* write to plane 1 */ outw(0x3C4, 0x0604); /* enable plane graphics */ outw(0x3CE, 0x0104); /* read plane 1 */ outw(0x3CE, 0x0005); /* write mode 0, read mode 0 */ outw(0x3CE, 0x0506); /* set graphics */ slowbcopy_tobus((char *)restore->TextInfo + TEXT_AMOUNT, vgaBase, TEXT_AMOUNT); }#endif }#endif /* defined(SAVE_TEXT) || defined(SAVE_FONT1) || defined(SAVE_FONT2) */ vgaSaveScreen(NULL, TRUE);#if !defined(PC98_NEC480) && !defined(PC98_EGC) tmp = inb(vgaIOBase + 0x0A); /* Reset flip-flop */ outb(0x3C0, 0x00); /* Enables pallete access */ /* Don't change the clock bits when using an external clock program */ if (restore->NoClock < 0) { tmp = inb(0x3CC); restore->MiscOutReg = (restore->MiscOutReg & 0xF3) | (tmp & 0x0C); } if (vgaIOBase == 0x3B0) restore->MiscOutReg &= 0xFE; else restore->MiscOutReg |= 0x01; outb(0x3C2, restore->MiscOutReg); for (i=1; i<5; i++) outw(0x3C4, (restore->Sequencer[i] << 8) | i); /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */ outw(vgaIOBase + 4, ((restore->CRTC[17] & 0x7F) << 8) | 17); for (i=0; i<25; i++) outw(vgaIOBase + 4,(restore->CRTC[i] << 8) | i); for (i=0; i<9; i++) outw(0x3CE, (restore->Graphics[i] << 8) | i); for (i=0; i<21; i++) { tmp = inb(vgaIOBase + 0x0A); outb(0x3C0,i); outb(0x3C0, restore->Attribute[i]); } if (clgd6225Lcd) { for (i= 0; i<768; i++) { /* The LCD doesn't like white */ if (restore->DAC[i] == 63) restore->DAC[i]= 62; } } outb(0x3C6,0xFF); outb(0x3C8,0x00); for (i=0; i<768; i++) { outb(0x3C9, restore->DAC[i]); DACDelay; } /* Turn on PAS bit */ tmp = inb(vgaIOBase + 0x0A); outb(0x3C0, 0x20);#endif /* !defined(PC98_NEC480) && !defined(PC98_EGC) */ /* If restoring text mode, and a text clock is specified with clkprog */ if (((restore->Attribute[0x10] & 0x01) == 0)) { if (vga256InfoRec.clockprog) { if (vga256InfoRec.textclock >= 0) setExternClock(vga256InfoRec.textclock); /* * Invalidate the saved extern clock when switching to text mode * because I think some systems modify this when VT switching. */ currentExternClock = -1; } } else /* If restoring a graphics mode */ { if (currentGraphicsClock >= 0) setExternClock(currentGraphicsClock); }}/* * vgaHWSave -- * save the current video mode */void *vgaHWSave(save, size) vgaHWPtr save; int size;{ int i,tmp; Bool first_time = FALSE; /* Should be static? */ if (save == NULL) { tmp = size; if (tmp < 0) tmp = -size; if (tmp < sizeof(vgaHWRec)) tmp = sizeof(vgaHWRec); save = (vgaHWPtr)xcalloc(1,tmp); /* * Here we are, when we first save the videostate. This means we came here * to save the original Text mode. Because some drivers may depend * on NoClock we set it here to a resonable value. */ first_time = TRUE; if (vga256InfoRec.clockprog && vga256InfoRec.textclock >= 0) save->NoClock = -1;#if !defined(PC98_NEC480) && !defined(PC98_EGC) else /* This isn't very useful -- it ignores the high order CS bits */ save->NoClock = (inb(0x3CC) >> 2) & 3;#endif /* !defined(PC98_NEC480) && !defined(PC98_EGC) */ }#if !defined(PC98_NEC480) && !defined(PC98_EGC) save->MiscOutReg = inb(0x3CC);#ifdef PC98 save->MiscOutReg |= 0x01;#endif vgaIOBase = (save->MiscOutReg & 0x01) ? 0x3D0 : 0x3B0; tmp = inb(vgaIOBase + 0x0A); /* reset flip-flop */ outb(0x3C0, 0x00);#ifdef NEED_SAVED_CMAP /* * Some recent (1991) ET4000 chips have a HW bug that prevents the reading * of the color lookup table. Mask rev 9042EAI is known to have this bug. * * XF86 already keeps track of the contents of the color lookup table so * reading the HW isn't needed. Therefore, as a workaround for this HW * bug, the following (correct) code has been #ifdef'ed out. This is also * a valid change for ET4000 chips that don't have the HW bug. The code * is really just being retained for reference. MWS 22-Aug-91 * * This is *NOT* true for 386BSD, Mach -- the initial colour map must be * restored. When saving the text mode, we check if the colourmap is * readable. If so we read it. If not, we set the saved map to a * default map (taken from Ferraro's "Programmer's Guide to the EGA and * VGA Cards" 2nd ed). */ if (first_time) { int read_error = 0; outb(0x3C6,0xFF); /* * check if we can read the lookup table */ outb(0x3C7,0x00); for (i=0; i<3; i++) save->DAC[i] = inb(0x3C9);#if defined(PC98_PW) || defined(PC98_XKB) || defined(PC98_NEC) || defined(PC98_PWLB) for (i=0; i<300; i++) inb(vgaIOBase + 4);#endif outb(0x3C8,0x00); for (i=0; i<3; i++) outb(0x3C9, ~save->DAC[i] & vgaRamdacMask);#if defined(PC98_PW) || defined(PC98_XKB) || defined(PC98_NEC) || defined(PC98_PWLB) for (i=0; i<300; i++) inb(vgaIOBase + 4);#endif outb(0x3C7,0x00); for (i=0; i<3; i++) { unsigned char tmp2 = inb(0x3C9);#if defined(PC98_PW) || defined(PC98_XKB) || defined(PC98_NEC) || defined(PC98_PWLB) if (tmp2 != (~save->DAC[i]&0xFF))#endif if (tmp2 != (~save->DAC[i] & vgaRamdacMask)) read_error++; } if (read_error) { /* * save the default lookup table */ bcopy(defaultDAC, save->DAC, 768); ErrorF("%s: Cannot read colourmap from VGA.", vga256InfoRec.name); ErrorF(" Will restore with default\n"); } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -