📄 s3.c
字号:
#define S3_LINEAR_FUNC s3_linear#else#define S3_LINEAR_FUNC 0#endif /* S3_LINEAR_SUPPORT *//* Function table (exported) */DriverSpecs __svgalib_s3_driverspecs ={ s3_saveregs, /* saveregs */ s3_setregs, /* setregs */ (void (*)(void)) nothing, /* unlock */ (void (*)(void)) nothing, /* lock */ s3_test, s3_init, s3_setpage, (void (*)(int)) nothing, (void (*)(int)) nothing, s3_setmode, s3_modeavailable, s3_setdisplaystart, s3_setlogicalwidth, s3_getmodeinfo, 0, /* bitblt */ 0, /* imageblt */ 0, /* fillblt */ 0, /* hlinelistblt */ 0, /* bltwait */ s3_ext_set, /* extset */ 0, /* accel */ S3_LINEAR_FUNC, /* linear */ NULL, /* Accelspecs */ NULL, /* Emulation */};/* S3-specific config file options. *//* * Currently this only handles Clocks. It would a good idea to have * higher-level code process options like Clocks that are valid for * more than one driver driver (with better error detection etc.). */static char *s3_config_options[] ={ "clocks", "ramdac", "dacspeed", "clockchip", NULL};static char *s3_process_option(int option, int mode){/* * option is the number of the option string in s3_config_options, * mode seems to be a 'hardness' indicator for security. */ if (option == 0) { /* "Clocks" */ /* Process at most 16 specified clocks. */ cardspecs->clocks = malloc(sizeof(int) * 16); /* cardspecs->nClocks should be already be 0. */ for (;;) { char *ptr; int freq; ptr = strtok(NULL, " "); if (ptr == NULL) break; /* * This doesn't protect against bad characters * (atof() doesn't detect errors). */ freq = atof(ptr) * 1000; cardspecs->clocks[cardspecs->nClocks] = freq; cardspecs->nClocks++; if (cardspecs->nClocks == 16) break; } } if (option == 1) { /* "Ramdac" */ char *ptr; ptr = strtok(NULL, " ");#ifdef INCLUDE_IBMRGB52x_DAC if (strcasecmp(ptr, "IBMRGB52x") == 0) dac_used = &__svgalib_IBMRGB52x_methods;#endif#ifdef INCLUDE_SIERRA_DAC if (strcasecmp(ptr, "Sierra32K") == 0) dac_used = &__svgalib_Sierra_32K_methods;#endif#ifdef INCLUDE_SC15025_DAC if (strcasecmp(ptr, "SC15025") == 0) dac_used = &__svgalib_SC15025_methods;#endif#ifdef INCLUDE_S3_SDAC_DAC if (strcasecmp(ptr, "SDAC") == 0) dac_used = &__svgalib_S3_SDAC_methods;#endif#ifdef INCLUDE_S3_GENDAC_DAC if (strcasecmp(ptr, "GenDAC") == 0) dac_used = &__svgalib_S3_GENDAC_methods;#endif#ifdef INCLUDE_ATT20C490_DAC if (strcasecmp(ptr, "ATT20C490") == 0) dac_used = &__svgalib_ATT20C490_methods;#endif#ifdef INCLUDE_ATT20C498_DAC if (strcasecmp(ptr, "ATT20C498") == 0) dac_used = &__svgalib_ATT20C498_methods;#endif#ifdef INCLUDE_NORMAL_DAC if (strcasecmp(ptr, "Normal") == 0) /* force normal VGA dac */ dac_used = &__svgalib_normal_dac_methods;#endif if (clk_used) clk_used->initialize(cardspecs, dac_used); } if (option == 2) { /* "Dacspeed" */ char *ptr; ptr = strtok(NULL, " "); /* * This doesn't protect against bad characters * (atoi() doesn't detect errors). */ dac_speed = atoi(ptr) * 1000; } if (option == 3) { /* "ClockChip" */ char *ptr; long freq; ptr = strtok(NULL, " \t"); if (strcasecmp(ptr, "ICD2061A") == 0 || strcasecmp(ptr, "DCS2824") == 0) /* Diamond, compatible to icd2061a */ clk_used = &__svgalib_I2061A_clockchip_methods; clk_used->initialize(cardspecs, dac_used); ptr = strtok(NULL, " \t"); if (ptr != NULL) { freq = atof(ptr) * 1000L; if (freq) { clk_used->TextFrequency = freq; ptr = strtok(NULL, " \t"); } } return ptr; } return strtok(NULL, " ");}/* Initialize driver (called after detection) *//* Derived from XFree86 SuperProbe and s3 driver. */static DacMethods *dacs_to_probe[] ={#ifdef INCLUDE_S3_SDAC_DAC_TEST &__svgalib_S3_SDAC_methods,#endif#ifdef INCLUDE_S3_GENDAC_DAC_TEST &__svgalib_S3_GENDAC_methods,#endif#ifdef INCLUDE_ATT20C490_DAC_TEST &__svgalib_ATT20C490_methods,#endif#ifdef INCLUDE_SC15025_DAC_TEST &__svgalib_SC15025_methods,#endif#ifdef INCLUDE_SC1148X_DAC_TEST &__svgalib_SC1148X_methods,#endif#ifdef INCLUDE_IBMRGB52x_DAC_TEST &__svgalib_IBMRGB52x_methods,#endif NULL};static int s3_init(int force, int par1, int par2){ int id, rev, config; s3_unlock(); s3_flags = 0; /* initialize */ id = __svgalib_inCR(0x30); /* Get chip id. */ rev = id & 0x0F; if (id >= 0xE0) { id |= __svgalib_inCR(0x2E) << 8; rev |= __svgalib_inCR(0x2F) << 4; } if (force) { s3_chiptype = par1; /* we already know the type */ s3_memory = par2; /* ARI: can we really trust the user's specification, or should we ignore it and probe ourselves ? */ if (s3_chiptype == S3_801 || s3_chiptype == S3_805) { if ((rev & 0x0F) < 2) s3_flags |= S3_OLD_STEPPING; /* can't handle 1152 width */ } else if (s3_chiptype == S3_928) { if ((rev & 0x0F) < 4) /* ARI: Stepping D or below */ s3_flags |= S3_OLD_STEPPING; /* can't handle 1152 width */ } } else { s3_chiptype = -1; config = __svgalib_inCR(0x36); /* get configuration info */ switch (id & 0xf0) { case 0x80: if (rev == 1) { s3_chiptype = S3_911; break; } if (rev == 2) { s3_chiptype = S3_924; break; } break; case 0xa0: switch (config & 0x03) { case 0x00: case 0x01: /* EISA or VLB - 805 */ s3_chiptype = S3_805; /* ARI: Test stepping: 0:B, 1:unknown, 2,3,4:C, 8:I, >=5:D */ if ((rev & 0x0F) < 2) s3_flags |= S3_OLD_STEPPING; /* can't handle 1152 width */ break; case 0x03: /* ISA - 801 */ s3_chiptype = S3_801; /* Stepping same as 805, just ISA */ if ((rev & 0x0F) < 2) s3_flags |= S3_OLD_STEPPING; /* can't handle 1152 width */ break; } break; case 0x90: s3_chiptype = S3_928; if ((rev & 0x0F) < 4) /* ARI: Stepping D or below */ s3_flags |= S3_OLD_STEPPING; /* can't handle 1152 width */ break; case 0xB0: /* 928P */ s3_chiptype = S3_928; break; case 0xC0: s3_chiptype = S3_864; break; case 0xD0: s3_chiptype = S3_964; break; case 0xE0: switch (id & 0xFFF0) { case 0x10E0: s3_chiptype = S3_TRIO32; break; case 0x3DE0: /* ViRGE/VX ID */ case 0x31E0: /* ViRGE ID */ case 0x01E0: /* S3Trio64V2/DX ... any others? */ case 0x04E0: case 0x11E0: if (rev & 0x0400) s3_chiptype = S3_765; else s3_chiptype = S3_TRIO64; break; case 0x80E0: s3_chiptype = S3_866; break; case 0x90E0: s3_chiptype = S3_868; break; case 0xF0E0: /* XXXX From data book; XF86 says 0xB0E0? */ s3_chiptype = S3_968; break; } } if (s3_chiptype == -1) { printf("svgalib: S3: Unknown chip id %02x\n", id); return -1; } if (s3_chiptype <= S3_924) { if ((config & 0x20) != 0) s3_memory = 512; else s3_memory = 1024; } else { /* look at bits 5, 6 and 7 */ switch ((config & 0xE0) >> 5) { case 0: s3_memory = 4096; break; case 2: s3_memory = 3072; break; case 3: s3_memory = 8192; break; case 4: s3_memory = 2048; break; case 5: s3_memory = 6144; break; case 6: s3_memory = 1024; break; case 7: s3_memory = 512; break; /* Trio32 */ } } if ((config & 0x03) < 3) /* XXXX 928P is ignored */ s3_flags |= S3_LOCALBUS; } if (__svgalib_driver_report) { printf("svgalib: Using S3 driver (%s, %dK).\n", s3_chipname[s3_chiptype], s3_memory); if (s3_flags & S3_OLD_STEPPING) printf("svgalib: Chip revision cannot handle modes with width 1152.\n"); if (s3_chiptype > S3_TRIO64) { printf("svgalib: s3: chipsets newer than S3 Trio64 is not supported well yet.\n"); } }/* begin: Initialize cardspecs. */ /* If IOPERM is set, assume permissions have already been set by Olaf Titz' */ /* ioperm(1). */ if (getenv("IOPERM") == NULL) { if (0 > iopl(3)) printf("svgalib: s3: cannot get I/O permissions for 8514."); }#ifdef S3_LINEAR_SUPPORT if (s3_chiptype > S3_805) { int found_pciconfig; unsigned long pci_conf[64]; found_pciconfig = __svgalib_pci_find_vendor_vga(0x5333, pci_conf, 0); if (!found_pciconfig) s3_linear_base = pci_conf[4] & 0xFF800000; } s3_cr59 = s3_linear_base >> 24; s3_cr5A = (s3_linear_base >> 16); if (! (s3_cr59 | s3_cr5A)) { s3_cr59 = __svgalib_inCR(0x59); s3_cr5A = __svgalib_inCR(0x5A); if (!s3_cr59) { s3_cr59 = 0xF3000000 >> 24; s3_cr5A = (0xF3000000 >> 16); } s3_linear_base = (s3_cr59 << 24) | (s3_cr5A << 16); } s3_linear_opt |= 0x10; switch (s3_memory) { case 512 : case 1024 : s3_linear_opt |= 0x01; break; case 2048 : s3_linear_opt |= 0x02; break; case 3072 : case 4096 : case 6144 : case 8192 : s3_linear_opt |= 0x03; break; default : s3_linear_opt = 0x14; /* like XFree */ }#endif cardspecs = malloc(sizeof(CardSpecs)); cardspecs->videoMemory = s3_memory; cardspecs->nClocks = 0; /* cardspecs->maxHorizontalCrtc = 2040; SL: kills 800x600x32k and above */ cardspecs->maxHorizontalCrtc = 4088; cardspecs->flags = INTERLACE_DIVIDE_VERT; /* Process S3-specific config file options. */ __svgalib_read_options(s3_config_options, s3_process_option);#ifdef INCLUDE_S3_TRIO64_DAC if ((s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) && dac_used == NULL) dac_used = &__svgalib_Trio64_methods;#endif if (dac_used == NULL) dac_used = __svgalib_probeDacs(dacs_to_probe); else dac_used->initialize(); if (dac_used == NULL) { /* Not supported. */ printf("svgalib: s3: Assuming normal VGA DAC.\n");#ifdef INCLUDE_NORMAL_DAC dac_used = &__svgalib_normal_dac_methods; dac_used->initialize();#else printf("svgalib: Alas, normal VGA DAC support is not compiled in, goodbye.\n"); return 1;#endif } if (clk_used) clk_used->initialize(cardspecs, dac_used); dac_used->qualifyCardSpecs(cardspecs, dac_speed); /* Initialize standard clocks for unknown DAC. */ if ((!(cardspecs->flags & CLOCK_PROGRAMMABLE)) && cardspecs->nClocks == 0) { /* * Almost all cards have 25 and 28 MHz on VGA clocks 0 and 1, * so use these for an unknown DAC, yielding 640x480x256. */ cardspecs->nClocks = 2; cardspecs->clocks = malloc(sizeof(int) * 2); cardspecs->clocks[0] = 25175; cardspecs->clocks[1] = 28322; } /* Limit pixel clocks according to chip specifications. */ if (s3_chiptype == S3_864 || s3_chiptype == S3_868) { /* Limit max clocks according to 95 MHz DCLK spec. */ /* SL: might just be 95000 for 4/8bpp since no pixmux'ing */ LIMIT(cardspecs->maxPixelClock4bpp, 95000 * 2); LIMIT(cardspecs->maxPixelClock8bpp, 95000 * 2); LIMIT(cardspecs->maxPixelClock16bpp, 95000); /* see explanation below */ LIMIT(cardspecs->maxPixelClock24bpp, 36000); /* * The official 32bpp limit is 47500, but we allow * 50 MHz for VESA 800x600 timing (actually the * S3-864 doesn't have the horizontal timing range * to run unmodified VESA 800x600 72 Hz timings). */ LIMIT(cardspecs->maxPixelClock32bpp, 50000); }#ifndef S3_16_COLORS cardspecs->maxPixelClock4bpp = 0; /* 16-color doesn't work. */#endif/* end: Initialize cardspecs. */ __svgalib_driverspecs = &__svgalib_s3_driverspecs; __svgalib_banked_mem_base=0xa0000; __svgalib_banked_mem_size=0x10000;#ifdef S3_LINEAR_SUPPORT __svgalib_linear_mem_base=s3_linear_base; __svgalib_linear_mem_size=s3_memory*0x400;#endif return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -