nv3.c

来自「linux 下svgalib编的一个界面程序示例」· C语言 代码 · 共 736 行 · 第 1/2 页

C
736
字号
static int nv3_setmode(int mode, int prv_mode){    unsigned char *moderegs;    ModeTiming *modetiming;    ModeInfo *modeinfo;    int i;    if ((mode < G640x480x256 /*&& mode != G320x200x256*/)	|| mode == G720x348x2) {	unsigned int k;        if(nv3_chiptype==Riva128)            PRAMDAC_Write(PLL_COEFF_SELECT,0x00000100);            else PRAMDAC_Write(PLL_COEFF_SELECT,0x00000500);        __svgalib_outcrtc(NV_PCRTC_REPAINT0,0);        __svgalib_outcrtc(NV_PCRTC_REPAINT1,0x3d);        __svgalib_outcrtc(NV_PCRTC_EXTRA,0);        __svgalib_outcrtc(NV_PCRTC_PIXEL,0);        __svgalib_outcrtc(NV_PCRTC_HORIZ_EXTRA,0);        __svgalib_outcrtc(NV_PCRTC_FIFO_CONTROL,0x83);        __svgalib_outcrtc(0x1c,0x18);        __svgalib_outcrtc(0x1d,0);        __svgalib_outcrtc(0x1e,0);        __svgalib_outcrtc(0x30,0);        __svgalib_outcrtc(0x31,0);        k =  PRAMDAC_Read(GENERAL_CONTROL);        k &= ~0x00100000;        PRAMDAC_Write(GENERAL_CONTROL,k);	return __svgalib_vga_driverspecs.setmode(mode, prv_mode);    }    if (!nv3_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(NV3_TOTAL_REGS);    nv3_initializemode(moderegs, modetiming, modeinfo, mode);    free(modetiming);    __svgalib_setregs(moderegs);	/* Set standard regs. */    nv3_setregs(moderegs, mode);	/* Set extended regs. */    free(moderegs);    __svgalib_InitializeAcceleratorInterface(modeinfo);    for(i=0;i<256;i++)vga_setpalette(i,i,i,i);    free(modeinfo);    return 0;}/* Unlock chipset-specific registers */static void nv3_unlock(void){    __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f);    __svgalib_outseq(LOCK_EXT_INDEX,UNLOCK_EXT_MAGIC);    }static void nv4_unlock(void){    __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f);    __svgalib_outcrtc(0x1f, UNLOCK_EXT_MAGIC);}/* Relock chipset-specific registers *//* (currently not used) */static void nv3_lock(void){__svgalib_outseq(LOCK_EXT_INDEX,UNLOCK_EXT_MAGIC+1);    }/* Indentify chipset, initialize and return non-zero if detected */static int nv3_test(void){  unsigned long buf[64];   int found=0;   int _ioperm=0;   if (getenv("IOPERM") == NULL) {     _ioperm=1;     if (iopl(3) < 0) {       printf("svgalib: nv3: cannot get I/O permissions\n");       exit(1);     }   }   found=__svgalib_pci_find_vendor_vga(0x12d2,buf,0);   if (found) {      found=__svgalib_pci_find_vendor_vga(0x10de,buf,0);      if (_ioperm) iopl(0);      if(found)return 0;   };   if (_ioperm) iopl(0);   switch(buf[0]>>16){      case 0x18: nv3_chiptype=Riva128; break;      case 0x20:      case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:      case 0xA0:      case 0x28: nv3_chiptype=RivaTNT; break;      case 0x150: case 0x151: case 0x152: case 0x153:      case 0x110: case 0x111: case 0x113:      case 0x101: case 0x103:      case 0x100: nv3_chiptype=GEFORCE; break;      default: nv3_chiptype=-1;   };   if(nv3_chiptype==-1)return 0;   MMIOBASE=0;   LINEARBASE=0;   nv3_init(0,0,0);return 1;}/* No r/w paging - I guess it's possible, but is it useful? */static void nv3_setrdpage(int page){}static void nv3_setwrpage(int page){}/* Set display start address (not for 16 color modes) */static void nv3_setdisplaystart(int address){  unsigned char byte;  address=address >> 2;  __svgalib_outcrtc(0x0d,address&0xff);  __svgalib_outcrtc(0x0c,(address>>8)&0xff);  byte=PCRTC_Read(REPAINT0) & 0xe0;  PCRTC_Write(REPAINT0,((address>>16)&0x1f)|byte);  }/* Set logical scanline length (usually multiple of 8) */static void nv3_setlogicalwidth(int width){  int byte ;  __svgalib_outcrtc(0x13,(width >> 3)&0xff);  byte=PCRTC_Read(REPAINT0) & 0x1f;  PCRTC_Write(REPAINT0,SetBitField(width,13:11,7:5)|byte);}static int nv3_linear(int op, int param){if (op==LINEAR_ENABLE || op==LINEAR_DISABLE){ nv3_is_linear=1-nv3_is_linear; return 0;}if (op==LINEAR_QUERY_BASE) { return LINEARBASE ;}if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0;		/* No granularity or range. */    else return -1;		/* Unknown function. */}static int nv3_match_programmable_clock(int clock){return clock ;}static int nv3_map_clock(int bpp, int clock){return clock ;}static int nv3_map_horizontal_crtc(int bpp, int pixelclock, int htiming){return htiming;}/* Function table (exported) */DriverSpecs __svgalib_nv3_driverspecs ={    nv3_saveregs,    nv3_setregs,    nv3_unlock,    nv3_lock,    nv3_test,    nv3_init,    nv3_setpage,    nv3_setrdpage,    nv3_setwrpage,    nv3_setmode,    nv3_modeavailable,    nv3_setdisplaystart,    nv3_setlogicalwidth,    nv3_getmodeinfo,    0,				/* old blit funcs */    0,    0,    0,    0,    0,				/* ext_set */    0,				/* accel */    nv3_linear,    0				/* accelspecs, filled in during init. */};#define MapDevice(device,base) \  nv##device##Port=(unsigned*)(mmap(0, \     	DEVICE_SIZE(device),PROT_WRITE,MAP_SHARED,__svgalib_mem_fd,\        (MMIOBASE)+DEVICE_BASE(device)))/* Initialize chipset (called after detection) */static int nv3_init(int force, int par1, int par2){       char *architectures[3]={"nv3, Riva128/Riva128ZX",                            "nv4, RivaTNT/RivaTNT2",                             "nv10, GeForce"};        nv3_unlock();        if(MMIOBASE==0) {       unsigned long buf[64];       int _ioperm=0,found;              if (getenv("IOPERM") == NULL) {         _ioperm=1;         if (iopl(3) < 0) {           printf("svgalib: nv3: cannot get I/O permissions\n");           exit(1);         }       }              found=__svgalib_pci_find_vendor_vga(0x12d2,buf,0);       if (found) {          found=__svgalib_pci_find_vendor_vga(0x10de,buf,0);          if (_ioperm) iopl(0);          if(found)return 0;       } else if (_ioperm) iopl(0);       switch(buf[0]>>16){          case 0x18: nv3_chiptype=Riva128; break;          case 0x20:          case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:          case 0xA0:          case 0x28: nv3_chiptype=RivaTNT; break;          case 0x150: case 0x151: case 0x152: case 0x153:          case 0x110: case 0x111: case 0x113:          case 0x101: case 0x103:          case 0x100: nv3_chiptype=GEFORCE; break;          default: nv3_chiptype=Riva128;       };       MMIOBASE=buf[4]&0xffffff00;       LINEARBASE=buf[5]&0xffffff00;    };    if (force) {	nv3_memory = par1;	nv3_chiptype = par2;    };    MapDevice(PRAMDAC,regBase);    MapDevice(PFB,regBase);    MapDevice(PEXTDEV,regBase);         if(!force){       int boot0;              boot0=PFB_Read(BOOT_0);       switch(nv3_chiptype){          case Riva128:                 if(boot0&0x20)nv3_memory=8192; else nv3_memory=1024<<(boot0&3);                  if(nv3_memory==1024)nv3_memory=8192;                 break;          case RivaTNT:                  nv3_memory=2048<<(boot0&3);                  if(nv3_memory==2048)nv3_memory=32768;                 break;          case GEFORCE:             	 nv3_memory=16384; /* do this later */                 break;       };    };    {       int temp;              temp=PEXTDEV_Read(0);       switch(nv3_chiptype){          case Riva128:             PLL_INPUT_FREQ= (temp&0x20) ? 14318 : 13500;             break;          case RivaTNT:          case GEFORCE:             PLL_INPUT_FREQ= (temp&0x40) ? 14318 : 13500;             break;       };           };    if (__svgalib_driver_report) {	printf("Using RIVA driver, %iKB, Type:%s.\n",nv3_memory,architectures[nv3_chiptype]);    };    cardspecs = malloc(sizeof(CardSpecs));    cardspecs->videoMemory = nv3_memory;    cardspecs->maxPixelClock4bpp = 75000;    cardspecs->maxPixelClock8bpp = 230000;    cardspecs->maxPixelClock16bpp = 230000;    cardspecs->maxPixelClock24bpp = 0;    cardspecs->maxPixelClock32bpp = 230000;    cardspecs->flags = CLOCK_PROGRAMMABLE ;    cardspecs->maxHorizontalCrtc = 4088;    cardspecs->maxPixelClock4bpp = 0;    cardspecs->nClocks =0;    cardspecs->clocks = NULL;    cardspecs->mapClock = nv3_map_clock;    cardspecs->mapHorizontalCrtc = nv3_map_horizontal_crtc;    cardspecs->matchProgrammableClock=nv3_match_programmable_clock;    __svgalib_driverspecs = &__svgalib_nv3_driverspecs;        if((nv3_chiptype==RivaTNT)||(nv3_chiptype==GEFORCE))      __svgalib_driverspecs->unlock=nv4_unlock;        __svgalib_banked_mem_base=0xa0000;    __svgalib_banked_mem_size=0x10000;    __svgalib_linear_mem_base=LINEARBASE;    __svgalib_linear_mem_size=nv3_memory*0x400;    return 0;}static int NV3ClockSelect(float clockIn,float *clockOut,int *mOut,                                        int *nOut,int *pOut){   int m,n,p;  float bestDiff=1e10;  float target=0.0;  float best=0.0;  float diff;  int nMax,nMin;    *clockOut=0.0;  for(p=P_MIN;p<=P_MAX;p++) {    for(m=M_MIN;m<=M_MAX;m++) {      float fm=(float)m;      /* Now calculate maximum and minimum values for n */      nMax=(int) (((256000/PLL_INPUT_FREQ)*fm)-0.5);      nMin=(int) (((128000/PLL_INPUT_FREQ)*fm)+0.5);      n=(int)(((clockIn*((float)(1<<p)))/PLL_INPUT_FREQ)*fm);      if(n>=nMin && n<=nMax) {          float fn=(float)n;        target=(PLL_INPUT_FREQ*(fn/fm))/((float)(1<<p));        diff=fabs(target-clockIn);        if(diff<bestDiff) {          bestDiff=diff;          best=target;          *mOut=m;*nOut=n;*pOut=p;          *clockOut=best;	}      }    }  }  return (best!=0.0);    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?