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

📄 neo.c

📁 linux 下svgalib编的一个界面程序示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    NeoMagic chipset driver 	Written by Shigehiro Nomura <s.nomura@mba.nifty.ne.jp>Does not support external screen.Remarks:Problem: The modes whose width is longer than the width of LCD panel         are also reported by vgatest, but not displaying properly. --> Please do not select such modes :-)Note:  When use Toshiba Libretto100,110, please define "LIBRETTO100" at  line 19 in src/neo.c  And add the following lines to libvga.config  -------------------------------------------------------------------   HorizSync 31.5 70   VertRefresh 50 100   Modeline "800x480"   50  800  856  976 1024   480  483  490  504 +hsync+vsync   newmode  800 480 256       800 1   newmode  800 480 32768    1600 2   newmode  800 480 65536    1600 2   newmode  800 480 16777216 2400 3  -------------------------------------------------------------------*/#include <stdlib.h>#include <stdio.h>		#include <string.h>#include <unistd.h>#include "vga.h"#include "libvga.h"#include "driver.h"#include "timing.h"#include "vgaregs.h"#include "interface.h"#include "accel.h"#include "vgapci.h"#undef DEBUG#undef NEO_PCI_BURST#undef LIBRETTO100  /* Define if Toshiba Libretto100/110 */#define TRUE (1)#define FALSE (0)#define VENDOR_ID 0x10c8   /* NeoMagic */#define PCI_CHIP_NM2070		0x0001#define PCI_CHIP_NM2090		0x0002#define PCI_CHIP_NM2093		0x0003#define PCI_CHIP_NM2097		0x0083#define PCI_CHIP_NM2160		0x0004#define PCI_CHIP_NM2200		0x0005#define GRAX	  0x3ce#define NEO_EXT_CR_MAX 0x85#define NEO_EXT_GR_MAX 0xC7#define NEOREG_SAVE(i) (VGA_TOTAL_REGS+i)#define  GeneralLockReg       NEOREG_SAVE(0)   /* GRAX(0x0a) */#define  ExtCRTDispAddr       NEOREG_SAVE(1)   /* GRAX(0x0e) */#define  ExtCRTOffset         NEOREG_SAVE(2)   /* GRAX(0x0f) */#define  SysIfaceCntl1        NEOREG_SAVE(3)   /* GRAX(0x10) */#define  SysIfaceCntl2        NEOREG_SAVE(4)   /* GRAX(0x11) */#define  SingleAddrPage       NEOREG_SAVE(5)   /* GRAX(0x15) */#define  DualAddrPage         NEOREG_SAVE(6)   /* GRAX(0x16) */#define  PanelDispCntlReg1    NEOREG_SAVE(7)   /* GRAX(0x20) */#define  PanelDispCntlReg2    NEOREG_SAVE(8)   /* GRAX(0x25) */#define  PanelDispCntlReg3    NEOREG_SAVE(9)   /* GRAX(0x30) */#define  PanelVertCenterReg1  NEOREG_SAVE(10)  /* GRAX(0x28) */#define  PanelVertCenterReg2  NEOREG_SAVE(11)  /* GRAX(0x29) */#define  PanelVertCenterReg3  NEOREG_SAVE(12)  /* GRAX(0x2a) */#define  PanelVertCenterReg4  NEOREG_SAVE(13)  /* GRAX(0x32) */#define  PanelVertCenterReg5  NEOREG_SAVE(14)  /* GRAX(0x37) */#define  PanelHorizCenterReg1 NEOREG_SAVE(15)  /* GRAX(0x33) */#define  PanelHorizCenterReg2 NEOREG_SAVE(16)  /* GRAX(0x34) */#define  PanelHorizCenterReg3 NEOREG_SAVE(17)  /* GRAX(0x35) */#define  PanelHorizCenterReg4 NEOREG_SAVE(18)  /* GRAX(0x36) */#define  PanelHorizCenterReg5 NEOREG_SAVE(19)  /* GRAX(0x38) */#define  ExtColorModeSelect   NEOREG_SAVE(20)  /* GRAX(0x90) */#define  VCLK3NumeratorLow    NEOREG_SAVE(21)  /* GRAX(0x9b) */#define  VCLK3NumeratorHigh   NEOREG_SAVE(22)  /* GRAX(0x8f) */#define  VCLK3Denominator     NEOREG_SAVE(23)  /* GRAX(0x9f) */#define  VerticalExt          NEOREG_SAVE(24)#define  EXT_SAVED            NEOREG_SAVE(25)  /* EXT regs. saved ? */#define   EXTCR               NEOREG_SAVE(26)              /* CR(0x00..) */#define   EXTGR               (EXTCR + NEO_EXT_CR_MAX + 1) /* GR(0x00..) */#define  DAC                  (EXTGR + NEO_EXT_GR_MAX + 1) /* DAC */#define NEO_TOTAL_REGS  (DAC + 768)#define DACDelay \	{ \		unsigned char temp = inb(vgaIOBase + 0x0A); \		temp = inb(vgaIOBase + 0x0A); \	}static int neo_init(int, int, int);static void neo_unlock(void);static void neo_lock(void);static int neo_memory;static int NeoChipset;static int NeoPanelWidth, NeoPanelHeight;static int neo_is_linear, neo_linear_base;static int vgaIOBase;static CardSpecs *cardspecs;static void neo_setpage(int page){#ifdef DEBUG  fprintf(stderr, "neo_setpage: %d\n", page);#endif  outb(GRAX, 0x11);  outw(GRAX, ((inb(GRAX+1) & 0xfc) << 8) | 0x11);  outw(GRAX, (page << 10) | 0x15); /* set read/write bank */}static void neo_setrdpage(int page){#ifdef DEBUG  fprintf(stderr, "neo_setrdpage: %d\n", page);#endif  outb(GRAX, 0x11);  outw(GRAX, (((inb(GRAX+1) & 0xfc) | 0x01) << 8) | 0x11);  outw(GRAX, (page << 10) | 0x15); /* set read bank */}static void neo_setwrpage(int page){#ifdef DEBUG  fprintf(stderr, "neo_setwrpage: %d\n", page);#endif  outb(GRAX, 0x11);  outw(GRAX, (((inb(GRAX+1) & 0xfc) | 0x01) << 8) | 0x11);  outw(GRAX, (page << 10) | 0x16); /* set write bank */}static int __svgalib_neo_inlinearmode(void){#ifdef DEBUG  fprintf(stderr, "neo_inlinearmode\n");#endifreturn neo_is_linear;}/* Fill in chipset specific mode information */static void neo_getmodeinfo(int mode, vga_modeinfo *modeinfo){#ifdef DEBUG    fprintf(stderr, "neo_getmodeinfo: %d\n", mode);#endif    if(modeinfo->colors==16)return;    modeinfo->maxpixels = neo_memory*1024/modeinfo->bytesperpixel;    if (NeoChipset == PCI_CHIP_NM2200)      modeinfo->maxlogicalwidth = 1280;    else      modeinfo->maxlogicalwidth = 1024;    modeinfo->startaddressrange = neo_memory * 1024 - 1;    modeinfo->haveblit = 0;    modeinfo->flags |= HAVE_RWPAGE;#if 1    if (modeinfo->bytesperpixel >= 1) {	if(neo_linear_base)modeinfo->flags |= CAPABLE_LINEAR;        if (__svgalib_neo_inlinearmode())	    modeinfo->flags |= IS_LINEAR;    }#endif}/* Read and save chipset-specific registers */static int neo_saveregs(unsigned char regs[]){   int i;#ifdef DEBUG  fprintf(stderr, "neo_saveregs\n");#endif  neo_unlock();  outw(GRAX, 0x0015);   /* bank#0 */  outb(GRAX, 0x0a); regs[GeneralLockReg] = inb(GRAX + 1);  outb(GRAX, 0x0e); regs[ExtCRTDispAddr] = inb(GRAX + 1);  outb(GRAX, 0x0f); regs[ExtCRTOffset] = inb(GRAX + 1);  outb(GRAX, 0x10); regs[SysIfaceCntl1] = inb(GRAX + 1);  outb(GRAX, 0x11); regs[SysIfaceCntl2] = inb(GRAX + 1);  outb(GRAX, 0x15); regs[SingleAddrPage] = inb(GRAX + 1);  outb(GRAX, 0x16); regs[DualAddrPage] = inb(GRAX+1);  outb(GRAX, 0x20); regs[PanelDispCntlReg1] = inb(GRAX+1);  outb(GRAX, 0x25); regs[PanelDispCntlReg2] = inb(GRAX+1);  outb(GRAX, 0x30); regs[PanelDispCntlReg3] = inb(GRAX+1);  outb(GRAX, 0x28); regs[PanelVertCenterReg1] = inb(GRAX+1);  outb(GRAX, 0x29); regs[PanelVertCenterReg2] = inb(GRAX+1);  outb(GRAX, 0x2a); regs[PanelVertCenterReg3] = inb(GRAX+1);  if (NeoChipset != PCI_CHIP_NM2070){    outb(GRAX, 0x32); regs[PanelVertCenterReg4] = inb(GRAX+1);    outb(GRAX, 0x33); regs[PanelHorizCenterReg1] = inb(GRAX+1);    outb(GRAX, 0x34); regs[PanelHorizCenterReg2] = inb(GRAX+1);    outb(GRAX, 0x35); regs[PanelHorizCenterReg3] = inb(GRAX+1);  }  if (NeoChipset == PCI_CHIP_NM2160){    outb(GRAX, 0x36); regs[PanelHorizCenterReg4] = inb(GRAX+1);  }  if (NeoChipset == PCI_CHIP_NM2200){    outb(GRAX, 0x36); regs[PanelHorizCenterReg4] = inb(GRAX+1);    outb(GRAX, 0x37); regs[PanelVertCenterReg5]  = inb(GRAX+1);    outb(GRAX, 0x38); regs[PanelHorizCenterReg5] = inb(GRAX+1);  }  outb(GRAX, 0x90); regs[ExtColorModeSelect] = inb(GRAX+1);  outb(GRAX, 0x9B); regs[VCLK3NumeratorLow]  = inb(GRAX+1);  if (NeoChipset == PCI_CHIP_NM2200){    outb(GRAX, 0x8F); regs[VCLK3NumeratorHigh] = inb(GRAX+1);  }  outb(GRAX, 0x9F); regs[VCLK3Denominator] = inb(GRAX+1);  regs[EXT_SAVED] = TRUE;  outb(vgaIOBase + 4, 0x25); regs[EXTCR + 0x25] = inb(vgaIOBase + 5);  outb(vgaIOBase + 4, 0x2F); regs[EXTCR + 0x2F] = inb(vgaIOBase + 5);  for (i = 0x40; i <= 0x59; i++){    outb(vgaIOBase + 4, i); regs[EXTCR + i] = inb(vgaIOBase + 5);  }  for (i = 0x60; i <= 0x69; i++){    outb(vgaIOBase + 4, i); regs[EXTCR + i] = inb(vgaIOBase + 5);  }  for (i = 0x70; i <= NEO_EXT_CR_MAX; i++){    outb(vgaIOBase + 4, i); regs[EXTCR + i] = inb(vgaIOBase + 5);  }  for (i = 0x0A; i <= NEO_EXT_GR_MAX; i++){    outb(GRAX, i); regs[EXTGR + i] = inb(GRAX+1);  }  /* DAC */  outb(0x3C6,0xFF); /* mask */  outb(0x3C7,0x00); /* read address */  for (i = 0; i < 768; i++){    regs[DAC + i] = inb(0x3C9);    DACDelay;  }  return NEO_TOTAL_REGS - VGA_TOTAL_REGS;}/* Set chipset-specific registers */static void neo_setregs(const unsigned char regs[], int mode){  int i;  unsigned char temp;#ifdef DEBUG  fprintf(stderr, "neo_setregs\n");#endif  neo_unlock();		  outw(GRAX, 0x0015);   /* bank#0 */  outb(GRAX, 0x0a); outb(GRAX+1, regs[GeneralLockReg]);  /* set color mode first */  outb(GRAX, 0x90); temp = inb(GRAX+1);  switch (NeoChipset){  case PCI_CHIP_NM2070:    temp &= 0xF0; /* Save bits 7:4 */    temp |= (regs[ExtColorModeSelect] & ~0xF0);    break;  case PCI_CHIP_NM2090: case PCI_CHIP_NM2093: case PCI_CHIP_NM2097:  case PCI_CHIP_NM2160: case PCI_CHIP_NM2200:    temp &= 0x70; /* Save bits 6:4 */    temp |= (regs[ExtColorModeSelect] & ~0x70);    break;  }  outb(GRAX, 0x90); outb(GRAX+1, temp);  /* Disable horizontal and vertical graphics and text expansions */  outb(GRAX, 0x25);  temp = inb(GRAX+1);  outb(GRAX, 0x25);  temp &= 0x39;  outb(GRAX+1, temp);  usleep(200000);  /* DAC */  outb(0x3C6,0xFF); /* mask */  outb(0x3C8,0x00); /* write address */  for (i = 0; i < 768; i++){    outb(0x3C9, regs[DAC + i]);    DACDelay;  }  outb(GRAX, 0x0E); outb(GRAX+1, regs[ExtCRTDispAddr]);  outb(GRAX, 0x0F); outb(GRAX+1, regs[ExtCRTOffset]);  outb(GRAX, 0x10); temp = inb(GRAX+1);  temp &= 0x0F; /* Save bits 3:0 */  temp |= (regs[SysIfaceCntl1] & ~0x0F);  outb(GRAX, 0x10); outb(GRAX+1, temp);  outb(GRAX, 0x11); outb(GRAX+1, regs[SysIfaceCntl2]);  outb(GRAX, 0x15); outb(GRAX+1, regs[SingleAddrPage]);  outb(GRAX, 0x16); outb(GRAX+1, regs[DualAddrPage]);  outb(GRAX, 0x20); temp = inb(GRAX+1);  switch (NeoChipset){  case PCI_CHIP_NM2070:    temp &= 0xFC; /* Save bits 7:2 */    temp |= (regs[PanelDispCntlReg1] & ~0xFC);    break;  case PCI_CHIP_NM2090:  case PCI_CHIP_NM2093: case PCI_CHIP_NM2097:  case PCI_CHIP_NM2160:    temp &= 0xDC; /* Save bits 7:6,4:2 */    temp |= (regs[PanelDispCntlReg1] & ~0xDC);    break;  case PCI_CHIP_NM2200:    temp &= 0x98; /* Save bits 7,4:3 */    temp |= (regs[PanelDispCntlReg1] & ~0x98);    break;  }  outb(GRAX, 0x20); outb(GRAX+1, temp);  outb(GRAX, 0x25); temp = inb(GRAX+1);  temp &= 0x38; /* Save bits 5:3 */  temp |= (regs[PanelDispCntlReg2] & ~0x38);  outb(GRAX, 0x25); outb(GRAX+1, temp);  if (NeoChipset != PCI_CHIP_NM2070){    outb(GRAX, 0x30); temp = inb(GRAX+1);    temp &= 0xEF; /* Save bits 7:5 and bits 3:0 */    temp |= (regs[PanelDispCntlReg3] & ~0xEF);    outb(GRAX, 0x30); outb(GRAX+1, temp);  }  outb(GRAX, 0x28); outb(GRAX+1, regs[PanelVertCenterReg1]);  outb(GRAX, 0x29); outb(GRAX+1, regs[PanelVertCenterReg2]);  outb(GRAX, 0x2a); outb(GRAX+1, regs[PanelVertCenterReg3]);  if (NeoChipset != PCI_CHIP_NM2070){    outb(GRAX, 0x32); outb(GRAX+1, regs[PanelVertCenterReg4]);    outb(GRAX, 0x33); outb(GRAX+1, regs[PanelHorizCenterReg1]);    outb(GRAX, 0x34); outb(GRAX+1, regs[PanelHorizCenterReg2]);    outb(GRAX, 0x35); outb(GRAX+1, regs[PanelHorizCenterReg3]);  }  if (NeoChipset == PCI_CHIP_NM2160){    outb(GRAX, 0x36); outb(GRAX+1, regs[PanelHorizCenterReg4]);  }  if (NeoChipset == PCI_CHIP_NM2200){    outb(GRAX, 0x36); outb(GRAX+1, regs[PanelHorizCenterReg4]);    outb(GRAX, 0x37); outb(GRAX+1, regs[PanelVertCenterReg5]);    outb(GRAX, 0x38); outb(GRAX+1, regs[PanelHorizCenterReg5]);  }#if 0  outb(GRAX, 0x9B); outb(GRAX+1, regs[VCLK3NumeratorLow]);  if (NeoChipset == PCI_CHIP_NM2200){    outb(GRAX, 0x8F); temp = inb(GRAX+1);    temp &= 0x0F; /* Save bits 3:0 */    temp |= (regs[VCLK3NumeratorHigh] & ~0x0F);    outb(GRAX, 0x8F); outb(GRAX+1, temp);  }  outb(GRAX, 0x9F); outb(GRAX+1, regs[VCLK3Denominator]);#endif  if (regs[EXT_SAVED]){    outb(vgaIOBase + 4, 0x25); outb(vgaIOBase + 5, regs[EXTCR + 0x25]);    outb(vgaIOBase + 4, 0x2F); outb(vgaIOBase + 5, regs[EXTCR + 0x2F]);    for (i = 0x40; i <= 0x59; i++){      outb(vgaIOBase + 4, i); outb(vgaIOBase + 5, regs[EXTCR + i]);    }    for (i = 0x60; i <= 0x69; i++){      outb(vgaIOBase + 4, i); outb(vgaIOBase + 5, regs[EXTCR + i]);    }    for (i = 0x70; i <= NEO_EXT_CR_MAX; i++){      outb(vgaIOBase + 4, i); outb(vgaIOBase + 5, regs[EXTCR + i]);    }    for (i = 0x0a; i <= 0x3f; i++){      outb(GRAX, i); outb(GRAX+1, regs[EXTGR + i]);    }    for (i = 0x90; i <= NEO_EXT_GR_MAX; i++){      outb(GRAX, i); outb(GRAX+1, regs[EXTGR + i]);    }  }  /* Program vertical extension register */  if (NeoChipset == PCI_CHIP_NM2200){    outb(vgaIOBase + 4, 0x70); outb(vgaIOBase + 5, regs[VerticalExt]);  }}#if 0/* * NeoCalcVCLK -- * * Determine the closest clock frequency to the one requested. */#define REF_FREQ 14.31818#define MAX_N 127#define MAX_D 31#define MAX_F 1static void NeoCalcVCLK(long freq, unsigned char *moderegs){    int n, d, f;    double f_out;    double f_diff;    int n_best = 0, d_best = 0, f_best = 0;    double f_best_diff = 999999.0;    double f_target = freq/1000.0;    for (f = 0; f <= MAX_F; f++)	for (n = 0; n <= MAX_N; n++)	    for (d = 0; d <= MAX_D; d++) {		f_out = (n+1.0)/((d+1.0)*(1<<f))*REF_FREQ;		f_diff = abs(f_out-f_target);		if (f_diff < f_best_diff) {		    f_best_diff = f_diff;		    n_best = n;		    d_best = d;		    f_best = f;		}	    }    if (NeoChipset == PCI_CHIP_NM2200){      /* NOT_DONE:  We are trying the full range of the 2200 clock.	 We should be able to try n up to 2047 */      moderegs[VCLK3NumeratorLow]  = n_best;      moderegs[VCLK3NumeratorHigh] = (f_best << 7);    } else {      moderegs[VCLK3NumeratorLow]  = n_best | (f_best << 7);    }    moderegs[VCLK3Denominator] = d_best;}#endif/* Return nonzero if mode is available */static int neo_modeavailable(int mode){    struct info *info;    ModeTiming *modetiming;    ModeInfo *modeinfo;#ifdef DEBUG    fprintf(stderr, "neo_modeavaailable: %d\n", mode);#endif    if ((mode < G640x480x256 )	|| mode == G720x348x2)	return __svgalib_vga_driverspecs.modeavailable(mode);    info = &__svgalib_infotable[mode];    if (neo_memory * 1024 < info->ydim * info->xbytes)	return 0;    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);    modetiming = malloc(sizeof(ModeTiming));    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {	free(modetiming);	free(modeinfo);	return 0;    }    free(modetiming);    free(modeinfo);    return SVGADRV;}/* Local, called by neo_setmode(). */static void neo_initializemode(unsigned char *moderegs,			    ModeTiming * modetiming, ModeInfo * modeinfo, int mode){  int i, hoffset, voffset;#ifdef DEBUG  fprintf(stderr, "neo_initializemode: %d\n", mode);#endif  neo_saveregs(moderegs);  __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);  moderegs[EXT_SAVED] = FALSE;  moderegs[VGA_AR10] = 0x01;  /* Attribute 0x10 */  moderegs[0x13] = modeinfo->lineWidth >> 3;  moderegs[ExtCRTOffset] = modeinfo->lineWidth >> 11;  switch (modeinfo->bitsPerPixel){  case  8:    moderegs[ExtColorModeSelect] = 0x11;

⌨️ 快捷键说明

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