/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/vga/vga.c,v 3.71.2.16 1999/04/15 12:37:03 hohndel Exp $ */ /* * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Thomas Roell not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Thomas Roell makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Thomas Roell, roell@informatik.tu-muenchen.de * */ /* $XConsortium: vga.c /main/29 1996/10/25 10:34:12 kaleb $ */ #include "X.h" #include "Xmd.h" #include "input.h" #include "pixmapstr.h" #include "regionstr.h" #include "cursor.h" #include "mipointer.h" #include "cursorstr.h" #include "gcstruct.h" #include "compiler.h" #include "xf86.h" #include "xf86Priv.h" #include "xf86Procs.h" #include "xf86_OSlib.h" #include "xf86_Config.h" #include "vga.h" #include "vgaPCI.h" #ifdef XFreeXDGA #include "scrnintstr.h" #include "servermd.h" #define _XF86DGA_SERVER_ #include "extensions/xf86dgastr.h" #endif #if !defined(MONOVGA) && !defined(XF86VGA16) #include "vga256.h" #include "cfb16.h" #include "cfb24.h" #include "cfb32.h" #include "xf86scrin.h" #include "xf86xaa.h" #else #include "windowstr.h" #endif #ifdef PC98_EGC #define EGC_PLANE 0x4a0 #define EGC_MODE 0x4a4 #define EGC_FGC 0x4a6 #define EGC_COPY_MODE 0x2cac #endif #if defined(PC98_TGUI) extern pointer pc98PvramBase; #endif #ifndef XF86VGA16 #ifdef MONOVGA extern void mfbDoBitbltCopy(); extern void mfbDoBitbltCopyInverted(); #ifdef BANKEDMONOVGA extern void mfbDoBitbltTwoBanksCopy(); extern void mfbDoBitbltTwoBanksCopyInverted(); void (*ourmfbDoBitbltCopy)(); void (*ourmfbDoBitbltCopyInverted)(); #endif #else unsigned long useSpeedUp = 0; #if !defined(__alpha__) extern void speedupvga256TEGlyphBlt8(); extern void speedupvga2568FillRectOpaqueStippled32(); extern void speedupvga2568FillRectTransparentStippled32(); #else /* !__alpha__ */ extern void vga256TEGlyphBlt8(); extern void vga2568FillRectOpaqueStippled32(); extern void vga2568FillRectTransparentStippled32(); #endif /* !__alpha__ */ extern void OneBankvgaBitBlt(); #endif /* MONOVGA */ #endif /* !XF86VGA16 */ extern Bool xf86Exiting, xf86Resetting, xf86ProbeFailed; extern char *xf86VisualNames[]; extern Bool miDCInitialize(); ScrnInfoRec vga256InfoRec = { FALSE, /* Bool configured */ -1, /* int tmpIndex */ -1, /* int scrnIndex */ vgaProbe, /* Bool (* Probe)() */ vgaScreenInit, /* Bool (* Init)() */ vgaValidMode, /* Bool (* ValidMode)() */ vgaEnterLeaveVT, /* void (* EnterLeaveVT)() */ (void (*)())NoopDDA, /* void (* EnterLeaveMonitor)() */ (void (*)())NoopDDA, /* void (* EnterLeaveCursor)() */ vgaAdjustFrame, /* void (* AdjustFrame)() */ vgaSwitchMode, /* Bool (* SwitchMode)() */ vgaDPMSSet, /* void (* DPMSSet)() */ vgaPrintIdent, /* void (* PrintIdent)() */ #ifdef MONOVGA 1, /* int depth */ #else #ifdef XF86VGA16 4, /* int depth */ #else 8, /* int depth */ #endif #endif {0, 0, 0}, /* xrgb weight */ #ifdef MONOVGA 1, /* int bitsPerPixel */ #else 8, /* int bitsPerPixel */ #endif -1, /* int defaultVisual */ -1, -1, /* int virtualX,virtualY */ -1, /* int displayWidth */ -1, -1, -1, -1, /* int frameX0, frameY0, frameX1, frameY1 */ {0, }, /* OFlagSet options */ {0, }, /* OFlagSet clockOptions */ {0, }, /* OFlagSet xconfigFlag */ NULL, /* char *chipset */ NULL, /* char *ramdac */ {0, 0, 0, 0}, /* int dacSpeeds[MAXDACSPEEDS] */ 0, /* int dacSpeedBpp */ 0, /* int clocks */ {0, }, /* int clock[MAXCLOCKS] */ DEFAULT_MAX_CLOCK, /* int maxClock */ 0, /* int videoRam */ #ifndef PC98_EGC 0xC0000, /* int BIOSbase */ #else 0xE8000, /* int BIOSbase */ #endif 0, /* unsigned long MemBase, unused for this driver */ 240, 180, /* int width, height */ 0, /* unsigned long speedup */ NULL, /* DisplayModePtr modes */ NULL, /* MonPtr monitor */ NULL, /* char *clockprog */ -1, /* int textclock */ FALSE, /* Bool bankedMono */ #ifdef MONOVGA "VGA2", /* char *name */ #else #ifdef XF86VGA16 "VGA16", /* char *name */ #else "SVGA", /* char *name */ #endif #endif {0, 0, 0}, /* xrgb blackColour */ {0x3F, 0x3F, 0x3F}, /* xrgb whiteColour */ #ifdef MONOVGA vga2ValidTokens, /* int *validTokens */ VGA2_PATCHLEVEL, /* char *patchLevel */ #else #ifdef XF86VGA16 vga16ValidTokens, /* int *validTokens */ VGA16_PATCHLEVEL, /* char *patchLevel */ #else vga256ValidTokens, /* int *validTokens */ SVGA_PATCHLEVEL, /* char *patchLevel */ #endif #endif 0, /* int IObase */ 0, /* int PALbase */ 0, /* int COPbase */ 0, /* int POSbase */ 0, /* int instance */ 0, /* int s3Madjust */ 0, /* int s3Nadjust */ 0, /* int s3MClk */ 0, /* int chipID */ 0, /* int chipRev */ #if defined (PC98_WAB) || defined(PC98_WABEP) 0x0E0000, /* unsigned long VGAbase */ #else #if defined(PC98_GANB_WAP) || defined(PC98_WSNA) || defined(PC98_NKVNEC) 0xF00000, /* unsigned long VGAbase */ #else #if defined(PC98_EGC) || defined(PC98_PEGC) 0x0A8000, /* unsigned long VGAbase */ #else 0x0A0000, /* unsigned long VGAbase */ #endif /* PC98_EGC || PC98_PEGC */ #endif /* PC98_GANB_WAP || PC98_WSNA || PC98_NKVNEC */ #endif /* PC98_WAB || PC98_WABEP */ 0, /* int s3RefClk */ -1, /* int s3BlankDelay */ 0, /* int textClockFreq */ NULL, /* char* DCConfig */ NULL, /* char* DCOptions */ 0, /* int MemClk */ 0 /* int LCDClk */ #ifdef XFreeXDGA ,0, /* int directMode */ NULL, /* Set Vid Page */ 0, /* unsigned long physBase */ 0 /* int physSize */ #endif }; pointer vgaOrigVideoState = NULL; pointer vgaNewVideoState = NULL; pointer vgaBase = NULL; pointer vgaVirtBase = NULL; pointer vgaLinearBase = NULL; pointer vgaLinearOrig = NULL; vgaPCIInformation *vgaPCIInfo = NULL; Bool vgaDAC8BitComponents = FALSE; void (* vgaEnterLeaveFunc)( #if NeedFunctionPrototypes Bool #endif ) = (void (*)())NoopDDA; Bool (* vgaInitFunc)( #if NeedFunctionPrototypes DisplayModePtr #endif ) = (Bool (*)())NoopDDA; int (* vgaValidModeFunc)( #if NeedFunctionPrototypes DisplayModePtr, Bool, int #endif ) = (Bool (*)())NoopDDA; void * (* vgaSaveFunc)( #if NeedFunctionPrototypes void * #endif ) = (void *(*)())NoopDDA; void (* vgaRestoreFunc)( #if NeedFunctionPrototypes void * #endif ) = (void (*)())NoopDDA; void (* vgaAdjustFunc)( #if NeedFunctionPrototypes int, int #endif ) = (void (*)())NoopDDA; void (* vgaSaveScreenFunc)() = vgaHWSaveScreen; void (* vgaFbInitFunc)() = (void (*)())NoopDDA; Bool (* vgaScrInitFunc)() = (Bool (*)())NoopDDA; int (* vgaPitchAdjustFunc)() = (int (*)())NoopDDA; int (* vgaLinearOffsetFunc)() = (int (*)())NoopDDA; void (* vgaSetReadFunc)() = (void (*)())NoopDDA; void (* vgaSetWriteFunc)() = (void (*)())NoopDDA; void (* vgaSetReadWriteFunc)() = (void (*)())NoopDDA; int vgaMapSize; int vgaSegmentSize; int vgaSegmentShift; int vgaSegmentMask; void *vgaReadBottom; void *vgaReadTop; void *vgaWriteBottom; void *vgaWriteTop = (pointer)&writeseg; /* dummy for linking */ Bool vgaReadFlag; Bool vgaWriteFlag; Bool vgaUse2Banks; int vgaInterlaceType; OFlagSet vgaOptionFlags; extern Bool clgd6225Lcd; Bool vgaUseLinearAddressing; int vgaPhysLinearBase; int vgaLinearSize; int vgaBitsPerPixel = 0; int vgaBytesPerPixel = 0; #ifdef MONOVGA int vgaReadseg=0; int vgaWriteseg=0; int vgaReadWriteseg=0; #endif int vgaIOBase; static ScreenPtr savepScreen = NULL; static PixmapPtr ppix = NULL; static Bool (* saveInitFunc)(); static void * (* saveSaveFunc)(); static void (* saveRestoreFunc)(); static void (* saveAdjustFunc)(); static void (* saveSaveScreenFunc)(); static void (* saveSetReadFunc)(); static void (* saveSetWriteFunc)(); static void (* saveSetReadWriteFunc)(); vgaHWCursorRec vgaHWCursor; #ifdef MONOVGA static int validDepth = 1; #endif #ifdef XF86VGA16 static int validDepth = 4; #endif extern miPointerScreenFuncRec xf86PointerScreenFuncs; extern int defaultColorVisualClass; #define Drivers vgaDrivers extern vgaVideoChipPtr Drivers[]; /* * vgaPrintIdent -- * Prints out identifying strings for drivers included in the server */ void vgaPrintIdent() { int i, j, n, c; char *id; #ifdef MONOVGA ErrorF(" %s: server for monochrome VGA (Patchlevel %s):\n ", vga256InfoRec.name, vga256InfoRec.patchLevel); #else #ifdef XF86VGA16 ErrorF(" %s: server for 4-bit colour VGA (Patchlevel %s):\n ", vga256InfoRec.name, vga256InfoRec.patchLevel); #else ErrorF(" %s: server for SVGA graphics adaptors (Patchlevel %s):\n ", vga256InfoRec.name, vga256InfoRec.patchLevel); #endif #endif n = 0; c = 0; for (i=0; Drivers[i]; i++) for (j = 0; id = (Drivers[i]->ChipIdent)(j); j++, n++) { if (n) { ErrorF(","); c++; if (c + 1 + strlen(id) < 70) { ErrorF(" "); c++; } else { ErrorF("\n "); c = 0; } } ErrorF("%s", id); c += strlen(id); } ErrorF("\n"); } /* * vgaProbe -- * probe and initialize the hardware driver */ Bool vgaProbe() { int i, j, k; DisplayModePtr pMode, pEnd, pmaxX = NULL, pmaxY = NULL; int maxX, maxY; int needmem, rounding; int tx,ty; Bool defaultVisualGiven = FALSE; /* * At this point xf86bpp is what's given as -bpp on the command * line, or what is specified as DefaultColorDepth in the XF86Config * file. The true depth/bits-per-pixel are yet to be determined. * At this point, the weights are uninitialized unless specifically * given by the user. Here we determine good defaults if weights haven't * been explicitly given. */ if(vga256InfoRec.defaultVisual >= 0) defaultVisualGiven = TRUE; if (xf86bpp <= 0) #ifdef MONOVGA xf86bpp = 1; #else #ifdef XF86VGA16 xf86bpp = 4; #else xf86bpp = 8; #endif #endif switch (xf86bpp) { #ifdef MONOVGA case 1: vga256InfoRec.depth = 1; vga256InfoRec.bitsPerPixel = 1; if (!defaultVisualGiven) vga256InfoRec.defaultVisual = StaticGray; xf86weight.red = 1; xf86weight.green = 1; xf86weight.blue = 1; break; #else #ifdef XF86VGA16 case 4: vga256InfoRec.depth = 4; vga256InfoRec.bitsPerPixel = 8; /* This is a special case though */ if (!defaultVisualGiven) vga256InfoRec.defaultVisual = StaticColor; xf86weight.red = 6; xf86weight.green = 6; xf86weight.blue = 6; break; #else case 8: vga256InfoRec.depth = 8; vga256InfoRec.bitsPerPixel = 8; xf86weight.red = 6; xf86weight.green = 6; xf86weight.blue = 6; break; case 15: vga256InfoRec.depth = 15; vga256InfoRec.bitsPerPixel = 16; if (!defaultVisualGiven) vga256InfoRec.defaultVisual = TrueColor; xf86weight.red = 5; xf86weight.green = 5; xf86weight.blue = 5; break; case 16: vga256InfoRec.bitsPerPixel = 16; if (!defaultVisualGiven) vga256InfoRec.defaultVisual = TrueColor; if (xf86weight.red && xf86weight.green && xf86weight.blue) { vga256InfoRec.depth = xf86weight.red + xf86weight.green + xf86weight.blue; if (vga256InfoRec.depth != 15 && vga256InfoRec.depth != 16) { ErrorF("\nError: Invalid weight specified for bpp 16: %d%d%d\n", xf86weight.red, xf86weight.green, xf86weight.blue); return FALSE; } } else { vga256InfoRec.depth = 16; xf86weight.red = 5; xf86weight.green = 6; xf86weight.blue = 5; } break; case 24: vga256InfoRec.depth = 24; vga256InfoRec.bitsPerPixel = 24; if (!defaultVisualGiven) vga256InfoRec.defaultVisual = TrueColor; xf86weight.red = 8; xf86weight.green = 8; xf86weight.blue = 8; break; case 32: vga256InfoRec.depth = 24; vga256InfoRec.bitsPerPixel = 32; if (!defaultVisualGiven) vga256InfoRec.defaultVisual = TrueColor; xf86weight.red = 8; xf86weight.green = 8; xf86weight.blue = 8; break; #endif #endif default: ErrorF("\nError: Unsupported bpp \"%i\"\n", xf86bpp); return FALSE; } #if !defined(MONOVGA) && !defined(XF86VGA16) vgaBitsPerPixel = vga256InfoRec.bitsPerPixel; vgaBytesPerPixel = vga256InfoRec.bitsPerPixel >> 3; #endif if (defaultColorVisualClass < 0) defaultColorVisualClass = vga256InfoRec.defaultVisual; switch (vga256InfoRec.depth) { case 1: if (defaultColorVisualClass != StaticGray) { ErrorF("\nError: Visual \"%s\" isn't supported at depth %d\n", xf86VisualNames[defaultColorVisualClass], vga256InfoRec.depth); return FALSE; } case 4: switch (defaultColorVisualClass) { case StaticGray: case GrayScale: case StaticColor: case PseudoColor: break; /* these are OK */ default: ErrorF("\nError: Visual \"%s\" isn't supported at depth %d\n", xf86VisualNames[defaultColorVisualClass], vga256InfoRec.depth); return FALSE; } break; case 8: break; /* all visuals supported at 8bpp */ default: if (defaultColorVisualClass != TrueColor) { ErrorF("\nError: Visual \"%s\" isn't supported at depth %d\n", xf86VisualNames[defaultColorVisualClass], vga256InfoRec.depth); return FALSE; } } #if !defined(PC98) || defined(PC98_TGUI) || defined(PC98_MGA) || defined(PC98_SVGA) /* First do a general PCI probe (unless disabled) */ if (!OFLG_ISSET(OPTION_NO_PCI_PROBE, &vga256InfoRec.options)) { vgaPCIInfo = vgaGetPCIInfo(); } #endif for (i=0; Drivers[i]; i++) { if ((Drivers[i]->ChipProbe)()) { vgaSaveScreenFunc = Drivers[i]->ChipSaveScreen; xf86ProbeFailed = FALSE; #ifdef MONOVGA #ifdef BANKEDMONOVGA /* * In the mono mode we use, the memory is divided into 4 planes * so we can only effectively use 1/4 of the total. For cards * with < 256K there should be fewer planes. */ if (vga256InfoRec.videoRam <= 256 || !vga256InfoRec.bankedMono) needmem = Drivers[i]->ChipSegmentSize * 8; else needmem = vga256InfoRec.videoRam / 4 * 1024 * 8; #else /* BANKEDMONOVGA */ needmem = Drivers[i]->ChipSegmentSize * 8; #endif /* BANKEDMONOVGA */ rounding = 32; #else /* MONOVGA */ #ifdef XF86VGA16 #ifdef PC98_EGC needmem = Drivers[i]->ChipSegmentSize * 8; #else needmem = vga256InfoRec.videoRam / 4 * 1024 * 8; #endif rounding = 32; #else needmem = vga256InfoRec.videoRam * 1024; rounding = Drivers[i]->ChipRounding; /* * Correct 'needmem' for 16/32bpp. * For 8/16/32bpp, needmem is defined as the max. number of pixels. */ needmem /= (vgaBitsPerPixel / 8); #endif /* XF86VGA16 */ #endif /* MONOVGA */ if (xf86Verbose) { ErrorF("%s %s: chipset: %s\n", OFLG_ISSET(XCONFIG_CHIPSET,&vga256InfoRec.xconfigFlag) ? XCONFIG_GIVEN : XCONFIG_PROBED , vga256InfoRec.name, vga256InfoRec.chipset); #ifdef MONOVGA ErrorF("%s %s: videoram: %dk (using %dk)", #else #ifdef XF86VGA16 ErrorF("%s %s: videoram: %dk (using %dk)", #else ErrorF("%s %s: videoram: %dk", #endif #endif OFLG_ISSET(XCONFIG_VIDEORAM,&vga256InfoRec.xconfigFlag) ? XCONFIG_GIVEN : XCONFIG_PROBED , vga256InfoRec.name, vga256InfoRec.videoRam #ifdef MONOVGA , needmem / 8 / 1024 #endif #ifdef XF86VGA16 , needmem / 2 / 1024 #endif ); for (j=0; j < vga256InfoRec.clocks; j++) { if ((j % 8) == 0) ErrorF("\n%s %s: clocks:", OFLG_ISSET(XCONFIG_CLOCKS,&vga256InfoRec.xconfigFlag) ? XCONFIG_GIVEN : XCONFIG_PROBED , vga256InfoRec.name); ErrorF(" %6.2f", (double)vga256InfoRec.clock[j]/1000.0); } ErrorF("\n"); } /* Scale raw clocks to give pixel clocks if driver requires it */ if ((Drivers[i]->ChipClockMulFactor > 1) || (Drivers[i]->ChipClockDivFactor > 1)) { for (j = 0; j < vga256InfoRec.clocks; j++) { vga256InfoRec.clock[j] *= Drivers[i]->ChipClockDivFactor; vga256InfoRec.clock[j] /= Drivers[i]->ChipClockMulFactor; } vga256InfoRec.maxClock *= Drivers[i]->ChipClockDivFactor; vga256InfoRec.maxClock /= Drivers[i]->ChipClockMulFactor; if (xf86Verbose) { ErrorF("%s %s: Effective pixel clocks available:\n", XCONFIG_PROBED, vga256InfoRec.name); for (j=0; j < vga256InfoRec.clocks; j++) { if ((j % 8) == 0) { if (j != 0) ErrorF("\n"); ErrorF("%s %s: pixel clocks:", XCONFIG_PROBED, vga256InfoRec.name); } ErrorF(" %6.2f", (double)vga256InfoRec.clock[j] / 1000.0); } ErrorF("\n"); } } #if !defined(MONOVGA) && !defined(XF86VGA16) /* * If bpp is > 8, make sure the driver supports it. */ if ((vgaBitsPerPixel == 16 && !Drivers[i]->ChipHas16bpp) || (vgaBitsPerPixel == 24 && !Drivers[i]->ChipHas24bpp) || (vgaBitsPerPixel == 32 && !Drivers[i]->ChipHas32bpp)) { ErrorF("\n%s %s: %dbpp not supported for this chipset\n", XCONFIG_GIVEN, vga256InfoRec.name, vgaBitsPerPixel); Drivers[i]->ChipEnterLeave(LEAVE); return(FALSE); } #endif vgaEnterLeaveFunc = Drivers[i]->ChipEnterLeave; vgaInitFunc = Drivers[i]->ChipInit; vgaValidModeFunc = Drivers[i]->ChipValidMode; vgaSaveFunc = Drivers[i]->ChipSave; vgaRestoreFunc = Drivers[i]->ChipRestore; vgaAdjustFunc = Drivers[i]->ChipAdjust; vgaFbInitFunc = Drivers[i]->ChipFbInit; #ifndef PC98_EGC vgaSetReadFunc = Drivers[i]->ChipSetRead; vgaSetWriteFunc = Drivers[i]->ChipSetWrite; vgaSetReadWriteFunc = Drivers[i]->ChipSetReadWrite; #endif vgaMapSize = Drivers[i]->ChipMapSize; vgaSegmentSize = Drivers[i]->ChipSegmentSize; vgaSegmentShift = Drivers[i]->ChipSegmentShift; vgaSegmentMask = Drivers[i]->ChipSegmentMask; vgaReadBottom = (pointer)((unsigned long)Drivers[i]->ChipReadBottom); vgaReadTop = (pointer)((unsigned long)Drivers[i]->ChipReadTop); vgaWriteBottom = (pointer)((unsigned long)Drivers[i]->ChipWriteBottom); vgaWriteTop = (pointer)((unsigned long)Drivers[i]->ChipWriteTop); vgaUse2Banks = Drivers[i]->ChipUse2Banks; vgaInterlaceType = Drivers[i]->ChipInterlaceType; vgaOptionFlags = Drivers[i]->ChipOptionFlags; OFLG_SET(OPTION_POWER_SAVER, &vgaOptionFlags); OFLG_SET(OPTION_CLGD6225_LCD, &vgaOptionFlags); OFLG_SET(OPTION_NO_PCI_PROBE, &vgaOptionFlags); OFLG_SET(OPTION_CLKDIV2, &vgaOptionFlags); /* For XAA */ OFLG_SET(OPTION_XAA_BENCHMARK, &vgaOptionFlags); OFLG_SET(OPTION_XAA_NO_COL_EXP, &vgaOptionFlags); OFLG_SET(OPTION_NO_PIXMAP_CACHE, &vgaOptionFlags); xf86VerifyOptions(&vgaOptionFlags, &vga256InfoRec); #if !defined(MONOVGA) && !defined(XF86VGA16) /* We do this after the option has been verified. */ if (vgaBitsPerPixel == 8 && OFLG_ISSET(OPTION_DAC_8_BIT, &vga256InfoRec.options)) { ErrorF("%s %s: Using 8 bits per color component\n", XCONFIG_GIVEN, vga256InfoRec.name); vgaDAC8BitComponents = TRUE; xf86weight.red = xf86weight.green = xf86weight.blue = 8; } vga256InfoRec.blackColour.red = 0; vga256InfoRec.blackColour.green = 0; vga256InfoRec.blackColour.blue = 0; vga256InfoRec.weight.red = xf86weight.red; vga256InfoRec.weight.green = xf86weight.green; vga256InfoRec.weight.blue = xf86weight.blue; vga256InfoRec.whiteColour.red = (0x0001 << xf86weight.red) - 1; vga256InfoRec.whiteColour.green = (0x0001 << xf86weight.green) - 1; vga256InfoRec.whiteColour.blue = (0x0001 << xf86weight.blue) - 1; ErrorF("%s %s: Using %d bpp, Depth %d, Color weight: %d%d%d\n", XCONFIG_GIVEN, vga256InfoRec.name, vgaBitsPerPixel, vga256InfoRec.depth, vga256InfoRec.weight.red, vga256InfoRec.weight.green, vga256InfoRec.weight.blue); #endif #ifdef DPMSExtension if (DPMSEnabledSwitch || (OFLG_ISSET(OPTION_POWER_SAVER, &vga256InfoRec.options) && !DPMSDisabledSwitch)) defaultDPMSEnabled = DPMSEnabled = TRUE; #endif if (OFLG_ISSET(OPTION_CLGD6225_LCD, &vga256InfoRec.options)) clgd6225Lcd = TRUE; /* if Virtual given: is the virtual size too big? */ #ifdef BANKEDMONOVGA if (vga256InfoRec.virtualX > (2048)) { ErrorF("%s: Virtual width %i exceeds max. virtual width %i\n", vga256InfoRec.name, vga256InfoRec.virtualX, (2048)); vgaEnterLeaveFunc(LEAVE); return(FALSE); } vga256InfoRec.displayWidth = ((vga256InfoRec.virtualX + rounding - 1) / rounding) * rounding; if (vga256InfoRec.displayWidth*vga256InfoRec.virtualY <= 8*vgaSegmentSize) { /* may be unbanked */ if (vga256InfoRec.displayWidth > vga256InfoRec.virtualX) ErrorF("%s %s: Display width set to %d (a multiple of" " %d)\n", XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.displayWidth, rounding); } else if (vga256InfoRec.virtualX > (1024)) vga256InfoRec.displayWidth=2048; else vga256InfoRec.displayWidth=1024; if (vga256InfoRec.virtualX > 0 && vga256InfoRec.displayWidth * vga256InfoRec.virtualY > needmem) { ErrorF("%s: Too little memory for virtual resolution\n" " %d (display width %d) x %d\n", vga256InfoRec.name, vga256InfoRec.virtualX, vga256InfoRec.displayWidth, vga256InfoRec.virtualY); vgaEnterLeaveFunc(LEAVE); return(FALSE); } #else #ifndef USE_OLD_ROUNDING if (vga256InfoRec.virtualX > 0) { /* Let the driver have a chance to use a larger screen pitch if it needs. This ability is particularly useful for the Cirrus Laguna family, which uses tiled memory. Each scanline must be an integer number of tiles wide, where tiles are 128 or 256 bytes wide. Furthermore, there are only a few tile pitches allowed. It just so happens that none of these tile pitches yield a screen byte pitch that is divisible by 3. The upshot: you can't have 24bpp if the screen pitch is not a multiple of three -- i.e., if the screen pitch is not an integer number of _pixels_. */ if (vgaPitchAdjustFunc != (int (*)())NoopDDA) vga256InfoRec.displayWidth = (*vgaPitchAdjustFunc)(); else { if (vga256InfoRec.virtualX % rounding) { vga256InfoRec.displayWidth = vga256InfoRec.virtualX + (rounding - (vga256InfoRec.virtualX % rounding)); ErrorF("%s %s: Display width set to %d (a multiple of %d)\n", XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.displayWidth, rounding); } else { vga256InfoRec.displayWidth = vga256InfoRec.virtualX; } } if (vga256InfoRec.displayWidth * vga256InfoRec.virtualY > needmem) { ErrorF("%s: Too little memory for virtual resolution %d %d\n", vga256InfoRec.name, vga256InfoRec.virtualX, vga256InfoRec.virtualY); vgaEnterLeaveFunc(LEAVE); return(FALSE); } } #else if (vga256InfoRec.virtualX > 0 && vga256InfoRec.virtualX * vga256InfoRec.virtualY > needmem) { ErrorF("%s: Too little memory for virtual resolution %d %d\n", vga256InfoRec.name, vga256InfoRec.virtualX, vga256InfoRec.virtualY); vgaEnterLeaveFunc(LEAVE); return(FALSE); } #endif #endif maxX = maxY = -1; tx = vga256InfoRec.virtualX; ty = vga256InfoRec.virtualY; if (Drivers[i]->ChipBuiltinModes) { pEnd = pMode = vga256InfoRec.modes = Drivers[i]->ChipBuiltinModes; ErrorF("%s %s: Using builtin driver modes\n", XCONFIG_PROBED, vga256InfoRec.name); do { ErrorF("%s %s: Builtin Mode: %s\n", XCONFIG_PROBED, vga256InfoRec.name, pMode->name); if (pMode->HDisplay > maxX) { maxX = pMode->HDisplay; pmaxX = pMode; } if (pMode->VDisplay > maxY) { maxY = pMode->VDisplay; pmaxY = pMode; } pMode = pMode->next; } while (pMode != pEnd); } else if (vga256InfoRec.modes == NULL) { ErrorF("No modes supplied in XF86Config\n"); vgaEnterLeaveFunc(LEAVE); return(FALSE); } else { pMode = vga256InfoRec.modes; pEnd = (DisplayModePtr) NULL; do { DisplayModePtr pModeSv; /* * xf86LookupMode returns FALSE if it ran into an invalid * parameter */ if(xf86LookupMode(pMode, &vga256InfoRec, LOOKUP_DEFAULT) == FALSE) { pModeSv = pMode->next; xf86DeleteMode(&vga256InfoRec, pMode); pMode = pModeSv; } else if (pMode->HDisplay * pMode->VDisplay > needmem) { pModeSv=pMode->next; ErrorF("%s %s: Insufficient video memory for all resolutions\n", XCONFIG_PROBED, vga256InfoRec.name); xf86DeleteMode(&vga256InfoRec, pMode); pMode = pModeSv; } else if (((tx > 0) && (pMode->HDisplay > tx)) || ((ty > 0) && (pMode->VDisplay > ty))) { pModeSv=pMode->next; ErrorF("%s %s: Resolution %dx%d too large for virtual %dx%d\n", XCONFIG_PROBED, vga256InfoRec.name, pMode->HDisplay, pMode->VDisplay, tx, ty); xf86DeleteMode(&vga256InfoRec, pMode); pMode = pModeSv; } else { /* * Successfully looked up this mode. If pEnd isn't * initialized, set it to this mode. */ if (pEnd == (DisplayModePtr) NULL) pEnd = pMode; if (pMode->HDisplay > maxX) { maxX = pMode->HDisplay; pmaxX = pMode; } if (pMode->VDisplay > maxY) { maxY = pMode->VDisplay; pmaxY = pMode; } pMode = pMode->next; } } while (pMode != pEnd); } vga256InfoRec.virtualX = max(maxX, vga256InfoRec.virtualX); vga256InfoRec.virtualY = max(maxY, vga256InfoRec.virtualY); #ifdef BANKEDMONOVGA if (vga256InfoRec.virtualX > (2048)) { ErrorF("%s: Max. width %i exceeds max. virtual width %i\n", vga256InfoRec.name, vga256InfoRec.virtualX, (2048)); vgaEnterLeaveFunc(LEAVE); return(FALSE); } /* Now that modes are resolved and max. extents are found, * test size again */ vga256InfoRec.displayWidth = ((vga256InfoRec.virtualX + rounding - 1) / rounding) * rounding; if (vga256InfoRec.displayWidth*vga256InfoRec.virtualY > 8*vgaSegmentSize) { if (vga256InfoRec.virtualX > (1024)) vga256InfoRec.displayWidth=2048; else vga256InfoRec.displayWidth=1024; } if ((xf86Verbose) && (vga256InfoRec.displayWidth != vga256InfoRec.virtualX)) ErrorF("%s %s: Display width set to %d (a multiple of %d)\n", XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.displayWidth, rounding); #endif #ifndef BANKEDMONOVGA #ifndef USE_OLD_ROUNDING if (vga256InfoRec.displayWidth < 0) { /* Let the driver have a chance to use a larger screen pitch if it needs. This ability is particularly useful for the Cirrus Laguna family, which uses tiled memory. Each scanline must be an integer number of tiles wide, where tiles are 128 or 256 bytes wide. Furthermore, there are only a few tile pitches allowed. It just so happens that none of these tile pitches yield a screen byte pitch that is divisible by 3. The upshot: you can't have 24bpp if the screen pitch is not a multiple of three -- i.e., if the screen pitch is not an integer number of _pixels_. */ if (vgaPitchAdjustFunc != (int (*)())NoopDDA) vga256InfoRec.displayWidth = (*vgaPitchAdjustFunc)(); else { if (vga256InfoRec.virtualX % rounding) { vga256InfoRec.displayWidth = vga256InfoRec.virtualX + (rounding - (vga256InfoRec.virtualX % rounding)); ErrorF("%s %s: Display width set to %d (a multiple of %d)\n", XCONFIG_PROBED, vga256InfoRec.name, vga256InfoRec.displayWidth, rounding); } else { vga256InfoRec.displayWidth = vga256InfoRec.virtualX; } } if (vga256InfoRec.displayWidth * vga256InfoRec.virtualY > needmem) { ErrorF("%s: Too little memory for virtual resolution %d %d\n", vga256InfoRec.name, vga256InfoRec.virtualX, vga256InfoRec.virtualY); vgaEnterLeaveFunc(LEAVE); return(FALSE); } } #else if (vga256InfoRec.virtualX % rounding) { vga256InfoRec.virtualX -= vga256InfoRec.virtualX % rounding; ErrorF( "%s %s: Virtual width rounded down to a multiple of %d (%d)\n", XCONFIG_PROBED, vga256InfoRec.name, rounding, vga256InfoRec.virtualX); if (vga256InfoRec.virtualX < maxX) { ErrorF( "%s: Rounded down virtual width (%d) is too small for mode %s", vga256InfoRec.name, vga256InfoRec.virtualX, pmaxX->name); vgaEnterLeaveFunc(LEAVE); return(FALSE); } } if ( vga256InfoRec.virtualX * vga256InfoRec.virtualY > needmem) { if (vga256InfoRec.virtualX != maxX || vga256InfoRec.virtualY != maxY) ErrorF( "%s: Too little memory to accomodate virtual size and mode %s\n", vga256InfoRec.name, (vga256InfoRec.virtualX == maxX) ? pmaxX->name : pmaxY->name); else ErrorF("%s: Too little memory to accomodate modes %s and %s\n", vga256InfoRec.name, pmaxX->name, pmaxY->name); vgaEnterLeaveFunc(LEAVE); return(FALSE); } #endif #else if ( vga256InfoRec.displayWidth * vga256InfoRec.virtualY > needmem) { ErrorF("%s: Too little memory to accomodate display width %i" " and virtual height %i\n", vga256InfoRec.name, vga256InfoRec.displayWidth, vga256InfoRec.virtualY); vgaEnterLeaveFunc(LEAVE); return(FALSE); } #endif if ((tx != vga256InfoRec.virtualX) || (ty != vga256InfoRec.virtualY)) OFLG_CLR(XCONFIG_VIRTUAL,&vga256InfoRec.xconfigFlag); #ifdef USE_OLD_ROUNDING #ifndef BANKEDMONOVGA /* Let the driver have a chance to use a larger screen pitch if it needs. This ability is particularly useful for the Cirrus Laguna family, which uses tiled memory. Each scanline must be an integer number of tiles wide, where tiles are 128 or 256 bytes wide. Furthermore, there are only a few tile pitches allowed. It just so happens that none of these tile pitches yield a screen byte pitch that is divisible by 3. The upshot: you can't have 24bpp if the screen pitch is not a multiple of three -- i.e., if the screen pitch is not an integer number of _pixels_. */ if (vgaPitchAdjustFunc != (int (*)())NoopDDA) vga256InfoRec.displayWidth = (*vgaPitchAdjustFunc)(); else vga256InfoRec.displayWidth = vga256InfoRec.virtualX; #endif #endif if (xf86Verbose) ErrorF("%s %s: Virtual resolution set to %dx%d\n", OFLG_ISSET(XCONFIG_VIRTUAL,&vga256InfoRec.xconfigFlag) ? XCONFIG_GIVEN : XCONFIG_PROBED , vga256InfoRec.name, vga256InfoRec.virtualX, vga256InfoRec.virtualY); #if !defined(XF86VGA16) #if !defined(MONOVGA) if ((vga256InfoRec.speedup & ~SPEEDUP_ANYWIDTH) && vga256InfoRec.displayWidth != 1024) { ErrorF( "%s %s: SpeedUp code selection modified because virtualX != 1024\n", XCONFIG_PROBED, vga256InfoRec.name); vga256InfoRec.speedup &= SPEEDUP_ANYWIDTH; OFLG_CLR(XCONFIG_SPEEDUP,&vga256InfoRec.xconfigFlag); } /* * Currently the 16bpp and 32bpp modes use stock cfb with linear * addressing, so avoid the SpeedUp code for these depths. */ if (vgaBitsPerPixel == 8) { useSpeedUp = vga256InfoRec.speedup & SPEEDUP_ANYCHIPSET; if (useSpeedUp && xf86Verbose) ErrorF("%s %s: Generic SpeedUps selected (Flags=0x%x)\n", OFLG_ISSET(XCONFIG_SPEEDUP,&vga256InfoRec.xconfigFlag) ? XCONFIG_GIVEN : XCONFIG_PROBED , vga256InfoRec.name, useSpeedUp); /* We deal with the generic speedups here */ if (useSpeedUp & SPEEDUP_TEGBLT8) { #if !defined(__alpha__) vga256LowlevFuncs.teGlyphBlt8 = speedupvga256TEGlyphBlt8; vga256TEOps1Rect.ImageGlyphBlt = speedupvga256TEGlyphBlt8; vga256TEOps.ImageGlyphBlt = speedupvga256TEGlyphBlt8; #else /* !__alpha__ */ vga256LowlevFuncs.teGlyphBlt8 = vga256TEGlyphBlt8; vga256TEOps1Rect.ImageGlyphBlt = vga256TEGlyphBlt8; vga256TEOps.ImageGlyphBlt = vga256TEGlyphBlt8; #endif /* !__alpha__ */ } if (useSpeedUp & SPEEDUP_RECTSTIP) { #if !defined(__alpha__) vga256LowlevFuncs.fillRectOpaqueStippled32 = speedupvga2568FillRectOpaqueStippled32; vga256LowlevFuncs.fillRectTransparentStippled32 = speedupvga2568FillRectTransparentStippled32; #else /* !__alpha__ */ vga256LowlevFuncs.fillRectOpaqueStippled32 = vga2568FillRectOpaqueStippled32; vga256LowlevFuncs.fillRectTransparentStippled32 = vga2568FillRectTransparentStippled32; #endif /* !__alpha__ */ } if (!vgaUse2Banks) { vga256LowlevFuncs.vgaBitblt = OneBankvgaBitBlt; } } /* endif vgaBitsPerPixel == 8 */ /* Initialise chip-specific enhanced fb functions */ vgaHWCursor.Initialized = FALSE; (*vgaFbInitFunc)(); /* The driver should now have determined whether linear */ /* addressing is possible */ vgaUseLinearAddressing = Drivers[i]->ChipUseLinearAddressing; vgaPhysLinearBase = Drivers[i]->ChipLinearBase; vgaLinearSize = Drivers[i]->ChipLinearSize; #ifdef XFreeXDGA if (vga256InfoRec.directMode & XF86DGADirectPresent) vga256InfoRec.directMode |= XF86DGAAccelPresent; if (vgaUseLinearAddressing) { vga256InfoRec.physBase = vgaPhysLinearBase; vga256InfoRec.physSize = vga256InfoRec.videoRam * 1024; } else { vga256InfoRec.physBase = 0xA0000 + Drivers[i]->ChipWriteBottom; vga256InfoRec.physSize = Drivers[i]->ChipSegmentSize; vga256InfoRec.setBank = vgaSetVidPage; } #endif /* Currently linear addressing is required for 16/32bpp. */ /* Bail out if it is not enabled. */ if (vgaBitsPerPixel > 8 && !vgaUseLinearAddressing) { ErrorF("%s: Linear addressing is required for %dbpp\n", vga256InfoRec.name, vgaBitsPerPixel); vgaEnterLeaveFunc(LEAVE); return(FALSE); } #else #ifdef BANKEDMONOVGA if (vgaUse2Banks) { ourmfbDoBitbltCopy = mfbDoBitbltTwoBanksCopy; ourmfbDoBitbltCopyInverted = mfbDoBitbltTwoBanksCopyInverted; } else { ourmfbDoBitbltCopy = mfbDoBitbltCopy; ourmfbDoBitbltCopyInverted = mfbDoBitbltCopyInverted; } #else ourmfbDoBitbltCopy = mfbDoBitbltTwoBanksCopy; ourmfbDoBitbltCopyInverted = mfbDoBitbltTwoBanksCopyInverted; #endif /* BANKEDMONOVGA */ #endif /* !MONOVGA */ #endif /* !XF86VGA16 */ #if !defined(PC98) || defined(PC98_TGUI) || defined(PC98_MGA) || defined(PC98_SVGA) if (!OFLG_ISSET(OPTION_NO_PCI_PROBE, &vga256InfoRec.options)) { /* Free PCI information */ xf86cleanpci(); if (vgaPCIInfo) { vgaPCIInfo->ThisCard = (pciConfigPtr)NULL; vgaPCIInfo->AllCards = (pciConfigPtr *)NULL; } } #endif return TRUE; } } vgaSaveScreenFunc = vgaHWSaveScreen; /* Free PCI information */ xf86cleanpci(); if (vga256InfoRec.chipset) ErrorF("%s: '%s' is an invalid chipset", vga256InfoRec.name, vga256InfoRec.chipset); return FALSE; } /* Allow each driver to optionally set a display pitch other than the (default) virtualX size. This functionality was added by Corin Anderson while he was bringing up support for 24bpp and the Laguna family of Cirrus Logic chips. */ void vgaSetPitchAdjustHook(int (* ChipPitchAdjust)()) { vgaPitchAdjustFunc = ChipPitchAdjust; } /* Allow each driver to optionally set an offset of the frame buffer data from the linear base address. */ void vgaSetLinearOffsetHook(int (* ChipLinearOffset)()) { vgaLinearOffsetFunc = ChipLinearOffset; } /* Allow each driver to hook the ScreenInit function */ void vgaSetScreenInitHook(Bool (* ChipScrInit)()) { vgaScrInitFunc = ChipScrInit; } /* * vgaScreenInit -- * Attempt to find and initialize a VGA framebuffer * Most of the elements of the ScreenRec are filled in. The * video is enabled for the frame buffer... */ Bool vgaScreenInit (scr_index, pScreen, argc, argv) int scr_index; /* The index of pScreen in the ScreenInfo */ ScreenPtr pScreen; /* The Screen to initialize */ int argc; /* The number of the Server's arguments. */ char **argv; /* The arguments themselves. Don't change! */ { int displayResolution = 75; /* default to 75dpi */ extern int monitorResolution; if (serverGeneration == 1) { #if defined(PC98_WAB) || defined(PC98_WABEP) vgaBase = xf86MapVidMem(scr_index, VGA_REGION, (pointer)0xE0000, vgaMapSize); #else #if defined(PC98_GANB_WAP) || defined(PC98_WSNA) || defined(PC98_NKVNEC) vgaBase = xf86MapVidMem(scr_index, VGA_REGION, (pointer)0xF00000, vgaMapSize); #else #if defined(PC98_TGUI) if(!vgaUseLinearAddressing && pc98PvramBase != NULL) vgaBase = xf86MapVidMem(scr_index, VGA_REGION, pc98PvramBase, vgaMapSize); #else #if defined(PC98_EGC) || defined(PC98_NEC480) vgaBase = xf86MapVidMem(scr_index, VGA_REGION, (pointer)0xA8000, vgaMapSize); #else vgaBase = xf86MapVidMem(scr_index, VGA_REGION, (pointer)0xA0000, vgaMapSize); #endif /* PC98_EGC || PC98_NE480 */ #endif /* PC98_TGUI */ #endif /* PC98_GANB_WAP || PC98_WSNA || PC98_NKVNEC */ #endif /* PC98_WAB || PC98_WABEP */ if (vgaUseLinearAddressing) { vgaLinearBase = xf86MapVidMem(scr_index, LINEAR_REGION, (pointer) ((unsigned long)vgaPhysLinearBase), vgaLinearSize); vgaLinearOrig = vgaLinearBase; /* save copy of original base */ } #ifdef MONOVGA if (vga256InfoRec.displayWidth * vga256InfoRec.virtualY >= vgaSegmentSize * 8) { /* ^ mfb bug */ ErrorF("%s %s: Using banked mono vga mode\n", XCONFIG_PROBED, vga256InfoRec.name); vgaVirtBase = (pointer)VGABASE; } else { ErrorF("%s %s: Using non-banked mono vga mode\n", XCONFIG_PROBED, vga256InfoRec.name); vgaVirtBase = vgaBase; } #else #ifdef XF86VGA16 vgaVirtBase = vgaBase; #else vgaVirtBase = (pointer)VGABASE; #endif #endif /* This doesn't mean anything yet for SVGA 16/32bpp (no banking). */ if (vgaUseLinearAddressing) { if (vgaLinearOffsetFunc != (int (*)())NoopDDA) vgaLinearBase = (void *)((unsigned long)vgaLinearBase + (*vgaLinearOffsetFunc)()); vgaReadBottom = vgaLinearBase; vgaReadTop = (void *)((unsigned int)vgaLinearSize + (unsigned long)vgaLinearBase); vgaWriteBottom = vgaLinearBase; vgaWriteTop = (void *)((unsigned int)vgaLinearSize + (unsigned long)vgaLinearBase); vgaSegmentSize = vgaLinearSize; /* override */ vgaSegmentMask = vgaLinearSize - 1; vgaSetReadFunc = (void (*)())NoopDDA; vgaSetWriteFunc = (void (*)())NoopDDA; vgaSetReadWriteFunc = (void (*)())NoopDDA; } else { vgaReadBottom = (void *)((unsigned long)vgaReadBottom + (unsigned long)vgaBase); vgaReadTop = (void *)((unsigned long)vgaReadTop + (unsigned long)vgaBase); vgaWriteBottom = (void *)((unsigned long)vgaWriteBottom + (unsigned long)vgaBase); vgaWriteTop = (void *)((unsigned long)vgaWriteTop + (unsigned long)vgaBase); } } if (!(*vgaInitFunc)(vga256InfoRec.modes)) FatalError("%s: hardware initialisation failed\n", vga256InfoRec.name); /* * This function gets called while in graphics mode during a server * reset, and this causes the original video state to be corrupted. * So, only initialise vgaOrigVideoState if it hasn't previously been done * DHD Dec 1991. */ if (!vgaOrigVideoState) vgaOrigVideoState = (pointer)(*vgaSaveFunc)(vgaOrigVideoState); (*vgaRestoreFunc)(vgaNewVideoState); #ifndef DIRTY_STARTUP vgaSaveScreen(NULL, FALSE); /* blank the screen */ #endif (*vgaAdjustFunc)(vga256InfoRec.frameX0, vga256InfoRec.frameY0); /* * Take display resolution from the -dpi flag if specified */ if (monitorResolution) displayResolution = monitorResolution; /* * Inititalize the dragon to color display */ #ifndef XF86VGA16 #ifdef MONOVGA if (!mfbScreenInit(pScreen, (pointer) vgaVirtBase, vga256InfoRec.virtualX, vga256InfoRec.virtualY, displayResolution, displayResolution, vga256InfoRec.displayWidth)) #else xf86AccelInfoRec.ServerInfoRec = &vga256InfoRec; if (vgaBitsPerPixel == 8) if (!xf86XAAScreenInitvga256(pScreen, (pointer) vgaVirtBase, vga256InfoRec.virtualX, vga256InfoRec.virtualY, displayResolution, displayResolution, vga256InfoRec.displayWidth)) return(FALSE); if (vgaBitsPerPixel == 16) if (!xf86XAAScreenInit16bpp(pScreen, vgaLinearBase, vga256InfoRec.virtualX, vga256InfoRec.virtualY, displayResolution, displayResolution, vga256InfoRec.displayWidth)) return(FALSE); if (vgaBitsPerPixel == 24) if (!xf86XAAScreenInit24bpp(pScreen, vgaLinearBase, vga256InfoRec.virtualX, vga256InfoRec.virtualY, displayResolution, displayResolution, vga256InfoRec.displayWidth)) return(FALSE); if (vgaBitsPerPixel == 32) if (!xf86XAAScreenInit32bpp(pScreen, vgaLinearBase, vga256InfoRec.virtualX, vga256InfoRec.virtualY, displayResolution, displayResolution, vga256InfoRec.displayWidth)) #endif return(FALSE); #else /* XF86VGA16 */ Init16Output(pScreen, (pointer) vgaVirtBase, vga256InfoRec.virtualX, vga256InfoRec.virtualY, displayResolution, displayResolution, vga256InfoRec.displayWidth); #endif /* XF86VGA16 */ pScreen->whitePixel = 1; pScreen->blackPixel = 0; XF86FLIP_PIXELS(); #ifndef MONOVGA /* For 16/32bpp, the cfb defaults are OK. */ if (vgaBitsPerPixel <= 8) { /* For 8bpp SVGA and VGA16 */ pScreen->InstallColormap = vgaInstallColormap; pScreen->UninstallColormap = vgaUninstallColormap; pScreen->ListInstalledColormaps = vgaListInstalledColormaps; pScreen->StoreColors = vgaStoreColors; } /* Let each chip driver have a whack at hooking functions, etc. */ if (!(*vgaScrInitFunc)(pScreen, vgaLinearBase, vga256InfoRec.virtualX, vga256InfoRec.virtualY, displayResolution, displayResolution, vga256InfoRec.displayWidth)) return FALSE; #endif if (vgaHWCursor.Initialized) { xf86PointerScreenFuncs.WarpCursor = vgaHWCursor.Warp; pScreen->QueryBestSize = vgaHWCursor.QueryBestSize; vgaHWCursor.Init(0, pScreen); } else { miDCInitialize (pScreen, &xf86PointerScreenFuncs); } pScreen->CloseScreen = vgaCloseScreen; pScreen->SaveScreen = vgaSaveScreen; #ifndef XF86VGA16 #ifdef MONOVGA if (!mfbCreateDefColormap(pScreen)) #else if (!cfbCreateDefColormap(pScreen)) #endif return(FALSE); #else /* XF86VGA16 */ vga16CreateDefColormap(pScreen); #endif /* XF86VGA16 */ #ifndef DIRTY_STARTUP /* Fill the screen with black */ if (serverGeneration == 1) { #ifdef PC98_NEC480 { int i; extern short *vramwindow; outb(0xa8, 0xff); outb(0xaa, 0x00); outb(0xac, 0x00); outb(0xae, 0x00); for(i=0;i<10;i++) { *(vramwindow+2) = i; memset(vgaBase, 0xff, 0x8000); } *(vramwindow+2) = 0; } #else /* PC98_NEC480 */ #if (defined(MONOVGA) && !defined (BANKEDMONOVGA)) /* || defined(XF86VGA16) */ memset(vgaBase,pScreen->blackPixel,vgaSegmentSize); #else #ifdef PC98_EGC #if 1 { outw(EGC_PLANE, 0); outw(EGC_MODE, EGC_COPY_MODE); outw(EGC_FGC, pScreen->blackPixel); memset(vgaBase, 0xff, 0x8000); } #else vgaFillSolid( pScreen->blackPixel, GXcopy, 0x0F /* planes */, 0, 0, pScreen->width, pScreen->height ); #endif #else pointer vgaVirtPtr; pointer vgaPhysPtr; #if !defined(BANKEDMONOVGA) if (vgaUseLinearAddressing) { /* use original linear base from MapVidMem() */ memset(vgaLinearOrig, pScreen->blackPixel, vga256InfoRec.videoRam * 1024); } else /* banked: */ #endif for (vgaVirtPtr = vgaVirtBase; #if defined(MONOVGA) || defined(XF86VGA16) vgaVirtPtr<(pointer)((char *)vgaVirtBase+(vga256InfoRec.videoRam*256)); #else vgaVirtPtr<(pointer)((char *)vgaVirtBase+(vga256InfoRec.videoRam*1024)); #endif vgaVirtPtr = (pointer)((char *)vgaVirtPtr + vgaSegmentSize)) { #if defined(MONOVGA) if (vgaVirtBase == vgaBase) { /* Not using banking mode */ vgaPhysPtr = vgaBase; } else #endif { /* Set the bank, then clear it */ vgaPhysPtr=vgaSetWrite(vgaVirtPtr); } memset(vgaPhysPtr,pScreen->blackPixel,vgaSegmentSize); } #endif /* !PC98_EGC */ #endif /* MONOVGA */ #endif /* !PC98_NEC480 */ } vgaSaveScreen(NULL, TRUE); /* unblank the screen */ #endif /* ! DIRTY_STARTUP */ savepScreen = pScreen; return(TRUE); } static void saveDummy() {} /* * Assign a new serial number to the window. * Used to force GC validation on VT switch. */ /*ARGSUSED*/ static int vgaNewSerialNumber(pWin, data) WindowPtr pWin; pointer data; { pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; return WT_WALKCHILDREN; } /* * vgaEnterLeaveVT -- * grab/ungrab the current VT completely. */ void vgaEnterLeaveVT(enter, screen_idx) Bool enter; int screen_idx; { BoxRec pixBox; RegionRec pixReg; DDXPointRec pixPt; PixmapPtr pspix; ScreenPtr pScreen = savepScreen; if (!xf86Resetting && !xf86Exiting) { pixBox.x1 = 0; pixBox.x2 = pScreen->width; pixBox.y1 = 0; pixBox.y2 = pScreen->height; pixPt.x = 0; pixPt.y = 0; (pScreen->RegionInit)(&pixReg, &pixBox, 1); #if !defined(MONOVGA) && !defined(XF86VGA16) if (vgaBitsPerPixel == 8) pspix = (PixmapPtr)pScreen->devPrivate; if (vgaBitsPerPixel == 16) pspix = (PixmapPtr)pScreen->devPrivates[cfb16ScreenPrivateIndex].ptr; if (vgaBitsPerPixel == 24) pspix = (PixmapPtr)pScreen->devPrivates[cfb24ScreenPrivateIndex].ptr; if (vgaBitsPerPixel == 32) pspix = (PixmapPtr)pScreen->devPrivates[cfb32ScreenPrivateIndex].ptr; #else pspix = (PixmapPtr)pScreen->devPrivate; #endif } #ifdef XFreeXDGA /* * Patch up things to allow a graphics operations to go to the screen * while remaining in direct graphics mode. */ if (vga256InfoRec.directMode & XF86DGADoAccel) { if (enter) { #if !defined(MONOVGA) && !defined(XF86VGA16) if (vgaBitsPerPixel == 8) pspix->devPrivate.ptr = (pointer)vgaVirtBase; else pspix->devPrivate.ptr = vgaLinearBase; #else pspix->devPrivate.ptr = (pointer)vgaVirtBase; #endif } else { #if !defined(MONOVGA) && !defined(XF86VGA16) if (xf86AccelInfoRec.Sync != NULL) xf86AccelInfoRec.Sync(); /* XXX */ #endif pspix->devPrivate.ptr = ppix->devPrivate.ptr; } return; } #endif /* XFreeXDGA */ /* Force every GC writing to the screen to be validated. */ if (pScreen && !xf86Exiting && !xf86Resetting) WalkTree(pScreen, vgaNewSerialNumber, 0); if (enter) { vgaInitFunc = saveInitFunc; vgaSaveFunc = saveSaveFunc; vgaRestoreFunc = saveRestoreFunc; vgaAdjustFunc = saveAdjustFunc; vgaSaveScreenFunc = saveSaveScreenFunc; vgaSetReadFunc = saveSetReadFunc; vgaSetWriteFunc = saveSetWriteFunc; vgaSetReadWriteFunc = saveSetReadWriteFunc; xf86MapDisplay(screen_idx, VGA_REGION); if (vgaUseLinearAddressing) xf86MapDisplay(screen_idx, LINEAR_REGION); (*vgaEnterLeaveFunc)(ENTER); #if defined(__linux__) && defined(PC98_EGC) outb(0x62, 0x0c); outb(0xa2, 0x0d); #endif #ifdef XFreeXDGA if (vga256InfoRec.directMode & XF86DGADirectGraphics) { /* Should we do something here or not ? */ } else #endif { vgaOrigVideoState = (pointer)(*vgaSaveFunc)(vgaOrigVideoState); } (*vgaRestoreFunc)(vgaNewVideoState); #ifdef SCO /* * This is a temporary fix for et4000's, it shouldn't affect the other * drivers and the user doesn't notice it so, here it is. What does it * fix, et4000 driver leaves the screen blank when you switch back to it. * A mode toggle, even on the same mode, fixes it. */ vgaSwitchMode(vga256InfoRec.modes); #endif /* * point pspix back to vgaVirtBase, and copy the dummy buffer to the * real screen. */ if (!xf86Resetting) { ScrnInfoPtr pScr = XF86SCRNINFO(pScreen); if ((pointer)pspix->devPrivate.ptr != (pointer)vgaVirtBase && ppix) { #if !defined(MONOVGA) && !defined(XF86VGA16) if (vgaBitsPerPixel == 8) pspix->devPrivate.ptr = (pointer)vgaVirtBase; else pspix->devPrivate.ptr = vgaLinearBase; #else pspix->devPrivate.ptr = (pointer)vgaVirtBase; #endif #ifndef XF86VGA16 #ifdef MONOVGA mfbDoBitblt(&ppix->drawable, &pspix->drawable, GXcopy, &pixReg, &pixPt); #else if (vgaBitsPerPixel == 8) vga256DoBitblt(&ppix->drawable, &pspix->drawable, GXcopy, &pixReg, &pixPt, 0xFF); if (vgaBitsPerPixel == 16) cfb16DoBitblt(&ppix->drawable, &pspix->drawable, GXcopy, &pixReg, &pixPt, 0xFFFF); if (vgaBitsPerPixel == 24) cfb24DoBitblt(&ppix->drawable, &pspix->drawable, GXcopy, &pixReg, &pixPt, 0xFFFFFF); if (vgaBitsPerPixel == 32) cfb32DoBitblt(&ppix->drawable, &pspix->drawable, GXcopy, &pixReg, &pixPt, 0xFFFFFFFF); #endif #else /* XF86VGA16 */ vgaRestoreScreenPix(pScreen,ppix); #endif /* XF86VGA16 */ } if (vgaHWCursor.Initialized) { vgaHWCursor.Init(0, pScreen); vgaHWCursor.Restore(pScreen); vgaAdjustFunc(pScr->frameX0, pScr->frameY0); } } if (ppix) { (pScreen->DestroyPixmap)(ppix); ppix = NULL; } } else { /* Make sure that another driver hasn't disabeled IO */ xf86MapDisplay(screen_idx, VGA_REGION); if (vgaUseLinearAddressing) xf86MapDisplay(screen_idx, LINEAR_REGION); (*vgaEnterLeaveFunc)(ENTER); /* * Create a dummy pixmap to write to while VT is switched out. * Copy the screen to that pixmap */ if (!xf86Exiting) { ppix = (pScreen->CreatePixmap)(pScreen, vga256InfoRec.displayWidth, pScreen->height, pScreen->rootDepth); if (ppix) { #ifndef XF86VGA16 #ifdef MONOVGA mfbDoBitblt(&pspix->drawable, &ppix->drawable, GXcopy, &pixReg, &pixPt, 0xFF); #else if (vgaBitsPerPixel == 8) vga256DoBitblt(&pspix->drawable, &ppix->drawable, GXcopy, &pixReg, &pixPt, 0xFF); if (vgaBitsPerPixel == 16) cfb16DoBitblt(&pspix->drawable, &ppix->drawable, GXcopy, &pixReg, &pixPt, 0xFFFF); if (vgaBitsPerPixel == 24){ cfb24DoBitblt(&pspix->drawable, &ppix->drawable, GXcopy, &pixReg, &pixPt, 0xFFFFFF); } if (vgaBitsPerPixel == 32) cfb32DoBitblt(&pspix->drawable, &ppix->drawable, GXcopy, &pixReg, &pixPt, 0xFFFFFFFF); #endif #else /* XF86VGA16 */ vgaSaveScreenPix(pScreen,ppix); #endif /* XF86VGA16 */ pspix->devPrivate.ptr = ppix->devPrivate.ptr; } (*vgaSaveFunc)(vgaNewVideoState); #if !defined(MONOVGA) && !defined(XF86VGA16) xf86InvalidatePixmapCache(); #endif } /* * We come here in many cases, but one is special: When the server aborts * abnormaly. Therefore there MUST be a check whether vgaOrigVideoState * is valid or not. */ #ifdef XFreeXDGA if (vga256InfoRec.directMode & XF86DGADirectGraphics) { /* make sure we are in linear mode */ /* hide any harware cursors */ (*vgaEnterLeaveFunc)(LEAVE); } else #endif { if (vgaOrigVideoState) (*vgaRestoreFunc)(vgaOrigVideoState); (*vgaEnterLeaveFunc)(LEAVE); xf86UnMapDisplay(screen_idx, VGA_REGION); if (vgaUseLinearAddressing) { xf86UnMapDisplay(screen_idx, LINEAR_REGION); } } saveInitFunc = vgaInitFunc; saveSaveFunc = vgaSaveFunc; saveRestoreFunc = vgaRestoreFunc; saveAdjustFunc = vgaAdjustFunc; saveSaveScreenFunc = vgaSaveScreenFunc; saveSetReadFunc = vgaSetReadFunc; saveSetWriteFunc = vgaSetWriteFunc; saveSetReadWriteFunc = vgaSetReadWriteFunc; #ifdef XFreeXDGA if (!(vga256InfoRec.directMode & XF86DGADirectGraphics)) { #endif vgaInitFunc = (Bool (*)())saveDummy; vgaSaveFunc = (void * (*)())saveDummy; vgaRestoreFunc = (void (*)())saveDummy; vgaAdjustFunc = (void (*)())saveDummy; vgaSetReadFunc = (void (*)())saveDummy; vgaSetWriteFunc = (void (*)())saveDummy; vgaSetReadWriteFunc = (void (*)())saveDummy; #ifdef XFreeXDGA } #endif vgaSaveScreenFunc = (void (*)())saveDummy; } } /* * vgaCloseScreen -- * called to ensure video is enabled when server exits. */ Bool vgaCloseScreen(screen_idx, pScreen) int screen_idx; ScreenPtr pScreen; { /* * Hmm... The server may shut down even if it is not running on the * current vt. Let's catch this case here. */ xf86Exiting = TRUE; #ifdef PC98_EGC /* clear screen */ { outw(EGC_PLANE, 0); outw(EGC_MODE, EGC_COPY_MODE); outw(EGC_FGC, 0); memset(vgaBase, 0xff, 0x8000); } outb(0x6a, 0x07); outb(0x6a, 0x04); outb(0x6a, 0x06); /* outb((hiresoflg)?0xa4:0x7c, 0x00); */ outb(0x7c, 0x00); #if defined(__linux__) outb(0x62, 0x0d); #endif /* __linux__ */ #endif /* PC98_EGC */ #ifdef PC98_NEC480 { int i; extern short *vramwindow; outb(0xa8, 0xff); outb(0xaa, 0x00); outb(0xac, 0x00); outb(0xae, 0x00); for(i=0;i<10;i++) { *(vramwindow+2) = i; memset(vgaBase, 0xff, 0x8000); } *(vramwindow+2) = 0; } outb(0x6a, 0x07); outb(0x6a, 0x04); outb(0x6a, 0x06); outb(0x7c, 0x00); #endif /* PC98_NEC480 */ if (xf86VTSema) vgaEnterLeaveVT(LEAVE, screen_idx); else if (ppix) { /* * 7-Jan-94 CEG: The server is not running on the current vt. * Free the screen snapshot taken when the server vt was left. */ (savepScreen->DestroyPixmap)(ppix); ppix = NULL; } return(TRUE); } /* * vgaAdjustFrame -- * Set a new viewport */ void vgaAdjustFrame(x, y) int x, y; { (*vgaAdjustFunc)(x, y); } /* * vgaSwitchMode -- * Set a new display mode */ Bool vgaSwitchMode(mode) DisplayModePtr mode; { if ((*vgaInitFunc)(mode)) { (*vgaRestoreFunc)(vgaNewVideoState); if (vgaHWCursor.Initialized) { vgaHWCursor.Restore(savepScreen); } return(TRUE); } else { ErrorF("Mode switch failed because of hardware initialisation error\n"); return(FALSE); } } /* * vgaValidMode -- * Validate a mode for VGA architecture. Also checks the chip driver * to see if the mode can be supported. */ int vgaValidMode(mode, verbose, flag) DisplayModePtr mode; Bool verbose; int flag; { return (*vgaValidModeFunc)(mode, verbose, flag); }