from the one for vesa and probably has extra cruft, but it does the job. Thes files expect to be in hw/xfree86/drivers/hga. You will need the resource conflict fixes I posted earlier to get it running.
Don't forget to add hga to your driver list in site.def if you want it built automatically.
If you run linux and use mdacon, there are some interaction issues. XFree86 switches the active
console to an unused one, but you have two in use, so one is exposed to console driver activities.
Bringing up a dual headed X from an mda console steps through a console driver bad pointer when X
terminates (at least it does on Redhat 7.3, 2.4.18-3), leaving stuck displays. Ctrl-alt-del still works,
but thats about it.
Enjoy
Lee Olsen
[EMAIL PROTECTED]
/* * Copyright 2003 by Lee Olsen [EMAIL PROTECTED] * * 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 Lee Olsen not be used in advertising or publicity * pertaining to distribution of the software without specific, written * prior permission. Lee Olsen makes no representations about the suitability * of this software for any purpose. It is provided "as-is" express or * implied warranty. * * LEE OLSEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL LEE OLSEN 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. */
#ifndef _HGA_H_ #define _HGA_H_ /* All drivers should typically include these */ #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Resources.h" /* All drivers need this */ #include "xf86_ansic.h" #include "compiler.h" #if 0 /* Drivers for PCI hardware need this */ #include "xf86PciInfo.h" /* Drivers that need to access the PCI config space directly need this */ #include "xf86Pci.h" #endif /* ShadowFB support */ /* from hw/xfree86/shadowfb, not miext/shadow */ #include "shadowfb.h" /* bank switching */ #include "mibank.h" #if 0 /* Dga definitions */ #include "dgaproc.h" #include "xf86Resources.h" #include "xf86RAC.h" #endif #include "xf1bpp.h" #include "fb.h" #include "mfb.h" #define HGA_VERSION 4000 #define HGA_NAME "HGA" #define HGA_DRIVER_NAME "hercules" #define HGA_MAJOR_VERSION 0 #define HGA_MINOR_VERSION 1 #define HGA_PATCHLEVEL 0 #ifdef CSRG_BASED #define MONOBASE 0xFF000000 #else #define MONOBASE 0xF0000000 #endif /* * Define the generic HGA I/O Ports */ #define HGA_INDEX 0x3B4 #define HGA_DATA 0x3B5 #define HGA_MODE 0x3B8 #define HGA_STATUS 0x3BA #define HGA_CONFIG 0x3BF #define DSP_VSYNC_MASK 0x80 #define DSP_ID_MASK 0x70 #define BITS_PER_GUN 1 #define COLORMAP_SIZE 2 #define HGA6845MapBase ((unsigned char *)0xB0000) #define HGA6845MapSize 0x8000 #define HGA6845ScanLineWidth 720 #define HGA6845HDisplay 720 #define HGA6845VDisplay 348 /*XXX*/ typedef struct { unsigned char config; /* write only conf register at port 0x3BF */ unsigned char mode; /* write only mode register at port 0x3B8 */ unsigned char tbl[16]; } hga6845Rec, *hga6845Ptr; typedef struct _HGARec { EntityInfoPtr pEnt; CARD16 major, minor; GDevPtr device; #if 0 pciVideoPtr pciInfo; PCITAG pciTag; #endif miBankInfoRec bank; int curBank, bankSwitchWindowB; CARD16 maxBytesPerScanline; int mapPhys, mapOff, mapSize; /* video memory */ void *base, *VGAbase; hga6845Ptr state, pstate; /* Video state */ int statePage, stateSize, stateMode; int page; Bool shadowFB, primary; CARD8 *textContents; CARD8 *shadowPtr; CARD32 shadowPitch; CARD32 windowAoffset; CARD32 frameX; CARD32 frameY; CloseScreenProcPtr CloseScreen; OptionInfoPtr Options; } HGARec, *HGAPtr; typedef enum save_restore { MODE_SAVE, MODE_RESTORE } SaveRestoreFunction; #endif /* _HGA_H_ */
/* * Copyright 2003 by Lee Olsen [EMAIL PROTECTED] * * 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 Lee Olsen not be used in advertising or publicity * pertaining to distribution of the software without specific, written * prior permission. Lee Olsen makes no representations about the suitability * of this software for any purpose. It is provided "as-is" express or * implied warranty. * * LEE OLSEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL LEE OLSEN 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. */ /* * This driver was built by stripping down the 4.2.0 vesa and vga drivers * and adapting them to the hardware. The 3.3.6 driver and mdacon console * driver were used as models for talking to the hardware. */ #define DEBUG_VERB 2 #include "hga.h" /* All drivers initialising the SW cursor need this */ #include "mipointer.h" /* All drivers implementing backing store need this */ #include "mibstore.h" /* Colormap handling */ #include "micmap.h" #include "xf86cmap.h" /* Mandatory functions */ static const OptionInfoRec * HGAAvailableOptions(int chipid, int busid); static void HGAIdentify(int flags); static Bool HGAProbe(DriverPtr drv, int flags); static Bool HGAPreInit(ScrnInfoPtr pScrn, int flags); static Bool HGAScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); static Bool HGAEnterVT(int scrnIndex, int flags); static void HGALeaveVT(int scrnIndex, int flags); static Bool HGACloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool HGASaveScreen(ScreenPtr pScreen, int mode); static Bool HGASwitchMode(int scrnIndex, DisplayModePtr pMode, int flags); static Bool HGASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode); static void HGAAdjustFrame(int scrnIndex, int x, int y, int flags); static void HGAFreeScreen(int scrnIndex, int flags); static void HGAFreeRec(ScrnInfoPtr pScrn); /* locally used functions */ static int HGAFindIsaDevice(GDevPtr dev); static Bool HGAMapVidMem(ScrnInfoPtr pScrn); static void HGAUnmapVidMem(ScrnInfoPtr pScrn); static Bool HGASaveRestore(ScrnInfoPtr pScrn, SaveRestoreFunction function); static void HGARefreshArea1bpp(ScrnInfoPtr pScrn, int num, BoxPtr pbox); /* * This contains the functions needed by the server after loading the * driver module. It must be supplied, and gets added the driver list by * the Module Setup funtion in the dynamic case. In the static case a * reference to this is compiled in, and this requires that the name of * this DriverRec be an upper-case version of the driver name. */ DriverRec HGA = { HGA_VERSION, HGA_DRIVER_NAME, HGAIdentify, HGAProbe, HGAAvailableOptions, NULL, 0 }; /* * Since the conf and mode registers are write only, we need to keep * a local copy of the state here. The initial state is assumed to be: * conf: enable setting of graphics mode, and disable page one * (allows coexistence with a color graphics board) * mode: text, deactivate screen, enable text blink, and page zero at 0xB0000 * * Since the table of 6845 registers is write only, we need to keep * a local copy of the state here. The initial state is assumed to * be 80x25 text mode. * Note the last byte, cursor X, is used to hold the mode flags */ hga6845Rec hga_state = { 0x01, 0x20, {0x61, 0x50, 0x52, 0x0F, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0D, 0x0C, 0x0D, 0x00, 0x00, 0x00, 0x00} }; /* 720x348 graphics mode parameters */ hga6845Rec hga_graphics = { 0x03, 0x22, {0x35, 0x2D, 0x2E, 0x07, 0x5B, 0x02, 0x57, 0x57, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; /* The default mode */ static DisplayModeRec HerculesDefaultMode = { NULL, NULL, /* prev & next */ "720x348", MODE_OK, /* Mode status */ M_T_DEFAULT, /* Mode type */ 19000, /* Pixel clock */ 720, 736, 872, 872, /* HTiming */ 0, /* HSkew */ 348, 350, 434, 434, /* VTiming */ 1, /* VScan */ V_NHSYNC | V_PVSYNC, /* Flags */ 0, 19000, /* 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 */ }; static DisplayModeRec HerculesDefaultMode2 = { NULL, NULL, /* prev & next */ "720x522", MODE_OK, /* Mode status */ M_T_BUILTIN, /* Mode type */ 26800, /* Pixel clock */ 720, 736, 872, 872, /* HTiming */ 0, /* HSkew */ 522, 530, 614, 614, /* VTiming */ 1, /* VScan */ V_NHSYNC | V_PVSYNC, /* Flags */ 0, 26800, /* 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 */ }; enum HGATypes { CHIP_HERCULES }; /* Supported chipsets */ static SymTabRec HGAChipsets[] = { {CHIP_HERCULES, "hercules"}, {-1, NULL} }; #define _HGA_EXCLUSIVE \ {ResExcMemBlock | ResBios | ResBus, 0x000B0000, 0x000B7FFF},\ {ResExcIoBlock | ResBios | ResBus, 0x03B0, 0x03BF} #define _HGA_SHARED \ {ResShrMemBlock | ResBios | ResBus, 0x000B0000, 0x000B7FFF},\ {ResShrIoBlock | ResBios | ResBus, 0x03B0, 0x03BF} static resRange resShrHga[] = {_HGA_SHARED, _END}; static resRange resExcHga[] = {_HGA_EXCLUSIVE, _END}; #define RES_EXCLUSIVE_HGA resExcHga /* Note these resources are SHARED, not exclusive to prevent * a conflict (and fatal error) with the VGA driver. */ static IsaChipsets HGAISAchipsets[] = { {CHIP_HERCULES, RES_EXCLUSIVE_HGA}, {-1, 0 } }; #if 0 /* These dont exist, but if they did... */ static PciChipsets HGAPCIchipsets[] = { { CHIP_HERCULES, PCI_CHIP_VGA, RES_SHARED_HGA }, { -1, -1, RES_UNDEFINED }, }; #endif typedef enum { OPTION_SHADOW_FB } HGAOpts; static const OptionInfoRec HGAOptions[] = { { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; /* * List of symbols from other modules that this module references. This * list is used to tell the loader that it is OK for symbols here to be * unresolved providing that it hasn't been told that they haven't been * told that they are essential via a call to xf86LoaderReqSymbols() or * xf86LoaderReqSymLists(). The purpose is this is to avoid warnings about * unresolved symbols that are not required. */ static const char *miscfbSymbols[] = { "xf1bppScreenInit", "mfbScreenInit", NULL }; #if 0 static const char *fbSymbols[] = { "fbPictureInit", "fbScreenInit", NULL }; #endif /* hw/xfree86/shadowfb, not miext/shadow */ static const char *shadowSymbols[] = { "ShadowFBInit", NULL }; #ifdef XFree86LOADER /* Module loader interface */ static MODULESETUPPROTO(HGASetup); static XF86ModuleVersionInfo HGAVersionRec = { HGA_DRIVER_NAME, MODULEVENDORSTRING, MODINFOSTRING1, MODINFOSTRING2, XF86_VERSION_CURRENT, HGA_MAJOR_VERSION, HGA_MINOR_VERSION, HGA_PATCHLEVEL, ABI_CLASS_VIDEODRV, /* This is a video driver */ 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 hgaModuleData = { &HGAVersionRec, HGASetup, NULL }; static pointer HGASetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor) { static Bool Initialised = FALSE; if (!Initialised) { Initialised = TRUE; xf86AddDriver(&HGA, Module, 0); LoaderRefSymLists(miscfbSymbols, shadowSymbols, NULL); return (pointer)TRUE; } if (ErrorMajor) *ErrorMajor = LDR_ONCEONLY; return (NULL); } #endif static const OptionInfoRec * HGAAvailableOptions(int chipid, int busid) { return (HGAOptions); } static void HGAIdentify(int flags) { xf86PrintChipsets(HGA_NAME, "driver for HGA monochrome chipsets", HGAChipsets); } /* * This function is called once, at the start of the first server generation to * do a minimal probe for supported hardware. */ static Bool HGAProbe(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(HGA_NAME, &devSections)) <= 0) return (FALSE); /* Isa Bus */ numUsed = xf86MatchIsaInstances(HGA_NAME,HGAChipsets, HGAISAchipsets, drv, HGAFindIsaDevice, devSections, numDevSections, &usedChips); if(numUsed > 0) { if (flags & PROBE_DETECT) foundScreen = TRUE; else for (i = 0; i < numUsed; i++) { ScrnInfoPtr pScrn = NULL; if ((pScrn = xf86ConfigIsaEntity(pScrn, 0,usedChips[i], HGAISAchipsets, NULL, NULL, NULL, NULL, NULL))) { pScrn->driverVersion = HGA_VERSION; pScrn->driverName = HGA_DRIVER_NAME; pScrn->name = HGA_NAME; pScrn->Probe = HGAProbe; pScrn->PreInit = HGAPreInit; pScrn->ScreenInit = HGAScreenInit; pScrn->SwitchMode = HGASwitchMode; pScrn->AdjustFrame = HGAAdjustFrame; pScrn->EnterVT = HGAEnterVT; pScrn->LeaveVT = HGALeaveVT; pScrn->FreeScreen = HGAFreeScreen; foundScreen = TRUE; } } xfree(usedChips); } xfree(devSections); return (foundScreen); } /* * HGAFindIsaDevice -- * check whether an HGA6845 based board is installed * Called from HGAProbe */ static int HGAFindIsaDevice(GDevPtr dev) { unsigned char dsp, dsp_old; int i; /* * Checks if there is a HGA 6845 based board in the system. * The following loop tries to see if the HGA display * status port register is counting vertical syncs (50Hz). */ dsp = dsp_old = inb(HGA_STATUS) & DSP_VSYNC_MASK; for (i = 0; i < 0x50000 && dsp == dsp_old; i++) { dsp = inb(HGA_STATUS) & DSP_VSYNC_MASK; } if (dsp != dsp_old) return CHIP_HERCULES; return -1; } static HGAPtr HGAGetRec(ScrnInfoPtr pScrn) { if (!pScrn->driverPrivate) pScrn->driverPrivate = xcalloc(sizeof(HGARec), 1); return ((HGAPtr)pScrn->driverPrivate); } static void HGAFreeRec(ScrnInfoPtr pScrn) { xfree(pScrn->driverPrivate); pScrn->driverPrivate = NULL; } /* * 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 HGAPreInit(ScrnInfoPtr pScrn, int flags) { HGAPtr pHGA; char *mod = NULL; const char *reqSym = NULL; Gamma gzeros = {0.0, 0.0, 0.0}; if (flags & PROBE_DETECT) return (FALSE); pHGA = HGAGetRec(pScrn); pHGA->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); pHGA->device = xf86GetDevFromEntity(pScrn->entityList[0], pScrn->entityInstanceList[0]); #if 0 if (pHGA->pEnt->location.type == BUS_PCI) { pHGA->pciInfo = xf86GetPciInfoForEntity(pHGA->pEnt->index); pHGA->pciTag = pciTag(pHGA->pciInfo->bus, pHGA->pciInfo->device, pHGA->pciInfo->func); pHGA->primary = xf86IsPrimaryPci(pHGA->pciInfo); } else #endif pHGA->primary = TRUE; pScrn->chipset = (char *)xf86TokenToString(HGAChipsets, pHGA->pEnt->chipset); pScrn->monitor = pScrn->confScreen->monitor; pScrn->progClock = FALSE; pScrn->rgbBits = 1; if (!xf86SetDepthBpp(pScrn, 1, 1, 1, NoDepth24Support)) { return (FALSE); } xf86PrintDepthBpp(pScrn); /* The Plus and InColor versions have an ID code as well. */ switch(inb(HGA_STATUS) & DSP_ID_MASK) { case 0x10: /* Plus */ pScrn->videoRam = 64; break; case 0x50: /* InColor */ pScrn->videoRam = 256; break; } if (!pScrn->videoRam) { /* videoram not given in XF86Config */ pScrn->videoRam=32; } /* We do 'virtual' handling here as it is highly chipset specific */ if (!pScrn->display || pScrn->display->virtualX < 0) { /* virtual not set in XF86Config */ pScrn->virtualX = HGA6845HDisplay; pScrn->virtualY = HGA6845VDisplay; pScrn->virtualFrom = X_PROBED; } else { pScrn->virtualX = pScrn->display->virtualX; pScrn->virtualY = pScrn->display->virtualY; pScrn->virtualFrom = X_CONFIG; } pScrn->displayWidth = HGA6845HDisplay; pScrn->modes = xalloc(sizeof(DisplayModeRec)); *pScrn->modes = HerculesDefaultMode; pScrn->modes->next = pScrn->modes; pScrn->modes->prev = pScrn->modes; if (pScrn->display->modes) { char **mode_name; for (mode_name = pScrn->display->modes; *mode_name; ++mode_name) { if (!strcmp(*mode_name, HerculesDefaultMode2.name) == 0) { pScrn->modes->next = xalloc(sizeof(DisplayModeRec)); *pScrn->modes->next = HerculesDefaultMode2; pScrn->modes->prev = pScrn->modes->next; pScrn->modes->next->prev = pScrn->modes; pScrn->modes->next->next = pScrn->modes; } } } pScrn->currentMode = pScrn->modes; /* visual init */ if (!xf86SetDefaultVisual(pScrn, -1)) { return (FALSE); } xf86SetGamma(pScrn, gzeros); /* Set display resolution */ xf86SetDpi(pScrn, 75, 45); pScrn->currentMode = pScrn->modes; pScrn->displayWidth = pScrn->virtualX; xf86PrintModes(pScrn); if (pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes\n"); return (FALSE); } /* options */ xf86CollectOptions(pScrn, NULL); if (!(pHGA->Options = xalloc(sizeof(HGAOptions)))) { return FALSE; } memcpy(pHGA->Options, HGAOptions, sizeof(HGAOptions)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pHGA->Options); /* Use shadow by default */ if (xf86ReturnOptValBool(pHGA->Options, OPTION_SHADOW_FB, TRUE)) pHGA->shadowFB = TRUE; /* Until xf1bpp and/or mfb get banked Scanline access... */ if (!pHGA->shadowFB && (pScrn->depth == 1)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Architecture requires special FB access for this depth:" " ShadowFB enabled\n"); pHGA->shadowFB = TRUE; } if (pHGA->shadowFB) { xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using \"Shadow Framebuffer\"\n"); /* Reversal done in RefreshArea1Bpp */ pScrn->bitmapBitOrder = BITMAP_BIT_ORDER; #if 1 /* this is broken for mono, we should just use the defaults */ pScrn->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; #endif if (pScrn->depth == 1) { mod = "mfb"; reqSym = "mfbScreenInit"; } if (!xf86LoadSubModule(pScrn, "shadowfb")) { return (FALSE); } xf86LoaderReqSymLists(shadowSymbols, NULL); } else { mod = "xf1bpp"; reqSym = "xf1bppScreenInit"; } if (mod && xf86LoadSubModule(pScrn, mod) == NULL) { HGAFreeRec(pScrn); return (FALSE); } if (mod) { if (reqSym) { xf86LoaderReqSymbols(reqSym, NULL); #if 0 } else { xf86LoaderReqSymLists(fbSymbols, NULL); #endif } } return (TRUE); } static Bool HGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; HGAPtr pHGA = HGAGetRec(pScrn); if (pHGA->mapPhys == 0) { pHGA->mapPhys = 0xb0000; pHGA->mapSize = 0x08000; } if (!HGAMapVidMem(pScrn)) { if (pHGA->mapPhys != 0xb0000) { pHGA->mapPhys = 0xb0000; pHGA->mapSize = 0x08000; if (!HGAMapVidMem(pScrn)) return (FALSE); } else return (FALSE); } pHGA->maxBytesPerScanline = 90; pHGA->windowAoffset = 0; pHGA->textContents = (unsigned char *)xalloc(HGA6845MapSize); if (pHGA->textContents) memcpy(pHGA->textContents, pHGA->base, HGA6845MapSize); if (pHGA->shadowFB) { pHGA->shadowPitch = ((pScrn->virtualX + 31) >> 3) & ~3L; if ((pHGA->shadowPtr = xalloc(pHGA->shadowPitch * pScrn->virtualY)) == NULL) return (FALSE); } /* save current video state */ HGASaveRestore(pScrn, MODE_SAVE); /* set first video mode */ if (!HGASetMode(pScrn, pScrn->currentMode)) return (FALSE); /* mi layer */ miClearVisualTypes(); if (!xf86SetDefaultVisual(pScrn, -1)) return (FALSE); if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), pScrn->rgbBits, pScrn->defaultVisual)) return (FALSE); if (!miSetPixmapDepths()) return (FALSE); if (pHGA->shadowFB) { if (pScrn->depth == 1) { if (!mfbScreenInit(pScreen, pHGA->shadowPtr, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) return FALSE; } } else { switch (pScrn->bitsPerPixel) { case 1: if (!xf1bppScreenInit(pScreen, pHGA->base, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth)) return (FALSE); break; default: xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unsupported bpp: %d", pScrn->bitsPerPixel); return (FALSE); } } if (pHGA->shadowFB) { ShadowFBInit(pScreen, HGARefreshArea1bpp); } xf86SetBlackWhitePixels(pScreen); miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); /* software cursor */ miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); /* colormap */ if (!miCreateDefColormap(pScreen)) return (FALSE); pHGA->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = HGACloseScreen; pScreen->SaveScreen = HGASaveScreen; /* Report any unused options (only for the first generation) */ if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); return (TRUE); } static Bool HGAEnterVT(int scrnIndex, int flags) { return (HGASetMode(xf86Screens[scrnIndex], xf86Screens[scrnIndex]->currentMode)); } static void HGALeaveVT(int scrnIndex, int flags) { HGASaveRestore(xf86Screens[scrnIndex], MODE_RESTORE); } static Bool HGACloseScreen(int scrnIndex, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; HGAPtr pHGA = HGAGetRec(pScrn); if (pScrn->vtSema) { /* Restore original mode, not current */ *pHGA->state = *pHGA->pstate; HGASaveRestore(pScrn, MODE_RESTORE); HGAUnmapVidMem(pScrn); } if (pHGA->shadowPtr) { xfree(pHGA->shadowPtr); pHGA->shadowPtr = NULL; } pScrn->vtSema = FALSE; pScreen->CloseScreen = pHGA->CloseScreen; return pScreen->CloseScreen(scrnIndex, pScreen); } static Bool HGASwitchMode(int scrnIndex, DisplayModePtr pMode, int flags) { return HGASetMode(xf86Screens[scrnIndex], pMode); } /* Set a graphics mode */ static Bool HGASetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode) { HGAPtr pHGA = HGAGetRec(pScrn); if (!pHGA->state) HGASaveRestore(pScrn, MODE_SAVE); *pHGA->state = hga_graphics; HGASaveRestore(pScrn, MODE_RESTORE); pScrn->vtSema = TRUE; return (TRUE); } static void HGAAdjustFrame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; HGAPtr pHGA = HGAGetRec(pScrn); struct _Box box; x = (x + 7) & ~7; box.x1 = x; box.y1 = y; box.x2 = pScrn->currentMode->HDisplay + x; box.y2 = pScrn->currentMode->VDisplay + y; pHGA->frameX = x; pHGA->frameY = y; HGARefreshArea1bpp(pScrn, 1, &box); } static void HGAFreeScreen(int scrnIndex, int flags) { HGAFreeRec(xf86Screens[scrnIndex]); } static Bool HGAMapVidMem(ScrnInfoPtr pScrn) { HGAPtr pHGA = HGAGetRec(pScrn); if (pHGA->base != NULL) return (TRUE); pScrn->memPhysBase = pHGA->mapPhys; pScrn->fbOffset = pHGA->mapOff; #if 0 if (pHGA->mapPhys != 0xb0000 && pHGA->pEnt->location.type == BUS_PCI) pHGA->base = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, pHGA->pciTag, pScrn->memPhysBase, pHGA->mapSize); else #endif pHGA->base = xf86MapVidMem(pScrn->scrnIndex, 0, pScrn->memPhysBase, pHGA->mapSize); if (pHGA->base) { if (pHGA->mapPhys != 0xb0000) pHGA->VGAbase = xf86MapVidMem(pScrn->scrnIndex, 0, 0xb0000, 0x8000); else pHGA->VGAbase = pHGA->base; } xf86ErrorFVerb(DEBUG_VERB, "virtual address = %p - physical address = %p - size = %d\n", pHGA->base, pScrn->memPhysBase, pHGA->mapSize); return (pHGA->base != NULL); } static void HGAUnmapVidMem(ScrnInfoPtr pScrn) { HGAPtr pHGA = HGAGetRec(pScrn); if (pHGA->base == NULL) return; xf86UnMapVidMem(pScrn->scrnIndex, pHGA->base, pHGA->mapSize); if (pHGA->mapPhys != 0xb0000) xf86UnMapVidMem(pScrn->scrnIndex, pHGA->VGAbase, 0x8000); pHGA->base = NULL; } static CARD8 *HGAScanlineOffset( CARD8 *p, int row, int offset) { return p + ((row % 4) * 8192) + ((row / 4) * 90) + (offset >> 3); } static void HGARefreshArea1bpp(ScrnInfoPtr pScrn, int num, BoxPtr pbox) { HGAPtr pHGA = HGAGetRec(pScrn); int width, height, FBPitch, left, i, j, phase, row, virtual_row; int compress; struct _Box clipped; CARD8 *dst, *dstPtr, *src, *srcPtr; FBPitch = pScrn->displayWidth >> 3; compress = pScrn->currentMode->VDisplay > HGA6845VDisplay; for(;num--; pbox++) { clipped = *pbox; if (clipped.x1 < pHGA->frameX) clipped.x1 = pHGA->frameX; if (clipped.y1 < pHGA->frameY) clipped.y1 = pHGA->frameY; if (clipped.x2 > pHGA->frameX + HGA6845HDisplay) clipped.x2 = pHGA->frameX + HGA6845HDisplay; if (clipped.y2 > pHGA->frameY + pScrn->currentMode->VDisplay) clipped.y2 = pHGA->frameY + pScrn->currentMode->VDisplay; left = clipped.x1 & ~7; width = (clipped.x2 - left) + 7; left -= pHGA->frameX; if (width > pScrn->currentMode->HDisplay) width = pScrn->currentMode->HDisplay; else if (width <= 0) continue; width >>= 3; virtual_row = row = clipped.y1 - pHGA->frameY; if (compress) row = (row/3) * 2 + row % 3; height = clipped.y2 - clipped.y1; src = pHGA->shadowPtr + (clipped.y1 * pHGA->shadowPitch) + (clipped.x1 >> 3); if((phase = (long)dst & 3L)) { phase = 4 - phase; if(phase > width) phase = width; width -= phase; } for(;height-- > 0; ++virtual_row, src += pHGA->shadowPitch) { if (compress && ((virtual_row % 3) == 2)) continue; row++; dst = HGAScanlineOffset(((CARD8*)pHGA->base), row, left); dstPtr = dst; srcPtr = src; i = width; j = phase; while(j-- > 0) *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-- > 0) *dstPtr++ = byte_reversed[*srcPtr++]; } } } static Bool HGASaveScreen(ScreenPtr pScreen, int mode) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; if (mode == SCREEN_SAVER_FORCER) { SetTimeSinceLastInputEvent(); } else { if (pScrn->vtSema) { /* our VT is active */ if (mode) outb(HGA_MODE, hga_state.mode |= 0x08); /* activate screen */ else outb(HGA_MODE, hga_state.mode &= 0xF7); /* deactivate screen */ } else { /* if we are not on the active VT, don't do anything - the screen * will be visible as soon as we switch back anyway (?) */ } } return (TRUE); } Bool HGASaveRestore(ScrnInfoPtr pScrn, SaveRestoreFunction function) { HGAPtr pHGA = HGAGetRec(pScrn); unsigned char i; if (function == MODE_SAVE) { if (NULL==pHGA->state) pHGA->state = (hga6845Ptr)xcalloc(1,sizeof(hga6845Rec)); *pHGA->state = hga_state; if (NULL==pHGA->pstate) { pHGA->pstate = (hga6845Ptr)xcalloc(1,sizeof(hga6845Rec)); *pHGA->pstate = hga_state; } } else { if (pHGA->state) { /* Clear screen first */ memset(pHGA->base, 0, pHGA->mapSize); outb(HGA_CONFIG, pHGA->state->config); outb(HGA_MODE, pHGA->state->mode); for (i = 0; i < sizeof(pHGA->state->tbl); i++) { outb(HGA_INDEX, i); outb(HGA_DATA, pHGA->state->tbl[i]); } outb(HGA_MODE,pHGA->state->mode | 8); hga_state = *pHGA->state; if (hga_state.config == 1 && pHGA->textContents) memcpy(pHGA->base, pHGA->textContents, HGA6845MapSize); } } return (TRUE); }
hga.man
Description: Unix manual page
XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/hga/Imakefile,v 1.3 2001/01/24 00:06:33 dawes Exp $ #define IHaveModules #include <Server.tmpl> SRCS = hga.c OBJS = hga.o #if defined(XF86DriverSDK) INCLUDES = -I. -I../../include #else INCLUDES = -I. -I$(SERVERSRC)/fb -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \ -I$(XF86SRC)/xf24_32bpp \ -I$(SERVERSRC)/mfb -I$(SERVERSRC)/afb -I$(SERVERSRC)/mi \ -I$(SERVERSRC)/miext/shadow -I$(SERVERSRC)/render \ -I$(XF86SRC)/vgahw \ -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(SERVERSRC)/Xext \ -I$(SERVERSRC)/include -I$(FONTINCSRC) -I$(XINCLUDESRC)\ -I$(XF86SRC)/rac -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ -I$(XF86SRC)/os-support/vbe -I$(XF86SRC)/int10 \ -I$(XF86SRC)/shadowfb \ -I$(XTOP)/include/extensions #endif #if MakeHasPosixVariableSubstitutions SubdirLibraryRule($(OBJS)) #endif ModuleObjectRule() ObjectModuleTarget(hga,$(OBJS)) InstallObjectModule(hga,$(MODULEDIR),drivers) #if !defined(XF86DriverSDK) InstallModuleManPage(hga) #endif DependTarget() InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/hga) InstallDriverSDKNonExecFile(hga.c,$(DRIVERSDKDIR)/drivers/hga) InstallDriverSDKObjectModule(hga,$(DRIVERSDKMODULEDIR),drivers)