📄 chips.c
字号:
{ unsigned char temp, msr; int i; #ifdef DEBUG printf("CHIPS: ctClockRestore\n");#endif msr = inb(0x3CC); /* Select fixed clock */ outb(0x3C2, (msr & 0xFE) | ctVgaIOBaseFlag); if (ctisHiQV) { outb(0x3D0,0x03); temp = inb(0x3D1); outb(0x3D1, ((temp & ~0xC) | 0x04)); /* Select alt fixed clk */ temp = (regs[HiQVFR03] & 0xC) >> 2; if (temp == 3) temp = 2; temp = temp << 2; for (i = 0; i < 4; i++) { outb(0x3D6,0xC0 + i + temp); outb(0x3D7,regs[VCLK(i)]); } outb(0x3D0,0x03); temp = inb(0x3D1); /* restore alternate clock select reg. */ outb(0x3D1,((regs[HiQVFR03]&0xC) | (temp&~0xC))); } else { outb(0x3D6,0x54); /* Select alt fixed clk */ temp = inb(0x3D7); outb(0x3D7,((temp & 0xF3) | 0x4)); if ((CHIPSchipset == CT_535 || CHIPSchipset == CT_540 || CHIPSchipset == CT_545 || CHIPSchipset == CT_546 || CHIPSchipset == CT_548 || CHIPSchipset == CT_4300) && (((regs[XR54] & 0xC) == 0xC) || ((regs[XR54] & 0xC) == 0x8))) { outb(0x3D6,0x33); temp = inb(0x3D7); outb(0x3D7,(temp & ~0x20)); /* Select Vclk */ outb(0x3D6,0x30); outb(0x3D7,regs[VCLK(0)]); outb(0x3D6,0x31); outb(0x3D7,regs[VCLK(1)]); outb(0x3D6,0x32); outb(0x3D7,regs[VCLK(2)]); } outb(0x3D6,0x33); /* restore status of MCLK/VCLK select reg.*/ temp = inb(0x3D7); outb(0x3D7,((regs[XR33] & 0x20) | (temp & ~0x20))); outb(0x3D6,0x54); /* restore alternate clock select reg. */ temp = inb(0x3D7); outb(0x3D7,((regs[XR54] & 0xC) | (temp & ~0xC))); } usleep(10000); outb(0x3C2, (regs[MSR] & 0xC) | (msr & 0xFE) | ctVgaIOBaseFlag); usleep(10000);}static int CHIPS_matchProgrammableClock(int clock){#ifdef DEBUG printf("CHIPS: CHIPS_matchProgrammableClock(%d)\n",clock);#endif /* Basically we can program any valid clock */ return clock;}static int CHIPS_mapClock(int bpp, int pixelclock){#ifdef DEBUG printf("CHIPS: CHIPS_mapClock(%d, %d)\n",bpp, pixelclock);#endif if (ctisHiQV) { return pixelclock; } else { switch (bpp) { case 24: return pixelclock*3; break; case 16: return pixelclock*2; break; case 15: return pixelclock*2; break; default: return pixelclock; break; } }}static int CHIPS_mapHorizontalCrtc(int bpp, int pixelclock, int htiming){#ifdef DEBUG printf("CHIPS: CHIPS_mapHorizontalCrtc(%d, %d, %d)\n",bpp, pixelclock, htiming);#endif if (ctisHiQV) { return htiming; } else { switch (bpp) { case 24: return htiming*3; break; case 16: return htiming*2; break; case 15: return htiming*2; break; default: return htiming; break; } }}static void CHIPS_unlock(void){ unsigned char tmp; #ifdef DEBUG printf("CHIPS: CHIPS_unlock\n");#endif /* set registers so that we can program the controller */ if (ctisHiQV) { outw(0x3D6, 0x0E); } else { outw(0x3D6, 0x10);#if defined(seperated_read_write_bank) outw(0x3D6, (1 << 11) | 0x11);#endif outw(0x3D6, 0x15); /* unprotect all registers */ outb(0x3D6, 0x14); tmp = inb(0x3D7); outb(0x3D7, (tmp & ~0x20)); /* enable vsync on ST01 */ } outb(vgaIOBase + 4, 0x11); tmp = inb(vgaIOBase + 5); outb(vgaIOBase + 5, (tmp & 0x7F)); /*group 0 protection off */}/*----------------------------------------------------------------------*//* Read and store chipset-specific registers *//*----------------------------------------------------------------------*/static int CHIPS_saveregs(unsigned char regs[]){ int i;#ifdef DEBUG printf("CHIPS: CHIPS_saveregs\n");#endif CHIPS_unlock(); if (ctisHiQV) { for (i = 0; i < NUM_HiQVXRregs; i++) { outb(0x3D6,__svgalib_HiQVXRregs[i]); regs[CHIPSREG_HiQVXR(i)] = inb(0x3D7); } for (i = 0; i < NUM_HiQVFRregs; i++) { outb(0x3D0,__svgalib_HiQVFRregs[i]); regs[CHIPSREG_HiQVFR(i)] = inb(0x3D1); } for (i = 0; i < NUM_HiQVCRregs; i++) { outb(vgaIOBase + 4,__svgalib_HiQVCRregs[i]); regs[CHIPSREG_HiQVCR(i)] = inb(vgaIOBase + 5); } } else { for (i = 0; i < NUM_XRregs; i++) { outb(0x3D6,__svgalib_XRregs[i]); regs[CHIPSREG_XR(i)] = inb(0x3D7); } } ctClockSave(regs); return CHIPS_TOTAL_REGS - VGA_TOTAL_REGS;}/*----------------------------------------------------------------------*//* Set chipset-specific registers *//*----------------------------------------------------------------------*/static void CHIPS_setregs(const unsigned char regs[], int mode){ int i,tmp; #ifdef DEBUG printf("CHIPS: CHIPS_setregs(*, %d)\n", mode);#endif CHIPS_unlock(); while (((inb(0x3DA)) & 0x08) == 0x08 );/* wait VSync off */ while (((inb(0x3DA)) & 0x08) == 0 ); /* wait VSync on */ outw(SEQ_I,0x07); /* reset hsync - just in case... */ if (ctisHiQV) { for (i = 0; i < NUM_HiQVXRregs; i++) { outb(0x3D6,__svgalib_HiQVXRregs[i]); if (inb(0x3D7) != regs[CHIPSREG_HiQVXR(i)]) outb(0x3D7,regs[CHIPSREG_HiQVXR(i)]); } for (i = 0; i < NUM_HiQVFRregs; i++) { if ((__svgalib_HiQVFRregs[i] == 0x40) || (__svgalib_HiQVFRregs[i] == 0x48)) { /* Be careful to leave stretching off */ outb(0x3D0,__svgalib_HiQVFRregs[i]); outb(0x3D1,(regs[CHIPSREG_HiQVFR(i)]&0xFE)); } else if (__svgalib_HiQVFRregs[i] == 0x3) { /* Leave clock bits alone */ outb(0x3D0,3); tmp = inb(0x3D1); outb(0x3D0,3); outb(0x3D1,(regs[CHIPSREG_HiQVFR(i)] & 0xC3) | (tmp & ~0xC3)); } else { outb(0x3D0,__svgalib_HiQVFRregs[i]); if (inb(0x3D1) != regs[CHIPSREG_HiQVFR(i)]) outb(0x3D1,regs[CHIPSREG_HiQVFR(i)]); } } for (i = 0; i < NUM_HiQVCRregs; i++) { outb(vgaIOBase + 4,__svgalib_HiQVCRregs[i]); outb(vgaIOBase + 5,regs[CHIPSREG_HiQVCR(i)]); } } else { for (i = 0; i < NUM_XRregs; i++) { if ((__svgalib_XRregs[i] == 0x55) || (__svgalib_XRregs[i] == 0x57)) { /* Be careful to leave stretching off */ outb(0x3D6,__svgalib_XRregs[i]); outb(0x3D7,(regs[CHIPSREG_XR(i)]&0xFE)); } else if (__svgalib_XRregs[i] == 0x54) { outb(0x3D6, 0x54); tmp = inb(0x3D7); /* restore the non clock bits */ outb(0x3D6, 0x54); /* Don't touch alternate clock sel. reg. */ outb(0x3D7, ((regs[CHIPSREG_XR(i)] & 0xF3) | (tmp & ~0xF3))); } else { outb(0x3D6,__svgalib_XRregs[i]); outb(0x3D7,regs[CHIPSREG_XR(i)]); } } } ctClockRestore(regs); /* Turn the stretching back on if needed. */ if (ctisHiQV) { /* Why Twice? It seems that strecthing on the text console is not * always restored well even though the register contain the right * values. Restoring them twice is a work around. */ outb(0x3D0, 0x40); outb(0x3D1, regs[HiQVFR40]); outb(0x3D0, 0x48); outb(0x3D1, regs[HiQVFR48]); usleep(10000); outb(0x3D0, 0x40); outb(0x3D1, regs[HiQVFR40]); outb(0x3D0, 0x48); outb(0x3D1, regs[HiQVFR48]); } else { outb(0x3D6, 0x55); outb(0x3D7, regs[XR55]); outb(0x3D6, 0x57); outb(0x3D7, regs[XR57]); } usleep(10000);}/*----------------------------------------------------------------------*//* Return nonzero if mode is available *//*----------------------------------------------------------------------*/static int CHIPS_modeavailable(int mode){ struct info *info; ModeTiming *modetiming; ModeInfo *modeinfo;#ifdef DEBUG printf("CHIPS: CHIPS_modeavailable(%d)\n", mode);#endif if (mode < G640x480x256 || mode == G720x348x2) return __svgalib_vga_driverspecs.modeavailable(mode); info = &__svgalib_infotable[mode]; if (video_memory * 1024 < info->ydim * info->xbytes) return 0; modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode); modetiming = malloc(sizeof(ModeTiming)); if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) { free(modetiming); free(modeinfo); return 0; } free(modetiming); free(modeinfo); return SVGADRV;}/* Set a mode *//* Local, called by CHIPS_setmode(). */static void CHIPS_initializemode(unsigned char * moderegs, ModeTiming * mode, ModeInfo * modeinfo){ unsigned char tmp; static int HSyncStart, HDisplay; int lcdHTotal, lcdHDisplay; int lcdVTotal, lcdVDisplay; int lcdHRetraceStart, lcdHRetraceEnd; int lcdVRetraceStart, lcdVRetraceEnd; int CrtcHDisplay; int temp;#ifdef DEBUG printf("CHIPS: CHIPS_initializemode\n");#endif /* Get current values. Must be called before CalcClock */ CHIPS_saveregs(moderegs); /* Set up the standard VGA registers for a generic SVGA. */ __svgalib_setup_VGA_registers(moderegs, mode, modeinfo); /* store orig. HSyncStart needed for flat panel mode */ HSyncStart = mode->CrtcHSyncStart / modeinfo->bytesPerPixel - 16; HDisplay = (mode->CrtcHDisplay + 1) / modeinfo->bytesPerPixel; /* init clock */ if ((CHIPSchipset == CT_520) || (CHIPSchipset == CT_525) || (CHIPSchipset == CT_530)) { ctHWCalcClock(moderegs,mode->selectedClockNo); } else { ctCalcClock(moderegs,mode->programmedClock); } moderegs[VGA_AR10] = 0x01; /* mode */ moderegs[VGA_AR11] = 0x00; /* overscan (border) color */ moderegs[VGA_AR12] = 0x0F; /* enable all color planes */ moderegs[VGA_AR13] = 0x00; /* horiz pixel panning 0 */ moderegs[VGA_GR5] = 0x00; /* normal read/write mode */ moderegs[VGA_CR13] = ((mode->CrtcHDisplay) >> 3) & 0xFF ; moderegs[XR1E] = ((mode->CrtcHDisplay) >> 3) & 0xFF ; moderegs[XR0D] = (((mode->CrtcHDisplay) >> 11) & 0x1) | (((mode->CrtcHDisplay) >> 10) & 0x2); moderegs[XR04] |= 4; /* enable addr counter bits 16-17 */#if defined(seperated_read_write_bank) moderegs[XR0B] = moderegs[XR0B] | 0x7; /* extended mode, dual maps */#else moderegs[XR0B] = (moderegs[XR0B] & 0xF8) | 0x5; /* single maps */#endif moderegs[XR28] |= 0x10; /* 256-colour video */ /* Setup extended display timings */ if (ctCRT) { /* in CRTonly mode this is simple: only set overflow for CR00-CR06 */ moderegs[XR17] = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) | ((((mode->CrtcHSyncEnd >> 3)) & 0x20) >> 2) | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 4) | (((mode->CrtcHSyncEnd >> 3) & 0x40) >> 1); } else { /* horizontal timing registers */ /* in LCD/dual mode use saved bios values to derive timing values if * not told otherwise*/ if (!(ctFlagsSet & ctFlags_UseModeline)) { lcdHTotal = __svgalib_ctSize.HTotal;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -