📄 mach32.c
字号:
if (mach32_chiptype & MACH32_APERTURE_4M) mach32_chiptype |= MACH32_APERTURE; } } if (mach32_dac > 5) { printf("mach32: Warning, unknown DAC type: %d. Assuming stupid 8bpp DAC rated at 80Mhz!\n", mach32_dac); /* Assumption is already done in all tables used... */ } if (!(DAC_SAFETY & (1 << mach32_dac))) { char *cptr; /* Safety notification */ cptr = getenv("SVGALIB_MACH32"); if (cptr == NULL) { messexit: puts("\aWarning!! The mach32 driver of svgalib was never tried with a DAC type\n" "!=4,3,2,0. Nevertheless, I put every knowledge I got from the DOCs in this\n" "driver, so it should work. If you think you can stand this risk\n" "(for example, your monitor will just switch off if he can't stand the\n" "video signal) then set the environment variable SVGALIB_MACH32 to\n" "ILLTRYIT or --- of course --- recompile svgalib after changing the\n" "#define DAC_SAFETY in mach32.c\n\n" "To reduce possibility of damage to your card you should check that no\n" "video mode above 80Mhz dotclock is used with dacs !=2 or 5. To check\n" "recompile with DEBUG defined in mach32.c and look at the output.\n" "In any case, that is, if it works or not (and what went wrong),\n" "please tell me about:\n" "Michael Weller, eowmob@exp-math.uni-essen.de,\n" "eowmob@pollux.exp-math.uni-essen.de, or mat42b@aixrs1.hrz.uni-essen.de.\n."); exit(-1); } if (strcmp(cptr, "ILLTRYIT")) goto messexit; } if (mach32_dac != 2) pos_ext_settings &= ~VGA_CLUT8;/* Access aperture */ if ((mach32_chiptype & MACH32_APERTURE) && (mach32_aperture == NULL)) { if (((cfg1 & BUS_TYPE) == PCI) || ((cfg2 & Z4GBYTE) && !(cfg2 & LOCAL_BUS_CONF2))) { /* 4GB address range... */ apertloc = ((unsigned long) (mach32_memcfg & 0xfff0)) << 16; } else { /* 128MB address range... */ apertloc = ((unsigned long) (mach32_memcfg & 0xff00)) << 12; }#ifdef DEBUG printf("mach32: Physical aperture starts at %08lx.\n", apertloc);#endif mach32_aperture = (char *) mmap(NULL, (mach32_chiptype & MACH32_APERTURE_4M) ? 4194304 : 1048576, PROT_READ | PROT_WRITE, MAP_SHARED, __svgalib_mem_fd, apertloc); /* I trust the comment about memory waste in vgamisc.c... */ if (((long) mach32_aperture) < 0) { i = errno; printf("mach32: Mmaping of aperture failed.\nError was %d", i); errno = i; perror(" - "); exit(-1); }#ifdef DEBUG printf("mach32: Aperture mapped to %08lx.\n", (long) mach32_aperture);#endif#ifdef BACKGROUND#if BACKGROUND == 1 __svgalib_graph_mem_linear_orginal=(unsigned char *)mach32_aperture; __svgalib_linear_memory_size=(mach32_chiptype & MACH32_APERTURE_4M) ? 4194304 : 1048576; if ((__svgalib_linearframebuffer = valloc(__svgalib_linear_memory_size)) == NULL) { printf("svgalib(mach32): allocation error \n"); exit(-1); } __svgalib_graph_mem_linear_check=__svgalib_linearframebuffer; __svgalib_linearframebuffer = (unsigned char *) mmap((caddr_t) __svgalib_linearframebuffer, __svgalib_linear_memory_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, __svgalib_virtual_mem_fd, (int)__svgalib_graph_mem_linear_orginal); if ((int)__svgalib_linearframebuffer == -1) { printf("svgalib(mach32): mmapping failed\n"); exit(-1); } mach32_aperture = __svgalib_linearframebuffer;#endif#endif } __svgalib_driverspecs = &__svgalib_mach32_driverspecs; __svgalib_banked_mem_base=0xa0000; __svgalib_banked_mem_size=0x10000;/* __svgalib_linear_mem_base=MACH32_APERTURE; __svgalib_linear_mem_sizemach32_memory*0x400; *//* Check if imageblit emulation possible: */ i = 0; if (mach32_chiptype & MACH32_APERTURE_4M) i = (4 << 10); else if (mach32_chiptype & MACH32_APERTURE) i = (1 << 10); if (i < mach32_memory) { /*aperture to small */ emuimage &= ~(EMU_OVER | EMU_POSS); } if (!mach32_modes) { mach32_modes = malloc(__svgalib_max_modes * sizeof(mode_entry *)); if (!mach32_modes) { puts("mach32: No memory for dynamic mode table."); exit(1); } }/*Calculate the double and triple clocks */ for (i = 0; i < 32; i++) mach32_clock_by2[i] = mach32_search_clk(mach32_clocks[i] << 1); for (i = 0; i < 32; i++) mach32_clock_by3[i] = mach32_search_clk(mach32_clocks[i] * 3);#ifdef DEBUG puts("15/16bpp DAC1/4 clock_maps:"); for (i = 0; i < 32; i++) { if (!(i & 7)) putchar('\n'); if (mach32_clock_by2[i]) printf("%3d->%3d ", mach32_clocks[i], mach32_clocks[mach32_clock_by2[i] - 1]); else printf("%3d-> - ", mach32_clocks[i]); } puts("\n24bpp DAC1/4 clock_maps:"); for (i = 0; i < 32; i++) { if (!(i & 7)) putchar('\n'); if (mach32_clock_by3[i]) printf("%3d->%3d ", mach32_clocks[i], mach32_clocks[mach32_clock_by3[i] - 1]); else printf("%3d-> - ", mach32_clocks[i]); } putchar('\n');#endif/*Populating database: */ if (verbose) puts("Populating mode table:"); for (i = 0; i < __svgalib_max_modes; i++) mach32_modes[i] = NULL; for (i = 0; i < NUM_MODES; i++) { if ((predef_modes[i].offset == 0) || (mach32_eeprom[predef_modes[i].offset] & predef_modes[i].mask)) mach32_modfill(predef_modes + i, mach32_max_mask(predef_modes[i].h_disp), -1); } if (mach32_eeprom[7] & 2) { i = (mach32_eeprom[7] >> 8) & 0xff; if ((mach32_eeprom[i] & 0x140) == 0x140) mach32_modfill((mode_entry *) (mach32_eeprom + i + 2), max2msk[3 & (mach32_eeprom[i] >> 9)], -1); } if (mach32_eeprom[8] & 0x80) { i = (mach32_eeprom[8] >> 8) & 0xff; if ((mach32_eeprom[i] & 0x140) == 0x140) mach32_modfill((mode_entry *) (mach32_eeprom + i + 2), max2msk[3 & (mach32_eeprom[i] >> 9)], -1); } if (mach32_eeprom[9] & 0x80) { i = (mach32_eeprom[9] >> 8) & 0xff; if ((mach32_eeprom[i] & 0x140) == 0x140) mach32_modfill((mode_entry *) (mach32_eeprom + i + 2), max2msk[3 & (mach32_eeprom[i] >> 9)], -1); } if (mach32_eeprom[10] & 0x80) { i = (mach32_eeprom[10] >> 8) & 0xff; if ((mach32_eeprom[i] & 0x140) == 0x140) mach32_modfill((mode_entry *) (mach32_eeprom + i + 2), max2msk[3 & (mach32_eeprom[i] >> 9)], -1); } if (verbose) puts("Squeeze in run-time config:"); mach32_final_modefixup(); if (__svgalib_driver_report) { sprintf(messbuf, " at %dM", (int) (apertloc >> 20)); printf("Using Mach32 driver 2.1 (%s apert%s (%s), %dK mem, DAC %d%s%s).\n", (mach32_chiptype & MACH32_APERTURE) ? ((mach32_chiptype & MACH32_APERTURE_4M) ? "4M" : "1M") : "no", (mach32_chiptype & MACH32_APERTURE) ? messbuf : "", mach32_apsiz ? (eeapert ? "EEPROM" : "setup") : "autodetect", mach32_memory, mach32_dac, (dac_override < 6) ? "(set)" : "", force ? ", forced" : ""); } return 0;}static inline int col2msk(struct info *iptr){ switch (iptr->colors) { case 1 << 24: if (iptr->bytesperpixel == 3) return 4;#ifdef SUPP_32BPP if (iptr->bytesperpixel == 4) return 8;#endif else return 0; case 1 << 15: case 1 << 16: if (iptr->bytesperpixel == 2) return 2; else return 0; case 256: if (iptr->bytesperpixel == 1) return 1; else return 0; } return 0;}static inline int col2bypp(struct info *iptr){ return iptr->bytesperpixel;}static int mach32_log2(struct info *iptr){ int res = -1, n = iptr->colors; while (n) { res++; n >>= 1; } if ((res == 24) && (iptr->bytesperpixel == 4)) return 32; return res;}static void mach32_modfill(const mode_entry * mode, int modemask, int forcein){ register int i; register struct info *iptr; register unsigned wid, hei; float horz, vert, n_horz, n_vert, cmpvert; int clock, n_clock, tmp; clock = mach32_clocks[n_clock = 0x1f & (mode->clock_sel >> 2)]; if (!clock) { if (verbose) puts("Illegal clock #%d of unknown frequency! (rejected)"); return; } horz = (1e3 * clock) / (float) (mode->h_total * 8 + 8); hei = mode->v_total; if (!(mode->disp_cntl & 0x6)) hei = ((hei >> 2) & 0xfffe) | (hei & 1); else hei = ((hei >> 1) & 0xfffc) | (hei & 3); hei++; vert = (horz * 1000) / hei; wid = mode->h_disp * 8 + 8; hei = mode->v_disp; if (!(mode->disp_cntl & 0x6)) hei = ((hei >> 2) & 0xfffe) | (hei & 1); else hei = ((hei >> 1) & 0xfffc) | (hei & 3); hei++;/*Maskout impossible colorsettings for high clock rates: */ i = modemask; modemask &= mach32_mmask[(clock > 80) ? 1 : 0][mach32_dac]; if (verbose && (i != modemask)) { printf("Modemask (32bpp,24bpp,16bpp,8bpp) %x cut down to %x by DAC restrictions.\n", i, modemask); }/*Check if needed multiples are available */ if ((mach32_dac == MACH32_BT481) || (mach32_dac == MACH32_SC11483)) { if ((modemask & 2) && (!mach32_clock_by2[n_clock])) { modemask &= ~2; if (verbose) printf("DAC1/4: There is no clock with two times the requested\n" "\tfreq. of %dMHz => no 15 or 16 bpp.\n", clock); } if ((mach32_dac == MACH32_BT481) && (modemask & 4) && (!mach32_clock_by3[n_clock])) { modemask &= ~4; if (verbose) printf("DAC4: There is no clock with three times the requested\n" "\tfreq. of %dMHz => no 24bpp.\n", clock); } } i = modemask;/*Rate down clocks exceeding mem bandwidth */ if (clock > mach32_maxclk8) modemask &= ~1; if (clock > mach32_maxclk16) modemask &= ~2; if (clock > mach32_maxclk24) modemask &= ~4; if (clock > mach32_maxclk32) modemask &= ~8; if (verbose && (i != modemask)) printf("Modemask (32bpp,24bpp,16bpp,8bpp) %x cut down to %x by maxclocks.\n", i, modemask); if (forcein >= 0) { /*Well hack the next loop to run exactly one time for i=forcein.. */ /*I know it's dirty... */ i = forcein; iptr = infotable + i; goto jumpin; /*Show that to a Pascal coder and he falls down dead.. */ } for (i = 0, iptr = infotable; (i < __svgalib_max_modes) && (forcein < 0); i++, iptr++) { jumpin: if ((iptr->xdim != wid) || (iptr->ydim != hei) || !(modemask & col2msk(iptr))) continue; cmpvert = (mode->disp_cntl & 0x10) ? 2.0 * vert : vert; if (verbose) { printf("%4ux%4ux%2u: ", wid, hei, mach32_log2(iptr)); printf("%3d MHz Clock, %6.3f KHz horz., %6.3f Hz vert.,\n\t%s, VFIFO(16-%d,24-%d)", clock, horz, cmpvert, (mode->disp_cntl & 0x10) ? "Interlaced" : "Non-Interlaced", mode->vfifo16, mode->vfifo24); } if (iptr->xbytes * iptr->ydim > mach32_memory * 1024) { if (verbose) puts(" (not enough memory)"); continue; } if (__svgalib_horizsync.max < OFF_ALLOWANCE(horz * 1000)) { if (verbose) puts(" (rejected, hsync too high)"); continue; } if (__svgalib_horizsync.min > ADD_ALLOWANCE(horz * 1000)) { if (verbose) puts(" (rejected, hsync too low)"); continue; } if (__svgalib_vertrefresh.max < OFF_ALLOWANCE(cmpvert)) { if (verbose) puts(" (rejected, vsync too high)"); continue; } if (__svgalib_vertrefresh.min > ADD_ALLOWANCE(cmpvert)) { if (verbose) puts(" (rejected, vsync too low)"); continue; } if ((mach32_modes[i] == NULL) || (forcein >= 0)) { if (verbose) puts(" (accepted)"); fillin: mach32_modes[i] = mode; continue; } if ((mach32_modes[i]->disp_cntl ^ mode->disp_cntl) & 0x10) { if (mode->disp_cntl & 0x10) { if (verbose) puts(" (rejected, is interlaced)"); continue; } else { if (verbose) puts(" (preferred, is non-interlaced)"); goto fillin; } } n_clock = mach32_clocks[0x1f & (mach32_modes[i]->clock_sel >> 2)]; n_horz = (1e3 * n_clock) / (float) (mach32_modes[i]->h_total * 8 + 8); tmp = mach32_modes[i]->v_total; if (!(mach32_modes[i]->disp_cntl & 0x6)) tmp = ((tmp >> 2) & 0xfffe) | (tmp & 1); else tmp = ((tmp >> 1) & 0xfffc) | (tmp & 3); tmp++; /* Note: both modes are either interlaced or not, hence we directly compare vsyncs */ n_vert = (n_horz * 1000) / tmp; if (n_vert < vert) { if (verbose) puts(" (higher V_SYNC preferred)"); goto fillin; } if (verbose) puts(" (rejected, have a better one already)"); }}static int mach32_modeavailable(int mode){ if (mode >= __svgalib_max_modes) return 0; if (mach32_modes[mode] == NULL) return __svgalib_vga_driverspecs.modeavailable(mode); return SVGADRV;}static void mach32_getmodeinfo(int mode, vga_modeinfo * modeinfo){ if (mode >= __svgalib_max_modes) return; modeinfo->flags |= HAVE_EXT_SET; modeinfo->haveblit = 0; if (mach32_modes[mode] == NULL) return; if (infotable[mode].bytesperpixel <= 2) modeinfo->haveblit = acc_supp; else if (emuimage & EMU_POSS) { /* imageblt can
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -