📄 i740.c
字号:
p_best = p = log(MAX_VCO_FREQ/f_target)/log((double)2); d_best = d = 0; f_vco = f_target * (1 << p); n = 2; do { n++; m = f_vco / (REF_FREQ / (double)n) / (double)4.0 + 0.5; if (m < 3) m = 3; f_out = CALC_VCLK(m,n,p,d); f_err = 1.0 - (f_target/f_out); if (fabs(f_err) < err_max) { m_best = m; n_best = n; err_best = f_err; } } while ((fabs(f_err) >= err_target) && ((n <= TARGET_MAX_N) || (fabs(err_best) > err_max))); if (fabs(f_err) < err_target) { m_best = m; n_best = n; } *M = (m_best-2) & 0xFF; *N = (n_best-2) & 0xFF; *MN = ((((n_best-2) >> 4) & VCO_N_MSBS) | (((m_best-2) >> 8) & VCO_M_MSBS)); *DIVSEL= ((p_best << 4) | (d_best ? 4 : 0) | REF_DIV_1);#if 0 printf("Setting dot clock to %.6lf MHz " "[ %02X %02X %02X ] " "[ %d %d %d %d ]\n", CALC_VCLK(m_best,n_best,p_best,d_best), new->VideoClk2_M, new->VideoClk2_N, new->VideoClk2_DivisorSel, m_best, n_best, p_best, d_best);#endif}/* Local, called by i740_setmode(). */static void i740_initializemode(unsigned char *moderegs, ModeTiming * modetiming, ModeInfo * modeinfo, int mode){ vgaI740Ptr new; int n, m, mn, divsel; __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo); new = (vgaI740Ptr)(moderegs+VGA_TOTAL_REGS); moderegs[0x13] = modeinfo->lineWidth >> 3; new->ExtOffset = modeinfo->lineWidth >> 11; switch (modeinfo->bitsPerPixel) { case 8: new->PixelPipeCfg1 = DISPLAY_8BPP_MODE; break; case 15: case 16: if (modeinfo->greenWeight == 5) { new->PixelPipeCfg1 = DISPLAY_15BPP_MODE; } else { new->PixelPipeCfg1 = DISPLAY_16BPP_MODE; } break; case 24: new->PixelPipeCfg1 = DISPLAY_24BPP_MODE; break; case 32: new->PixelPipeCfg1 = DISPLAY_32BPP_MODE; break; default: break; } if (modeinfo->bitsPerPixel>8) new->PixelPipeCfg0 = DAC_8_BIT; else new->PixelPipeCfg0 = DAC_6_BIT; new->PixelPipeCfg2 = 0; /* Turn on Extended VGA Interpretation */ new->IOControl = EXTENDED_CRTC_CNTL; /* Turn on linear and page mapping */ new->AddressMapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE; /* Turn on GUI mode */ new->DisplayControl = HIRES_MODE; /* Set the MCLK freq */ if (0) new->PLLControl = PLL_MEMCLK__66667KHZ; /* 66 MHz */ else new->PLLControl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */ /* Calculate the extended CRTC regs */ new->ExtVertTotal = (modetiming->CrtcVTotal - 2) >> 8; new->ExtVertDispEnd = (modetiming->CrtcVDisplay - 1) >> 8; new->ExtVertSyncStart = modetiming->CrtcVSyncStart >> 8; new->ExtVertBlankStart = modetiming->CrtcVSyncStart >> 8; new->ExtHorizTotal = ((modetiming->CrtcHTotal >> 3) - 5) >> 8; new->ExtHorizBlank = ((modetiming->CrtcHSyncEnd >> 3) & 0x40) >> 6; /* Turn on interlaced mode if necessary */ if (modetiming->flags & INTERLACED) new->InterlaceControl = INTERLACE_ENABLE; else new->InterlaceControl = INTERLACE_DISABLE; moderegs[0x11] = 0; I740CalcVCLK(modetiming->pixelClock/1000, &m, &n, &mn, &divsel); new->VideoClk2_M = m; new->VideoClk2_N = n; new->VideoClk2_MN_MSBs = mn; new->VideoClk2_DivisorSel = divsel; /* Since we program the clocks ourselves, always use VCLK2. */ moderegs[59] |= 0x0C; new->ExtStartAddr=0; new->ExtStartAddrHi=0; /* Calculate the FIFO Watermark and Burst Length. */ new->LMI_FIFO_Watermark = I740CalcFIFO(modetiming->pixelClock/1000,modeinfo->bitsPerPixel); return ;}static int i740_setmode(int mode, int prv_mode){ unsigned char *moderegs; ModeTiming *modetiming; ModeInfo *modeinfo; if ((mode < G640x480x256)||(mode==G720x348x2)) { return __svgalib_vga_driverspecs.setmode(mode, prv_mode); } if (!i740_modeavailable(mode)) return 1; modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode); modetiming = malloc(sizeof(ModeTiming)); if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) { free(modetiming); free(modeinfo); return 1; } moderegs = malloc(I740_TOTAL_REGS); i740_initializemode(moderegs, modetiming, modeinfo, mode); free(modetiming); __svgalib_setregs(moderegs); /* Set standard regs. */ i740_setregs(moderegs, mode); /* Set extended regs. */ free(moderegs); __svgalib_InitializeAcceleratorInterface(modeinfo); free(modeinfo); return 0;}/* Unlock chipset-specific registers */static void i740_unlock(void){ int vgaIOBase, temp; vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0; outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5); outb(vgaIOBase + 5, temp & 0x7F); }static void i740_lock(void){ int vgaIOBase, temp; vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0; outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5); outb(vgaIOBase + 5, temp & 0x7F); }#define VENDOR_ID 0x8086#define I740_ID_PCI 0x00d1#define I740_ID_AGP 0x7800/* Indentify chipset, initialize and return non-zero if detected */static int i740_test(void){ int _ioperm=0,found; long buf[64]; if (getenv("IOPERM") == NULL) { _ioperm=1; if (iopl(3) < 0) { printf("svgalib: cannot get I/O permissions\n"); exit(1); } } found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0); if (_ioperm) iopl(0); if(!found&& ((((buf[0]>>16)&0xffff)==I740_ID_PCI)|| (((buf[0]>>16)&0xffff)==I740_ID_AGP))){ i740_init(0,0,0); return 1; }; return 0;}/* Set display start address (not for 16 color modes) *//* Cirrus supports any address in video memory (up to 2Mb) */static void i740_setdisplaystart(int address){ address=address >> 2; outw(CRT_IC, (address & 0x00FF00) | 0x0C); outw(CRT_IC, ((address & 0x00FF) << 8) | 0x0D); __svgalib_outCR(EXT_START_ADDR_HI,(address&0x3fc00000)>>22); __svgalib_outCR(EXT_START_ADDR,((address&0x3f0000)>>16)|EXT_START_ADDR_ENABLE);}/* Set logical scanline length (usually multiple of 8) *//* Cirrus supports multiples of 8, up to 4088 */static void i740_setlogicalwidth(int width){ int offset = width >> 3; __svgalib_outCR(0x13,offset&0xff);}static int i740_linear(int op, int param){ if (op==LINEAR_ENABLE){i740_is_linear=1; return 0;}; if (op==LINEAR_DISABLE){i740_is_linear=0; return 0;}; if (op==LINEAR_QUERY_BASE) return i740_linear_base; if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0; /* No granularity or range. */ else return -1; /* Unknown function. */}static int i740_match_programmable_clock(int clock){return clock ;}static int i740_map_clock(int bpp, int clock){return clock ;}static int i740_map_horizontal_crtc(int bpp, int pixelclock, int htiming){return htiming;}/* Function table (exported) */DriverSpecs __svgalib_i740_driverspecs ={ i740_saveregs, i740_setregs, i740_unlock, i740_lock, i740_test, i740_init, i740_setpage, NULL, NULL, i740_setmode, i740_modeavailable, i740_setdisplaystart, i740_setlogicalwidth, i740_getmodeinfo, 0, /* old blit funcs */ 0, 0, 0, 0, 0, /* ext_set */ 0, /* accel */ i740_linear, 0, /* accelspecs, filled in during init. */ NULL, /* Emulation */};/* Initialize chipset (called after detection) */static int i740_init(int force, int par1, int par2){ unsigned long buf[64]; int found=0; int _ioperm=0; int temp; i740_unlock(); if (force) { i740_memory = par1;/* i740_chiptype = par2;*/ } else { outb(XRX, DRAM_ROW_TYPE); if ((inb(XRX+1) & DRAM_ROW_1) == DRAM_ROW_1_SDRAM) outb(XRX, DRAM_ROW_BNDRY_1); else outb(XRX, DRAM_ROW_BNDRY_0); i740_memory = inb(XRX+1)*1024; }; outb(XRX, DRAM_ROW_CNTL_LO); temp = inb(XRX+1); I740HasSGRAM = !((temp & DRAM_RAS_TIMING) || (temp & DRAM_RAS_PRECHARGE)); if (getenv("IOPERM") == NULL) { _ioperm=1; if (iopl(3) < 0) { printf("svgalib: cannot get I/O permissions\n"); exit(1); } } found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0); if (_ioperm) iopl(0); i740_linear_base=0; if(!found&&((((buf[0]>>16)&0xffff)==I740_ID_PCI)||(((buf[0]>>16)&0xffff)==I740_ID_AGP))){ i740_linear_base=buf[4]&0xffffff00; i740_mmio_base=buf[5]&0xffffff00; }; if (__svgalib_driver_report) { printf("Using I740 driver, %iKB.\n",i740_memory); }; cardspecs = malloc(sizeof(CardSpecs)); cardspecs->videoMemory = i740_memory; cardspecs->maxPixelClock4bpp = 75000; cardspecs->maxPixelClock8bpp = 203000; cardspecs->maxPixelClock16bpp = 163000; cardspecs->maxPixelClock24bpp = 128000; cardspecs->maxPixelClock32bpp = 86000; cardspecs->flags = CLOCK_PROGRAMMABLE; cardspecs->maxHorizontalCrtc = 4088; cardspecs->maxPixelClock4bpp = 0; cardspecs->nClocks =0; cardspecs->mapClock = i740_map_clock; cardspecs->mapHorizontalCrtc = i740_map_horizontal_crtc; cardspecs->matchProgrammableClock=i740_match_programmable_clock; __svgalib_driverspecs = &__svgalib_i740_driverspecs; __svgalib_banked_mem_base=0xa0000; __svgalib_banked_mem_size=0x10000; __svgalib_linear_mem_base=i740_linear_base; __svgalib_linear_mem_size=i740_memory*0x400; __svgalib_mmio_base=i740_mmio_base; __svgalib_mmio_size=512*0x400; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -