📄 chips.c
字号:
__svgalib_driverspecs->accelspecs->Sync = CHIPS_mmio_Sync; } } else { if (modeinfo->bitsPerPixel == 24) { __svgalib_driverspecs->accelspecs->FillBox = __svgalib_CHIPS_FillBox24; } else { __svgalib_driverspecs->accelspecs->FillBox = __svgalib_CHIPS_FillBox; __svgalib_driverspecs->accelspecs->PutBitmap = __svgalib_CHIPS_PutBitmap; } __svgalib_driverspecs->accelspecs->ScreenCopy = CHIPS_ScreenCopy; __svgalib_driverspecs->accelspecs->Sync = CHIPS_Sync; } } return 0;}/* Enable linear mode (0 to turn off) */static void CHIPS_setlinear(int addr){#ifdef DEBUG printf("CHIPS: CHIPS_setlinear(0x%X)\n", addr);#endif if (ctisHiQV) { outb(0x3D6, 0x0A); if (addr) outb(0x3D7, inb(0x3D7) | 0x02); /* enable linear mode */ else outb(0x3D7, inb(0x3D7) & ~0x02); /* disable linear mode */ } else { outb(0x3D6, 0x0B); if (addr) outb(0x3D7, inb(0x3D7) | 0x10); /* enable linear mode */ else outb(0x3D7, inb(0x3D7) & ~0x10); /* disable linear mode */ }}static int CHIPS_linear(int op, int param){#ifdef DEBUG printf("CHIPS: CHIPS_linear(%d, %d)\n", op, param);#endif if (CHIPSchipset != CT_520) { /* The 65520 doesn't support it */ if (op == LINEAR_ENABLE) { CHIPS_setlinear(1); return 0; } if (op == LINEAR_DISABLE) { CHIPS_setlinear(0); return 0; } if (op == LINEAR_QUERY_BASE) { Bool isPCI; /* First deal with the user set MEMBASE */ if (ctFlagsSet & ctFlags_SetLinear) { switch (param) { case 0: return __svgalib_CHIPS_LinearBase; break; default: return -1; break; } } __svgalib_CHIPS_LinearBase = -1; if (ctisHiQV) { outb(0x3D6,0x08); isPCI = (((inb(0x3D7) & 1) == 1) ? TRUE : FALSE); } else { outb(0x3D6,0x01); isPCI = (((inb(0x3D7) & 7) == 6) ? TRUE : FALSE); } if (isPCI) { /* PCI linear address requires access to MEMBASE * in PCI register. How do we do this in svgalib? * For now just try a few possible PCI addresses * that I know about. */ switch (param) { case 0: __svgalib_CHIPS_LinearBase = 0xFE000000; break; case 1: __svgalib_CHIPS_LinearBase = 0xC0000000; break; case 2: __svgalib_CHIPS_LinearBase = 0xFD000000; break; case 3: __svgalib_CHIPS_LinearBase = 0x41000000; break; default: __svgalib_CHIPS_LinearBase = -1; break; } } else { if (param == 0) { if (ctisHiQV) { outb(0x3D6, 0x6); __svgalib_CHIPS_LinearBase = ((0xFF & inb(0x3D7)) << 24); outb(0x3D6, 0x5); __svgalib_CHIPS_LinearBase |= ((0x80 & inb(0x3D7)) << 16); } else { outb(0x3D6, 0x8); __svgalib_CHIPS_LinearBase = ((0xFF & inb(0x3D7)) << 20); } } } return __svgalib_CHIPS_LinearBase; } } if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0; /* No granularity or range. */ else return -1; /* Unknown function. */}/*----------------------------------------------------------------------*//* Indentify chipset; return non-zero if detected *//*----------------------------------------------------------------------*/static int CHIPS_test(void){ unsigned char temp;#ifdef DEBUG printf("CHIPS: CHIPS_test\n");#endif /* * OK. We have to actually test the hardware. The * EnterLeave() function (described below) unlocks access * to registers that may be locked, and for OSs that require * it, enables I/O access. So we do this before we probe, * even though we don't know for sure that this chipset * is present. */ CHIPS_EnterLeave(ENTER); /* * Here is where all of the probing code should be placed. * The best advice is to look at what the other drivers are * doing. If you are lucky, the chipset reference will tell * how to do this. Other resources include SuperProbe/vgadoc2, * and the Ferraro book. */ outb(0x3D6, 0x00); temp = inb(0x3D6+1);/* * Reading 0x103 causes segmentation violation, like 46E8 ??? * So for now just force what I want! * * Need to look at ioctl(console_fd, PCCONIOCMAPPORT, &ior) * for bsdi! */ CHIPSchipset = 99; if (temp != 0xA5) { if ((temp & 0xF0) == 0x70) { CHIPSchipset = CT_520; } else if ((temp & 0xF0) == 0x80) /* Could also be a 65525 */ { CHIPSchipset = CT_530; } else if ((temp & 0xF8) == 0xC0) { CHIPSchipset = CT_535; } else if ((temp & 0xF8) == 0xD0) { CHIPSchipset = CT_540; } else if ((temp & 0xF8) == 0xD8) { switch (temp&0x7) { case 3: CHIPSchipset = CT_546; break; case 4: CHIPSchipset = CT_548; break; default: CHIPSchipset = CT_545; } } } /* At this point the chip could still be a ct65550, so check */ if ((temp != 0) && (CHIPSchipset == 99)) { outb(0x3D6, 0x02); temp = inb(0x03D7); if (temp == 0xE0) { CHIPSchipset = CT_550; ctisHiQV = TRUE; } if (temp == 0xE4) { CHIPSchipset = CT_554; ctisHiQV = TRUE; } } if (CHIPSchipset == 99) { /* failure, if no good, then leave */ /* * Turn things back off if the probe is going to fail. * Returning FALSE implies failure, and the server * will go on to the next driver. */ CHIPS_EnterLeave(LEAVE); return(FALSE); } CHIPS_init(0, 0, 0); return TRUE;}/*----------------------------------------------------------------------*//* CHIPS_EnterLeave -- *//* *//* This function is called when the virtual terminal on which the *//* server is running is entered or left, as well as when the server *//* starts up and is shut down. Its function is to obtain and *//* relinquish I/O permissions for the SVGA device. This includes *//* unlocking access to any registers that may be protected on the *//* chipset, and locking those registers again on exit. *//* *//*----------------------------------------------------------------------*/static void CHIPS_EnterLeave(Bool enter){ unsigned char temp;#ifdef DEBUG printf("CHIPS: CHIPS_EnterLeave(%d)\n", enter);#endif /* (taken from XFree86) */ if (enter) { /* * This is a global. The CRTC base address depends on * whether the VGA is functioning in color or mono mode. * This is just a convenient place to initialize this * variable. */ vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0; /* * Here we deal with register-level access locks. This * is a generic VGA protection; most SVGA chipsets have * similar register locks for their extended registers * as well. */ /* Unprotect CRTC[0-7] */ outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5); outb(vgaIOBase + 5, temp & 0x7F); /* Enters Setup Mode *//* outb(0x46E8, inb(0x46E8) | 16); */ /* Extension registers access enable *//* outb(0x103, inb(0x103) | 0x80); */ } else { /* * Here undo what was done above. */ /* Exits Setup Mode *//* outb(0x46E8, inb(0x46E8) & 0xEF); */ /* Extension registers access disable *//* outb(0x103, inb(0x103) & 0x7F); */ /* Protect CRTC[0-7] */ outb(vgaIOBase + 4, 0x11); temp = inb(vgaIOBase + 5); outb(vgaIOBase + 5, (temp & 0x7F) | 0x80); }}/*----------------------------------------------------------------------*//* Bank switching function - set 64K bank number *//*----------------------------------------------------------------------*/static void CHIPS_setpage(int page){#ifdef DEBUG printf("CHIPS: CHIPS_setpage(%d)\n",page);#endif if (ctisHiQV) { outw(0x3D6, ((page&0x7F) << 8) | 0x0E); } else {#if !defined(seperated_read_write_bank) outw(0x3D6, (page << 12) | 0x10); /* bank 0 ( 64k window at 0xA0000 )*/#else int temp; temp = (page << 12); outw(0x3D6, temp | 0x10); /* bank 0 ( 32k window at 0xA0000 ) */ outw(0x3D6, temp + ((1 << 11) | 0x11)); /* bank 1 ( 32k window at 0xA8000 ) */#endif } }/*----------------------------------------------------------------------*//* W A R N I N G : *//* when using seperate banks, each bank can only access a maximum *//* of 32k. bank0 is accessed at 0xA0000 .. 0xA7FFF and bank1 *//* is accessed at 0xA8000 .. 0xAFFFF *//* The GL library shipped with SVGALIB expects to be able to *//* access a 64k contiguoius window at 0xA0000 .. 0xAFFFF *//*----------------------------------------------------------------------*//*----------------------------------------------------------------------*//* Bank switching function - set 32K bank number *//* WARNING: this function uses a granularity or 32k not 64k *//*----------------------------------------------------------------------*/static void CHIPS_setreadpage(int page){#ifdef DEBUG printf("CHIPS: CHIPS_setreadpage(%d)\n",page);#endif outw(0x3D6, (page << 11) | 0x10); /* bank 0 */}/*----------------------------------------------------------------------*//* Bank switching function - set 32K bank number *//* WARNING: this function uses a granularity or 32k not 64k *//*----------------------------------------------------------------------*/static void CHIPS_setwritepage(int page){#ifdef DEBUG printf("CHIPS: CHIPS_setwritepage(%d)\n",page);#endif outw(0x3D6, (page << 11) | 0x11); /* bank 1 */}/*----------------------------------------------------------------------*//* Set display start address (not for 16 color modes) *//*----------------------------------------------------------------------*/static void CHIPS_setdisplaystart(int addr){#ifdef DEBUG printf("CHIPS: CHIPS_setdisplaystart(%d)\n",addr);#endif addr >>= 2; /* * These are the generic starting address registers. * (taken from XFree86) */ outw(vgaIOBase + 4, (addr & 0x00FF00) | 0x0C); outw(vgaIOBase + 4, ((addr & 0x00FF) << 8) | 0x0D); /* * Here the high-order bits are masked and shifted, and put into * the appropriate extended registers. */ /* MH - plug in the high order starting address bits */ if (ctisHiQV) { outb(0x3D6, 0x09); if ((inb(0x3D7) & 0x1) == 0x1) outw(vgaIOBase + 4, ((addr & 0x0F0000) >> 8) | 0x8000 | 0x40); } else { outb(0x3D6, 0x0C); outb(0x3D7, ((addr & 0xFF0000) >> 16)); }}/*----------------------------------------------------------------------*//* Set logical scanline length (usually multiple of 8) *//*----------------------------------------------------------------------*/static void CHIPS_setlogicalwidth(int width){#ifdef DEBUG printf("CHIPS: CHIPS_setlogicalwidth(%d)\n",width);#endif outw(vgaIOBase + 4, 0x13 | (((width >> 3) << 8) & 0xFF00)); if (ctisHiQV) { outw(vgaIOBase + 4, 0x41 | ((width >>3) & 0xF00)); } else { outb(0x3D6,0x1E); outb(0x3D7,((width>>3)&0xFF)); outb(0x3D6,0x0D); outb(0x3D7,(((width>>11)&0x1)|((width>>10)&0x2))); } }/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -