📄 s3.c
字号:
setclut8: dac_used->saveState(regs); if (regs[0] == 0x00) { /* 8bpp, 6 bits/color */ s3_flags |= S3_CLUT8_8; if (dac_used->id == SIERRA_15025) regs[1] = 1; regs[0] = 0x02; } dac_used->restoreState(regs); return old_values; } else { clearclut8: dac_used->saveState(regs); if (regs[0] == 0x02) { /* 8bpp, 8 bits/color */ s3_flags &= ~S3_CLUT8_8; if (dac_used->id == SIERRA_15025) regs[1] = 0; regs[0] = 0x00; } dac_used->restoreState(regs); return old_values; } default: } return 0;}/* Return non-zero if mode is available */static int s3_modeavailable(int mode){ struct info *info; ModeInfo *modeinfo; ModeTiming *modetiming; if (mode < G640x480x256 || mode == G720x348x2) return __svgalib_vga_driverspecs.modeavailable(mode); /* Enough memory? */ info = &__svgalib_infotable[mode]; if (s3_memory * 1024 < info->ydim * s3_adjlinewidth(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;}/* * save S3 registers. Lock registers receive special treatment * so dumpreg will work under X. */static int s3_saveregs(unsigned char regs[]){ unsigned char b, bmax; unsigned char cr38, cr39, cr40; cr38 = __svgalib_inCR(0x38); __svgalib_outCR(0x38, 0x48); /* unlock S3 VGA regs (CR30-CR3B) */ cr39 = __svgalib_inCR(0x39); __svgalib_outCR(0x39, 0xA5); /* unlock S3 system control (CR40-CR4F) */ /* and extended regs (CR50-CR6D) */ cr40 = __svgalib_inCR(0x40); /* unlock enhanced regs */ __svgalib_outCR(0x40, cr40 | 0x01); /* retrieve values from private copy */ memcpy(regs + S3_8514_OFFSET, s3_8514regs, S3_8514_COUNT * 2); /* get S3 VGA/Ext registers */ bmax = 0x4F; if (s3_chiptype >= S3_801) bmax = 0x66; if (s3_chiptype >= S3_864) bmax = 0x6D; for (b = 0x30; b <= bmax; b++) regs[EXT + b - 0x30] = __svgalib_inCR(b); /* get S3 ext. SR registers */ /* if (s3_chiptype >= S3_864) { */ if (s3_chiptype == S3_TRIO32 || s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) {/* SL: actually Trio32/64/V+ */ regs[S3_SR08] = __svgalib_inSR(0x08); __svgalib_outSR(0x08, 0x06); /* unlock extended seq regs */ regs[S3_SR09] = __svgalib_inSR(0x09); regs[S3_SR0A] = __svgalib_inSR(0x0A); regs[S3_SR0D] = __svgalib_inSR(0x0D); regs[S3_SR10] = __svgalib_inSR(0x10); regs[S3_SR11] = __svgalib_inSR(0x11); regs[S3_SR12] = __svgalib_inSR(0x12); regs[S3_SR13] = __svgalib_inSR(0x13); regs[S3_SR15] = __svgalib_inSR(0x15); regs[S3_SR18] = __svgalib_inSR(0x18); __svgalib_outSR(0x08, regs[S3_SR08]); } dac_used->saveState(regs + S3_DAC_OFFSET); /* leave the locks the way we found it */ __svgalib_outCR(0x40, regs[EXT + 0x40 - 0x30] = cr40); __svgalib_outCR(0x39, regs[EXT + 0x39 - 0x30] = cr39); __svgalib_outCR(0x38, regs[EXT + 0x38 - 0x30] = cr38);#if 0#include "ramdac/IBMRGB52x.h" do { unsigned char m, n, df; printf("pix_fmt = 0x%02X, 8bpp = 0x%02X, 16bpp = 0x%02X, 24bpp = 0x%02X, 32bpp = 0x%02X,\n" "CR58 = 0x%02X, CR66 = 0x%02X, CR67 = 0x%02X, CR6D = 0x%02X\n", regs[S3_DAC_OFFSET + IBMRGB_pix_fmt], regs[S3_DAC_OFFSET + IBMRGB_8bpp], regs[S3_DAC_OFFSET + IBMRGB_16bpp], regs[S3_DAC_OFFSET + IBMRGB_24bpp], regs[S3_DAC_OFFSET + IBMRGB_32bpp], regs[S3_CR58], regs[S3_CR66], regs[S3_CR67], regs[S3_CR6D]); m = regs[S3_DAC_OFFSET + IBMRGB_m0 + 4]; n = regs[S3_DAC_OFFSET + IBMRGB_n0 + 4]; df = m >> 6; m &= ~0xC0; printf("m = 0x%02X %d, n = 0x%02X %d, df = 0x%02X %d, freq = %.3f\n", m, m, n, n, df, df, ((m + 65.0) / n) / (8 >> df) * 16.0); } while (0);#endif return S3_DAC_OFFSET - VGA_TOTAL_REGS + dac_used->stateSize;}/* Set chipset-specific registers */static void s3_setregs(const unsigned char regs[], int mode){ unsigned char b, bmax; /* * Right now, anything != 0x00 gets written in s3_setregs. * May change this into a bitmask later. */ static unsigned char s3_regmask[] = { 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x00, 0x00, /* CR30-CR37 */ 0x00, 0x00, 0x3A, 0x3B, 0x3C, 0x00, 0x00, 0x00, /* CR38-CR3F */ 0x00, 0x00, 0x42, 0x43, 0x44, 0x00, 0x00, 0x00, /* CR40-CR47 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CR48-CR4F */ 0x50, 0x51, 0x00, 0x00, 0x54, 0x55, 0x00, 0x00, /* CR50-CR57 */ 0x58, 0x59, 0x5A, 0x00, 0x00, 0x5D, 0x5E, 0x00, /* CR58-CR5F */ 0x60, 0x61, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, /* CR60-CR67 */ 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00 /* CR68-CR6D */ }; s3_unlock_enh(); /* save a private copy */ memcpy(s3_8514regs, regs + S3_8514_OFFSET, S3_8514_COUNT * 2); /* * set this first, so if we segfault on this (e.g. we didn't do a iopl(3)) * we don't get a screwed up display */ outw(ADVFUNC_CNTL, s3_8514regs[S3_ADVFUNC_CNTL]); /* get S3 VGA/Ext registers */ bmax = 0x4F; if (s3_chiptype >= S3_801) bmax = 0x66; if (s3_chiptype >= S3_864) bmax = 0x6D; for (b = 0x30; b <= bmax; b++) { if (s3_regmask[b - 0x30]) __svgalib_outCR(b, regs[EXT + b - 0x30]); } if (dac_used->id != NORMAL_DAC) { unsigned char CR1; /* Blank the screen. */ CR1 = __svgalib_inCR(0x01); __svgalib_outCR(0x01, CR1 | 0x20); __svgalib_outbCR(0x55, __svgalib_inCR(0x55) | 1); __svgalib_outCR(0x66, regs[S3_CR66]); __svgalib_outCR(0x67, regs[S3_CR67]); /* S3 pixmux. */ dac_used->restoreState(regs + S3_DAC_OFFSET); __svgalib_outCR(0x6D, regs[S3_CR6D]); __svgalib_outbCR(0x55, __svgalib_inCR(0x55) & ~1); __svgalib_outCR(0x01, CR1); /* Unblank screen. */ }#ifdef S3_LINEAR_SUPPORT if (mode == TEXT && s3_linear_addr) s3_linear_disable(); /* make sure linear is off */#endif /* restore CR38/39 (may lock other regs) */ if (mode == TEXT) { /* restore lock registers as well */ __svgalib_outCR(0x40, regs[S3_CR40]); __svgalib_outCR(0x39, regs[S3_CR39]); __svgalib_outCR(0x38, regs[S3_CR38]); } else s3_lock_enh();}/* * Initialize register state for a mode. */static void s3_initializemode(unsigned char *moderegs, ModeTiming * modetiming, ModeInfo * modeinfo){ /* Get current values. */ s3_saveregs(moderegs); /* Set up the standard VGA registers for a generic SVGA. */ __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo); /* Set up the extended register values, including modifications */ /* of standard VGA registers. */ moderegs[VGA_SR0] = 0x03; moderegs[VGA_CR13] = modeinfo->lineWidth >> 3; moderegs[VGA_CR17] = 0xE3; if (modeinfo->lineWidth / modeinfo->bytesPerPixel == 2048) moderegs[S3_CR31] = 0x8F; else moderegs[S3_CR31] = 0x8D;#ifdef S3_LINEAR_MODE_BANKING_864 if (s3_chiptype >= S3_864) { /* moderegs[S3_ENHANCEDMODE] |= 0x01; */ /* Enable enhanced memory mode. */ moderegs[S3_CR31] |= 0x04; /* Enable banking via CR6A in linear mode. */ moderegs[S3_CR31] |= 0x01; }#endif moderegs[S3_CR32] = 0; moderegs[S3_CR33] = 0x20; moderegs[S3_CR34] = 0x10; /* 1024 */ moderegs[S3_CR35] = 0; /* Call cebank() here when setting registers. */ if (modeinfo->bitsPerPixel >= 8) { moderegs[S3_CR3A] = 0xB5; if (s3_chiptype == S3_928) /* ARI: Turn on CHAIN4 for 928, since __svgalib_setup_VGA_registers initializes ModeX */ moderegs[VGA_CR14] = 0x60; } else { /* 16 color mode */ moderegs[VGA_CR13] = modeinfo->lineWidth >> 1; moderegs[VGA_GR0] = 0x0F; moderegs[VGA_GR1] = 0x0F; moderegs[VGA_GR5] = 0x00; /* write mode 0 */ moderegs[VGA_AR11] = 0x00; moderegs[S3_CR3A] = 0x85; } moderegs[S3_CR3B] = (moderegs[VGA_CR0] + moderegs[VGA_CR4] + 1) / 2; moderegs[S3_CR3C] = moderegs[VGA_CR0] / 2; if (s3_chiptype == S3_911) { moderegs[S3_CR40] &= 0xF2; moderegs[S3_CR40] |= 0x09; } else if (s3_flags & S3_LOCALBUS) { moderegs[S3_CR40] &= 0xF2; /* Pegasus wants 0x01 for zero wait states. */#ifdef S3_0_WAIT_805_864 moderegs[S3_CR40] |= 0x09; /* use fifo + 0 wait state */#else moderegs[S3_CR40] |= 0x05;#endif } else { moderegs[S3_CR40] &= 0xF6; moderegs[S3_CR40] |= 0x01; } if (modeinfo->bitsPerPixel >= 24) { /* 24/32 bit color */ if (s3_chiptype == S3_864 || s3_chiptype == S3_964) moderegs[S3_CR43] = 0x08; else if (s3_chiptype == S3_928 && dac_used->id == SIERRA_15025) moderegs[S3_CR43] = 0x01; /* ELSA Winner 1000 */ } else if (modeinfo->bitsPerPixel >= 15) { /* 15/16 bit color */ if (s3_chiptype <= S3_864 || s3_chiptype >= S3_866) { /* XXXX Trio? */ moderegs[S3_CR43] = 0x08; if (dac_used->id == IBMRGB52x) moderegs[S3_CR43] = 0x10; else if (s3_chiptype == S3_928 && dac_used->id == SIERRA_15025) moderegs[S3_CR43] = 0x01; if (s3_chiptype <= S3_924 && dac_used->id != NORMAL_DAC) moderegs[S3_CR43] = 0x01; } else /* XXXX some DAC might need this; XF86 source says... */ moderegs[S3_CR43] = 0x09; } else { /* 4/8 bit color */ moderegs[S3_CR43] = 0x00; } if (s3_chiptype >= S3_924 && s3_chiptype <= S3_928) { /* different for 864+ */ s3_8514regs[S3_ADVFUNC_CNTL] = 0x0002; if ((s3_chiptype == S3_928 && modeinfo->bitsPerPixel != 4) || !(s3_flags & S3_OLD_STEPPING)) s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0001; if (modeinfo->bitsPerPixel == 4) s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;#if 0 /* 864 databook says it is for enhanced 4bpp */ if (modeinfo->lineWidth > 640) s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;#endif } else if (s3_chiptype == S3_968) { s3_8514regs[S3_ADVFUNC_CNTL] = 0x0002; if (modeinfo->bitsPerPixel == 4) s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;#ifdef PIXEL_MULTIPLEXING else s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0001;#endif } else if (modeinfo->lineWidth / modeinfo->bytesPerPixel == 1024) s3_8514regs[S3_ADVFUNC_CNTL] = 0x0007; else s3_8514regs[S3_ADVFUNC_CNTL] = 0x0003; moderegs[S3_CR44] = 0; /* Skip CR45, 'hi/truecolor cursor color enable'. */ if (s3_chiptype >= S3_801) { int m, n; /* for FIFO balancing */ /* XXXX Not all chips support all widths. */ moderegs[S3_CR50] &= ~0xF1; switch (modeinfo->bitsPerPixel) { case 16: moderegs[S3_CR50] |= 0x10; break; case 24: /* XXXX 868/968 only */ if (s3_chiptype >= S3_868) moderegs[S3_CR50] |= 0x20; break; case 32: moderegs[S3_CR50] |= 0x30; break; } switch (modeinfo->lineWidth / modeinfo->bytesPerPixel) { case 640: moderegs[S3_CR50] |= 0x40; break; case 800: moderegs[S3_CR50] |= 0x80; break; case 1152: if (!(s3_flags & S3_OLD_STEPPING)) { moderegs[S3_CR50] |= 0x01; break; } /* else fall through */ case 1280: moderegs[S3_CR50] |= 0xC0; break; case 1600: moderegs[S3_CR50] |= 0x81; break; /* 1024/2048 no change. */ } moderegs[S3_CR51] &= 0xC0; moderegs[S3_CR51] |= (modeinfo->lineWidth >> 7) & 0x30; /* moderegs[S3_CR53] |= 0x10; *//* Enable MMIO. */ /* moderegs[S3_CR53] |= 0x20; *//* DRAM interleaving for S3_805i with 2MB */ n = 0xFF; if (s3_chiptype >= S3_864 || s3_chiptype == S3_801 || s3_chiptype == S3_805) { /* * CRT FIFO balancing for DRAM cards and 964/968 * in VGA mode. */ int clock, mclk; if (modeinfo->bitsPerPixel < 8) { clock = modetiming->pixelClock; } else { clock = modetiming->pixelClock * modeinfo->bytesPerPixel; } if (s3_memory < 2048 || s3_chiptype == S3_TRIO32) clock *= 2; if (s3Mclk > 0) mclk = s3Mclk; else if (s3_chiptype == S3_801 || s3_chiptype == S3_805) mclk = 50000; /* Assumption. */ else mclk = 60000; /* Assumption. */ m = (int) ((mclk / 1000.0 * .72 + 16.867) * 89.736 / (clock / 1000.0 + 39) - 21.1543); if (s3_memory < 2048 || s3_chiptype == S3_TRIO32) m /= 2; if (m > 31) m = 31; else if (m < 0) { m = 0; n = 16; } } else if (s3_memory == 512 || modetiming->HDisplay > 1200) m = 0; else if (s3_memory == 1024) m = 2; else m = 20; moderegs[S3_CR54] = m << 3; moderegs[S3_CR60] = n; moderegs[S3_CR55] &= 0x08; moderegs[S3_CR55] |= 0x40;#ifdef S3_LINEAR_MODE_BANKING_864 if (s3_chiptype >= S3_864) { if (modeinfo->bitsPerPixel >= 8) { /* Enable linear addressing. */ moderegs[S3_CR58] |= 0x10; /* Set window size to 64K. */ moderegs[S3_CR58] &= ~0x03; /* Assume CR59/5A are correctly set up for 0xA0000. */ /* Set CR6A linear bank to zero. */ moderegs[S3_CR6A] &= ~0x3F; /* use alternate __svgalib_setpage() function */ __svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage864; } else { /* doesn't work for 4bpp. */ __svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage; } }#endif#ifdef S3_LINEAR_SUPPORT moderegs[S3_CR59] = s3_cr59; moderegs[S3_CR5A] = s3_cr5A;#endif /* Extended CRTC timing. */ moderegs[S3_CR5E] = (((modetiming->CrtcVTotal - 2) & 0x400) >> 10) |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -