📄 rage.c
字号:
return __svgalib_vga_driverspecs.setmode(mode, prv_mode); } if (!rage_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(MAX_REGS); ATINewHWPtr=(ATIHWPtr)(moderegs+VGA_TOTAL_REGS); rage_initializemode(moderegs, modetiming, modeinfo, mode); free(modetiming); __svgalib_setregs(moderegs); rage_setregs(moderegs, mode); free(moderegs); __svgalib_InitializeAcceleratorInterface(modeinfo); free(modeinfo); return 0;}/* Unlock chipset-specific registers */static void rage_unlock(void){}static void rage_lock(void){}/* Indentify chipset, initialize and return non-zero if detected */static int rage_test(void){ int i, found; unsigned long buf[64]; if (getenv("IOPERM") == NULL) { if (iopl(3) < 0) { printf("svgalib: rage: cannot get I/O permissions\n"); exit(1); } } found=__svgalib_pci_find_vendor_vga(0x1002,buf,0); if(found)return 0; if (!found){ ATIIOBase=buf[5]&BLOCK_IO_BASE; }; if(ATIIOBase) { ATIIODecoding=BLOCK_IO; i=rage_probe(); } else { ATIIOBase=0x2EC; ATIIODecoding=SPARSE_IO; if(!(i=rage_probe())){ ATIIOBase=0x1C8; if(!(i=rage_probe())){ ATIIOBase=0x1CC; i=rage_probe(); }; }; }; if(!i)return 0; rage_init(0,0,0); return 1;}/* Set display start address (not for 16 color modes) *//* Cirrus supports any address in video memory (up to 2Mb) */static void rage_setdisplaystart(int address){ unsigned int t;address>>=3;t=inl(ATIIOPortCRTC_OFF_PITCH);outl(ATIIOPortCRTC_OFF_PITCH,(t&~CRTC_OFFSET)|address);}static void rage_setlogicalwidth(int width){ unsigned int t;if(rage_bpp>0)width=width/rage_bpp;t=inl(ATIIOPortCRTC_OFF_PITCH);outl(ATIIOPortCRTC_OFF_PITCH,(t&~CRTC_PITCH)|((width>>3)<<22));}static int rage_linear(int op, int param){if (op==LINEAR_ENABLE || op==LINEAR_DISABLE){ rage_is_linear=1-rage_is_linear; return 0;}if (op==LINEAR_QUERY_BASE) return rage_linear_base;if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0; /* No granularity or range. */ else return -1; /* Unknown function. */}static int rage_match_programmable_clock(int clock){return clock ;}static int rage_map_clock(int bpp, int clock){return clock ;}static int rage_map_horizontal_crtc(int bpp, int pixelclock, int htiming){return htiming;}/* Function table (exported) */DriverSpecs __svgalib_rage_driverspecs ={ rage_saveregs, rage_setregs, rage_unlock, rage_lock, rage_test, rage_init, rage_setpage, rage_setrdpage, rage_setwrpage, rage_setmode, rage_modeavailable, rage_setdisplaystart, rage_setlogicalwidth, rage_getmodeinfo, 0, /* old blit funcs */ 0, 0, 0, 0, 0, /* ext_set */ 0, /* accel */ rage_linear, 0, /* accelspecs, filled in during init. */ NULL, /* Emulation */};/* Initialize chipset (called after detection) */static int rage_init(int force, int par1, int par2){ unsigned long buf[64]; int found=0; int _ioperm=0; int i,j; unsigned char *BIOS; static int videoRamSizes[] = { 0 , 256 , 512 , 1024, 2*1024 , 4*1024 , 6*1024 , 8*1024 , 12*1024 , 16*1024 , 0 }; rage_unlock(); if (force) { rage_memory = par1; rage_chiptyperev = par2; } else { }; if (getenv("IOPERM") == NULL) { _ioperm=1; if (iopl(3) < 0) { printf("svgalib: rage: cannot get I/O permissions\n"); exit(1); } } found=__svgalib_pci_find_vendor_vga(0x1002,buf,0); rage_linear_base=0; if (!found){ rage_linear_base=buf[4]&0xffffff00ul; ATIIOBase=buf[5]&BLOCK_IO_BASE; }; if(ATIIOBase) { ATIIODecoding=BLOCK_IO; i=rage_probe(); } else { ATIIOBase=0x2EC; ATIIODecoding=SPARSE_IO; if(!(i=rage_probe())){ ATIIOBase=0x1C8; if(!(i=rage_probe())){ ATIIOBase=0x1CC; i=rage_probe(); }; }; }; if(found || !i){ printf("svgalib: Rage driver must be used, but not found\n"); exit(1); }; rage_chiptyperev=(buf[0]&0xffff0000) | (buf[2]&0xff); rage_ChipID(); ATIIOPortCRTC_H_TOTAL_DISP=ATIIOPort(CRTC_H_TOTAL_DISP); ATIIOPortCRTC_H_SYNC_STRT_WID=ATIIOPort(CRTC_H_SYNC_STRT_WID); ATIIOPortCRTC_V_TOTAL_DISP=ATIIOPort(CRTC_V_TOTAL_DISP); ATIIOPortCRTC_V_SYNC_STRT_WID=ATIIOPort(CRTC_V_SYNC_STRT_WID); ATIIOPortCRTC_OFF_PITCH=ATIIOPort(CRTC_OFF_PITCH); ATIIOPortCRTC_INT_CNTL=ATIIOPort(CRTC_INT_CNTL); ATIIOPortCRTC_GEN_CNTL=ATIIOPort(CRTC_GEN_CNTL); ATIIOPortDSP_CONFIG=ATIIOPort(DSP_CONFIG); ATIIOPortDSP_ON_OFF=ATIIOPort(DSP_ON_OFF); ATIIOPortOVR_CLR=ATIIOPort(OVR_CLR); ATIIOPortOVR_WID_LEFT_RIGHT=ATIIOPort(OVR_WID_LEFT_RIGHT); ATIIOPortOVR_WID_TOP_BOTTOM=ATIIOPort(OVR_WID_TOP_BOTTOM); ATIIOPortCLOCK_CNTL=ATIIOPort(CLOCK_CNTL); ATIIOPortBUS_CNTL=ATIIOPort(BUS_CNTL); ATIIOPortMEM_INFO=ATIIOPort(MEM_INFO); ATIIOPortMEM_VGA_WP_SEL=ATIIOPort(MEM_VGA_WP_SEL); ATIIOPortMEM_VGA_RP_SEL=ATIIOPort(MEM_VGA_RP_SEL); ATIIOPortDAC_REGS=ATIIOPort(DAC_REGS); ATIIOPortDAC_CNTL=ATIIOPort(DAC_CNTL); ATIIOPortGEN_TEST_CNTL=ATIIOPort(GEN_TEST_CNTL); ATIIOPortCONFIG_CNTL=ATIIOPort(CONFIG_CNTL); ATIIOPortCONFIG_STATUS64_0=ATIIOPort(CONFIG_STATUS64_0); i = inl(ATIIOPort(MEM_INFO)); j = inl(ATIIOPort(CONFIG_STATUS64_0)); if(ATIChip<ATI_CHIP_264CT) { ATIMemoryType=GetBits(j,CFG_MEM_TYPE); } else { ATIMemoryType=GetBits(j,CFG_MEM_TYPE_T); }; if(ATIChip>=ATI_CHIP_264VTB) { i = GetBits(i, CTL_MEM_SIZEB); if (i < 8) rage_memory = (i + 1) * 512; else if (i < 12) rage_memory = (i - 3) * 1024; else rage_memory = (i - 7) * 2048; } else { i = GetBits(i, CTL_MEM_SIZE); rage_memory = videoRamSizes[i+2]; }; if(ATIChip>=ATI_CHIP_264CT){ M=ATIGetMach64PLLReg(PLL_REF_DIV); minN=2; maxN=255; fref=28636; Nadj=0; if(__svgalib_ragedoubleclock)fref*=2; } else { rage_dac=(j>>9)&7; if(rage_dac==5) { rage_clock=1; M=46; minN=257; maxN=512; Nadj=257; for(i=0;i<4;i++)postdiv[i]=1<<i; for(i=4;i<8;i++)postdiv[i]=0; fref=14318; }; }; if (__svgalib_driver_report) { printf("Using RAGE driver, %iKB. ChipID:%i MemType:%i\n",rage_memory,ATIChip,ATIMemoryType); if(rage_dac)printf("Using external DAC:%i\n",rage_dac); } cardspecs = malloc(sizeof(CardSpecs)); cardspecs->videoMemory = rage_memory; switch(ATIChip){ case ATI_CHIP_264GTPRO: case ATI_CHIP_264LTPRO: cardspecs->maxPixelClock8bpp = 230000; cardspecs->maxPixelClock16bpp = 230000; cardspecs->maxPixelClock24bpp = 230000; cardspecs->maxPixelClock32bpp = 230000; break; case ATI_CHIP_264GTDVD: case ATI_CHIP_264LT: case ATI_CHIP_264VT4: case ATI_CHIP_264GT2C: case ATI_CHIP_264VT3: cardspecs->maxPixelClock8bpp = 200000; cardspecs->maxPixelClock16bpp = 200000; cardspecs->maxPixelClock24bpp = 200000; cardspecs->maxPixelClock32bpp = 200000; break; case ATI_CHIP_264VTB: case ATI_CHIP_264GTB: cardspecs->maxPixelClock8bpp = 170000; cardspecs->maxPixelClock16bpp = 170000; cardspecs->maxPixelClock24bpp = 170000; cardspecs->maxPixelClock32bpp = 170000; break; default: cardspecs->maxPixelClock8bpp = 135000; cardspecs->maxPixelClock16bpp = 80000; cardspecs->maxPixelClock24bpp = 40000; cardspecs->maxPixelClock32bpp = 40000; }; cardspecs->flags = CLOCK_PROGRAMMABLE; cardspecs->maxHorizontalCrtc = 4088; cardspecs->nClocks = 0; cardspecs->maxPixelClock4bpp = 0; cardspecs->mapClock = rage_map_clock; cardspecs->mapHorizontalCrtc = rage_map_horizontal_crtc; cardspecs->matchProgrammableClock=rage_match_programmable_clock; __svgalib_driverspecs = &__svgalib_rage_driverspecs; __svgalib_banked_mem_base=0xa0000; __svgalib_banked_mem_size=0x10000; __svgalib_linear_mem_base=rage_linear_base; __svgalib_linear_mem_size=rage_memory*0x400;#define BIOSWord(x) ((int)BIOS[x]+256*(int)BIOS[x+1]) BIOS=mmap(0,32*1024,PROT_READ|PROT_WRITE,MAP_SHARED,__svgalib_mem_fd,0xc0000); i=BIOSWord(0x48); j=BIOSWord(i+0x10); ATIClockToProgram=BIOS[j+6]; if(ATIChip>=ATI_CHIP_264CT){ M=ATIGetMach64PLLReg(PLL_REF_DIV); minN=2; maxN=255; switch (BIOSWord(j+0x08)/10) { case 143: fref=14318; break; case 286: fref=28636; break; default: fref=BIOSWord(j+0x08)*10; break; } Nadj=0; fref*=2; /* X says double for all chips */#if 0 if(__svgalib_ragedoubleclock)fref/=2; /* just in case */#endif if (__svgalib_driver_report) { printf("Rage: BIOS reports base frequency=%.3fMHz Denominator=%3i\n",fref/1000,M); } } else { rage_dac=(j>>9)&7; if(rage_dac==5) { rage_clock=1; M=46; minN=257; maxN=512; Nadj=257; for(i=0;i<4;i++)postdiv[i]=1<<i; for(i=4;i<8;i++)postdiv[i]=0; fref=14318; }; }; munmap(BIOS,32768); return 0;}#define WITHIN(v,c1,c2) (((v) >= (c1)) && ((v) <= (c2)))static unsignedcomp_lmn(unsigned clock, int *np, int *mp, int *lp){ int n, m, l; double fvco; double fout; double fvco_goal; for (m = M; m <= M; m++) { for (l = 0;(l < 8); l++) if(postdiv[l]) { for (n = minN; n <= maxN; n++) { fout = ((double)(n) * fref)/((double)(m) * (postdiv[l])); fvco_goal = (double)clock * (double)(postdiv[l]); fvco = fout * (double)(postdiv[l]); if (!WITHIN(fvco, 0.995*fvco_goal, 1.005*fvco_goal)) continue; *lp=l; *np=n-Nadj; *mp=m; return 1 ; } } }printf("Can't do clock=%i\n",clock);printf("fref=%f, M=%i, N in %i - %i\n",fref,M,minN,maxN);{int i; for (i=0;i<8;i++)printf("%i ",postdiv[i]); printf("\n");}; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -