📄 s3dacs.c
字号:
pixmux = 0x30; break; case RGB16_565: pixmux = 0x50; break; case RGB24_888_B: /* Use 0x40 for 3 VCLK/pixel. Change SDAC_map_clock and CR67 as well. */ pixmux = 0x90; break; case RGB32_888_B: pixmux = 0x70; break; } regs[SDAC_COMMAND] = pixmux; GENDAC_SDAC_initialize_clock_state(regs, SDAC_map_clock(bpp, pixelclock));}static void SDAC_qualify_cardspecs(CardSpecs * cardspecs, int dacspeed){ dacspeed = __svgalib_setDacSpeed(dacspeed, 110000); /* most can do 135MHz. */ cardspecs->maxPixelClock4bpp = dacspeed; cardspecs->maxPixelClock8bpp = dacspeed; cardspecs->maxPixelClock16bpp = dacspeed; cardspecs->maxPixelClock24bpp = dacspeed * 2 / 3; cardspecs->maxPixelClock32bpp = dacspeed / 2; cardspecs->mapClock = SDAC_map_clock; cardspecs->matchProgrammableClock = GENDAC_SDAC_match_programmable_clock; cardspecs->mapHorizontalCrtc = SDAC_map_horizontal_crtc; cardspecs->flags |= CLOCK_PROGRAMMABLE;}DacMethods __svgalib_S3_SDAC_methods ={ S3_SDAC, "S3-SDAC (86C716)", DAC_HAS_PROGRAMMABLE_CLOCKS, SDAC_probe, GENDAC_SDAC_init, SDAC_qualify_cardspecs, GENDAC_SDAC_savestate, GENDAC_SDAC_restorestate, SDAC_initializestate, SDAC_STATESIZE};#endif/* S3-GENDAC, 8-bit DAC. */#ifdef INCLUDE_S3_GENDAC_DAC_TESTstatic int GENDAC_probe(void){ return GENDAC_SDAC_probe() == 1;}#else#define GENDAC_probe 0#endif#ifdef INCLUDE_S3_GENDAC_DACstatic int GENDAC_map_clock(int bpp, int pixelclock){ if (bpp == 16) return pixelclock * 2; if (bpp == 24) return pixelclock * 3; if (bpp == 32) return pixelclock * 4; return pixelclock;}static int GENDAC_map_horizontal_crtc(int bpp, int pixelclock, int htiming){ /* XXXX Not sure. */ if (bpp == 24) return htiming * 3; if (bpp == 16) return htiming * 2; return htiming;}static void GENDAC_initializestate(unsigned char *regs, int bpp, int colormode, int pixelclock){ int daccomm; /* DAC command register. */ daccomm = 0; if (colormode == RGB16_555) daccomm = 0x20; else if (colormode == RGB16_565) daccomm = 0x60; else if (colormode == RGB24_888_B) daccomm = 0x40; regs[GENDAC_COMMAND] = daccomm; GENDAC_SDAC_initialize_clock_state(regs, GENDAC_map_clock(bpp, pixelclock));}static void GENDAC_qualify_cardspecs(CardSpecs * cardspecs, int dacspeed){ dacspeed = __svgalib_setDacSpeed(dacspeed, 110000); cardspecs->maxPixelClock4bpp = dacspeed; cardspecs->maxPixelClock8bpp = dacspeed; cardspecs->maxPixelClock16bpp = dacspeed / 2; cardspecs->maxPixelClock24bpp = dacspeed / 3; cardspecs->maxPixelClock32bpp = 0; cardspecs->mapClock = GENDAC_map_clock; cardspecs->matchProgrammableClock = GENDAC_SDAC_match_programmable_clock; cardspecs->mapHorizontalCrtc = GENDAC_map_horizontal_crtc; cardspecs->flags |= CLOCK_PROGRAMMABLE;}DacMethods __svgalib_S3_GENDAC_methods ={ S3_GENDAC, "S3-GENDAC (86C708)", DAC_HAS_PROGRAMMABLE_CLOCKS, GENDAC_probe, GENDAC_SDAC_init, GENDAC_qualify_cardspecs, GENDAC_SDAC_savestate, GENDAC_SDAC_restorestate, GENDAC_initializestate, GENDAC_STATESIZE};#endif#ifdef INCLUDE_S3_TRIO64_DAC/* S3-Trio64, 16-bit integrated DAC. */#define TRIO64_SR15 0#define TRIO64_SR18 1#define TRIO64_PLL_N1_N2 2#define TRIO64_PLL_M 3#define TRIO64_CR67 4#define TRIO64_SRB 5#define TRIO64_STATESIZE 6/* Note: s3.c also defines CR67, but doesn't use it for the Trio64. */extern int s3Mclk;static int Trio64_get_mclk(void){ unsigned char sr8; int m, n, n1, n2; outb(0x3c4, 0x08); sr8 = inb(0x3c5); outb(0x3c5, 0x06); outb(0x3c4, 0x11); m = inb(0x3c5); outb(0x3c4, 0x10); n = inb(0x3c5); outb(0x3c4, 0x08); outb(0x3c5, sr8); m &= 0x7f; n1 = n & 0x1f; n2 = (n >> 5) & 0x03; /* Calculate MCLK in kHz. */ return ((1431818 * (m + 2)) / (n1 + 2) / (1 << n2) + 50) / 100;}#if 0static void Trio64_set_mclk(int khz)/* Doesn't work. Locks computer up. Why? */{ int sr8; int min_m, min_n1, n2; if (!S3dacsFindClock(khz, 0, 40000, 70000, &min_m, &min_n1, &n2)) { printf("Bad MCLK %0.3f MHz.\n", khz / 1000.0); return; } printf("%0.3f MHz MCLK, m = %d, n = %d, r = %d\n", khz / 1000.0, min_m - 2, min_n1 - 2, n2); outb(0x3C4, 0x08); sr8 = inb(0x3C5); outb(0x3C5, 0x06); /* Unlock. */ outb(0x3c4, 0x15); outb(0x3c5, inb(0x3c5) & ~0x20); /* MCLK. */ __svgalib_outSR(0x10, (min_n1 - 2) | (n2 << 5)); __svgalib_outSR(0x11, min_m - 2); outb(0x3c4, 0x15); outb(0x3c5, inb(0x3c5) | 0x20); outb(0x3c5, inb(0x3c5) & ~0x20); __svgalib_outSR(0x08, sr8);}#endifstatic void Trio64_init(void){ int mclk; mclk = Trio64_get_mclk(); if (__svgalib_driver_report) printf("svgalib: RAMDAC: Trio64: MCLK = %0.3f MHz\n", mclk / 1000.0); s3Mclk = mclk;}static int Trio64_map_clock(int bpp, int pixelclock){ if (bpp == 8 && pixelclock >= 67500) /* use pixel doubling */ return pixelclock / 2; if (bpp == 24) return pixelclock * 3; return pixelclock;}static int Trio64_map_horizontal_crtc(int bpp, int pixelclock, int htiming){ if (bpp == 16) return htiming * 2; /* Normal mapping for 8bpp and 32bpp. */ return htiming;}static void Trio64_initialize_clock_state(unsigned char *regs, int freq){ int min_m, min_n1, n2; int n, m; if (!S3dacsFindClock(freq, 0, 130000, 270000, &min_m, &min_n1, &n2)) { printf("Bad dot clock %0.3f MHz.\n", freq / 1000.0); return; } n = (min_n1 - 2) | (n2 << 5); m = min_m - 2; regs[TRIO64_PLL_M] = m; regs[TRIO64_PLL_N1_N2] = n;}static int Trio64_match_programmable_clock(int desiredclock){ int min_m, min_n1, n2; if (!S3dacsFindClock(desiredclock, 0, 130000, 270000, &min_m, &min_n1, &n2)) return 0; return ((float) (min_m) / (float) (min_n1) / (1 << n2)) * BASE_FREQ * 1000;}static void Trio64_initializestate(unsigned char *regs, int bpp, int colormode, int pixelclock){ int pixmux, reserved_CR67_1; regs[TRIO64_SR15] &= ~0x50; regs[TRIO64_SR18] &= ~0x80; pixmux = 0; reserved_CR67_1 = 0; if (bpp == 8 && pixelclock >= 67500) { pixmux = 0x10; reserved_CR67_1 = 2; regs[TRIO64_SR15] |= 0x50; regs[TRIO64_SR18] |= 0x80; } else if (bpp == 16) { /* moderegs[S3_CR33] |= 0x08; *//* done in s3.c. */ if (colormode == RGB16_555) pixmux = 0x30; else pixmux = 0x50; reserved_CR67_1 = 2; } else if (colormode == RGB24_888_B) { /* remember to adjust SRB as well. */ pixmux = 0x00; } else if (colormode == RGB32_888_B) { pixmux = 0xD0; /* 32-bit color, 2 VCLKs/pixel. */ reserved_CR67_1 = 2; } regs[TRIO64_CR67] = pixmux | reserved_CR67_1; Trio64_initialize_clock_state(regs, pixelclock);}static void Trio64_savestate(unsigned char *regs){ unsigned char sr8; outb(0x3C4, 0x08); sr8 = inb(0x3C5); outb(0x3C5, 0x06); /* Unlock. */ regs[TRIO64_SR15] = __svgalib_inSR(0x15); regs[TRIO64_SR18] = __svgalib_inSR(0x18); regs[TRIO64_PLL_N1_N2] = __svgalib_inSR(0x12); regs[TRIO64_PLL_M] = __svgalib_inSR(0x13); regs[TRIO64_CR67] = __svgalib_inCR(0x67); __svgalib_outSR(0x08, sr8);}static void Trio64_restorestate(const unsigned char *regs){ unsigned char sr8, tmp; outb(0x3C4, 0x08); sr8 = inb(0x3C5); outb(0x3C5, 0x06); /* Unlock. */ __svgalib_outCR(0x67, regs[TRIO64_CR67]); __svgalib_outSR(0x15, regs[TRIO64_SR15]); __svgalib_outSR(0x18, regs[TRIO64_SR18]); /* Clock. */ __svgalib_outSR(0x12, regs[TRIO64_PLL_N1_N2]); __svgalib_outSR(0x13, regs[TRIO64_PLL_M]);#if 0 /* * XFree86 XF86_S3 (common_hw/gendac.c) has this, but it looks * incorrect, it should flip the bit by writing to 0x3c5, not * 0x3c4. */ outb(0x3c4, 0x15); tmp = inb(0x3c5); outb(0x3c4, tmp & ~0x20); outb(0x3c4, tmp | 0x20); outb(0x3c4, tmp & ~0x20);#else outb(0x3c4, 0x15); tmp = inb(0x3c5); outb(0x3c5, tmp & ~0x20); outb(0x3c5, tmp | 0x20); outb(0x3c5, tmp & ~0x20);#endif __svgalib_outSR(0x08, sr8);}static void Trio64_qualify_cardspecs(CardSpecs * cardspecs, int dacspeed){ if (dacspeed) { if (__svgalib_driver_report) printf("svgalib: using 'dacspeed' not recommended for this RAMDAC.\n"); cardspecs->maxPixelClock4bpp = dacspeed; cardspecs->maxPixelClock8bpp = 135000; cardspecs->maxPixelClock16bpp = dacspeed; cardspecs->maxPixelClock24bpp = 0; /* dacspeed / 3; *//* How to program? */ cardspecs->maxPixelClock32bpp = 50000; } else { cardspecs->maxPixelClock4bpp = 80000; cardspecs->maxPixelClock8bpp = 135000; cardspecs->maxPixelClock16bpp = 80000; cardspecs->maxPixelClock24bpp = 0; /* 25000; *//* How to program? */ cardspecs->maxPixelClock32bpp = 50000; } cardspecs->mapClock = Trio64_map_clock; cardspecs->matchProgrammableClock = Trio64_match_programmable_clock; cardspecs->mapHorizontalCrtc = Trio64_map_horizontal_crtc; cardspecs->flags |= CLOCK_PROGRAMMABLE;}DacMethods __svgalib_Trio64_methods ={ TRIO64, "S3-Trio64 internal DAC", DAC_HAS_PROGRAMMABLE_CLOCKS, NULL, /* probe */ Trio64_init, Trio64_qualify_cardspecs, Trio64_savestate, Trio64_restorestate, Trio64_initializestate, TRIO64_STATESIZE};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -