📄 savage.c
字号:
OFLG_ISSET(OPTION_FIFO_CONSERV, &vga256InfoRec.options)) { new->MMPR1 = 0x0200; /* Low P. stream waits before filling */ new->MMPR2 = 0x1808; /* Let the FIFO refill itself */ new->MMPR3 = 0x08081810; /* And let the GE hold the bus for a while */ }#endif /* And setup here the new value for MCLK. We use the XConfig * option "set_mclk", whose value gets stored in vga256InfoRec.s3MClk. * I'm not sure what the maximum "permitted" value should be, probably * 100 MHz is more than enough for now. */ new->SR10 = 255; /* This is a reserved value, so we use as flag */ new->SR11 = 255; if (modeinfo->colorBits == 8) { if (dclk <= 110000) new->CR67 = 0x00; /* 8bpp, 135MHz */ else new->CR67 = 0x10; /* 8bpp, 220MHz */ } else if (modeinfo->colorBits == 15) { if (dclk <= 110000) new->CR67 = 0x20; /* 15bpp, 135MHz */ else new->CR67 = 0x30; /* 15bpp, 220MHz */ } else if (modeinfo->colorBits == 16) { if (dclk <= 110000) new->CR67 = 0x40; /* 16bpp, 135MHz */ else new->CR67 = 0x50; /* 16bpp, 220MHz */ } else if (modeinfo->colorBits == 24) { new->CR67 = 0xd0; /* 24bpp, 135MHz */ } { unsigned int m, n, r; savageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r); new->SR12 = (r << 6) | (n & 0x3F); new->SR13 = m & 0xFF; new->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2; }#if 0 /* Now adjust the value of the FIFO based upon options specified */ if(OFLG_ISSET(OPTION_FIFO_MODERATE, &vga256InfoRec.options)) { if(modeinfo->colorBits < 24) new->MMPR0 -= 0x8000; else new->MMPR0 -= 0x4000; } else if(OFLG_ISSET(OPTION_FIFO_AGGRESSIVE, &vga256InfoRec.options)) { if(modeinfo->colorBits < 24) new->MMPR0 -= 0xc000; else new->MMPR0 -= 0x6000; }#endif /* If we have an interlace mode, set the interlace bit. Note that mode * vertical timings are already adjusted by the standard VGA code */ if (modetiming->flags & INTERLACED) { new->CR42 = 0x20; /* Set interlace mode */ } else { new->CR42 = 0x00; } /* Set display fifo */ new->CR34 = 0x10; /* Now we adjust registers for extended mode timings */ /* This is taken without change from the accel/s3_virge code */ i = ((((modetiming->CrtcHTotal >> 3) - 5) & 0x100) >> 8) | ((((modetiming->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) | ((((modetiming->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) | ((modetiming->CrtcHSyncStart & 0x800) >> 7); if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 64) i |= 0x08; /* add another 64 DCLKs to blank pulse width */ if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 32) i |= 0x20; /* add another 32 DCLKs to hsync pulse width */ j = ( moderegs[0] + ((i&0x01)<<8) + moderegs[4] + ((i&0x10)<<4) + 1) / 2; if (j-(moderegs[4] + ((i&0x10)<<4)) < 4) { if (moderegs[4] + ((i&0x10)<<4) + 4 <= moderegs[0]+ ((i&0x01)<<8)) j = moderegs[4] + ((i&0x10)<<4) + 4; else j = moderegs[0]+ ((i&0x01)<<8) + 1; } new->CR3B = j & 0xFF; i |= (j & 0x100) >> 2; new->CR3C = (moderegs[0] + ((i&0x01)<<8))/2; new->CR5D = i; new->CR5E = (((modetiming->CrtcVTotal - 2) & 0x400) >> 10) | (((modetiming->CrtcVDisplay - 1) & 0x400) >> 9) | (((modetiming->CrtcVSyncStart) & 0x400) >> 8) | (((modetiming->CrtcVSyncStart) & 0x400) >> 6) | 0x40; width = modeinfo->lineWidth >> 3; moderegs[19] = 0xFF & width; new->CR51 = (0x300 & width) >> 4; /* Extension bits */ /* And finally, select clock source 2 for programmable PLL */ moderegs[VGA_MISCOUTPUT] |= 0x0c; /* Set frame buffer description */ if (modeinfo->colorBits <= 8) { new->CR50 = 0; } else { if (modeinfo->colorBits <= 16) { new->CR50 = 0x10; } else { new->CR50 = 0x30; } } if (modeinfo->width == 640) new->CR50 |= 0x40; else if (modeinfo->width == 800) new->CR50 |= 0x80; else if (modeinfo->width == 1024); else if (modeinfo->width == 1152) new->CR50 |= 0x01; else if (modeinfo->width == 1280) new->CR50 |= 0x41; else if (modeinfo->width == 2048 && new->CR31 & 2); else if (modeinfo->width == 1600) new->CR50 |= 0x81; /* TODO: need to consider bpp=4 */ else new->CR50 |= 0xC1; /* default to use GlobalBD */ new->CR33 = 0x08; /* Now we handle various XConfig memory options and others */ new->CR36 = __svgalib_incrtc(0x36); #if 0 if (mode->Private) { new->CR67 &= ~1; if( (s3vPriv.chip != S3_SAVAGE2000) && (mode->Private[0] & (1 << S3_INVERT_VCLK)) && (mode->Private[S3_INVERT_VCLK]) ) new->CR67 |= 1; if (mode->Private[0] & (1 << S3_BLANK_DELAY)) { new->CR65 = (new->CR65 & ~0x38) | (mode->Private[S3_BLANK_DELAY] & 0x07) << 3; } }#endif new->CR68 = __svgalib_incrtc(0x68); new->CR69 = 0; new->CR6F = __svgalib_incrtc(0x6f); new->CR86 = __svgalib_incrtc(0x86); new->CR88 = __svgalib_incrtc(0x88); new->CRB0 = __svgalib_incrtc(0xb0) | 0x80; return ;}static int savage_setmode(int mode, int prv_mode){ unsigned char *moderegs; ModeTiming *modetiming; ModeInfo *modeinfo; if (IS_IN_STANDARD_VGA_DRIVER(mode)) { __svgalib_outcrtc(0x34,0); return __svgalib_vga_driverspecs.setmode(mode, prv_mode); } if (!savage_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(SAVAGE_TOTAL_REGS); savage_initializemode(moderegs, modetiming, modeinfo, mode); free(modetiming); __svgalib_setregs(moderegs); /* Set standard regs. */ savage_setregs(moderegs, mode); /* Set extended regs. */ free(moderegs); __svgalib_InitializeAcceleratorInterface(modeinfo); free(modeinfo); return 0;}/* Unlock chipset-specific registers */static void savage_unlock(void){ __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f); __svgalib_outcrtc(0x38, 0x48); __svgalib_outcrtc(0x39, 0xa5); __svgalib_outcrtc(0x40,__svgalib_incrtc(0x40)&0xfe); }static void savage_lock(void){}#define VENDOR_ID 0x5333/* Indentify chipset, initialize and return non-zero if detected */static int savage_test(void){ int found; int id; unsigned long buf[64]; found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0); id=(buf[0]>>16)&0xffff; if(found)return 0; switch(id) { case 0x8a20: case 0x8a21: case 0x8a22: case 0x8a23: case 0x8c10: case 0x8c12: case 0x9102: savage_init(0,0,0); return 1; break; default: return 0; }}/* Set display start address (not for 16 color modes) *//* Cirrus supports any address in video memory (up to 2Mb) */static void savage_setdisplaystart(int address){ address=address >> 2; __svgalib_outcrtc(0x0d,address&0xff); __svgalib_outcrtc(0x0c,(address>>8)&0xff); __svgalib_outcrtc(0x69,(address>>16)&0xff); }/* Set logical scanline length (usually multiple of 8) *//* Cirrus supports multiples of 8, up to 4088 */static void savage_setlogicalwidth(int width){ int offset = width >> 3; __svgalib_outcrtc(0x13,offset&0xff);}static int savage_linear(int op, int param){ if (op==LINEAR_ENABLE){ __svgalib_outcrtc(0x58,0x13); savage_is_linear=1; return 0; }; if (op==LINEAR_DISABLE) { __svgalib_outcrtc(0x58,0); savage_is_linear=0; return 0; }; if (op==LINEAR_QUERY_BASE) return savage_linear_base; if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0; /* No granularity or range. */ else return -1; /* Unknown function. */}static int savage_match_programmable_clock(int clock){return clock ;}static int savage_map_clock(int bpp, int clock){return clock ;}static int savage_map_horizontal_crtc(int bpp, int pixelclock, int htiming){return htiming;}/* Function table (exported) */DriverSpecs __svgalib_savage_driverspecs ={ savage_saveregs, savage_setregs, savage_unlock, savage_lock, savage_test, savage_init, savage_setpage, NULL, NULL, savage_setmode, savage_modeavailable, savage_setdisplaystart, savage_setlogicalwidth, savage_getmodeinfo, 0, /* old blit funcs */ 0, 0, 0, 0, 0, /* ext_set */ 0, /* accel */ savage_linear, 0, /* accelspecs, filled in during init. */ NULL, /* Emulation */};/* Initialize chipset (called after detection) */static int savage_init(int force, int par1, int par2){ unsigned long buf[64]; unsigned long savage_mmio_base; int found=0, config1; int mems[8]={2,4,8,12,16,32,64,2}; char *chipnames[6] = {"Unknown", "Savage3D", "SavageMX", "Savage4", "SavagePro", "Savage2000"}; int id; savage_unlock(); if (force) { savage_memory = par1; savage_chipset = par2; } else { }; found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0); savage_linear_base=buf[5]&0xffffff00; savage_mmio_base =buf[4]&0xffffff00; config1=__svgalib_incrtc(0x36);#if 0 id=__svgalib_incrtc(0x2e) | (__svgalib_incrtc(0x2d)<<8)#else id=(buf[0]>>16)&0xffff;#endif switch(id) { case 0x8a20: case 0x8a21: savage_chipset = SAVAGE3D; break; case 0x8c10: case 0x8c12: savage_chipset = SAVAGEMX; break; case 0x8a22: case 0x8a23: savage_chipset = SAVAGE4; break; case 0x9102: savage_chipset = SAVAGE2000; break; default: savage_chipset = UNKNOWN; } if(savage_chipset >= SAVAGE4) { savage_memory=mems[config1>>5]*1024; } else { switch(config1>>6) { case 0: savage_memory=8192; break; case 0x40: case 0x80: savage_memory=4096; break; case 0xC0: savage_memory=2048; break; } } if (__svgalib_driver_report) { printf("Using SAVAGE driver, %iKB. Chipset: %s\n",savage_memory, chipnames[savage_chipset]); }; cardspecs = malloc(sizeof(CardSpecs)); cardspecs->videoMemory = savage_memory; cardspecs->maxPixelClock4bpp = 0; cardspecs->maxPixelClock8bpp = 250000; cardspecs->maxPixelClock16bpp = 250000; cardspecs->maxPixelClock24bpp = 220000; cardspecs->maxPixelClock32bpp = 220000; cardspecs->flags = INTERLACE_DIVIDE_VERT | CLOCK_PROGRAMMABLE; cardspecs->maxHorizontalCrtc = 4088; cardspecs->nClocks =0; cardspecs->mapClock = savage_map_clock; cardspecs->mapHorizontalCrtc = savage_map_horizontal_crtc; cardspecs->matchProgrammableClock=savage_match_programmable_clock; __svgalib_driverspecs = &__svgalib_savage_driverspecs; __svgalib_banked_mem_base=0xa0000; __svgalib_banked_mem_size=0x10000; __svgalib_linear_mem_base=savage_linear_base; __svgalib_linear_mem_size=savage_memory*0x400; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -