📄 chips.c
字号:
} 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; #ifdef DEBUG printf("CHIPS: CHIPS_setregs(*, %d)\n", mode);#endif CHIPS_unlock(); if (ctisHiQV) { for (i = 0; i < NUM_HiQVXRregs; i++) { outb(0x3D6,__svgalib_HiQVXRregs[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 { outb(0x3D0,__svgalib_HiQVFRregs[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 { 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. */ 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 * nor told otherwise*/ if (!(ctFlagsSet & ctFlags_UseModeline)) { lcdHTotal = __svgalib_ctSize.HTotal; lcdHRetraceStart = __svgalib_ctSize.HRetraceStart; lcdHRetraceEnd = __svgalib_ctSize.HRetraceEnd; if (modeinfo->bitsPerPixel == 16) { lcdHRetraceStart <<= 1; lcdHRetraceEnd <<= 1; lcdHTotal <<= 1; } else if (modeinfo->bitsPerPixel == 24) { lcdHRetraceStart += (lcdHRetraceStart << 1); lcdHRetraceEnd += (lcdHRetraceEnd << 1); lcdHTotal += (lcdHTotal << 1); } lcdHRetraceStart -=8; /* HBlank = HRetrace - 1: for */ lcdHRetraceEnd -=8; /* compatibility with vgaHW.c */ } else { /* use modeline values if bios values don't work */ lcdHTotal = mode->CrtcHTotal; lcdHRetraceStart = mode->CrtcHSyncStart; lcdHRetraceEnd = mode->CrtcHSyncEnd; } /* The chip takes the size of the visible display area from the * CRTC values. We use bios screensize for LCD in LCD/dual mode * wether or not we use modeline for LCD. This way we can specify * always specify a smaller than default display size on LCD * by writing it to the CRTC registers. */ lcdHDisplay = __svgalib_ctSize.HDisplay; if (modeinfo->bitsPerPixel == 16) { lcdHDisplay++; lcdHDisplay <<= 1; lcdHDisplay--; } else if (modeinfo->bitsPerPixel == 24) { lcdHDisplay++; lcdHDisplay += (lcdHDisplay << 1); lcdHDisplay--; } lcdHTotal = (lcdHTotal >> 3) - 5; lcdHDisplay = (lcdHDisplay >> 3) - 1; lcdHRetraceStart = (lcdHRetraceStart >> 3); lcdHRetraceEnd = (lcdHRetraceEnd >> 3); /* This ugly hack is needed because CR01 and XR1C share the 8th bit!*/ CrtcHDisplay = ((mode->CrtcHDisplay >> 3) - 1); if((lcdHDisplay & 0x100) != ( CrtcHDisplay & 0x100)){ printf("This display configuration might cause problems !\n"); lcdHDisplay = 255;} /* now init register values */ moderegs[XR17] = (((lcdHTotal) & 0x100) >> 8) | ((lcdHDisplay & 0x100) >> 7) | ((lcdHRetraceStart & 0x100) >> 6) | (((lcdHRetraceEnd) & 0x20) >> 2); moderegs[XR19] = lcdHRetraceStart & 0xFF; moderegs[XR1A] = lcdHRetraceEnd & 0x1F; moderegs[XR1B] = lcdHTotal & 0xFF; moderegs[XR1C] = lcdHDisplay & 0xFF; if (ctFlagsSet & ctFlags_UseModeline) { /* for ext. packed pixel mode on 64520/64530 */ /* no need to rescale: used only in 65530 */ moderegs[XR21] = lcdHRetraceStart & 0xFF; moderegs[XR22] = lcdHRetraceEnd & 0x1F; moderegs[XR23] = lcdHTotal & 0xFF; /* vertical timing registers */ lcdVTotal = mode->CrtcVTotal - 2; lcdVDisplay = __svgalib_ctSize.VDisplay - 1; lcdVRetraceStart = mode->CrtcVSyncStart; lcdVRetraceEnd = mode->CrtcVSyncEnd; moderegs[XR64] = lcdVTotal & 0xFF; moderegs[XR66] = lcdVRetraceStart & 0xFF; moderegs[XR67] = lcdVRetraceEnd & 0x0F; moderegs[XR68] = lcdVDisplay & 0xFF; moderegs[XR65] = ((lcdVTotal & 0x100) >> 8) | ((lcdVDisplay & 0x100) >> 7) | ((lcdVRetraceStart & 0x100) >> 6) | ((lcdVRetraceStart & 0x400) >> 7) | ((lcdVTotal & 0x400) >> 6) | ((lcdVTotal & 0x200) >> 4) | ((lcdVDisplay & 0x200) >> 3) | ((lcdVRetraceStart & 0x200) >> 2); /* * These are important: 0x2C specifies the numbers of lines * (hsync pulses) between vertical blank start and vertical * line total, 0x2D specifies the number of clock ticks? to * horiz. blank start ( caution ! 16bpp/24bpp modes: that's * why we need HSyncStart - can't use mode->CrtcHSyncStart) */ tmp = ((__svgalib_ctPanelType == DD) && !(moderegs[XR6F] & 0x02)) ? 1 : 0; /* double LP delay, FLM: 2 lines iff DD+no acc*/ /* Currently we support 2 FLM scemes: #1: FLM coincides with * VTotal ie. the delay is programmed to the difference bet- * ween lctVTotal and lcdVRetraceStart. #2: FLM coincides * lcdVRetraceStart - in this case FLM delay will be turned * off. To decide which sceme to use we compare the value of * XR2C set by the bios to the two scemes. The one that fits * better will be used. */ if (moderegs[XR2C] < abs((__svgalib_ctSize.VTotal - __svgalib_ctSize.VRetraceStart - tmp - 1) - moderegs[XR2C])) moderegs[XR2F] |= 0x80; /* turn FLM delay off */ moderegs[XR2C] = lcdVTotal - lcdVRetraceStart - tmp; /*moderegs[XR2D] = (HSyncStart >> (3 - tmp)) & 0xFF;*/ moderegs[XR2D] = (HDisplay >> (3 - tmp)) & 0xFF; moderegs[XR2F] = (moderegs[XR2F] & 0xDF) | (((HSyncStart >> (3 - tmp)) & 0x100) >> 3); } if ((ctFlagsSet & ctFlags_StretchEnable) || (ctFlagsSet & ctFlags_StretchDisable) || (ctFlagsSet & ctFlags_CenterEnable) || (ctFlagsSet & ctFlags_CenterDisable)) { moderegs[XR51] |= 0x40; /* enable FP compensation */ moderegs[XR55] |= 0x01; /* enable horiz compensation */ moderegs[XR57] |= 0x01; /* enable vert compensation */ moderegs[XR57] &= 0x7F; /* disable fast-centre */ moderegs[XR58] = 0; } /* Screen Centering */ if (ctFlagsSet & ctFlags_CenterEnable) { moderegs[XR57] |= 0x02; /* enable v-centring */ if (mode->CrtcHDisplay < 1489) /* HWBug */ moderegs[XR55] |= 0x02; /* enable h-centring */ else if (modeinfo->bitsPerPixel == 24) { moderegs[XR55] &= ~0x02; moderegs[XR56] = (lcdHDisplay - CrtcHDisplay) >> 1; } } else if (ctFlagsSet & ctFlags_CenterDisable) { moderegs[XR55] &= 0xFD; /* disable h-centering */ moderegs[XR56] = 0; moderegs[XR57] &= 0xFD; /* disable v-centering */ } /* Screen Stretching */ if (ctFlagsSet & ctFlags_StretchEnable) { moderegs[XR55] |= 0x20; /* h-comp on, h-double off */ moderegs[XR57] |= 0x60; /* vertical stretching on */ printf("0x%X, 0x%X\n", mode->flags, DOUBLESCAN); printf("%d, %d\n", mode->CrtcVDisplay, __svgalib_ctSize.VDisplay); if (2*mode->CrtcVDisplay <= __svgalib_ctSize.VDisplay) { /* We assume that automatic double scanning occurs */ if (2 * mode->CrtcVDisplay == __svgalib_ctSize.VDisplay) temp = 0; else temp = (( 2 * mode->CrtcVDisplay) / (__svgalib_ctSize.VDisplay - (2 * mode->CrtcVDisplay))); } else { if (mode->CrtcVDisplay == __svgalib_ctSize.VDisplay) temp = 0; else temp = (mode->CrtcVDisplay / (__svgalib_ctSize.VDisplay -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -