📄 s3init.c
字号:
changed = TRUE; } } if (s3Bpp == 3) { /* for packed 24bpp CrtcHTotal must be multiple of 3*8... */ if ((mode->CrtcHTotal >> 3) % 3 != 0) { mode->CrtcHTotal >>= 3; mode->CrtcHTotal += 3 - mode->CrtcHTotal % 3; mode->CrtcHTotal <<= 3; changed = TRUE; p24_fact = 3; } } if (changed) { ErrorF("%s %s: mode line has to be modified ...\n", XCONFIG_PROBED, s3InfoRec.name); ErrorF("\t\tfrom %4d %4d %4d %4d %4d %4d %4d %4d\n" ,mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal ,mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal ); ErrorF("\t\tto %4d %4d %4d %4d %4d %4d %4d %4d\n" ,((mode->CrtcHDisplay << 8) >> (8-pixMuxShift)) * 4 / p24_fact ,((mode->CrtcHSyncStart << 8) >> (8-pixMuxShift)) * 4 / p24_fact ,((mode->CrtcHSyncEnd << 8) >> (8-pixMuxShift)) * 4 / p24_fact ,((mode->CrtcHTotal << 8) >> (8-pixMuxShift)) * 4 / p24_fact ,mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal ); } } if (!vgaHWInit(mode, sizeof(vgaS3Rec))) return(FALSE); new->MiscOutReg |= 0x0C; /* enable CR42 clock selection */ new->Sequencer[0] = 0x03; /* XXXX shouldn't need this */ new->CRTC[19] = s3BppDisplayWidth >> 3; new->CRTC[23] = 0xE3; /* XXXX shouldn't need this */ new->Attribute[0x11] = currents3dac_border; /* The overscan colour AR11 gets */ /* disabled anyway */ if ((S3_TRIO64V_SERIES(s3ChipId) && (s3ChipRev <= 0x53) && (s3Bpp==1)) ^ !!OFLG_ISSET(OPTION_TRIO64VP_BUG2, &s3InfoRec.options)) { /* set correct blanking for broken Trio64V+ to avoid bright left border: blank signal needs to go off ~400 usec before video signal starts w/o border: blank_shift = 0 */ int blank_shift = 400 * s3InfoRec.clock[mode->Clock] / 1000000 / 8; new->CRTC[2] = mode->CrtcHDisplay >> 3; new->CRTC[3] &= ~0x1f; new->CRTC[3] |= ((mode->CrtcHTotal >> 3) - 2 - blank_shift) & 0x1f; new->CRTC[5] &= ~0x80; new->CRTC[5] |= (((mode->CrtcHTotal >> 3) - 2 - blank_shift) & 0x20) << 2; new->CRTC[21] = (mode->CrtcVDisplay - 1) & 0xff; new->CRTC[7] &= ~0x08; new->CRTC[7] |= ((mode->CrtcVDisplay - 1) & 0x100) >> 5; new->CRTC[9] &= ~0x20; new->CRTC[9] |= ((mode->CrtcVDisplay - 1) & 0x200) >> 4; new->CRTC[22] = (mode->CrtcVTotal - 2) & 0xFF; } vgaProtect(TRUE); if (vgaIOBase == 0x3B0) new->MiscOutReg &= 0xFE; else new->MiscOutReg |= 0x01; if (OFLG_ISSET(OPTION_SPEA_MERCURY, &s3InfoRec.options) && S3_928_ONLY(s3ChipId)) { /* * Make sure that parallel option is already set correctly before * changing the clock doubler state. * XXXX maybe the !s3PixelMultiplexing bit is not required? */ if (s3PixelMultiplexing) { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x20); outb(0x3C7, 0x21); /* set s3 reg53 to parallel addressing by or'ing 0x20 */ outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp | 0x20); outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x00); } else { outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x20); outb(0x3C7, 0x00); /* set s3 reg53 to non-parallel addressing by and'ing 0xDF */ outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg); outb(vgaCRReg, tmp & 0xDF); outb(vgaCRIndex, 0x5C); outb(vgaCRReg, 0x00); } if (s3Bpp == 4) s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 1); /* 0x06 -> 0x07 */ else s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 0); /* 0x06 */ } if( (DAC_IS_TI3026 || DAC_IS_TI3030) && (OFLG_ISSET(CLOCK_OPTION_ICD2061A, &s3InfoRec.clockOptions))){ /* * for the boards with Ti3026 and external ICD2061A clock chip we * need to enable clock doubling, if necessary */ if( mode->Flags & V_DBLCLK ) {#ifdef EXTENDED_DEBUG ErrorF("Putting Ti3026 into external double clock mode\n");#endif s3OutTi3026IndReg(TI_INPUT_CLOCK_SELECT,0x00,0x08); } else {#ifdef EXTENDED_DEBUG ErrorF("Putting Ti3026 into external clock mode\n");#endif s3OutTi3026IndReg(TI_INPUT_CLOCK_SELECT,0x00,0x00); } if (s3Bpp == 4) s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 1); /* 0x06 -> 0x07 */ else s3OutTi3026IndReg(TI_LATCH_CONTROL, ~1, 0); /* 0x06 */ } if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) && !OFLG_ISSET(OPTION_NOLINEAR_MODE, &s3InfoRec.options) && s3Mmio928) { /* Set bit 7 of CRTC register 5C to map video memory with LAW31-26 = 011111 rather than 000000. Note that this remaps all addresses seen by the 928, including the VGA Base Address. */ int CR5C; outb(vgaCRIndex, 0x5C); CR5C = inb(vgaCRReg); outb(vgaCRIndex, 0x5C); outb(vgaCRReg, CR5C | 0x80); vgaBase = vgaBaseHigh; } if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options) && !OFLG_ISSET(OPTION_NOLINEAR_MODE, &s3InfoRec.options) && s3Mmio928) { int CR5C; outb(vgaCRIndex, 0x5C); CR5C = inb(vgaCRReg); outb(vgaCRIndex, 0x5C); switch(s3InfoRec.depth) { case 24: case 32: outb(vgaCRReg, CR5C | 0xf0); break; case 16: case 15: outb(vgaCRReg, CR5C | 0x70); break; default: outb(vgaCRReg, CR5C | 0xa0); } vgaBase = vgaBaseHigh;} /* Don't change the clock bits when using an external clock program */ if (new->NoClock < 0) { tmp = inb(0x3CC); new->MiscOutReg = (new->MiscOutReg & 0xF3) | (tmp & 0x0C); } else { /* XXXX Should we really do something about the return value? */ if (OFLG_ISSET(CLOCK_OPTION_PROGRAMABLE, &s3InfoRec.clockOptions)) (void) (s3ClockSelectFunc)(mode->SynthClock); else (void) (s3ClockSelectFunc)(mode->Clock); if ((mode->Flags & V_DBLCLK) && (DAC_IS_TI3026 || DAC_IS_TI3030) && (OFLG_ISSET(CLOCK_OPTION_ICD2061A, &s3InfoRec.clockOptions))){ if (s3Bpp <= 2) Ti3026SetClock(mode->SynthClock / 2, 2, s3Bpp, TI_LOOP_CLOCK); else Ti3026SetClock(mode->SynthClock, 2, s3Bpp, TI_LOOP_CLOCK); s3OutTi3026IndReg(TI_MCLK_LCLK_CONTROL, ~0x20, 0x20); } if ((DAC_IS_TI3026 || DAC_IS_TI3030) && s3Bpp == 3) { s3OutTi3026IndReg(TI_MCLK_LCLK_CONTROL, ~0x20, 0x20); } }/* Initialize Ramdac */ if(!(s3Ramdacs[s3RamdacType].DacInit)(mode)) { /* blah */ } s3InitCursorFlag = TRUE; /* turn on the cursor during the next load */ outb(0x3C2, new->MiscOutReg); for (i = 1; i < 5; i++) outw(0x3C4, (new->Sequencer[i] << 8) | i); for (i = 0; i < 25; i++) outw(vgaCRIndex, (new->CRTC[i] << 8) | i); for (i = 0; i < 9; i++) outw(0x3CE, (new->Graphics[i] << 8) | i); i = inb(vgaIOBase + 0x0A); /* reset flip-flop */ for (i = 0; i < 16; i++) { outb(0x3C0, i); outb(0x3C0, new->Attribute[i]); } for (i = 16; i < 21; i++) { outb(0x3C0, i | 0x20); outb(0x3C0, new->Attribute[i]); } if (s3DisplayWidth == 2048) s3Port31 = 0x8f; else s3Port31 = 0x8d; outb(vgaCRIndex, 0x31); outb(vgaCRReg, s3Port31); outb(vgaCRIndex, 0x32); outb(vgaCRReg, 0x00); outb(vgaCRIndex, 0x33); if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options)) /* Blank border comes earlier than display enable. */ outb(vgaCRReg, 0x00); else if (!S3_TRIOxx_SERIES(s3ChipId)) outb(vgaCRReg, 0x20); outb(vgaCRIndex, 0x34); outb(vgaCRReg, 0x10); /* 1024 */ outb(vgaCRIndex, 0x35); outb(vgaCRReg, 0x00); cebank();#if 0 /* x64: set to 1 if PCI read bursts should be enabled * NOTE: there are known problems with PCI burst mode in SATURN * chipset rev. 2 so this is commented out, maybe a new XF86Config * option should be used */ if (S3_x64_SERIES(s3ChipId)) { outb(vgaCRIndex, 0x3a); outb(vgaCRReg, 0xb5 & 0x7f); } else#endif { int pci_disc; if (OFLG_ISSET(OPTION_NO_PCI_DISC, &s3InfoRec.options)) pci_disc = 0x00; else pci_disc = 0x80; outb(vgaCRIndex, 0x66); /* set CR66_7 before CR3A_7 */ tmp = inb(vgaCRReg) & 0x7f; outb(vgaCRReg, tmp | pci_disc); outb(vgaCRIndex, 0x3a); if (OFLG_ISSET(OPTION_SLOW_DRAM_REFRESH, &s3InfoRec.options)) outb(vgaCRReg, 0x37 | pci_disc); else outb(vgaCRReg, 0x35 | pci_disc); } outb(vgaCRIndex, 0x3b); outb(vgaCRReg, (new->CRTC[0] + new->CRTC[4] + 1) / 2); outb(vgaCRIndex, 0x3c); outb(vgaCRReg, new->CRTC[0]/2); /* Interlace mode frame offset */ /* x64: CR40 changed a lot for 864/964; wait and see if this still works */ outb(vgaCRIndex, 0x40); if (S3_911_SERIES (s3ChipId)) { i = (inb(vgaCRReg) & 0xf2); s3Port40 = (i | 0x09); outb(vgaCRReg, s3Port40); } else { if (s3Localbus) { i = (inb(vgaCRReg) & 0xf2); if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) || OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) /* Set no wait states on STB Pegasus. */ s3Port40 = (i | 0x01); else s3Port40 = (i | 0x05); outb(vgaCRReg, s3Port40); } else { i = (inb(vgaCRReg) & 0xf6); s3Port40 = (i | 0x01); outb(vgaCRReg, s3Port40); } } outb(vgaCRIndex, 0x43); switch (s3InfoRec.depth) { case 24: case 32: if (S3_864_SERIES(s3ChipId)) outb(vgaCRReg, 0x08); /* 0x88 can't be used for 864/964 */ else if (S3_801_928_SERIES(s3ChipId) && DAC_IS_SC15025) outb(vgaCRReg, 0x01); /* ELSA Winner 1000 */ else if (DAC_IS_BT485_SERIES && S3_928_SERIES(s3ChipId)) outb(vgaCRReg, 0x00); break; case 15: case 16: if (DAC_IS_ATT490 || DAC_IS_GENDAC || DAC_IS_SC1148x_SERIES /* JON */ || DAC_IS_SS2410 ) /*??? I'm not sure - but the 490 does it */ outb(vgaCRReg, 0x80); else if (DAC_IS_TI3025) outb(vgaCRReg, 0x10); else if (DAC_IS_TI3026 || DAC_IS_TI3030) outb(vgaCRReg, 0x10); else if (DAC_IS_IBMRGB) outb(vgaCRReg, 0x10); else if (S3_864_SERIES(s3ChipId)) outb(vgaCRReg, 0x08); /* 0x88 can't be used for 864/964 */ else if (S3_928_SERIES(s3ChipId)) { if (DAC_IS_SC15025) outb(vgaCRReg, 0x01); /* ELSA Winner 1000 */ else if (DAC_IS_BT485_SERIES || DAC_IS_TI3020) outb(vgaCRReg, 0x00); else outb(vgaCRReg, 0x09); /* who uses this ? */ } else if (DAC_IS_ATT498 && S3_805_I_SERIES(s3ChipId)) outb(vgaCRReg, 0x00); else outb(vgaCRReg, 0x09); break; case 8: default: outb(vgaCRReg, 0x00); /* DON'T enable XOR addresses */ break; } outb(vgaCRIndex, 0x44); outb(vgaCRReg, 0x00); outb(vgaCRIndex, 0x45); i = inb(vgaCRReg) & 0xf2; /* hi/true cursor color enable */ switch (s3InfoRec.bitsPerPixel) { case 16: if (!S3_x64_SERIES(s3ChipId) && !S3_805_I_SERIES(s3ChipId) && !DAC_IS_TI3020) i = i | 0x04; break; case 32: if (S3_x64_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId) || DAC_IS_TI3020) i = i | 0x04; /* for 16bit RAMDAC, 0x0c for 8bit RAMDAC */ else i = i | 0x08; break; } outb(vgaCRReg, i); if (S3_801_928_SERIES(s3ChipId) || S3_964_SERIES(s3ChipId)) { outb(vgaCRIndex, 0x50); i = inb(vgaCRReg); i &= ~0xf1; switch (s3InfoRec.bitsPerPixel) { case 8: break; case 16: i |= 0x10; break; case 24: i |= 0x20; break; case 32: i |= 0x30; break; } switch (s3DisplayWidth) { case 640: i |= 0x40; break; case 800: i |= 0x80; break; case 1152: i |= 0x01; break; case 1280: i |= 0xc0; break; case 1600: i |= 0x81; break; default: /* 1024 and 2048 */ ; } outb(vgaCRReg, i); outb(vgaCRIndex, 0x51); s3Port51 = (inb(vgaCRReg) & 0xC0) | ((s3BppDisplayWidth >> 7) & 0x30); if (OFLG_ISSET(OPTION_NO_SPLIT_XFER, &s3InfoRec.options)) s3Port51 |= 0x40; if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options) || OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) { if (s3PixelMultiplexing) /* In Pixel Multiplexing mode, disable split transfers. */ s3Port51 |= 0x40; else /* In VGA mode, enable split transfers. */ s3Port51 &= ~0x40; } outb(vgaCRReg, s3Port51); outb(vgaCRIndex, 0x58); outb(vgaCRReg, s3SAM256);#ifdef DEBUG ErrorF("Writing CR59 0x%02x, CR5A 0x%02x\n", s3Port59, s3Port5A);#endif outb(vgaCRIndex, 0x59); outb(vgaCRReg, s3Port59); outb(vgaCRIndex, 0x5A); outb(vgaCRReg, s3Port5A); outb(vgaCRIndex, 0x53); tmp = inb(vgaCRReg) & ~0x18; if (s3Mmio928) tmp |= 0x10; if (s3NewMmio) { if (s3InfoRec.MemBase != 0) { s3Port59 = (s3InfoRec.MemBase >> 24) & 0xfc; s3Port5A = 0; outb(vgaCRIndex, 0x59); outb(vgaCRReg, s3Port59); outb(vgaCRIndex, 0x5a); outb(vgaCRReg, s3Port5A); outb(vgaCRIndex, 0x53); } tmp |= 0x18; } /* * Now the DRAM interleaving bit for the 801/805 chips * Note, we don't touch this bit for 928 chips because they use it * for pixel multiplexing control. */ if (S3_801_SERIES(s3ChipId)) { if (S3_805_I_SERIES(s3ChipId) && s3InfoRec.videoRam == 2048) tmp |= 0x20; else tmp &= ~0x20; } outb(vgaCRReg, tmp); if (s3NewMmio) { outb (vgaCRIndex, 0x58); outb (vgaCRReg, (s3LinApOpt & ~0x04) | s3SAM256); /* window size for linear mode */ } n = 255; outb(vgaCRIndex, 0x54); if (S3_x64_SERIES(s3ChipId) || S3_805_I_SERIES(s3ChipId)) { int clock2,mclk; clock2 = s3InfoRec.clock[mode->Clock] * s3Bpp; if (s3InfoRec.s3MClk > 0) mclk = s3InfoRec.s3MClk; else if (S3_805_I_SERIES(s3ChipId)) mclk = 50000; /* 50 MHz, guess for 805i limit */ else mclk = 60000; /* 60 MHz, limit for 864 */ if (s3InfoRec.videoRam < 2048 || S3_TRIO32_SERIES(s3ChipId)) clock2 *= 2; m = (int)((mclk/1000.0*.72+16.867)*89.736/(clock2/1000.0+39)-21.1543); if (s3InfoRec.videoRam < 2048 || S3_TRIO32_SERIES(s3ChipId)) m /= 2; m -= s3InfoRec.s3Madjust; if (m > 31) m = 31; else if (m < 0) { m = 0; n = 16; } } else if (s3InfoRec.videoRam == 512 || mode->HDisplay > 1200) /* XXXX */ m = 0; else if (s3InfoRec.videoRam == 1024) m = 2; else m = 20; if (OFLG_ISSET(OPTION_STB_PEGASUS, &s3InfoRec.options)) s3Port54 = 0x7F; else if (OFLG_ISSET(OPTION_MIRO_MAGIC_S4, &s3InfoRec.options)) s3Port54 = 0; else s3Port54 = m << 3; outb(vgaCRReg, s3Port54); n -= s3InfoRec.s3Nadjust; if (n < 0) n = 0; else if (n > 255) n = 255; outb(vgaCRIndex, 0x60); outb(vgaCRReg, n);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -