📄 neo.c
字号:
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 + -