⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 neo.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
    break;  case 15:  case 16:    if (modeinfo->greenWeight == 5){ /* 15bpp */      for (i = 0; i < 64; i++){        moderegs[DAC + i*3+0] = i << 1;        moderegs[DAC + i*3+1] = i << 1;        moderegs[DAC + i*3+2] = i << 1;      }      moderegs[ExtColorModeSelect] = 0x12;    } else { /* 16bpp */      for (i = 0; i < 64; i++){	moderegs[DAC + i*3+0] = i << 1;	moderegs[DAC + i*3+1] = i;	moderegs[DAC + i*3+2] = i << 1;      }      moderegs[ExtColorModeSelect] = 0x13;    }    break;  case 24:    for (i = 0; i < 256; i++){      moderegs[DAC + i*3+0] = i;      moderegs[DAC + i*3+1] = i;      moderegs[DAC + i*3+2] = i;    }    moderegs[ExtColorModeSelect] = 0x14;    break;  }  moderegs[ExtCRTDispAddr] = 0x10;#if 0  /* Vertical Extension */  moderegs[VerticalExt] = (((modetiming->CrtcVTotal -2) & 0x400) >> 10 )    | (((modetiming->CrtcVDisplay -1) & 0x400) >> 9 )    | (((modetiming->CrtcVSyncStart) & 0x400) >> 8 )    | (((modetiming->CrtcVSyncStart) & 0x400) >> 7 );#endif  /* Disable read/write bursts if requested. */#ifdef NEO_PCI_BURST  moderegs[SysIfaceCntl1] = 0x30;#else /* NEO_PCI_BURST */  moderegs[SysIfaceCntl1] = 0x00;#endif /* NEO_PCI_BURST */  /* If they are used, enable linear addressing and/or enable MMIO. */  moderegs[SysIfaceCntl2] = 0x00;  moderegs[SysIfaceCntl2] |= 0x80; /* Linear */#if 0  moderegs[SysIfaceCntl2] |= 0x40; /* MMIO */#endif  moderegs[PanelDispCntlReg1] = 0x00;  moderegs[PanelDispCntlReg1] |= 0x02; /* Enable internal display */#if 0  moderegs[PanelDispCntlReg1] |= 0x01; /* Enable external display */#endif  /* If we are using a fixed mode, then tell the chip we are. */  switch (modetiming->HDisplay) {  case 1280:    moderegs[PanelDispCntlReg1] |= 0x60;    break;  case 1024:    moderegs[PanelDispCntlReg1] |= 0x40;    break;  case 800:    moderegs[PanelDispCntlReg1] |= 0x20;    break;  case 640:    break;  }  /* Setup shadow register locking. */  moderegs[GeneralLockReg] = 0x01;  moderegs[PanelDispCntlReg2] = 0x00;  moderegs[PanelDispCntlReg3] = 0x00;  /*   * If the screen is to be centerd, turn on the centering for the   * various modes.   */  moderegs[PanelVertCenterReg1] = 0x00;  moderegs[PanelVertCenterReg2] = 0x00;  moderegs[PanelVertCenterReg3] = 0x00;  moderegs[PanelVertCenterReg4] = 0x00;  moderegs[PanelVertCenterReg5] = 0x00;  moderegs[PanelHorizCenterReg1] = 0x00;  moderegs[PanelHorizCenterReg2] = 0x00;  moderegs[PanelHorizCenterReg3] = 0x00;  moderegs[PanelHorizCenterReg4] = 0x00;  moderegs[PanelHorizCenterReg5] = 0x00;  if (moderegs[PanelDispCntlReg1] & 0x02){    if (modetiming->HDisplay < NeoPanelWidth){      moderegs[PanelDispCntlReg3] |= 0x10;      hoffset = ((NeoPanelWidth - modetiming->HDisplay) >> 4) - 1;      moderegs[PanelHorizCenterReg1] = hoffset;      switch (modetiming->HDisplay){      case  320:	moderegs[PanelHorizCenterReg3] = hoffset;	break;      case  400:	moderegs[PanelHorizCenterReg4] = hoffset;	break;      case  640:	moderegs[PanelHorizCenterReg1] = hoffset;	break;      case  800:	moderegs[PanelHorizCenterReg2] = hoffset;	break;      case 1024:	moderegs[PanelHorizCenterReg5] = hoffset;	break;      case 1280:	/* No centering in these modes. */	break;      }    }    if (modetiming->VDisplay < NeoPanelHeight){      moderegs[PanelDispCntlReg2] |= 0x01;      voffset = ((NeoPanelHeight - modetiming->VDisplay) >> 1) - 2;      moderegs[PanelVertCenterReg2]  = voffset;      switch (modetiming->VDisplay){      case 240:	moderegs[PanelVertCenterReg2]  = voffset;	break;      case 300: case 384:	moderegs[PanelVertCenterReg1]  = voffset;	break;      case 480:	moderegs[PanelVertCenterReg3]  = voffset;	break;      case 600:	moderegs[PanelVertCenterReg4]  = voffset;	break;      case 768:	moderegs[PanelVertCenterReg5]  = voffset;	break;      case 1280:	/* No centering in these modes. */	break;      }    }  }#if 0  /*   * Calculate the VCLK that most closely matches the requested dot   * clock.   */  NeoCalcVCLK(modetiming->pixelClock, moderegs);#endif  /* Since we program the clocks ourselves, always use VCLK3. */  moderegs[MIS] |= 0x0C;  return ;}static int neo_setmode(int mode, int prv_mode){    unsigned char *moderegs;    ModeTiming *modetiming;    ModeInfo *modeinfo;#ifdef DEBUG    fprintf(stderr, "neo_setmode: %d\n", mode);#endif    if ((mode < G640x480x256)||(mode==G720x348x2)) {	return __svgalib_vga_driverspecs.setmode(mode, prv_mode);    }    if (!neo_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(NEO_TOTAL_REGS);    neo_initializemode(moderegs, modetiming, modeinfo, mode);    free(modetiming);    __svgalib_setregs(moderegs);	/* Set standard regs. */    neo_setregs(moderegs, mode);		/* Set extended regs. */    free(moderegs);    __svgalib_InitializeAcceleratorInterface(modeinfo);    free(modeinfo);    return 0;}/* Unlock chipset-specific registers */static void neo_unlock(void){    int temp;#ifdef DEBUG    fprintf(stderr, "neo_unlock\n");#endif    outb(vgaIOBase + 4, 0x11);    temp = inb(vgaIOBase + 5);    outb(vgaIOBase + 5, temp & 0x7F);    outw(GRAX, 0x2609); /* Unlock NeoMagic registers */}static void neo_lock(void){    int temp;#ifdef DEBUG    fprintf(stderr, "neo_lock\n");#endif    outb(vgaIOBase + 4, 0x11);    temp = inb(vgaIOBase + 5);    outb(vgaIOBase + 5, temp | 0x80);    outw(GRAX, 0x0009); /* Lock NeoMagic registers */}/* Indentify chipset, initialize and return non-zero if detected */static int neo_test(void){    unsigned long buf[64];    int found=0;    int _ioperm=0;        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 == 0){ /* found */      switch ((buf[0] >> 16) & 0xffff){      case PCI_CHIP_NM2070: case PCI_CHIP_NM2090: case PCI_CHIP_NM2093:      case PCI_CHIP_NM2097: case PCI_CHIP_NM2160: case PCI_CHIP_NM2200:       neo_init(0,0,0);       return (TRUE);      }    }    return (FALSE);}/* Set display start address (not for 16 color modes) *//* Cirrus supports any address in video memory (up to 2Mb) */static void neo_setdisplaystart(int address){   int oldExtCRTDispAddr;#ifdef DEBUG  fprintf(stderr, "neo_setdisplaystart: 0x%x\n", address);#endif  address=address >> 2;  outw(vgaIOBase + 4, (address & 0x00FF00) | 0x0C);  outw(vgaIOBase + 4, ((address & 0x00FF) << 8) | 0x0D);  outb(GRAX, 0x0E);  oldExtCRTDispAddr = inb(GRAX+1);  outw(GRAX,       ((((address >> 16) & 0x07) | (oldExtCRTDispAddr & 0xf8)) << 8) | 0x0E);}/* Set logical scanline length (usually multiple of 8) *//* Cirrus supports multiples of 8, up to 4088 */static void neo_setlogicalwidth(int width){       int offset = width >> 3; #ifdef DEBUG    fprintf(stderr, "neo_setlogicalwidth: %d\n", width);#endif    __svgalib_outCR(0x13,offset&0xff);    outb(GRAX, 0x0F);     outb(GRAX+1, width >> 11);}static int neo_linear(int op, int param){#ifdef DEBUG    fprintf(stderr, "neo_linear: %d\n", op);#endif    if (op==LINEAR_ENABLE){neo_is_linear=1; return 0;};    if (op==LINEAR_DISABLE){neo_is_linear=0; return 0;};    if (op==LINEAR_QUERY_BASE) return neo_linear_base;    if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0;		/* No granularity or range. */        else return -1;		/* Unknown function. */}static int neo_match_programmable_clock(int clock){return clock ;}static int neo_map_clock(int bpp, int clock){return clock ;}static int neo_map_horizontal_crtc(int bpp, int pixelclock, int htiming){return htiming;}/* Function table (exported) */DriverSpecs __svgalib_neo_driverspecs ={    neo_saveregs,    neo_setregs,#if 1    neo_unlock,    neo_lock,#else    0,    0,#endif    neo_test,    neo_init,    neo_setpage,    neo_setrdpage,    neo_setwrpage,    neo_setmode,    neo_modeavailable,    neo_setdisplaystart,    neo_setlogicalwidth,    neo_getmodeinfo,    0,				/* old blit funcs */    0,    0,    0,    0,    0,				/* ext_set */    0,				/* accel */    neo_linear,    0,				/* accelspecs, filled in during init. */    NULL,                       /* Emulation */};/* Initialize chipset (called after detection) */static int neo_init(int force, int par1, int par2){    unsigned long buf[64];    int found=0;    int _ioperm=0;    int w;    vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;    neo_unlock();    if (force) {	neo_memory = par1;        NeoChipset = par2;    } else {      neo_memory = -1;      NeoChipset = -1;    };    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);    neo_linear_base=0;    if (!found){ /* found */      neo_linear_base=buf[4]&0xffffff00;      if (NeoChipset < 0)	NeoChipset = (buf[0] >> 16) & 0xffff;      if (neo_memory < 0){	switch (NeoChipset){	case PCI_CHIP_NM2070:	  neo_memory = 896;	  break;	case PCI_CHIP_NM2090: case PCI_CHIP_NM2093: case PCI_CHIP_NM2097:	  neo_memory = 1152;	  break;	case PCI_CHIP_NM2160:	  neo_memory = 2048;	  break;	case PCI_CHIP_NM2200:	  neo_memory = 2560;	  break;	default:	  neo_memory = 0;	}      }    }    if (__svgalib_driver_report) {	printf("Using NeoMagic driver, %iKB. ",neo_memory);    };    cardspecs = malloc(sizeof(CardSpecs));    cardspecs->videoMemory = neo_memory;    cardspecs->maxPixelClock4bpp = 75000;    switch (NeoChipset){    case PCI_CHIP_NM2070:      cardspecs->maxPixelClock8bpp = 65000;      cardspecs->maxPixelClock16bpp = 65000;      cardspecs->maxPixelClock24bpp = 0;      cardspecs->maxPixelClock32bpp = 0;      break;    case PCI_CHIP_NM2090: case PCI_CHIP_NM2093: case PCI_CHIP_NM2097:      cardspecs->maxPixelClock8bpp = 80000;      cardspecs->maxPixelClock16bpp = 80000;      cardspecs->maxPixelClock24bpp = 80000;      cardspecs->maxPixelClock32bpp = 0;      break;    case PCI_CHIP_NM2160:      cardspecs->maxPixelClock8bpp = 90000;      cardspecs->maxPixelClock16bpp = 90000;      cardspecs->maxPixelClock24bpp = 90000;      cardspecs->maxPixelClock32bpp = 0;      break;    case PCI_CHIP_NM2200:      cardspecs->maxPixelClock8bpp = 110000;      cardspecs->maxPixelClock16bpp = 110000;      cardspecs->maxPixelClock24bpp = 110000;      cardspecs->maxPixelClock32bpp = 0;      break;    }    /* Determine panel width -- used in NeoValidMode. */    outb(GRAX, 0x20);    w = inb(GRAX+1);    switch ((w & 0x18) >> 3){    case 0x00:	NeoPanelWidth  = 640;	NeoPanelHeight = 480;	break;    case 0x01:	NeoPanelWidth  = 800;#ifdef LIBRETTO100	NeoPanelHeight = 480;#else /* LIBRETTO100 */	NeoPanelHeight = 600;#endif /* LIBRETTO100 */	break;    case 0x02:	NeoPanelWidth  = 1024;	NeoPanelHeight = 768;	break;    case 0x03:	NeoPanelWidth  = 1280;	NeoPanelHeight = 1024;	break;    default :	NeoPanelWidth  = 640;	NeoPanelHeight = 480;    }    cardspecs->flags = INTERLACE_DIVIDE_VERT | CLOCK_PROGRAMMABLE;    cardspecs->maxHorizontalCrtc = 2040;    cardspecs->maxPixelClock4bpp = 0;    cardspecs->nClocks =0;    cardspecs->mapClock = neo_map_clock;    cardspecs->mapHorizontalCrtc = neo_map_horizontal_crtc;    cardspecs->matchProgrammableClock=neo_match_programmable_clock;    __svgalib_driverspecs = &__svgalib_neo_driverspecs;    __svgalib_banked_mem_base=0xa0000;    __svgalib_banked_mem_size=0x10000;    __svgalib_linear_mem_base=neo_linear_base;    __svgalib_linear_mem_size=neo_memory*0x400;    neo_is_linear = FALSE;    return 0;}

⌨️ 快捷键说明

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