📄 mach32.c
字号:
{ const int knownind = 7; const double knownfreq = 44.9; char hstrt, hsync; int htotndisp, vdisp, vtotal, vstrt, vsync, clck, i; int count, saved_nice, loop; double scale; saved_nice = nice(0); nice(-20 - saved_nice); puts("Warning, about to measure clocks. Wait until system is completely idle!\n" "Any activity will disturb measuring, and therefor hinder correct driver\n" "function. Test will need about 3-4 seconds.\n" "If your monitor doesn't switch off when it gets signals it can't sync on\n" "better switch it off now before continuing. I'll beep when you can safely\n" "switch it back on.");#if 1 puts("\n(Enter Y<Return> to continue, any other text to bail out)"); if (getchar() != 'Y') { bailout: puts("\aBailed out."); exit(0); } if (getchar() != '\n') goto bailout;#endif htotndisp = inw(R_H_TOTAL); hstrt = inb(R_H_SYNC_STRT); hsync = inb(R_H_SYNC_WID); vdisp = inw(R_V_DISP); vtotal = inw(R_V_TOTAL); vstrt = inw(R_V_SYNC_STRT); vsync = inw(R_V_SYNC_WID); clck = inw(CLOCK_SEL); outb(DISP_CNTL, 0x63); outb(H_TOTAL, 0x63); outb(H_DISP, 0x4f); outb(H_SYNC_STRT, 0x52); outb(H_SYNC_WID, 0x2c); outw(V_TOTAL, 0x418); outw(V_DISP, 0x3bf); outw(V_SYNC_STRT, 0x3d6); outw(V_SYNC_WID, 0x22); for (i = 0; i < 16; i++) { outw(CLOCK_SEL, (i << 2) | 0xac1); outb(DISP_CNTL, 0x23); usleep(MODESWITCHDELAY); count = 0; loop = 200000; while (!(inb(DISP_STATUS) & 2)) if (loop-- == 0) goto done; while (inb(DISP_STATUS) & 2) if (loop-- == 0) goto done; while (!(inb(DISP_STATUS) & 2)) if (loop-- == 0) goto done; for (loop = 0; loop < 5; loop++) { while (!(inb(DISP_STATUS) & 2)) count++; while ((inb(DISP_STATUS) & 2)) count++; } done: mach32_clocks[i] = count; outb(DISP_CNTL, 0x63); } outw(CLOCK_SEL, clck); outb(H_TOTAL, htotndisp >> 8); outb(H_DISP, htotndisp); outb(H_SYNC_STRT, hstrt); outb(H_SYNC_WID, hsync); outw(V_DISP, vdisp); outw(V_TOTAL, vtotal); outw(V_SYNC_STRT, vstrt); outw(V_SYNC_WID, vsync); nice(20 + saved_nice);/*Recalculation: */ scale = ((double) mach32_clocks[knownind]) * knownfreq; for (i = 0; i < 16; i++) { if (i == knownind) continue; if (mach32_clocks[i]) mach32_clocks[i] = 0.5 + scale / ((double) mach32_clocks[i]); } mach32_clocks[knownind] = knownfreq + 0.5;}static signed char mach32_search_clk(int clk){ int i; if (!clk) return 0; if (clk > 80) /* Actually filter out the too high clocks here already */ return 0; for (i = 0; i < 32; i++) if (abs(clk - mach32_clocks[i]) <= 1) return i + 1; return 0;}static unsigned short dac14_clock_adjust(unsigned short clock, signed char *clock_map){ unsigned short clock_ind; if ((mach32_dac != MACH32_SC11483) && (mach32_dac != MACH32_BT481)) return clock; clock_ind = 0x1f & (clock >> 2); clock &= 0xff83; if (!clock_map[clock_ind]) { vga_setmode(TEXT); puts("svgalib-mach32: Panic, internal error: DAC1/4, invalid clock for >8bpp."); exit(1); } return clock | ((clock_map[clock_ind] - 1) << 2);}#ifdef BACKGROUND#include "vgabg.h"#endifstatic int mach32_init(int force, int chiptype, int memory){ char messbuf[12], eeapert = 0; static int max2msk[] = {1, 3, 0xf, 0xf}; static const short mem_conf[] = {512, 1024, 2048, 4096}; static const short mem_aper[] = {0, MACH32_APERTURE, MACH32_APERTURE | MACH32_APERTURE_4M, 0}; int i; unsigned short *ptr, cfg1, cfg2; unsigned long apertloc = 0;#ifdef BACKGROUND/* int old_modeinf;*/#endif#ifdef EXPERIMENTAL if (getenv("EXPERIMENTAL") != NULL) { mach32_experimental = atoi(getenv("EXPERIMENTAL")); printf("mach32: EXPERIMENTAL set to: %04x\n", mach32_experimental); } else { printf("mach32: EXPERIMENTAL defaults to: %04x\n", mach32_experimental); }#endif/* If IOPERM is set, assume permissions have already been set by Olaf Titz' *//* ioperm(1). */ if (getenv("IOPERM") == NULL) if (iopl(3) < 0) mach32_experm(); mach32_readconfig();/* Ensure we are idle. (Probable dead lock if no 8514 installed) */ mach32_bltwait();/*get main config registers */ cfg1 = inw(CONF_STAT1); cfg2 = inw(CONF_STAT2);/* get 2 eeprom buffers */ if (mach32_eeprom == NULL) { unsigned short sum, crea_eeprom = 1; if ((mach32_eeprom = malloc(sizeof(short) * 2 * 128)) == NULL) { printf("svgalib: mach32: Fatal error,\n" "not enough memory for EEPROM image (512 Bytes needed)\n"); /* svgamode not yet set.. */ exit(-1); } /* Do we have it already in a file ? */ if ((eeprom_fname != NULL) && !(eeprom_option & EEPROM_UPDATE)) { FILE *fd; fd = fopen(eeprom_fname, "rb"); if (fd == NULL) { readerr: printf("mach32: Warning, can't access EEPROM file >%s<\nError was %d - %s\n", eeprom_fname, errno, strerror(errno)); goto read_eeprom; } if (1 != fread(mach32_eeprom, sizeof(short) * 129, 1, fd)) { i = errno; fclose(fd); errno = i; goto readerr; } if (fclose(fd)) goto readerr; /*Checksum.. */ for (i = 0, sum = 0, ptr = mach32_eeprom; i < 128; i++) sum += *ptr++; if (sum == *ptr) { crea_eeprom = 0; /*Mark succesful read... */ goto skip_read; /* Use the read in file... */ } sum = 0; /*Mark unsuccesful read.. */ printf("mach32: Warning, EEPROM file >%s< corrupted.\n", eeprom_fname); } /* Read in eeprom */ read_eeprom: if (!(eeprom_option & (EEPROM_USE_CHKSUM | EEPROM_USE_MEMCFG | EEPROM_USE_TIMING))) { /* No need to bother reading the EEPROM */ goto skip_read; } for (i = 0, ptr = mach32_eeprom; i < 128; i++) *ptr++ = mach32_eeget(i); if (eeprom_option & EEPROM_USE_CHKSUM) { for (i = 0, sum = 0, ptr = mach32_eeprom; i < 128; i++) sum += *ptr++; sum &= 0xffff; if (sum) { /*Hmm.. no ATI checksum... try AST: */ sum -= (mach32_eeprom[0x7f] << 1) - 1; } } else sum = 0; if (sum & 0xffff) { puts("mach32: Warning, Illegal checksum in Mach32 EEPROM.\n" "Check configuration of your card and read README.mach32,\n" "esp. the Mach32 Eeprom Woe chapter.\n" "Ignoring contents..."); eeprom_option &= ~(EEPROM_USE_MEMCFG | EEPROM_USE_TIMING); } skip_read: if ((eeprom_fname != NULL) && (crea_eeprom || (eeprom_option & EEPROM_UPDATE))) /* create file if not there or unsuccesful or requested */ { FILE *fd; /*Calc valid checksum.. */ for (i = 0, sum = 0, ptr = mach32_eeprom; i < 128; i++) sum += *ptr++; /* Ensure that this fopen gets a file descriptor greater * than 2, else problems can occur with stdio functions * under certain strange conditions: */ if (fcntl(0,F_GETFD) < 0) open("/dev/null", O_RDONLY); if (fcntl(1,F_GETFD) < 0) open("/dev/null", O_WRONLY); if (fcntl(2,F_GETFD) < 0) open("/dev/null", O_WRONLY); fd = fopen(eeprom_fname, "wb"); if (fd == NULL) { writerr: printf("mach32: Warning, can't create new EEPROM file >%s<\nError was %d - %s\n", eeprom_fname, errno, strerror(errno)); crea_eeprom = 0; goto finish_w_eeprom; } if (1 != fwrite(mach32_eeprom, sizeof(short) * 128, 1, fd)) { fwri_err: i = errno; fclose(fd); errno = i; goto writerr; } if (1 != fwrite(&sum, sizeof(short), 1, fd)) goto fwri_err; if (fclose(fd)) goto writerr; printf("mach32: Notice: new EEPROM file >%s< succesful created.\n", eeprom_fname); finish_w_eeprom: } /* Change eeprom contents if requested: */ if (!(eeprom_option & EEPROM_USE_MEMCFG)) mach32_eeprom[6] = 0; if (!(eeprom_option & EEPROM_USE_TIMING)) { /* Consider ALL standard modes, but no user defined */ mach32_eeprom[0x07] = 0x01; /* 640 x 480 */ mach32_eeprom[0x08] = 0x3f; /* 640 x 480 */ mach32_eeprom[0x09] = 0x1f; /* 640 x 480 */ mach32_eeprom[0x0A] = 0x03; /* 640 x 480 */ mach32_eeprom[0x0B] = 0x00; /* no 1152x900 or 1120x750 */ } if (!clocks_set) { char linebuffer[512]; puts("mach32: Warning, no clocks defined.. please have a look at\n" "README.Mach32 and README.config for details.\n"); mach32_scan_clocks(); fputs("\a\nResulting clocks command for your libvga.config should be:\n\n" "clocks", stdout); for (i = 0; i < 16; i++) printf(" %3d", mach32_clocks[i]); fputs("\n\nPlease edit \"" SVGALIB_CONFIG_FILE "\" appropriately.\n" "Or shall I try to do it for you? You have to have write access to the\n" "config file to do it! (y/n) ", stdout); i = getchar(); if (i != '\n') while (getchar() != '\n'); if ((i != 'y') && (i != 'Y')) { puts("Ok, then do it yourself."); exit(0); } /* Toast setuid settings coz of security breach of system().. */ setreuid(getuid(), getuid()); setuid(getuid()); setgid(getgid()); strcpy(linebuffer, "rm -f " SVGALIB_CONFIG_FILE ".bak; mv " SVGALIB_CONFIG_FILE " " SVGALIB_CONFIG_FILE ".bak; echo clocks"); for (i = 0; i < 16; i++) sprintf(strchr(linebuffer, 0), " %d", mach32_clocks[i]); strcat(linebuffer, " | cat - " SVGALIB_CONFIG_FILE ".bak >" SVGALIB_CONFIG_FILE); if (system(linebuffer)) puts("Failed (at least partial, maybe there was just no config file yet)."); else puts("Ok. (But you should check it anyway)"); exit(0); }#ifdef DEBUG printf("ATI-EEPROM contents:"); for (i = 0; i < 128; i++) { if (i & 7) putchar(' '); else puts(""); printf("%02x - %04x", i, mach32_eeprom[i]); }#ifdef DEBUG_KEY fputs("\n(Hit Return)", stdout); while (getchar() != '\n');#else putchar('\n');#endif /* DEBUG_KEY */#endif /* DEBUG */ }/*create a scratch copy. */ memcpy(mach32_eeprom + 128, mach32_eeprom, (size_t) (128 * sizeof(short)));/*Get current memcfg */ mach32_memcfg = inw(MEM_CFG) & 0xfff3;/*If aperture not currently enabled but configured in EEPROM or setup already, then setup a faked setuplinear, switched off with setuplinear 0 0 */ if ((!(mach32_memcfg & 3)) && (((mach32_eeprom[6] + 1) & 3) > 1) && (!mach32_apsiz)) { /*create setup from eeprom: */ mach32_apsiz = (mach32_eeprom[6] & 3); mach32_apadd = (mach32_eeprom[6] >> 4); eeapert = 1; }/*setup up memory aperture if requested: */ if (mach32_apsiz) { unsigned new_memcfg; if (!mach32_apadd) mach32_memcfg = 0; /*disable any aperture */ else { if (((cfg1 & BUS_TYPE) == PCI) || ((cfg2 & Z4GBYTE) && !(cfg2 & LOCAL_BUS_CONF2))) { /* 4GB address range... */ new_memcfg = (mach32_apadd << 4) & 0xfff0; i = 4096; } else { /* 128MB address range... */ new_memcfg = (mach32_apadd << 8) & 0xff00; i = 128; } new_memcfg |= mach32_apsiz; if ((cfg1 & BUS_TYPE) == ISA) i = 16; i -= mach32_apadd; i -= (mach32_apsiz == 1) ? 1 : 4; if (i < 0) { puts("svgalib-mach32: Dangerous warning:\n" "\tsetuplinear setting exceeds phys. address range of card!\n" "\tSetting ignored."); mach32_apsiz = 0; } else { /* will be actually set by setappage(0) call in setmode */ mach32_memcfg = new_memcfg; } } } if (dac_override > 5) mach32_dac = (cfg1 >> 9) & 7; else mach32_dac = dac_override; mach32_chiptype = mem_aper[mach32_memcfg & 3]; if (!force) mach32_memory = mem_conf[(inw(MISC_OPTIONS) >> 2) & 3]; else { mach32_memory = memory; if (chiptype & MACH32_FORCEDAC) mach32_dac = chiptype & 0xf; if (chiptype & MACH32_FORCE_APERTURE) { mach32_chiptype = (chiptype & (MACH32_APERTURE | MACH32_APERTURE_4M));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -