📄 s3init.c
字号:
if(!OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) { outb(vgaCRIndex, 0x55); tmp = inb(vgaCRReg) & 0x08; /* save the external serial bit */ outb(vgaCRReg, tmp | 0x40); /* remove mysterious dot at 60Hz */ } /* This shouldn't be needed -- they should be set by vgaHWInit() */ if (!mode->CrtcVAdjusted) { mode->CrtcVTotal /= interlacedived; mode->CrtcVDisplay /= interlacedived; mode->CrtcVSyncStart /= interlacedived; mode->CrtcVSyncEnd /= interlacedived; mode->CrtcVAdjusted = TRUE; } if ((S3_TRIO64V_SERIES(s3ChipId) && (s3ChipRev <= 0x53) && (s3Bpp==1)) ^ !!OFLG_ISSET(OPTION_TRIO64VP_BUG2, &s3InfoRec.options)) i = (((mode->CrtcVTotal - 2) & 0x400) >> 10) | (((mode->CrtcVDisplay - 1) & 0x400) >> 9) | (((mode->CrtcVDisplay - 1) & 0x400) >> 8) | (((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40; else i = (((mode->CrtcVTotal - 2) & 0x400) >> 10) | (((mode->CrtcVDisplay - 1) & 0x400) >> 9) | (((mode->CrtcVSyncStart) & 0x400) >> 8) | (((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40; outb(vgaCRIndex, 0x5e); outb(vgaCRReg, i); if ((S3_TRIO64V_SERIES(s3ChipId) && (s3ChipRev <= 0x53) && (s3Bpp==1)) ^ !!OFLG_ISSET(OPTION_TRIO64VP_BUG2, &s3InfoRec.options)) { i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) | (((mode->CrtcHDisplay >> 3) & 0x100) >> 6) | ((mode->CrtcHSyncStart & 0x800) >> 7); if ((mode->CrtcHTotal >> 3) - (mode->CrtcHDisplay >> 3) > 64) i |= 0x08; /* add another 64 DCLKs to blank pulse width */ } else { i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) | ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) | ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) | ((mode->CrtcHSyncStart & 0x800) >> 7); if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 64) i |= 0x08; /* add another 64 DCLKs to blank pulse width */ } if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32) i |= 0x20; /* add another 32 DCLKs to hsync pulse width */ outb(vgaCRIndex, 0x3b); if (DAC_IS_IBMRGB528) { if (OFLG_ISSET(OPTION_MIRO_80SV, &s3InfoRec.options)) { itmp = (( (new->CRTC[0] + ((i&0x01)<<8)) * 3 + new->CRTC[4] + ((i&0x10)<<4) + 1) / 4) & ~1; if (itmp-(new->CRTC[4] + ((i&0x10)<<4)) < 4) itmp = ( new->CRTC[0] + ((i&0x01)<<8) - 2) & ~1; } else if (s3Bpp==1) itmp = ((new->CRTC[4] + ((i&0x10)<<4) + 2) + 1) & ~1; else itmp = ((new->CRTC[4] + ((i&0x10)<<4) + 4) + 1) & ~1; } else { itmp = ( new->CRTC[0] + ((i&0x01)<<8) + new->CRTC[4] + ((i&0x10)<<4) + 1) / 2; if (itmp-(new->CRTC[4] + ((i&0x10)<<4)) < 4) if (new->CRTC[4] + ((i&0x10)<<4) + 4 <= new->CRTC[0]+ ((i&0x01)<<8)) itmp = new->CRTC[4] + ((i&0x10)<<4) + 4; else itmp = new->CRTC[0]+ ((i&0x01)<<8) + 1; } outb(vgaCRReg, itmp & 0xff); i |= (itmp&0x100) >> 2; outb(vgaCRIndex, 0x3c); outb(vgaCRReg, (new->CRTC[0] + ((i&0x01)<<8)) /2); /* Interlace mode frame offset */ outb(vgaCRIndex, 0x5d); tmp = inb(vgaCRReg); outb(vgaCRReg, (tmp & 0x80) | i); if (s3InfoRec.videoRam > 1024 && S3_x64_SERIES(s3ChipId)) i = mode->HDisplay * s3Bpp / 8 + 1; else i = mode->HDisplay * s3Bpp / 4 + 1; /* XXX should be checked for 801/805 */ outb(vgaCRIndex, 0x61); tmp = inb(vgaCRReg); outb(vgaCRReg, 0x80 | (tmp & 0x60) | (i >> 8)); outb(vgaCRIndex, 0x62); outb(vgaCRReg, i & 0xff); } if ((mode->Flags & V_INTERLACE) != 0) { outb(vgaCRIndex, 0x42); tmp = inb(vgaCRReg); outb(vgaCRReg, 0x20 | tmp); } else { outb(vgaCRIndex, 0x42); tmp = inb(vgaCRReg); outb(vgaCRReg, ~0x20 & tmp); } if (mode->Private) { if (mode->Private[0] & (1 << S3_INVERT_VCLK)) { outb(vgaCRIndex, 0x67); tmp = inb(vgaCRReg) & 0xfe; if (mode->Private[S3_INVERT_VCLK]) tmp |= 1; outb(vgaCRReg, tmp); } if (mode->Private[0] & (1 << S3_BLANK_DELAY)) { outb(vgaCRIndex, 0x6d); outb(vgaCRReg, mode->Private[S3_BLANK_DELAY]); } if (mode->Private[0] & (1 << S3_EARLY_SC)) { outb(vgaCRIndex, 0x65); tmp = inb(vgaCRReg) & ~2; if (mode->Private[S3_EARLY_SC]) tmp |= 2; outb(vgaCRReg, tmp); } } if (OFLG_ISSET(OPTION_FAST_VRAM, &s3InfoRec.options)) { outb(vgaCRIndex, 0x39); outb(vgaCRReg, 0xa5); outb(vgaCRIndex, 0x68); tmp = inb(vgaCRReg); /* -RAS low timing 3.5 MCLKs, -RAS precharge timing 2.5 MCLKs */ outb(vgaCRReg, tmp | 0xf0); } if (OFLG_ISSET(OPTION_SLOW_VRAM, &s3InfoRec.options)) { /* * some Diamond Stealth 64 VRAM cards have a problem with VRAM timing, * increase -RAS low timing from 3.5 MCLKs to 4.5 MCLKs */ outb(vgaCRIndex, 0x39); outb(vgaCRReg, 0xa5); outb(vgaCRIndex, 0x68); tmp = inb(vgaCRReg); if ((tmp & 0x30) == 0x30) /* 3.5 MCLKs */ outb(vgaCRReg, tmp & 0xef); /* 4.5 MCLKs */ } if (OFLG_ISSET(OPTION_SLOW_DRAM, &s3InfoRec.options)) { /* * fixes some pixel errors for a SPEA Trio64V+ card * increase -RAS precharge timing from 2.5 MCLKs to 3.5 MCLKs */ outb(vgaCRIndex, 0x39); outb(vgaCRReg, 0xa5); outb(vgaCRIndex, 0x68); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xf7); /* 3.5 MCLKs */ } if (OFLG_ISSET(OPTION_SLOW_EDODRAM, &s3InfoRec.options)) { /* * fixes some pixel errors for a SPEA Trio64V+ card * increase from 1-cycle to 2-cycle EDO mode */ outb(vgaCRIndex, 0x39); outb(vgaCRReg, 0xa5); outb(vgaCRIndex, 0x36); tmp = inb(vgaCRReg); if ((tmp & 0x0c) == 0x00) /* 1-cycle EDO */ outb(vgaCRReg, tmp | 0x08); /* 2-cycle EDO */ } if (S3_964_SERIES(s3ChipId) && DAC_IS_BT485_SERIES) { if (OFLG_ISSET(OPTION_S3_964_BT485_VCLK, &s3InfoRec.options)) { /* * This is the design alert from S3 with Bt485A and Vision 964. */ int i1, last, tmp1, cr55, cr67; int port, bit;#define VerticalRetraceWait() \ { \ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x08) ; \ while ((inb(vgaIOBase + 0x0A) & 0x08) == 0x00) ; \ } if (OFLG_ISSET(OPTION_DIAMOND, &s3InfoRec.options)) { port = 0x3c2; bit = 0x10; } else { /* MIRO 20SV Rev.2 */ port = 0x3c8; bit = 0x04; } if (port == 0x3c8) { outb(vgaCRIndex, 0x55); cr55 = inb(vgaCRReg); outb(vgaCRReg, cr55 | 0x04); /* enable rad of general input */ } outb(vgaCRIndex, 0x67); cr67 = inb(vgaCRReg); for(last=i1=30; --i1;) { VerticalRetraceWait(); VerticalRetraceWait(); if ((inb(port) & bit) == 0) { /* if GD2 is low then */ last = i1; outb(vgaCRIndex, 0x67); tmp1 = inb(vgaCRReg); outb(vgaCRReg, tmp1 ^ 0x01); /* clock should be inverted */#if 0 ErrorF("inverted VCLK %d to 0x%02x\n",i1,tmp1 ^ 0x01);#endif } if (last-i1 > 4) break; } if (!i1) { /* didn't get stable input, restore original CR67 value */ outb(vgaCRIndex, 0x67); outb(vgaCRReg, cr67); } if (port == 0x3c8) { outb(vgaCRIndex, 0x55); outb(vgaCRReg, cr55); }#if 0 outb(vgaCRIndex, 0x67); tmp1 = inb(vgaCRReg); /* if ((cr67 ^ tmp1) & 0x01) */ ErrorF("VCLK has been inverted %d times from 0x%02x to 0x%02x now\n",i1,cr67,tmp1);#endif } } if (OFLG_ISSET(OPTION_MIRO_80SV, &s3InfoRec.options)) { outb(vgaCRIndex, 0x42); tmp = inb(vgaCRReg) & 0xf0; outb(vgaCRReg, tmp | 0x06); } if (OFLG_ISSET(OPTION_ELSA_W2000PRO_X8, &s3InfoRec.options)) { /* check LCLK/SCLK phase */ unsigned char cr5c, cr42; outb(vgaCRIndex, 0x42); cr42 = inb(vgaCRReg); if (inb(0x3cc) & 0x40) /* hsync polarity */ cr42 &= 0xfb; else cr42 |= 0x04; outb(vgaCRReg, cr42); outb(vgaCRIndex, 0x5c); cr5c = inb(vgaCRReg); outb(vgaCRReg, cr5c | 0xa0); /* set GD7 & GD5 */ usleep(100000); /* wait at least 2 VSYNCs to latch clock phase */ if (inb(0x3c2) & 0x10) /* query SENSE */ cr42 &= 0xf7; else cr42 |= 0x08; outb(vgaCRIndex, 0x42); outb(vgaCRReg, cr42); outb(vgaCRIndex, 0x5c); outb(vgaCRReg, cr5c & 0x7f | 0x20); } if (OFLG_ISSET(CLOCK_OPTION_ICS2595, &s3InfoRec.clockOptions)) (void) (s3ClockSelectFunc)(mode->SynthClock); /* fixes the ICS2595 initialisation problems */ s3AdjustFrame(s3InfoRec.frameX0, s3InfoRec.frameY0); if ( S3_TRIO64V2_SERIES(s3ChipId) ) { /* disable DAC power saving to avoid bright left edge */ outb(0x3d4,0x86); outb(0x3d5,0x80); /* disable the stream display fetch length control */ outb(0x3d4,0x90); outb(0x3d5,0x00); } #ifdef REG_DEBUG for (i=0; i<10; i++) { outb(vgaCRIndex, i); tmp = inb(vgaCRReg); ErrorF("CR%X = 0x%02x\n", i, tmp); } for (i=0x10; i<0x19; i++) { outb(vgaCRIndex, i); tmp = inb(vgaCRReg); ErrorF("CR%X = 0x%02x\n", i, tmp); } outb(vgaCRIndex, 0x3b); tmp = inb(vgaCRReg); ErrorF("CR%X = 0x%02x\n", 0x3b, tmp); outb(vgaCRIndex, 0x5d); tmp = inb(vgaCRReg); ErrorF("CR%X = 0x%02x\n", 0x5d, tmp); outb(vgaCRIndex, 0x5e); tmp = inb(vgaCRReg); ErrorF("CR%X = 0x%02x\n", 0x5e, tmp); for (i=0; i<0x40; i++) { tmp = s3InTiIndReg(i); ErrorF("TI%X = 0x%02x\n", i, tmp); }#endif vgaProtect(FALSE); if (s3DisplayWidth == 1024) /* this is unclear Jon */ outw(ADVFUNC_CNTL, 0x0007); else outw(ADVFUNC_CNTL, 0x0003); /* * Blank the screen temporarily to display color 0 by turning the display of * all planes off */ outb(DAC_MASK, 0x00); /* Reset the 8514/A, and disable all interrupts. */ outw(SUBSYS_CNTL, GPCTRL_RESET | CHPTEST_NORMAL); outw(SUBSYS_CNTL, GPCTRL_ENAB | CHPTEST_NORMAL); i = inw(SUBSYS_STAT); outw(MULTIFUNC_CNTL, MEM_CNTL | VRTCFG_4 | HORCFG_8); outb(DAC_MASK, 0xff); LOCK_SYS_REGS;#ifdef PC98 crtswitch(1);#endif return TRUE;}/* InitLUT() *//* * Loads the Look-Up Table with all black. Assumes 8-bit board is in use. */static voidInitLUT(){ short i; outb(DAC_R_INDEX, 0); for (i = 0; i < 256; i++) { oldlut[i].r = inb(DAC_DATA); oldlut[i].g = inb(DAC_DATA); oldlut[i].b = inb(DAC_DATA); } outb(DAC_W_INDEX, 0); /* Load all 256 LUT entries */ for (i = 0; i < 256; i++) { outb(DAC_DATA, 0); outb(DAC_DATA, 0); outb(DAC_DATA, 0); } if (s3InfoRec.bitsPerPixel > 8 && (DAC_IS_SC15025 || DAC_IS_TI3020_SERIES || DAC_IS_TI3026 || DAC_IS_TI3030 || DAC_IS_IBMRGB)) { int r,g,b; int mr,mg,mb; int nr=5, ng=5, nb=5; extern unsigned char xf86rGammaMap[], xf86gGammaMap[], xf86bGammaMap[]; extern LUTENTRY currents3dac[]; if (!LUTInited) { if (s3Weight == RGB32_888 || DAC_IS_TI3020_SERIES || DAC_IS_TI3026 || DAC_IS_TI3030 || DAC_IS_IBMRGB) { for(i=0; i<256; i++) { currents3dac[i].r = xf86rGammaMap[i]; currents3dac[i].g = xf86gGammaMap[i]; currents3dac[i].b = xf86bGammaMap[i]; } } else { if (s3Weight == RGB16_565) ng = 6; mr = (1<<nr)-1; mg = (1<<ng)-1; mb = (1<<nb)-1; for(i=0; i<256; i++) { r = (i >> (6-nr)) & mr; g = (i >> (6-ng)) & mg; b = (i >> (6-nb)) & mb; currents3dac[i].r = xf86rGammaMap[(r*255+mr/2)/mr]; currents3dac[i].g = xf86gGammaMap[(g*255+mg/2)/mg]; currents3dac[i].b = xf86bGammaMap[(b*255+mb/2)/mb]; } } } i = xf86getdaccomm(); xf86setdaccomm(i | 0x08); outb(DAC_W_INDEX, 0); for(i=0; i<256; i++) { outb(DAC_DATA, currents3dac[i].r); outb(DAC_DATA, currents3dac[i].g); outb(DAC_DATA, currents3dac[i].b); } } LUTInited = TRUE;}/* * s3InitEnvironment() * * Initializes the 8514/A's drawing environment and clears the display. */voids3InitEnvironment(){ /* Current mixes, src, foreground active */ WaitQueue(6); outw(FRGD_MIX, FSS_FRGDCOL | MIX_SRC); outw(BKGD_MIX, BSS_BKGDCOL | MIX_SRC); /* Clipping rectangle to full drawable space */ outw(MULTIFUNC_CNTL, SCISSORS_T | 0x000); outw(MULTIFUNC_CNTL, SCISSORS_L | 0x000); outw(MULTIFUNC_CNTL, SCISSORS_R | (s3DisplayWidth-1)); outw(MULTIFUNC_CNTL, SCISSORS_B | s3ScissB); /* Enable writes to all planes and reset color compare */ WaitQueue16_32(3,5); outw32(WRT_MASK, ~0); outw32(RD_MASK, 0); outw(MULTIFUNC_CNTL, PIX_CNTL | 0x0000); /* * Clear the display. Need to set the color, origin, and size. Then draw. */ WaitQueue16_32(6,7); if (xf86FlipPixels && s3Bpp == 1) outw32(FRGD_COLOR, 1); else outw32(FRGD_COLOR, 0); outw(CUR_X, 0); outw(CUR_Y, 0); outw(MAJ_AXIS_PCNT, s3InfoRec.virtualX - 1); outw(MULTIFUNC_CNTL, MIN_AXIS_PCNT | s3ScissB); outw(CMD, CMD_RECT | INC_Y | INC_X | DRAW | PLANAR | WRTDATA); WaitQueue16_32(4,6); /* Reset current draw position */ outw(CUR_X, 0); outw(CUR_Y, 0); /* Reset current colors, foreground is all on, background is 0. */ outw32(FRGD_COLOR, ~0); outw32(BKGD_COLOR, 0); /* Load the LUT */ InitLUT(); /* fix a bug in early Trio64 chips (with Trio32 labels) */ outb(DAC_MASK, 0xff); }voids3Unlock(){ unsigned char tmp; xf86EnableIOPorts(s3InfoRec.scrnIndex); /* unlock */ outb(vgaCRIndex, 0x38); outb(vgaCRReg, 0x48); outb(vgaCRIndex, 0x39); outb(vgaCRReg, 0xa5); outb(vgaCRIndex, 0x35); /* select segment 0 */ tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xf0); cebank(); outb(vgaCRIndex, 0x11); /* allow writting to CR0-7 */ tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0x7f);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -