The attachments are the pieces I used to build the hga driver for hercules cards. The Imakefile was cloned
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);
}

Attachment: 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)

Reply via email to