📄 mach32info.c
字号:
void putflag(char *str, int flag){ int i; i = 72 - strlen(str) - 10; printf(" %s ", str); while (i-- > 0) putchar('.'); puts(flag ? ". enabled" : " disabled");}void putint(char *str, char *format, int value){ char buffer[128]; int i; sprintf(buffer, format, value); i = 72 - strlen(str) - strlen(buffer); printf(" %s ", str); while (i-- > 0) putchar('.'); puts(buffer);}void putstr(char *str, char *strval){ putint(str, strval, 0);}unsigned short putword(int word){ printf("\n EEPROM Word %02xh:\t%04x\n", word, eeprom[word]); return eeprom[word];}char * offset(char *buffer, int word){ int tab; word >>= 8; if ((word < 0x0d) || (word > 0x67)) { illegal: sprintf(buffer, " %02xh words (no table there)", word); } else { tab = word - 0x0d; if (tab % (0x1c - 0x0d)) goto illegal; sprintf(buffer, " %02xh words (table %d)", word, tab / (0x1c - 0x0d) + 1); } return buffer;}char * hsyncstr(int pixels, int clock, double fclock){ static char buffer[50]; if (!clock) sprintf(buffer, " %d pixels", pixels); else sprintf(buffer, " %d pixels, %.3f us", pixels, pixels / fclock); return buffer;}char * vsyncstr(int lines, int clock, double lilen){ static char buffer[50]; if (!clock) sprintf(buffer, " %d lines", lines); else sprintf(buffer, " %d lines, %.3f ms", lines, lines / lilen); return buffer;}/* Shamelessly ripped out of Xfree2.1 (with slight changes) : */static void mach32_scan_clocks(void){ 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.");#if 0 puts("\n(Enter Y<Return> to continue, any other text to bail out)"); if (getchar() != 'Y') exit(0); if (getchar() != '\n') exit(0);#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(50000); 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); outw(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;}int main(int argc, char *argv[]){ char *ptr, buffer[40]; int i, j, lastfound, mask, index, flag; memset(eeprom, 0, sizeof(unsigned short) * (size_t) 256); if (argc != 2) usage(); if (strcmp(argv[1], "info")) { if (strcmp(argv[1], "force")) usage(); force = 1; } if (iopl(3) < 0) { fputs("mach32info needs to be run as root!\n", stderr); exit(1); } if (!force) { if (mach32_test()) puts("Mach32 succesful detected."); else { fputs("Sorry, no Mach32 detected.\n", stderr); exit(1); } } else puts("Mach32 autodetection skipped."); puts("\nThis tool is part of svgalib. Although this output maybe useful\n" "to debug Xfree86 Mach32 Servers, I am NOT related to Xfree86!!\n" "PLEASE DO NOT SEND ME (MICHAEL WELLER) ANY XFREE86 BUG REPORTS!!!\n" "Thanx in advance.\n"); mach32_scan_clocks(); puts("\nResulting clocks command for your libvga.config should be:\n"); fputs("clocks", stdout); for (i = 0; i < 16; i++) printf(" %3d", mach32_clocks[i]); fputs("\a", stderr); fflush(stderr); puts("\n\nParsing for chip id..."); lastfound = inw(CHIP_ID) & 0x3ff; flag = 0; for (i = 0; i < 10240; i++) { j = inw(CHIP_ID) & 0x3ff; index = (j >> 4); mask = 1 << (j & 15); if (!(eeprom[index] & mask)) printf("\tfound id: %c%c\n", 0x41 + ((j >> 5) & 0x1f), 0x41 + (j & 0x1f)); eeprom[index] |= mask; if (lastfound != j) flag = 1; }/* Build chip_id from last found id: */ chip_id = (j & 0x1f) + ((j << 3) & 0x1f00); chip_id += ATI68800_3; switch (chip_id) { case ATI68800_3: ptr = "ATI68800-3 (guessed)"; break; case ATI68800_6: ptr = "ATI68800-6"; break; case ATI68800_6HX: ptr = "ATI68800-6 (HX-id)"; break; case ATI68800LX: ptr = "ATI68800LX"; break; case ATI68800AX: ptr = "ATI68800AX"; break; default: ptr = "Unknown (assuming ATI68800-3)"; chip_id = ATI68800_3; flag = 1; break; } printf("Chipset: %s, Class: %d, Revision: %d\n", ptr, (j >> 10) & 3, (j >> 12) & 15); if (flag) { puts( "WARNING! Strange chipset id! Please report all output of this utility\n" "together with exact type of your card / type printed on your videochips\n" "to me, Michael Weller, eowmob@exp-math.uni-essen.de. Alternate\n" "email-addresses are in the source of this utility and in 'README.mach32'.\n" ); } j = inw(MAX_WAITSTATES); if (chip_id == ATI68800AX) { printf("\nAPERTURE_CNTL:\t\t%04x\n", j); putflag("Zero waitstates for PCI aperture", j & 0x400); putflag("Fifo read ahead for PCI aperture", j & 0x800); putflag("Pixel stream 1 SCLK delay", j & 0x1000); putflag("Decrement burst", j & 0x2000); putstr("Direction of burst", (j & 0x4000) ? "Increments burst" : "Decrements burst"); putflag("Bus timeout on burst read/writes", !(j & 0x8000)); } else { printf("\nMAX_WAITSTATES:\t\t%04x\n", j); putint("Max. I/O waitstates", " %d", 4 * (j & 15)); putint("BIOS-ROM waitstates", " %d", (j >> 4) & 15); putflag("Linedraw optimizations", j & 0x100); } j = inw(MISC_OPTIONS); printf("\nMISC_OPTIONS:\t\t%04x\n", j); putflag("Waitstates if FIFO is half full", j & 0x0001); putstr("Host data I/O size", (j & 0x0002) ? "8-bit" : "16-bit"); putint("Memory size", " %d KB", (1 << ((j >> 2) & 3)) * 512); putflag("VGA-controller", !(j & 0x0010)); putflag("16-bit 8514 I/O cycles", j & 0x0020); putflag("Local RAMDAC", !(j & 0x0040)); putflag("VRAM-serial/DRAM-memory(bits 63:0) data delay latch", j & 0x0080); putflag("Test-mode", j & 0x0100); putflag("Non ATI68800-3: Block-write", j & 0x0400); putflag("Non ATI68800-3: 64-bit Draw", j & 0x0800); putflag("Latch video memory read data", j & 0x1000); putflag("Memory data delay latch(bits 63:0)", j & 0x2000); putflag("Memory data latch full clock pulse", j & 0x4000); j = inw(R_EXT_GE_CONF); printf("\nR_EXT_GE_CONF:\t\t%04x\n", j); putint("Monitor alias id", " %d", j & 7); putflag("Monitor alias", j & 0x0008); putstr("Pixel width", pel_width[(j >> 4) & 3]); putstr("16 bit per plane organization", bpp16mode[(j >> 6) & 3]); putflag("Multiplex pixels", j & 0x0100); putstr("24 bit per plane organization", bpp24mode[(j >> 9) & 3]); putstr("Reserved (11)", (j & 0x0800) ? " 1" : " 0"); putint("Extended RAMDAC address", " %d", (j >> 12) & 3); putflag("8 bit RAMDAC operation", j & 0x4000); putstr("Reserved (15)", (j & 0x8000) ? " 1" : " 0"); j = inw(CONF_STAT1); printf("\nCONF_STAT1:\t\t%04x\n", j); putflag("VGA circuitry", !(j & 0x0001)); putstr("Bus Type", bustype[bus = ((j >> 1) & 7)]); putstr("Memory Type", (chip_id == ATI68800_3) ? memtype3[(j >> 4) & 7] : memtype6[(j >> 4) & 7]); putflag("Chip", !(j & 0x0080)); putflag("Delay memory write for tests", (j & 0x0100)); putstr("RAMDAC Type", dactype[(j >> 9) & 7]); putflag("Internal MicroChannel address decode", !(j & 0x1000)); putint("Controller id (0 if unsupported)", " %d", (j >> 13) & 7); j = inw(CONF_STAT2); printf("\nCONF_STAT2:\t\t%04x\n", j); if (chip_id == ATI68800_3) putflag("ATI68800-3: 2 clock sequencer timing", j & 0x0001); else putstr("Reserved (0)", (j & 0x0001) ? " 1" : " 0"); putflag("Memory address range FE0000-FFFFFF", !(j & 0x0002)); if (!bus) putflag("16-bit ISA Bus (ISA cards only)", (j & 0x0004)); else putstr("Reserved (2)", (j & 0x0004) ? " 1" : " 0"); putflag("Korean character font support", (j & 0x0008)); putstr("Local Bus signal (Local Bus only)", localbus[(j >> 4) & 3]); putflag("Local Bus 2 (non multiplexed) configuration", (j & 0x0040)); putflag("Read data 1 clk after RDY (Local Bus only)", (j & 0x0080)); putflag("Local decode of RAMDAC write (Local Bus only)", !(j & 0x0100)); putflag("1 clk RDY delay for write (Local Bus only)", !(j & 0x0200)); putstr("BIOS EPROM at", (j & 0x0400) ? " C000:0-C7FF:F" : " E000:0-E7FF:F"); switch (bus) { case 1: putflag("Enable POS register function (EISA)", (j & 0x0800)); break; case 4: case 5: case 6: putflag("Local decode of 102h register (Local Bus only)", !(j & 0x0800)); break; default: putstr("Reserved (11)", (j & 0x0800) ? " 1" : " 0"); break; } putflag("VESA compliant RDY format (Local Bus only)", !(j & 0x1000)); putflag("Non ATI68800-3: 4 GB aperture address", (j & 0x2000)); putstr("Non ATI68800-3: Memory support in LBus 2 config", (j & 0x4000) ? " 2MB DRAM" : " 1MB DRAM"); putstr("Reserved (15)", (j & 0x8000) ? " 1" : " 0"); j = inw(MEM_BNDRY); printf("\nMEM_BNDRY:\t\t%04x\n", j); putint("Video memory partition (VGA <, Mach32 >=)", " %d KB", (j & 15) * 256); putflag("Video memory partition write protection", j & 0x0010); putint("Reserved (15:5)", " %03xh", (j >> 5));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -