diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:55 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:55 +0000 |
commit | 8ab74f7dc71060c6c9e7d8b62c96dd322c5f5f51 (patch) | |
tree | 6f9859aac3e85aab2cadb8066753977094ba3495 |
Initial revisionXORG-STABLE
-rw-r--r-- | man/vga.man | 65 | ||||
-rw-r--r-- | src/generic.c | 1591 |
2 files changed, 1656 insertions, 0 deletions
diff --git a/man/vga.man b/man/vga.man new file mode 100644 index 0000000..5781c1b --- /dev/null +++ b/man/vga.man @@ -0,0 +1,65 @@ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vga/vga.man,v 1.3 2001/12/17 20:52:34 dawes Exp $ +.\" shorthand for double quote that works everywhere. +.ds q \N'34' +.TH VGA __drivermansuffix__ __vendorversion__ +.SH NAME +vga \- Generic VGA video driver +.SH SYNOPSIS +.nf +.B "Section \*qDevice\*q" +.BI " Identifier \*q" devname \*q +.B " Driver \*qvga\*q" +\ \ ... +.B EndSection +.fi +.SH DESCRIPTION +.B vga +is an XFree86 driver for generic VGA video cards. It can drive most +VGA-compatible video cards, but only makes use of the basic standard +VGA core that is common to these cards. The driver supports depths 1, 4 +and 8. All relevant visual types are supported at each depth. +Multi-head configurations +are supported in combination with some other drivers, but only when the +.B vga +driver is driving the primary head. +.SH SUPPORTED HARDWARE +The +.B vga +driver supports most VGA-compatible video cards. There are some known +exceptions, and those should be listed here. +.SH CONFIGURATION DETAILS +Please refer to XF86Config(__filemansuffix__) for general configuration +details. This section only covers configuration details specific to this +driver. +.PP +The driver auto-detects the presence of VGA-compatible hardware. The +.B ChipSet +name may optionally be specified in the config file +.B \*qDevice\*q +section, and will override the auto-detection: +.PP +.RS 4 +"generic" +.RE +.PP +The driver will only use 64k of video memory for depth 1 and depth 8 operation, +and 256k of video memory for depth 4 (this is the standard VGA limit). +.PP +When operating at depth 8, only a single built-in 320x200 video mode is +available. At other depths there is more flexibility regarding mode choice. +.PP +The following driver +.B Options +are supported: +.TP +.BI "Option \*qShadowFB\*q \*q" boolean \*q +Enable or disable use of the shadow framebuffer layer. Default: off. + +This option is recommended for performance reasons when running at depths +1 and 4, especially when using modern PCI-based hardware. It is required +when using those depths in a multi-head configuration where one or more +of the other screens is operating at a different depth. +.SH "SEE ALSO" +XFree86(1), XF86Config(__filemansuffix__), xf86config(1), Xserver(1), X(__miscmansuffix__) +.SH AUTHORS +Authors include: Marc La France, David Dawes, and Dirk Hohndel. diff --git a/src/generic.c b/src/generic.c new file mode 100644 index 0000000..fa9acd0 --- /dev/null +++ b/src/generic.c @@ -0,0 +1,1591 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vga/generic.c,v 1.62 2002/12/03 01:58:58 dickey Exp $ */ +/* + * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +/* + * This is essentially a merge of two different drivers: a VGA planar driver + * (originally by David Dawes <dawes@xfree86.org>) and a 256-colour VGA driver + * by Harm Hanemaayer <hhanemaa@cs.ruu.nl>. + * + * The port of this driver to XFree86 4.0 was done by: + * David Dawes <dawes@xfree86.org> + * Dirk H. Hohndel <hohndel@xfree86.org> + * Marc Aurele La France <tsi@xfree86.org> + */ + +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "compiler.h" +#include "vgaHW.h" +#include "xf86PciInfo.h" + +#include "fb.h" + +#include "xf4bpp.h" +#include "xf1bpp.h" + +#include "shadowfb.h" + +#include "mipointer.h" +#include "micmap.h" + +#include "xf86RAC.h" +#include "xf86Resources.h" +#include "xf86int10.h" + +/* Some systems #define VGA for their own purposes */ +#undef VGA + +/* A few things all drivers should have */ +#define VGA_NAME "VGA" +#define VGA_DRIVER_NAME "vga" +#define VGA_VERSION_NAME "4.0" +#define VGA_VERSION_MAJOR 4 +#define VGA_VERSION_MINOR 0 +#define VGA_PATCHLEVEL 0 +#define VGA_VERSION_CURRENT ((VGA_VERSION_MAJOR << 24) | \ + (VGA_VERSION_MINOR << 16) | VGA_PATCHLEVEL) + + +/* Forward definitions */ +static const OptionInfoRec * GenericAvailableOptions(int chipid, int busid); +static void GenericIdentify(int); +static Bool GenericProbe(DriverPtr, int); +static Bool GenericPreInit(ScrnInfoPtr, int); +static Bool GenericScreenInit(int, ScreenPtr, int, char **); +static Bool GenericSwitchMode(int, DisplayModePtr, int); +static void GenericAdjustFrame(int, int, int, int); +static Bool GenericEnterVT(int, int); +static void GenericLeaveVT(int, int); +static void GenericFreeScreen(int, int); +static int VGAFindIsaDevice(GDevPtr dev); +#ifdef SPECIAL_FB_BYTE_ACCESS +static Bool GenericMapMem(ScrnInfoPtr scrp); +#endif + +static int GenericValidMode(int, DisplayModePtr, Bool, int); + +/* The root of all evil... */ +DriverRec VGA = +{ + VGA_VERSION_CURRENT, + VGA_DRIVER_NAME, + GenericIdentify, + GenericProbe, + GenericAvailableOptions, + NULL, + 0 +}; + +typedef enum +{ + OPTION_SHADOW_FB, + OPTION_VGA_CLOCKS, + OPTION_KGA_UNIVERSAL +} GenericOpts; + +static const OptionInfoRec GenericOptions[] = +{ + { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VGA_CLOCKS, "VGAClocks", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_KGA_UNIVERSAL, "KGAUniversal", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static const char *vgahwSymbols[] = +{ + "vgaHWBlankScreen", + "vgaHWDPMSSet", + "vgaHWFreeHWRec", + "vgaHWGetHWRec", + "vgaHWGetIOBase", + "vgaHWGetIndex", + "vgaHWHandleColormaps", + "vgaHWInit", + "vgaHWLock", + "vgaHWMapMem", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWSave", + "vgaHWSaveScreen", + "vgaHWUnlock", + "vgaHWUnmapMem", + NULL +}; + +static const char *miscfbSymbols[] = +{ + "xf1bppScreenInit", + "xf4bppScreenInit", + NULL +}; + +static const char *fbSymbols[] = +{ + "fbPictureInit", + "fbScreenInit", + NULL +}; + +static const char *shadowfbSymbols[] = +{ + "ShadowFBInit", + NULL +}; + +static const char *int10Symbols[] = +{ + "xf86ExtendedInitInt10", + "xf86FreeInt10", + NULL +}; + +#ifdef XFree86LOADER + +/* Module loader interface */ + +static MODULESETUPPROTO(GenericSetup); + +static XF86ModuleVersionInfo GenericVersionRec = +{ + VGA_DRIVER_NAME, + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + VGA_VERSION_MAJOR, VGA_VERSION_MINOR, VGA_PATCHLEVEL, + ABI_CLASS_VIDEODRV, + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} +}; + +/* + * This data is accessed by the loader. The name must be the module name + * followed by "ModuleData". + */ +XF86ModuleData vgaModuleData = { &GenericVersionRec, GenericSetup, NULL }; + +static pointer +GenericSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) +{ + static Bool Initialised = FALSE; + + if (!Initialised) + { + Initialised = TRUE; + xf86AddDriver(&VGA, Module, 0); + LoaderRefSymLists(vgahwSymbols, miscfbSymbols, fbSymbols, + shadowfbSymbols, int10Symbols, NULL); + return (pointer)TRUE; + } + + if (ErrorMajor) + *ErrorMajor = LDR_ONCEONLY; + return NULL; +} + +#endif + + +enum GenericTypes +{ + CHIP_VGA_GENERIC +}; + +/* Supported chipsets */ +static SymTabRec GenericChipsets[] = +{ + {CHIP_VGA_GENERIC, "generic"}, + {-1, NULL} +}; + +static PciChipsets GenericPCIchipsets[] = +{ + {CHIP_VGA_GENERIC, PCI_CHIP_VGA, RES_SHARED_VGA}, + {-1, -1, RES_UNDEFINED}, +}; + +static IsaChipsets GenericISAchipsets[] = +{ + {CHIP_VGA_GENERIC, RES_EXCLUSIVE_VGA}, + {-1, 0} +}; + +static void +GenericIdentify(int flags) +{ + xf86PrintChipsets(VGA_NAME, + "Generic VGA driver (version " VGA_VERSION_NAME ") for chipsets", + GenericChipsets); +} + +static const OptionInfoRec * +GenericAvailableOptions(int chipid, int busid) +{ + return GenericOptions; +} + +/* + * This function is called once, at the start of the first server generation to + * do a minimal probe for supported hardware. + */ + +static Bool +GenericProbe(DriverPtr drv, int flags) +{ + Bool foundScreen = FALSE; + int numDevSections, numUsed; + GDevPtr *devSections; + int *usedChips; + int i; + + /* + * Find the config file Device sections that match this + * driver, and return if there are none. + */ + if ((numDevSections = xf86MatchDevice(VGA_NAME, &devSections)) <= 0) + return FALSE; + + /* PCI BUS */ + if (xf86GetPciVideoInfo()) + { + numUsed = xf86MatchPciInstances(VGA_NAME, PCI_VENDOR_GENERIC, + GenericChipsets, GenericPCIchipsets, + devSections, numDevSections, + drv, &usedChips); + if (numUsed > 0) + { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else + { + for (i = 0; i < numUsed; i++) + { + ScrnInfoPtr pScrn = NULL; + /* Allocate a ScrnInfoRec */ + pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], + GenericPCIchipsets, NULL, + NULL, NULL, NULL, NULL); + if (pScrn) + { + pScrn->driverVersion = VGA_VERSION_CURRENT; + pScrn->driverName = VGA_DRIVER_NAME; + pScrn->name = VGA_NAME; + pScrn->Probe = GenericProbe; + pScrn->PreInit = GenericPreInit; + pScrn->ScreenInit = GenericScreenInit; + pScrn->SwitchMode = GenericSwitchMode; + pScrn->AdjustFrame = GenericAdjustFrame; + pScrn->EnterVT = GenericEnterVT; + pScrn->LeaveVT = GenericLeaveVT; + pScrn->FreeScreen = GenericFreeScreen; + pScrn->ValidMode = GenericValidMode; + foundScreen = TRUE; + } + } + } + xfree(usedChips); + } + } + + /* Isa Bus */ + numUsed = xf86MatchIsaInstances(VGA_NAME, GenericChipsets, + GenericISAchipsets, drv, + VGAFindIsaDevice, devSections, + numDevSections, &usedChips); + if (numUsed > 0) + { + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else for (i = 0; i < numUsed; i++) + { + ScrnInfoPtr pScrn = NULL; + pScrn = xf86ConfigIsaEntity(pScrn, 0, usedChips[i], + GenericISAchipsets, + NULL, NULL, NULL, NULL, NULL); + if (pScrn) + { + pScrn->driverVersion = VGA_VERSION_CURRENT; + pScrn->driverName = VGA_DRIVER_NAME; + pScrn->name = VGA_NAME; + pScrn->Probe = GenericProbe; + pScrn->PreInit = GenericPreInit; + pScrn->ScreenInit = GenericScreenInit; + pScrn->SwitchMode = GenericSwitchMode; + pScrn->AdjustFrame = GenericAdjustFrame; + pScrn->EnterVT = GenericEnterVT; + pScrn->LeaveVT = GenericLeaveVT; + pScrn->FreeScreen = GenericFreeScreen; + pScrn->ValidMode = GenericValidMode; + foundScreen = TRUE; + } + + xfree(usedChips); + } + } + + xfree(devSections); + return foundScreen; +} + +static int +VGAFindIsaDevice(GDevPtr dev) +{ +#ifndef PC98_EGC + CARD16 GenericIOBase = VGAHW_GET_IOBASE(); + CARD8 CurrentValue, TestValue; + + /* There's no need to unlock VGA CRTC registers here */ + + /* VGA has one more read/write attribute register than EGA */ + (void) inb(GenericIOBase + 0x0AU); /* Reset flip-flop */ + outb(VGA_ATTR_INDEX, 0x14 | 0x20); + CurrentValue = inb(VGA_ATTR_DATA_R); + outb(VGA_ATTR_DATA_W, CurrentValue ^ 0x0F); + outb(VGA_ATTR_INDEX, 0x14 | 0x20); + TestValue = inb(VGA_ATTR_DATA_R); + outb(VGA_ATTR_DATA_W, CurrentValue); + + /* Quit now if no VGA is present */ + if ((CurrentValue ^ 0x0F) != TestValue) + return -1; +#endif + + return (int)CHIP_VGA_GENERIC; +} + +static Bool +GenericClockSelect(ScrnInfoPtr pScreenInfo, int ClockNumber) +{ +# ifndef PC98_EGC + vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); + static CARD8 save_misc; + + switch (ClockNumber) + { + case CLK_REG_SAVE: + save_misc = inb(pvgaHW->PIOOffset + VGA_MISC_OUT_R); + break; + + case CLK_REG_RESTORE: + outb(pvgaHW->PIOOffset + VGA_MISC_OUT_W, save_misc); + break; + + default: + outb(pvgaHW->PIOOffset + VGA_MISC_OUT_W, + (save_misc & 0xF3) | ((ClockNumber << 2) & 0x0C)); + break; + } +# endif + + return TRUE; +} + + +/* + * This structure is used to wrap the screen's CloseScreen vector. + */ +typedef struct _GenericRec +{ + Bool ShadowFB; + Bool KGAUniversal; + CARD8 * ShadowPtr; + CARD32 ShadowPitch; + CloseScreenProcPtr CloseScreen; + OptionInfoPtr Options; +} GenericRec, *GenericPtr; + + +static GenericPtr +GenericGetRec(ScrnInfoPtr pScreenInfo) +{ + if (!pScreenInfo->driverPrivate) + pScreenInfo->driverPrivate = xcalloc(sizeof(GenericRec), 1); + + return (GenericPtr)pScreenInfo->driverPrivate; +} + + +static void +GenericFreeRec(ScrnInfoPtr pScreenInfo) +{ + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(pScreenInfo); + xfree(pScreenInfo->driverPrivate); + pScreenInfo->driverPrivate = NULL; +} + + +static void +GenericProtect(ScrnInfoPtr pScreenInfo, Bool On) +{ + vgaHWProtect(pScreenInfo, On); +} + + +static Bool +GenericSaveScreen(ScreenPtr pScreen, int mode) +{ + return vgaHWSaveScreen(pScreen, mode); +} + +static void +GenericBlankScreen(ScrnInfoPtr pScreenInfo, Bool Unblank) +{ + vgaHWBlankScreen(pScreenInfo, Unblank); +} + + +/* The default mode */ +static DisplayModeRec GenericDefaultMode = +{ + NULL, NULL, /* prev & next */ + "Generic 320x200 default mode", + MODE_OK, /* Mode status */ + M_T_CRTC_C, /* Mode type */ + 12588, /* Pixel clock */ + 320, 336, 384, 400, /* HTiming */ + 0, /* HSkew */ + 200, 206, 207, 224, /* VTiming */ + 2, /* VScan */ + V_CLKDIV2 | V_NHSYNC | V_PVSYNC, /* Flags */ + 0, 25176, /* ClockIndex & SynthClock */ + 0, 0, 0, 0, 0, 0, /* Crtc timings set by ... */ + 0, /* ... xf86SetCrtcForModes() */ + 0, 0, 0, 0, 0, 0, + FALSE, FALSE, /* These are unadjusted timings */ + 0, NULL, /* PrivSize & Private */ + 0.0, 0.0 /* HSync & VRefresh */ +}; + + +/* + * This function is called once for each screen at the start of the first + * server generation to initialise the screen for all server generations. + */ +static Bool +GenericPreInit(ScrnInfoPtr pScreenInfo, int flags) +{ + static rgb defaultWeight = {0, 0, 0}; + static ClockRange GenericClockRange = + {NULL, 0, 80000, 0, FALSE, TRUE, 1, 1, 0}; + MessageType From; + int i, videoRam, Rounding, nModes = 0; + const char *Module = NULL; + const char *Sym = NULL; + vgaHWPtr pvgaHW; + GenericPtr pGenericPriv; + EntityInfoPtr pEnt; + + if (flags & PROBE_DETECT) + return FALSE; + + /* Set the monitor */ + pScreenInfo->monitor = pScreenInfo->confScreen->monitor; + + if (pScreenInfo->numEntities > 1) + return FALSE; + pEnt = xf86GetEntityInfo(*pScreenInfo->entityList); + if (pEnt->resources) + return FALSE; + + if (xf86LoadSubModule(pScreenInfo, "int10")) + { + xf86Int10InfoPtr pInt; + xf86LoaderReqSymLists(int10Symbols, NULL); + xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, "initializing int10.\n"); + pInt = xf86ExtendedInitInt10(pEnt->index, + SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); + xf86FreeInt10(pInt); + } + + + { + static resRange unusedmem[] = { {ResShrMemBlock, 0xB0000, 0xB7FFF}, + {ResShrMemBlock, 0xB8000, 0xBFFFF}, + _END }; + + /* XXX Should this be "disabled" or "unused"? */ + xf86SetOperatingState(unusedmem, pEnt->index, ResUnusedOpr); + } + + /* Determine depth, bpp, etc. */ + if (!xf86SetDepthBpp(pScreenInfo, 4, 0, 4, NoDepth24Support)) + return FALSE; + pScreenInfo->chipset = + (char *)xf86TokenToString(GenericChipsets, pEnt->chipset); + + switch (pScreenInfo->depth) + { + case 1: Module = "xf1bpp"; Sym = "xf1bppScreenInit"; break; + case 4: Module = "xf4bpp"; Sym = "xf4bppScreenInit"; break; + default: Module = "fb"; break; + } + + xf86PrintDepthBpp(pScreenInfo); + + /* Determine colour weights */ + pScreenInfo->rgbBits = 6; + if (!xf86SetWeight(pScreenInfo, defaultWeight, defaultWeight)) + return FALSE; + + /* XXX: Check that returned weight is supported */ + + /* Determine default visual */ + if (!xf86SetDefaultVisual(pScreenInfo, -1)) + return FALSE; + + /* The gamma fields must be initialised when using the new cmap code */ + if (pScreenInfo->depth > 1) + { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScreenInfo, zeros)) + return FALSE; + } + + /* + * Determine videoRam. For mode validation purposes, this needs to be + * limited to VGA specifications. + */ + if ((videoRam = pEnt->device->videoRam)) + { + pScreenInfo->videoRam = videoRam; + if (pScreenInfo->depth == 8) + { + if (videoRam > 64) + pScreenInfo->videoRam = 64; + } + else + { + if (videoRam > 256) + pScreenInfo->videoRam = 256; + } + From = X_CONFIG; + } + else + { + if (pScreenInfo->depth == 8) + videoRam = 64; + else + videoRam = 256; + pScreenInfo->videoRam = videoRam; + From = X_DEFAULT; /* Instead of X_PROBED */ + } + + if (pScreenInfo->depth == 1) + pScreenInfo->videoRam >>= 2; + xf86DrvMsg(pScreenInfo->scrnIndex, From, "videoRam: %d kBytes", videoRam); + if (videoRam != pScreenInfo->videoRam) + xf86ErrorF(" (using %d kBytes)", pScreenInfo->videoRam); + xf86ErrorF(".\n"); + + if (xf86RegisterResources(pEnt->index, NULL, ResNone)) + return FALSE; + + /* Ensure vgahw entry points are available for the clock probe */ + if (!xf86LoadSubModule(pScreenInfo, "vgahw")) + return FALSE; + + xf86LoaderReqSymLists(vgahwSymbols, NULL); + + /* Allocate driver private structure */ + if (!(pGenericPriv = GenericGetRec(pScreenInfo))) + return FALSE; + + /* Ensure vgahw private structure is allocated */ + if (!vgaHWGetHWRec(pScreenInfo)) + return FALSE; + + pvgaHW = VGAHWPTR(pScreenInfo); + pvgaHW->MapSize = 0x00010000; /* Standard 64kB VGA window */ + vgaHWGetIOBase(pvgaHW); /* Get VGA I/O base */ + + /* Deal with options */ + xf86CollectOptions(pScreenInfo, NULL); + + if (!(pGenericPriv->Options = xalloc(sizeof(GenericOptions)))) + return FALSE; + memcpy(pGenericPriv->Options, GenericOptions, sizeof(GenericOptions)); + xf86ProcessOptions(pScreenInfo->scrnIndex, pScreenInfo->options, + pGenericPriv->Options); + +#ifndef __NOT_YET__ + if (pScreenInfo->depth == 8) + { + pScreenInfo->numClocks = 1; + pScreenInfo->clock[0] = 25175; + goto SetDefaultMode; + } +#endif + + /* + * Determine clocks. Limit them to the first four because that's all that + * can be addressed. + */ + if ((pScreenInfo->numClocks = pEnt->device->numclocks)) + { + if (pScreenInfo->numClocks > 4) + pScreenInfo->numClocks = 4; + for (i = 0; i < pScreenInfo->numClocks; i++) + pScreenInfo->clock[i] = pEnt->device->clock[i]; + From = X_CONFIG; + } + else + if (xf86ReturnOptValBool(pGenericPriv->Options, OPTION_VGA_CLOCKS, FALSE)) + { + pScreenInfo->numClocks = 2; + pScreenInfo->clock[0] = 25175; + pScreenInfo->clock[1] = 28322; + } + else + { + xf86GetClocks(pScreenInfo, 4, + GenericClockSelect, GenericProtect, GenericBlankScreen, + pvgaHW->PIOOffset + pvgaHW->IOBase + VGA_IN_STAT_1_OFFSET, + 0x08, 1, 28322); + From = X_PROBED; + } + xf86ShowClocks(pScreenInfo, From); + + /* Set the virtual X rounding (in bits) */ + if (pScreenInfo->depth == 8) + Rounding = 16 * 8; + else + Rounding = 16; + + /* + * Validate the modes. Note that the limits passed to xf86ValidateModes() + * are VGA CRTC architectural limits. + */ + pScreenInfo->maxHValue = 2080; + pScreenInfo->maxVValue = 1025; + nModes = xf86ValidateModes(pScreenInfo, pScreenInfo->monitor->Modes, + pScreenInfo->display->modes, &GenericClockRange, + NULL, 8, 2040, Rounding, 1, 1024, + pScreenInfo->display->virtualX, + pScreenInfo->display->virtualY, 0x10000, + LOOKUP_CLOSEST_CLOCK | LOOKUP_CLKDIV2); + + if (nModes < 0) + return FALSE; + + /* Remove invalid modes */ + xf86PruneDriverModes(pScreenInfo); + + if (!nModes || !pScreenInfo->modes) + { +#ifndef __NOT_YET__ + SetDefaultMode: +#endif + /* Set a default mode, overridding any virtual settings */ + pScreenInfo->virtualX = pScreenInfo->displayWidth = 320; + pScreenInfo->virtualY = 200; + pScreenInfo->modes = xalloc(sizeof(DisplayModeRec)); + if (!pScreenInfo->modes) + return FALSE; + *pScreenInfo->modes = GenericDefaultMode; + pScreenInfo->modes->prev = pScreenInfo->modes; + pScreenInfo->modes->next = pScreenInfo->modes; + + pScreenInfo->virtualFrom = X_DEFAULT; + } + + /* Set CRTC values for the modes */ + xf86SetCrtcForModes(pScreenInfo, 0); + + /* Set current mode to the first in list */ + pScreenInfo->currentMode = pScreenInfo->modes; + + /* Print mode list */ + xf86PrintModes(pScreenInfo); + + /* Set display resolution */ + xf86SetDpi(pScreenInfo, 0, 0); + + if (xf86ReturnOptValBool(pGenericPriv->Options, OPTION_SHADOW_FB, FALSE)) + { + pGenericPriv->ShadowFB = TRUE; + xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\".\n"); + } + + if (xf86ReturnOptValBool(pGenericPriv->Options, OPTION_KGA_UNIVERSAL, + FALSE)) + { + pGenericPriv->KGAUniversal = TRUE; + xf86DrvMsg(pScreenInfo->scrnIndex, X_CONFIG, + "Enabling universal \"KGA\" treatment.\n"); + } + +#ifdef SPECIAL_FB_BYTE_ACCESS + if (!pGenericPriv->ShadowFB && (pScreenInfo->depth == 4)) + { + xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO, + "Architecture requires special FB access for this depth:" + " ShadowFB enabled.\n"); + pGenericPriv->ShadowFB = TRUE; + } +#endif + + if (pGenericPriv->ShadowFB) + { + pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + Module = "fb"; + Sym = NULL; + if (!xf86LoadSubModule(pScreenInfo, "shadowfb")) + return FALSE; + xf86LoaderReqSymLists(shadowfbSymbols, NULL); + } + + /* Ensure depth-specific entry points are available */ + if (Module) + { + if (!xf86LoadSubModule(pScreenInfo, Module)) + return FALSE; + + if (Sym) + xf86LoaderReqSymbols(Sym, NULL); + else + xf86LoaderReqSymLists(fbSymbols, NULL); + } + + /* Only one chipset here */ + if (!pScreenInfo->chipset) + pScreenInfo->chipset = (char *)GenericChipsets[0].name; + + return TRUE; /* Tada! */ +} + + +/* Save mode on server entry */ +static void +GenericSave(ScrnInfoPtr pScreenInfo) +{ + vgaHWSave(pScreenInfo, &VGAHWPTR(pScreenInfo)->SavedReg, VGA_SR_ALL); +} + + +/* Restore the mode that was saved on server entry */ +static void +GenericRestore(ScrnInfoPtr pScreenInfo) +{ + vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); + + vgaHWProtect(pScreenInfo, TRUE); + vgaHWRestore(pScreenInfo, &pvgaHW->SavedReg, VGA_SR_ALL); + vgaHWProtect(pScreenInfo, FALSE); +} + + +/* Set a graphics mode */ +static Bool +GenericSetMode(ScrnInfoPtr pScreenInfo, DisplayModePtr pMode) +{ + vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); + GenericPtr pGenericPriv = GenericGetRec(pScreenInfo); + + if (!vgaHWInit(pScreenInfo, pMode)) + return FALSE; + if (pGenericPriv->KGAUniversal) + { +#define KGA_FLAGS (KGA_FIX_OVERSCAN | KGA_BE_TOT_DEC) + vgaHWHBlankKGA(pMode, &pvgaHW->ModeReg, 0, KGA_FLAGS); + vgaHWHBlankKGA(pMode, &pvgaHW->ModeReg, 0, KGA_FLAGS); +#undef KGA_FLAGS + } + + pScreenInfo->vtSema = TRUE; + +#ifndef __NOT_YET__ + if (pScreenInfo->depth == 8) + { + int i; + + static const CARD8 CRTC[24] = + { +#ifndef DEBUGOVERSCAN + 0x5F, 0x4F, 0x4F, 0x80, 0x54, 0x00, 0xBE, 0x1F, + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x8F, 0xBF, 0xA3 +#else + /* These values make some of the overscan area visible */ + 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, + 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3 +#endif + }; + + /* Override vgaHW's CRTC timings */ + for (i = 0; i < 24; i++) + pvgaHW->ModeReg.CRTC[i] = CRTC[i]; + + /* Clobber any CLKDIV2 */ + pvgaHW->ModeReg.Sequencer[1] = 0x01; + } +#endif + + /* Programme the registers */ + vgaHWProtect(pScreenInfo, TRUE); + vgaHWRestore(pScreenInfo, &pvgaHW->ModeReg, VGA_SR_MODE | VGA_SR_CMAP); + vgaHWProtect(pScreenInfo, FALSE); + + return TRUE; +} + + +static Bool +GenericEnterGraphics(ScreenPtr pScreen, ScrnInfoPtr pScreenInfo) +{ + vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); + + /* Unlock VGA registers */ + vgaHWUnlock(pvgaHW); + + /* Save the current state and setup the current mode */ + GenericSave(pScreenInfo); + if (!GenericSetMode(pScreenInfo, pScreenInfo->currentMode)) + return FALSE; + + /* Possibly blank the screen */ + if (pScreen) + GenericSaveScreen(pScreen, SCREEN_SAVER_ON); + + (*pScreenInfo->AdjustFrame)(pScreenInfo->scrnIndex, + pScreenInfo->frameX0, pScreenInfo->frameY0, 0); + + return TRUE; +} + + +static void +GenericLeaveGraphics(ScrnInfoPtr pScreenInfo) +{ + GenericRestore(pScreenInfo); + vgaHWLock(VGAHWPTR(pScreenInfo)); +} + + +/* Unravel the screen */ +static Bool +GenericCloseScreen(int scrnIndex, ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + GenericPtr pGenericPriv = GenericGetRec(pScreenInfo); + Bool Closed = TRUE; + + if (pGenericPriv->ShadowPtr) + xfree(pGenericPriv->ShadowPtr); + + if (pGenericPriv && (pScreen->CloseScreen = pGenericPriv->CloseScreen)) + { + pGenericPriv->CloseScreen = NULL; + Closed = (*pScreen->CloseScreen)(scrnIndex, pScreen); + } + + if (pScreenInfo->vtSema) + { + GenericLeaveGraphics(pScreenInfo); + pScreenInfo->vtSema = FALSE; + } + + vgaHWUnmapMem(pScreenInfo); + + return Closed; +} + + +static void +GenericDPMSSet(ScrnInfoPtr pScreen, int mode, int flags) +{ + vgaHWDPMSSet(pScreen, mode, flags); +} + + +static void +GenericRefreshArea1bpp(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GenericPtr pPriv = GenericGetRec(pScrn); + vgaHWPtr pvgaHW = VGAHWPTR(pScrn); + int width, height, FBPitch, left, i, j, phase; + CARD8 *dst, *dstPtr, *src, *srcPtr; + + FBPitch = pScrn->displayWidth >> 3; + + while (num--) + { + left = pbox->x1 & ~7; + width = ((pbox->x2 - left) + 7) >> 3; + height = pbox->y2 - pbox->y1; + src = pPriv->ShadowPtr + (pbox->y1 * pPriv->ShadowPitch) + (left >> 3); + dst = (CARD8*)pvgaHW->Base + (pbox->y1 * FBPitch) + (left >> 3); + + if ((phase = (long)dst & 3L)) + { + phase = 4 - phase; + if (phase > width) + phase = width; + width -= phase; + } + + while (height--) + { + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + *dstPtr++ = byte_reversed[*srcPtr++]; + while (i >= 4) + { + *((CARD32*)dstPtr) = byte_reversed[srcPtr[0]] | + (byte_reversed[srcPtr[1]] << 8) | + (byte_reversed[srcPtr[2]] << 16) | + (byte_reversed[srcPtr[3]] << 24); + srcPtr += 4; + dstPtr += 4; + i -= 4; + } + while (i--) + *dstPtr++ = byte_reversed[*srcPtr++]; + dst += FBPitch; + src += pPriv->ShadowPitch; + } + + pbox++; + } + +} + +#ifndef SPECIAL_FB_BYTE_ACCESS + +static void +GenericRefreshArea4bpp(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GenericPtr pPriv = GenericGetRec(pScrn); + vgaHWPtr pvgaHW = VGAHWPTR(pScrn); + int width, height, FBPitch, left, i, j, SRCPitch, phase; + register CARD32 m; + CARD8 s1, s2, s3, s4; + CARD32 *src, *srcPtr; + CARD8 *dst, *dstPtr; + + FBPitch = pScrn->displayWidth >> 3; + SRCPitch = pPriv->ShadowPitch >> 2; + + (*pvgaHW->writeGr)(pvgaHW, 0x05, 0x00); + (*pvgaHW->writeGr)(pvgaHW, 0x01, 0x00); + (*pvgaHW->writeGr)(pvgaHW, 0x08, 0xFF); + + while (num--) + { + left = pbox->x1 & ~7; + width = ((pbox->x2 - left) + 7) >> 3; + height = pbox->y2 - pbox->y1; + src = (CARD32*)pPriv->ShadowPtr + (pbox->y1 * SRCPitch) + (left >> 2); + dst = (CARD8*)pvgaHW->Base + (pbox->y1 * FBPitch) + (left >> 3); + + if ((phase = (long)dst & 3L)) + { + phase = 4 - phase; + if (phase > width) phase = width; + width -= phase; + } + + while (height--) + { + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); + *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); + s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4); + s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4); + s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4); + s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); + *dstPtr++ = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + srcPtr += 2; + } + + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1 << 1); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); + *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); + s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4); + s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4); + s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4); + s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); + *dstPtr++ = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + srcPtr += 2; + } + + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1 << 2); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); + *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); + s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4); + s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4); + s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4); + s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); + *dstPtr++ = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + srcPtr += 2; + } + + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1 << 3); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); + *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); + s1 = (m >> 27) | (m >> 18) | (m >> 9) | m; + m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4); + s2 = (m >> 27) | (m >> 18) | (m >> 9) | m; + m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4); + s3 = (m >> 27) | (m >> 18) | (m >> 9) | m; + m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4); + s4 = (m >> 27) | (m >> 18) | (m >> 9) | m; + *((CARD32*)dstPtr) = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); + *dstPtr++ = (m >> 27) | (m >> 18) | (m >> 9) | m; + srcPtr += 2; + } + + dst += FBPitch; + src += SRCPitch; + } + + pbox++; + } + +} + +#else + +static void +GenericRefreshArea4bpp(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + GenericPtr pPriv = GenericGetRec(pScrn); + vgaHWPtr pvgaHW = VGAHWPTR(pScrn); + int width, height, FBPitch, left, i, j, SRCPitch, phase; + register CARD32 m; + CARD8 s1, s2, s3, s4; + CARD32 *src, *srcPtr; + int dst, dstPtr; + + FBPitch = pScrn->displayWidth >> 3; + SRCPitch = pPriv->ShadowPitch >> 2; + + (*pvgaHW->writeGr)(pvgaHW, 0x05, 0x00); + (*pvgaHW->writeGr)(pvgaHW, 0x01, 0x00); + (*pvgaHW->writeGr)(pvgaHW, 0x08, 0xFF); + + while (num--) + { + left = pbox->x1 & ~7; + width = ((pbox->x2 - left) + 7) >> 3; + height = pbox->y2 - pbox->y1; + src = (CARD32*)pPriv->ShadowPtr + (pbox->y1 * SRCPitch) + (left >> 2); + dst = (pbox->y1 * FBPitch) + (left >> 3); + + if ((phase = (long)dst & 3L)) + { + phase = 4 - phase; + if (phase > width) phase = width; + width -= phase; + } + + while (height--) + { + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 24) | (m >> 15) | (m >> 6) | (m << 3)); + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); + s1 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + m = (srcPtr[3] & 0x01010101) | ((srcPtr[2] & 0x01010101) << 4); + s2 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + m = (srcPtr[5] & 0x01010101) | ((srcPtr[4] & 0x01010101) << 4); + s3 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + m = (srcPtr[7] & 0x01010101) | ((srcPtr[6] & 0x01010101) << 4); + s4 = (m >> 24) | (m >> 15) | (m >> 6) | (m << 3); + MMIO_OUT32((CARD32*)pvgaHW->Base, dstPtr, + s1 | (s2 << 8) | (s3 << 16) | (s4 << 24)); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x01010101) | ((srcPtr[0] & 0x01010101) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 24) | (m >> 15) | (m >> 6) | (m << 3)); + srcPtr += 2; + } + + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1 << 1); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 25) | (m >> 16) | (m >> 7) | (m << 2)); + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); + s1 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + m = (srcPtr[3] & 0x02020202) | ((srcPtr[2] & 0x02020202) << 4); + s2 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + m = (srcPtr[5] & 0x02020202) | ((srcPtr[4] & 0x02020202) << 4); + s3 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + m = (srcPtr[7] & 0x02020202) | ((srcPtr[6] & 0x02020202) << 4); + s4 = (m >> 25) | (m >> 16) | (m >> 7) | (m << 2); + MMIO_OUT32((CARD32*)pvgaHW->Base, dstPtr, + s1 | (s2 << 8) | (s3 << 16) | (s4 << 24)); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x02020202) | ((srcPtr[0] & 0x02020202) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 25) | (m >> 16) | (m >> 7) | (m << 2)); + srcPtr += 2; + } + + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1 << 2); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 26) | (m >> 17) | (m >> 8) | (m << 1)); + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); + s1 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + m = (srcPtr[3] & 0x04040404) | ((srcPtr[2] & 0x04040404) << 4); + s2 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + m = (srcPtr[5] & 0x04040404) | ((srcPtr[4] & 0x04040404) << 4); + s3 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + m = (srcPtr[7] & 0x04040404) | ((srcPtr[6] & 0x04040404) << 4); + s4 = (m >> 26) | (m >> 17) | (m >> 8) | (m << 1); + MMIO_OUT32((CARD32*)pvgaHW->Base, dstPtr, + s1 | (s2 << 8) | (s3 << 16) | (s4 << 24)); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x04040404) | ((srcPtr[0] & 0x04040404) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 26) | (m >> 17) | (m >> 8) | (m << 1)); + srcPtr += 2; + } + + (*pvgaHW->writeSeq)(pvgaHW, 0x02, 1 << 3); + dstPtr = dst; + srcPtr = src; + i = width; + j = phase; + while (j--) + { + m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 27) | (m >> 18) | (m >> 9) | m); + srcPtr += 2; + } + while (i >= 4) + { + m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); + s1 = (m >> 27) | (m >> 18) | (m >> 9) | m; + m = (srcPtr[3] & 0x08080808) | ((srcPtr[2] & 0x08080808) << 4); + s2 = (m >> 27) | (m >> 18) | (m >> 9) | m; + m = (srcPtr[5] & 0x08080808) | ((srcPtr[4] & 0x08080808) << 4); + s3 = (m >> 27) | (m >> 18) | (m >> 9) | m; + m = (srcPtr[7] & 0x08080808) | ((srcPtr[6] & 0x08080808) << 4); + s4 = (m >> 27) | (m >> 18) | (m >> 9) | m; + MMIO_OUT32((CARD32*)pvgaHW->Base, dstPtr, + s1 | (s2 << 8) | (s3 << 16) | (s4 << 24)); + srcPtr += 8; + dstPtr += 4; + i -= 4; + } + while (i--) + { + m = (srcPtr[1] & 0x08080808) | ((srcPtr[0] & 0x08080808) << 4); + MMIO_OUT8((CARD8*)pvgaHW->Base, dstPtr++, + (m >> 27) | (m >> 18) | (m >> 9) | m); + srcPtr += 2; + } + + dst += FBPitch; + src += SRCPitch; + } + + pbox++; + } +} + +#endif /* SPECIAL_FB_BYTE_ACCESS */ + +static Bool +GenericScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + + vgaHWPtr pvgaHW; + GenericPtr pGenericPriv; + Bool Inited = FALSE; + + /* Get driver private */ + pGenericPriv = GenericGetRec(pScreenInfo); + + /* Map VGA aperture */ +#ifdef SPECIAL_FB_BYTE_ACCESS + if (pGenericPriv->ShadowFB && (pScreenInfo->depth == 4)) + { + if (!GenericMapMem(pScreenInfo)) + return FALSE; + } + else +#endif + if (!vgaHWMapMem(pScreenInfo)) + return FALSE; + + /* Initialise graphics mode */ + if (!GenericEnterGraphics(pScreen, pScreenInfo)) + return FALSE; + + /* Get vgahw private */ + pvgaHW = VGAHWPTR(pScreenInfo); + + miClearVisualTypes(); + + if (!miSetVisualTypes(pScreenInfo->depth, + miGetDefaultVisualMask(pScreenInfo->depth), + pScreenInfo->rgbBits, pScreenInfo->defaultVisual)) + return FALSE; + + miSetPixmapDepths(); + + /* Initialise the framebuffer */ + switch (pScreenInfo->depth) + { + case 1: + if (pGenericPriv->ShadowFB) + { + pGenericPriv->ShadowPitch = + ((pScreenInfo->virtualX + 31) >> 3) & ~3L; + pGenericPriv->ShadowPtr = + xalloc(pGenericPriv->ShadowPitch * pScreenInfo->virtualY); + if (pGenericPriv->ShadowPtr == NULL) + return FALSE; + Inited = fbScreenInit(pScreen, pGenericPriv->ShadowPtr, + pScreenInfo->virtualX, + pScreenInfo->virtualY, + pScreenInfo->xDpi, pScreenInfo->yDpi, + pScreenInfo->displayWidth, + pScreenInfo->bitsPerPixel); + if (!Inited) + break; +#ifdef RENDER + fbPictureInit (pScreen, 0, 0); +#endif + ShadowFBInit(pScreen, GenericRefreshArea1bpp); + } + else + { + Inited = xf1bppScreenInit(pScreen, pvgaHW->Base, + pScreenInfo->virtualX, + pScreenInfo->virtualY, + pScreenInfo->xDpi, pScreenInfo->yDpi, + pScreenInfo->displayWidth); + } + break; + case 4: + if (pGenericPriv->ShadowFB) + { + /* In order to use ShadowFB we do depth 4 / bpp 8 */ + pScreenInfo->bitsPerPixel = 8; + pGenericPriv->ShadowPitch = (pScreenInfo->virtualX + 3) & ~3L; + pGenericPriv->ShadowPtr = + xalloc(pGenericPriv->ShadowPitch * pScreenInfo->virtualY); + if (pGenericPriv->ShadowPtr == NULL) + return FALSE; + Inited = fbScreenInit(pScreen, pGenericPriv->ShadowPtr, + pScreenInfo->virtualX, + pScreenInfo->virtualY, + pScreenInfo->xDpi, pScreenInfo->yDpi, + pScreenInfo->displayWidth, + pScreenInfo->bitsPerPixel); + if (!Inited) + break; +#ifdef RENDER + fbPictureInit (pScreen, 0, 0); +#endif + ShadowFBInit(pScreen, GenericRefreshArea4bpp); + } + else + { + Inited = xf4bppScreenInit(pScreen, pvgaHW->Base, + pScreenInfo->virtualX, + pScreenInfo->virtualY, + pScreenInfo->xDpi, pScreenInfo->yDpi, + pScreenInfo->displayWidth); + } + break; + case 8: + Inited = fbScreenInit(pScreen, pvgaHW->Base, + pScreenInfo->virtualX, pScreenInfo->virtualY, + pScreenInfo->xDpi, pScreenInfo->yDpi, + pScreenInfo->displayWidth, + pScreenInfo->bitsPerPixel); +#ifdef RENDER + fbPictureInit (pScreen, 0, 0); +#endif + break; + default: + xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, + "Depth %i not supported by this driver\n", + pScreenInfo->depth); + break; + } + + if (!Inited) + return FALSE; + + miInitializeBackingStore(pScreen); + + xf86SetBlackWhitePixels(pScreen); + + /* Initialise cursor */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Setup default colourmap */ + Inited = miCreateDefColormap(pScreen); + + /* Try the new code based on the new colormap layer */ + if (pScreenInfo->depth > 1) + vgaHWHandleColormaps(pScreen); + + xf86DPMSInit(pScreen, GenericDPMSSet, 0); + + /* Wrap the screen's CloseScreen vector and set its SaveScreen vector */ + pGenericPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = GenericCloseScreen; + pScreen->SaveScreen = GenericSaveScreen; + + if (!Inited) + GenericCloseScreen(scrnIndex, pScreen); + + pScreenInfo->racIoFlags = RAC_COLORMAP | RAC_VIEWPORT; + if (pScreenInfo->depth < 8) + pScreenInfo->racIoFlags |= RAC_FB; + pScreenInfo->racMemFlags = RAC_FB; + if (serverGeneration == 1) + xf86ShowUnusedOptions(pScreenInfo->scrnIndex, pScreenInfo->options); + + return Inited; +} + + +static Bool +GenericSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) +{ + return GenericSetMode(xf86Screens[scrnIndex], pMode); +} + + +static void +GenericAdjustFrame(int scrnIndex, int x, int y, int flags) +{ +# ifndef PC98_EGC + ScrnInfoPtr pScreenInfo = xf86Screens[scrnIndex]; + vgaHWPtr pvgaHW = VGAHWPTR(pScreenInfo); + int Base = (y * pScreenInfo->displayWidth + x) >> 3; + + outw(pvgaHW->PIOOffset + pvgaHW->IOBase + 4, + (Base & 0x00FF00) | 0x0C); + outw(pvgaHW->PIOOffset + pvgaHW->IOBase + 4, + ((Base & 0x0000FF) << 8) | 0x0D); +# endif +} + + +static Bool +GenericEnterVT(int scrnIndex, int flags) +{ + return GenericEnterGraphics(NULL, xf86Screens[scrnIndex]); +} + + +static void +GenericLeaveVT(int scrnIndex, int flags) +{ + GenericLeaveGraphics(xf86Screens[scrnIndex]); +} + + +static void +GenericFreeScreen(int scrnIndex, int flags) +{ + GenericFreeRec(xf86Screens[scrnIndex]); +} + + +static int +GenericValidMode(int scrnIndex, DisplayModePtr pMode, Bool Verbose, int flags) +{ + if (pMode->Flags & V_INTERLACE) + return MODE_NO_INTERLACE; + + return MODE_OK; +} + +#ifdef SPECIAL_FB_BYTE_ACCESS + +static Bool +GenericMapMem(ScrnInfoPtr scrp) +{ + vgaHWPtr hwp = VGAHWPTR(scrp); + int scr_index = scrp->scrnIndex; + + if (hwp->Base) + return TRUE; + + /* If not set, initialise with the defaults */ + if (hwp->MapSize == 0) + hwp->MapSize = VGA_DEFAULT_MEM_SIZE; + if (hwp->MapPhys == 0) + hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR; + + hwp->Base = xf86MapDomainMemory(scr_index, VIDMEM_MMIO, hwp->Tag, + hwp->MapPhys, hwp->MapSize); + return hwp->Base != NULL; +} + +#endif |