/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   File            = EDDEFPDB                                       */
/*                                                                    */
/*   Description     = Enable : subfunction Fill pDeviceBlock         */
/*                                                                    */
/*   Function        = FillPdb establishes the display                */
/*                     configuration                                  */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design                   */
/*                                                                    */
/*                                                                    */
/* CHANGE ACTIVITY =                                                  */
/*   DATE      FLAG        APAR   CHANGE DESCRIPTION                  */
/*   --------  ----------  -----  ------------------------------------*/
/*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx                             */
/*   04/03/93              ?????  Added new function to give VVideo   */
/*                                access to VGA memory.               */
/**********************************************************************/
#define INCL_WINSHELLDATA
#define INCL_WINPROGRAMLIST
#define INCL_DOSDEVICES
#define INCL_DOSMEMMGR
#define INCL_DOSMODULEMGR
#define INCL_DOSRESOURCES
#define INCL_DOSNLS
#define INCL_DOSMISC
#define INCL_GRE_DEVICE
#define INCL_DDIMISC
#define INCL_WINSYS
#define INCL_WINERRORS
#define INCL_DOSERRORS
#define INCL_DOSMVDM
#include <eddinclt.h>

#include <eddhcone.h>
#include <eddfcone.h>
#include <eddmcone.h>
#include <eddvcone.h>
#include <eddecone.h>

#include <edddtypt.h>
#include <eddetypt.h>
#include <eddftype.h>

#include <eddaextf.h>
#include <eddbextf.h>
#include <eddcextf.h>
#include <eddeextf.h>
#include <eddgextf.h>
#include <eddmextf.h>
#include <eddtextf.h>
#include <eddqextf.h>

#include <edddlg.h>

#include <memman.h>
#include <cursor.h>
#include <plasma.h>
#include <seamless.h>
#ifdef VRAMPTR
#include <eddncach.h>
#endif /* VRAMPTR */

#ifdef VVGA
#include <vvga.h>
#endif /* VVGA */

/* definitions to be moved elsewhere */
typedef struct
{
   USHORT usWidth;
   USHORT usHeight;
   USHORT usBitCount;
   USHORT usHorizontalResolution;
   USHORT usVerticalResolution;
   USHORT usGraphicsCharWidth;
   USHORT usGraphicsCharHeight;
   USHORT usAlphaCellWidth;
   USHORT usAlphaCellHeight;
   BYTE   fbFlags;
} DISPLAYMODE;
typedef DISPLAYMODE FAR * PDISPLAYMODE;

VOID PASCAL AdjustDefaultSysCols(VOID);
BOOL PASCAL SwitchToExtendedGraphicsMode(VOID);
BOOL PASCAL SwitchToP75VGAMode(VOID);

#define XGA_OS2INI_SECTION "PM_IBMXGA"
#define XGA_INI_RES_KEYWORD "RESOLUTION"
#define XGA_INI_FONT_KEYWORD "SYSFONT"
#define XGA_INI_CURSOR_KEYWORD "CURSOR_TYPE"
#define XGA_INI_FONT_DIR_KEYWORD "FONT_DIR"

#define XGA_INI_FONT_DIR ":\\OS2\\DDFONTS"  /* Defect 68175 */
#define DEFAULT_RESOLUTION "H"
#define HIGH_RESOLUTION 'H'
#define DEFAULT_SYSFONT "0"
#define DEFAULT_CURSOR "H"
#define SOFTWARE_CURSOR 'S'

#define MAX_DEFAULT_FONTS 4
#define DEFAULT_DEFAULT_FONT 0

#define SIZE_INI_RES 2
#define SIZE_INI_FONT 2
#define SIZE_INI_CURSOR 2
#define SIZE_INI_FONT_DIR 32
#define MIN_SIZE_INI_FONT_DIR 2

typedef struct
{
  CHAR achResolution[SIZE_INI_RES];
  CHAR achSystemFont[SIZE_INI_FONT];
  CHAR achCursorType[SIZE_INI_CURSOR];
  CHAR achFontDir[SIZE_INI_FONT_DIR];
} XGAINIDATA;

typedef XGAINIDATA FAR * PXGAINIDATA;

#ifndef _8514
  ADAPTERINFO     aiXGAAdapter;
  ADAPTERINFO2    ai2XGAAdapter;
  XGAINSTANCE     InstanceData;
  HFILE           ring0_handle;
#else
  #include <8514.h>
  #define INCL_NONE
  #define INCL_VIDEOHW
  #define INCL_VIDEOSYSREQ
  #include <vvd.h>

  ADAPTER8514     ai8514Adapter;
  VVDRQ           vvdrq;
  ULONG           Screen8514VisHeight;
  ULONG           Screen8514VisWidth;
#endif

PBYTE           pbHWPollRegister;
/**********************************************************************/
/* Variable used during the delay loop that is used while polling the */
/* XGA hardware to see if it is ready.                                */
/* The delay is arbitrary and could be adjusted depending on the      */
/* hardware.  eg. NI hardware does not need a delay and this will be  */
/* zero.                                                              */
/**********************************************************************/
ULONG           ulPollingDelay;
HMODULE         font_hmod;

/* end of definitions to be moved elsewhere */

BOOL SetupFontInformation(VOID);
VOID SetupCursorInformation(VOID);
VOID SetupAVIOInformation(VOID);

extern HMODULE                hModule;
extern BitmapHeader           NewPatternTable[];

extern DDTType                DDT;
extern BitmapHeader           DirectListEntry;
extern BitmapHeader           DummyInfoBitmap;

extern RGB2                   AVIOColorTable[];
extern ULONG                  AVIOXlate256[];
extern PULONG                 pAVIOColorXlate;
extern USHORT                 ResidentFonts;

extern AvioFontTableType      AvioBaseFont[NO_OF_AVIO_FONTS];

extern SHORT                  softDrawInUse ;
#ifndef _8514
extern MMReg                  ShadowXGARegs ;
extern pMMReg                 pRealXGARegs ;
extern pMMReg                 pXGARegs ;
#else
extern MM8514Reg              Shadow8514Regs ;
extern pMM8514Reg             p8514Regs ;
#endif

extern drawFunctionsTable     hardDrawTable ;
extern pDrawFunctionsTable    pDrawFunctions ;

extern CURSORDATA               cursor_data;

BOOL                            SWCursorForced;

#ifdef PDP
USHORT  RequestBlk[32];
#endif /* PDP */

extern BYTE                     DefaultSmallFont;
extern BYTE                     DefaultNormalFont;
extern AvioDefaultFontTableType AvioDefaultFont[NO_OF_VIDEO_MODES];

extern USHORT                   VRAMK;
extern lpPDBI                   PDBInstance;
extern PVOID                    pDefaultFont;
extern ULONG                    ulSysFontId;
extern USHORT                   usDefaultCodePage;
extern USHORT                   usVersion;

extern BOOL                     UsePaletteMapping;
extern BOOL                     CurrentMappingValid;

#ifdef MATROX
extern BitmapHeader        VRAMBitmap;
#endif /* MATROX */

#ifdef _8514

  extern VOID    Notify_VDD( BOOL );
#ifdef SEAMLESS

  extern PVOID   *pWindowsSharedData;

#endif
#endif


USHORT                          IOBase;

#ifndef   _8514
CALLGATE                        PaletteRoutine;
CALLGATE                        SpriteShapeRoutine;
CALLGATE                        plasma_type_routine;
#endif

#ifdef VVGA
CALLGATE                        ActivatePlanarVGA_routine;
CALLGATE                        DeactivatePlanarVGA_routine;
#endif /* VVGA */

#ifndef _8514
/**********************************************************************/
/* CreateCallGates:                                                   */
/*                                                                    */
/* Create a way in which we can get some of our code which            */
/* requires IOPL to run at ring 0.                                    */
/*                                                                    */
/* CreateCallGates1 is called before the DDT is set up.               */
/* CreateCallGates2 is called after the DDT is set up.                */
/**********************************************************************/
VOID CreateCallGates1(VOID)
{
    ULONG       fn_id = IO_CREATE_CALLGATE;

    /******************************************************************/
    /* Do the SetSpriteShape routine                                  */
    /******************************************************************/
    SpriteShapeRoutine.linear_address = (PVOID)&SetSpriteShapeWorker;
    SpriteShapeRoutine.cParams = 0;

    DosDevIOCtl( ring0_handle,
                 XGA_CATEGORY,
                 GEN_FUNCTION,
                 (PVOID)&fn_id,
                 sizeof(fn_id),  /* not passed to level 1 ring0 code */
                 NULL,           /* not passed to level 1 ring0 code */
                 (PVOID)&SpriteShapeRoutine,
                 sizeof(SpriteShapeRoutine),
                                 /* not passed to level 1 ring0 code */
                 NULL            /* not passed to level 1 ring0 code */
               );

    /******************************************************************/
    /* Now do the plasma_type routine.                                */
    /******************************************************************/
    plasma_type_routine.linear_address = (PVOID)&plasma_type_worker;
    plasma_type_routine.cParams = 0;

    DosDevIOCtl( ring0_handle,
                 XGA_CATEGORY,
                 GEN_FUNCTION,
                 (PVOID)&fn_id,
                 sizeof(fn_id),  /* not passed to level 1 ring0 code */
                 NULL,           /* not passed to level 1 ring0 code */
                 (PVOID)&plasma_type_routine,
                 sizeof(plasma_type_routine),
                                 /* not passed to level 1 ring0 code */
                 NULL            /* not passed to level 1 ring0 code */
               );

#ifdef VVGA
    /******************************************************************/
    /* Do the ActivatePlanarVGA routine.                              */
    /******************************************************************/
    ActivatePlanarVGA_routine.linear_address = (PVOID)&ActivatePlanarVGAWorker;
    ActivatePlanarVGA_routine.cParams = 0;

    DosDevIOCtl( ring0_handle,
                 XGA_CATEGORY,
                 GEN_FUNCTION,
                 (PVOID)&fn_id,
                 sizeof(fn_id),  /* not passed to level 1 ring0 code */
                 NULL,           /* not passed to level 1 ring0 code */
                 (PVOID)&ActivatePlanarVGA_routine,
                 sizeof(ActivatePlanarVGA_routine),
                                 /* not passed to level 1 ring0 code */
                 NULL            /* not passed to level 1 ring0 code */
               );
    /******************************************************************/
    /* Do the DeactivatePlanarVGA routine.                            */
    /******************************************************************/
    DeactivatePlanarVGA_routine.linear_address = (PVOID)&DeactivatePlanarVGAWorker;
    DeactivatePlanarVGA_routine.cParams = 0;

    DosDevIOCtl( ring0_handle,
                 XGA_CATEGORY,
                 GEN_FUNCTION,
                 (PVOID)&fn_id,
                 sizeof(fn_id),  /* not passed to level 1 ring0 code */
                 NULL,           /* not passed to level 1 ring0 code */
                 (PVOID)&DeactivatePlanarVGA_routine,
                 sizeof(DeactivatePlanarVGA_routine),
                                 /* not passed to level 1 ring0 code */
                 NULL            /* not passed to level 1 ring0 code */
               );
#endif /* VVGA */

}

VOID CreateCallGates2(VOID)
{
    ULONG       fn_id = IO_CREATE_CALLGATE;

    if (DDT.BitCount == 16)
    {
        /**************************************************************/
        /* Use the special 'Direct color' palette load routine.       */
        /**************************************************************/
        PaletteRoutine.linear_address = (PVOID)&LoadDirectPaletteWorker;
        PaletteRoutine.cParams = 0;
    }
    else
    {
        /**************************************************************/
        /* Use the normal palette loading routine.                    */
        /**************************************************************/
        PaletteRoutine.linear_address = (PVOID)&LoadPaletteEntriesWorker;
        PaletteRoutine.cParams = 3;
    }

    DosDevIOCtl( ring0_handle,
                 XGA_CATEGORY,
                 GEN_FUNCTION,
                 (PVOID)&fn_id,
                 sizeof(fn_id),  /* not passed to level 1 ring0 code */
                 NULL,           /* not passed to level 1 ring0 code */
                 (PVOID)&PaletteRoutine,
                 sizeof(PaletteRoutine),
                                 /* not passed to level 1 ring0 code */
                 NULL            /* not passed to level 1 ring0 code */
               );

}

/**********************************************************************/
/* QueryAdapter                                                       */
/*                                                                    */
/* This function queries the selected HW configuration (sets up the   */
/* aiXGAAdapter and ai2XGAAdapter structures) by calling the ring0.   */
/*                                                                    */
/* Returns TRUE if successful, FALSE otherwise.                       */
/**********************************************************************/
BOOL QueryAdapter(VOID)
{
    ULONG      fn_id;
    ULONG      rc;

    fn_id = IO_GETADAPTERINFO;
    rc = DosDevIOCtl( ring0_handle,
                      XGA_CATEGORY,
                      GEN_FUNCTION,
                      (PVOID)&fn_id,
                      sizeof(fn_id),       /* not passed to level 1 ring0 code */
                      NULL,                /* not passed to level 1 ring0 code */
                      (PVOID)&aiXGAAdapter,
                      sizeof(ADAPTERINFO), /* not passed to level 1 ring0 code */
                      NULL                 /* not passed to level 1 ring0 code */
                     );

    if (rc != NO_ERROR)
    {
        return(FALSE);
    }

    fn_id = IO_GETADAPTERINFO2;
    rc = DosDevIOCtl( ring0_handle,
                      XGA_CATEGORY,
                      GEN_FUNCTION,
                      (PVOID)&fn_id,
                      sizeof(fn_id),       /* not passed to level 1 ring0 code */
                      NULL,                /* not passed to level 1 ring0 code */
                      (PVOID)&ai2XGAAdapter,
                      sizeof(ADAPTERINFO2),/* not passed to level 1 ring0 code */
                      NULL                 /* not passed to level 1 ring0 code */
                    );
    if (rc != NO_ERROR)
    {
        return(FALSE);
    }

    return(TRUE);

} /* QueryAdapter */
#endif //_8514


/**********************************************************************/
/* ChangeSysColors is used to change the entry describing the         */
/* system colors in OS2.INI. The change is only made if the           */
/* current OS2.INI entry matches the supplied search string           */
/* (pszSearchString), and is replaced with the replacement string     */
/* (pszReplaceString).                                                */
/**********************************************************************/

VOID PASCAL ChangeSysColors ( PSZ   pszEntryName,
                              PSZ   pszFieldName,
                              PSZ   pszSearchString,
                              PSZ   pszReplaceString )
{

    /******************************************************************/
    /* Define a local buffer.                                         */
    /* This must be big enough to hold the largest RGB string, which  */
    /* is held in the format "255 255 255" (for white). The largest   */
    /* string will therefore be 11 chars (plus a null->12). Add       */
    /* a bit of contingency too!                                      */
    /******************************************************************/
#define SIZE_BUFFER 20
    CHAR    achInputBuffer[SIZE_BUFFER];
    ULONG   cbReturned;

    /******************************************************************/
    /* Query the requested profile string.                            */
    /******************************************************************/
    cbReturned = PrfQueryProfileString( HINI_PROFILE,
                                        pszEntryName,
                                        pszFieldName,
                                        "",
                                        (PVOID)achInputBuffer,
                                        SIZE_BUFFER );

    /******************************************************************/
    /* Only proceed if some data was returned.                        */
    /******************************************************************/
    if ( (cbReturned > 0) &&
         (cbReturned <= SIZE_BUFFER) )
    {
        /**************************************************************/
        /* Put a NULL at the end of our buffer to ensure we don't     */
        /* overrun it (although the profile string SHOULD have a      */
        /* null at the end).                                          */
        /**************************************************************/
        achInputBuffer[SIZE_BUFFER-1] = 0;

        /**************************************************************/
        /* Now check to see if the profile string matches the         */
        /* string supplied as a parameter.                            */
        /**************************************************************/
        if (strcmp(achInputBuffer,
        pszSearchString) == 0)
        {
            /**********************************************************/
            /* Found the string that we are searching for!            */
            /* Now replace it with the supplied string.               */
            /**********************************************************/
            PrfWriteProfileString( HINI_PROFILE,
                                   pszEntryName,
                                   pszFieldName,
                                   pszReplaceString);
        }
    }
} /* ChangeSysColours */


/**********************************************************************/
/* AdjustDefaultSysCols changes the default system colors to avoid    */
/* hideous flickering which occurs at high-resolution 4bpp because    */
/* of our dither patterns.                                            */
/* Note that the colors are only changed if they are at their         */
/* default values. If the user changes the colors then we will not    */
/* touch them (we assume the user knows best!).                       */
/**********************************************************************/

VOID PASCAL AdjustDefaultSysCols()
{
    ChangeSysColors( "PM_Colors", "AppWorkspace",
                     "255 251 226", "255 255 255" );

    ChangeSysColors( "PM_Default_Colors", "AppWorkspace",
                     "255 251 226", "255 255 255" );

    ChangeSysColors( "PM_Colors", "Scrollbar",
                     "224 224 224", "255 255 255" );

    ChangeSysColors( "PM_Default_Colors", "Scrollbar",
                     "224 224 224", "255 255 255" );
} /* AdjustDefaultSysCols */


/**********************************************************************/
/* FontDirData                                                        */
/*                                                                    */
/* Reads the font directory data from os2.ini, storing the data in    */
/* pszFontDir and returning the length of the data.                   */
/**********************************************************************/
USHORT PASCAL FontDirData(PSZ pszFontDir)
{
   return ((USHORT)PrfQueryProfileString( HINI_PROFILE,
                                          XGA_OS2INI_SECTION,
                                          XGA_INI_FONT_DIR_KEYWORD,
                                          "",
                                          pszFontDir,
                                          SIZE_INI_FONT_DIR) );

} /* FontDirData */



/**********************************************************************/
/* CursorFontResData                                                  */
/*                                                                    */
/* Reads the resolution, default system font and cursor type from     */
/* os2.ini, storing the data in pxidUserConfig and returning the      */
/* total length of the data.                                          */
/**********************************************************************/
USHORT PASCAL CursorFontResData(PXGAINIDATA pxidUserConfig)
{
   return((USHORT)PrfQueryProfileString( HINI_PROFILE,
                                         XGA_OS2INI_SECTION,
                                         XGA_INI_RES_KEYWORD,
                                         "",
                                         pxidUserConfig->achResolution,
                                         SIZE_INI_RES) +

          (USHORT)PrfQueryProfileString( HINI_PROFILE,
                                         XGA_OS2INI_SECTION,
                                         XGA_INI_FONT_KEYWORD,
                                         "",
                                         pxidUserConfig->achSystemFont,
                                         SIZE_INI_FONT) +

          (USHORT)PrfQueryProfileString( HINI_PROFILE,
                                         XGA_OS2INI_SECTION,
                                         XGA_INI_CURSOR_KEYWORD,
                                         "",
                                         pxidUserConfig->achCursorType,
                                         SIZE_INI_CURSOR) );

} /* CursorFontResData */


/**********************************************************************/
/* Returns the default configuration (resolution, font directory,     */
/* hard/software cursor, default font) in pxidUserConfig and puts     */
/* this data in os2.ini to use next time                              */
/**********************************************************************/
VOID PASCAL GetAndSetDefaultConfig(PXGAINIDATA pxidUserConfig)
{
/*Defect 68175 Start */
   CHAR pBuf[4];

   if (DosQuerySysInfo(QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, pBuf, sizeof(pBuf)))
   {
      /* ERROR - Use drive C */
      pxidUserConfig->achFontDir[0] = 'C';
      strcpy(pxidUserConfig->achFontDir + 1, XGA_INI_FONT_DIR);
   }
   else
   {
      /* Use boot drive */
      pxidUserConfig->achFontDir[0] = (pBuf[0] + 'A' - 1);
      strcpy(pxidUserConfig->achFontDir + 1, XGA_INI_FONT_DIR);
   }
/* Defect 68175 End */

   strcpy(pxidUserConfig->achResolution, DEFAULT_RESOLUTION);
   strcpy(pxidUserConfig->achCursorType, DEFAULT_CURSOR);
   strcpy(pxidUserConfig->achSystemFont, DEFAULT_SYSFONT);

   PrfWriteProfileString( HINI_PROFILE,
                          XGA_OS2INI_SECTION,
                          XGA_INI_FONT_DIR_KEYWORD,
                          pxidUserConfig->achFontDir); /* Defect 68175 */

   PrfWriteProfileString( HINI_PROFILE,
                          XGA_OS2INI_SECTION,
                          XGA_INI_RES_KEYWORD,
                          DEFAULT_RESOLUTION);

   PrfWriteProfileString( HINI_PROFILE,
                          XGA_OS2INI_SECTION,
                          XGA_INI_FONT_KEYWORD,
                          DEFAULT_SYSFONT);

   PrfWriteProfileString( HINI_PROFILE,
                          XGA_OS2INI_SECTION,
                          XGA_INI_CURSOR_KEYWORD,
                          DEFAULT_CURSOR);

} /* GetAndSetDefaultConfig */


/**********************************************************************/
/* Returns the configuration info (resolution, font directory,        */
/* hard/software cursor, default font) in pxidUserConfig. Uses the    */
/* data in os2.ini if it's correct, otherwise uses defaults which it  */
/* then writes to os2.ini for next time. This also adds the utilities */
/* to a new group if the version is 1.2 or earlier.                   */
/**********************************************************************/
VOID PASCAL GetConfigInfo(PXGAINIDATA pxidUserConfig)
{

   if ( (CursorFontResData(pxidUserConfig) != (SIZE_INI_RES +
                                               SIZE_INI_FONT +
                                               SIZE_INI_CURSOR)) ||
        (FontDirData(pxidUserConfig->achFontDir) < MIN_SIZE_INI_FONT_DIR) )
   {
      GetAndSetDefaultConfig(pxidUserConfig);
   }

} /* GetConfigInfo */

#ifndef   _8514
/**********************************************************************/
/* QuerySystemUnit                                                    */
/*                                                                    */
/* Returns the plasma configuration:                                  */
/*   0 = no plasma                                                    */
/*   PLASMA_PRESENT = system unit with plasma displayed disabled      */
/*   PLASMA_PRESENT | PLASMA_ENABLED = mono plasma                    */
/*   PLASMA_PRESENT | PLASMA_ENABLED | PLASMA_COLOUR = colour plasma. */
/**********************************************************************/
USHORT PASCAL QuerySystemUnit()
{
   ULONG        SubModel;

   DosDevConfig(&SubModel,
                DEVINFO_SUBMODEL);

   if (SubModel == KAUAI_SUBMODEL)
   {
      /****************************************************************/
      /* P75 system unit so may be a plasma display                   */
      /****************************************************************/
      RequestBlk[0] = 64;         /* length in bytes */
      RequestBlk[1] = 0;          /* LID ?           */
      RequestBlk[2] = 0;          /* unit            */
      RequestBlk[3] = 3;          /* function        */
      RequestBlk[4] = 0;          /* reserved        */
      RequestBlk[5] = 0;          /* reserved        */
      RequestBlk[6] = 0xffff;     /* return code     */

      GetPlasmaStatus();

      /****************************************************************/
      /* check the ABIOS return code (in RequestBlk[0x10] for the     */
      /* status of the plasma                                         */
      /****************************************************************/
      if (RequestBlk[0x10] & 2)
      {
         /**********************************************************/
         /* plasma is enabled so check it is colour or mono        */
         /* NOTE: the colour/mono field in the ABIOS_ret value     */
         /*       gives the type of the external monitor, not of   */
         /*       the internal monitor (ie the plasma panel)       */
         /**********************************************************/
         if (plasma_type())
         {
            return( PLASMA_PRESENT | PLASMA_COLOUR | PLASMA_ENABLED );
         }
         else /* mono */
         {
            return( PLASMA_PRESENT | PLASMA_ENABLED );
         }
      }

      else /* plasma disabled */
      {
         return( PLASMA_PRESENT );
      }
   }

   else /* non-P75 so no plasma */
   {
      return(0);
   }

} /* QuerySystemUnit */




/**********************************************************************/
/* Routine to return the address of the (memory mapped) register to   */
/* poll to see if the hardware has finished.                          */
/**********************************************************************/
PBYTE HWPollRegisterAddress(VOID)
{
    if ( ExternalPollingEnabled() )
    {
        /**************************************************************/
        /* If external polling is enabled then we have no need to     */
        /* delay our polling loop at all.                             */
        /**************************************************************/
        ulPollingDelay = 0;

        /**************************************************************/
        /* H/W support ExtPolling so return ExtPolling address.       */
        /**************************************************************/
        return(&aiXGAAdapter.pMemRegBase->ExtPolling);
    }

    /******************************************************************/
    /* External Polling not enabled so return the PIControl address.  */
    /* and have a (currently) arbitrary value for the polling delay.  */
    /******************************************************************/
    ulPollingDelay = 100;

    return(&aiXGAAdapter.pMemRegBase->PIControl);

} /* HWPollRegisterAddress */


VOID GetPlasmaStatus(VOID)
{
    HFILE                FileHandle;      /* Font identifier          */
    ULONG                ulActionTaken;   /* Parameter for DosOpen    */

    DosOpen( "\\DEV\\SCREEN$",
             &FileHandle,
             &ulActionTaken,
             0,
             4,         /* open as system file       */
             1,         /* open flag- open if exists */
             0x4042,    /* open mode                 */
             0);        /* reserved                  */

    DosDevIOCtl( FileHandle,
                 0x03,          /* category 3         */
                 0x74,          /* ABIOS pass through */
                 (PVOID)&RequestBlk,
                 sizeof(RequestBlk),
                 NULL,
                 (PVOID)&RequestBlk,
                 sizeof(RequestBlk),
                 NULL
               );

    DosClose(FileHandle);
}
#endif //_8514


/**********************************************************************/
/* FillPdb establishes the display configuration...                   */
/**********************************************************************/

ULONG FillPdb ( VOID )

/**********************************************************************/
/* Executed once but may be called many times.                        */
/* Initialises the driver and adapter.                                */
/**********************************************************************/

{
    XGAINIDATA          xidUserConfig;
    ULONG               aSysInfo[QSV_VERSION_REVISION-QSV_VERSION_MAJOR+1];
    #ifndef _8514
    ULONG               ulActionTaken;   /* Parameter for DosOpen    */
    ULONG               ulDosReturn;
    USHORT              fn_id;
    #endif

    RequestDriverSemaphore();

    /******************************************************************/
    /* This routine can be called multiple times, particularly by     */
    /* brute force printing. Every time after the first there is no   */
    /* work to be done and we can return immediately. PDBInstance is  */
    /* initially set to null, a non-null value indicates the code has */
    /* already been executed.                                         */
    /******************************************************************/
    if (PDBInstance)
    {
        ReleaseDriverSemaphore();
        return((ULONG)PDBInstance);
    }

    /******************************************************************/
    /* We will be calling the ring 0 device driver, so get a handle   */
    /* for it                                                         */
    /******************************************************************/
    #ifndef _8514
    ring0_handle = (HFILE)0;
    ulDosReturn = DosOpen("\\DEV\\$$$XGA20",
                           &ring0_handle,
                           &ulActionTaken,
                           0,
                           FILE_SYSTEM,
                           OPEN_ACTION_OPEN_IF_EXISTS,
                           OPEN_FLAGS_WRITE_THROUGH |
                           OPEN_SHARE_DENYNONE |
                           OPEN_ACCESS_READWRITE,
                           0 );
    if (ulDosReturn != NO_ERROR)
    {
        DebugOutput("XGA: Unable to open XGA.SYS\n\r");
        LogDosError(ulDosReturn);
        goto FILLPDB_ERR_EXIT;
    }
    #endif //_8514

    /******************************************************************/
    /* Get a valid pointer to return to the engine as the PDB.        */
    /******************************************************************/
    PDBInstance = (lpPDBI)&PDBInstance;

    /******************************************************************/
    /* Get the version number - this call cannot fail so don't        */
    /* bother checking for an error.                                  */
    /*                                                                */
    /* DosGetVersion((PUSHORT)&usVersion);                            */
    /* At 1.2/1.3 we use the DosGetVersion call which gave us a single*/
    /* USHORT to specify the version.  This call is not in the 32bit  */
    /* API so we must get the version using DosQuerySysInfo, and then */
    /* juggle the value into our USHORT in order to avoid changing    */
    /* the rest of the code.                                          */
    /* We get the fields major,minor and revision for debugging       */
    /* though we only currently use major and minor when forming the  */
    /* version number.                                                */
    /******************************************************************/
    DosQuerySysInfo(QSV_VERSION_MAJOR,
                    QSV_VERSION_REVISION,
                    aSysInfo,
                    (QSV_VERSION_REVISION-QSV_VERSION_MAJOR+1) *
                                                     sizeof(ULONG));
    usVersion = (aSysInfo[0] << 8) | aSysInfo[1];


    /******************************************************************/
    /* Create ring 0 callgates that are not dependant on DDT.         */
    /******************************************************************/
    #ifndef _8514
    CreateCallGates1();
    #endif

#ifdef VVGA
    /******************************************************************/
    /* See if there is a free planar XGA that we can use for VVGA.    */
    /* This call !! MUST !! be made before the                        */
    /* QueryAndSelectNativeMode call (because it messes with the      */
    /* RING0 Instance Data).                                          */
    /******************************************************************/
    LookForFreePlanarXGA();
#endif /* VVGA */

    /******************************************************************/
    /* Determine if we are on a P75 system unit equipped with a       */
    /* plasma panel, and if so if it is enabled as colour emulation   */
    /* or mono. This is used in QueryAndSelectNativeMode.             */
    /******************************************************************/
    #ifndef _8514
    plasma_status = QuerySystemUnit();

    /******************************************************************/
    /* Call the ring0 to find out which modes are available for us to */
    /* use (supplied by DMQS) and then select one of the modes.  This */
    /* must be done before querying the adapter because if we have    */
    /* multiple adapters then we do not know which one we are going   */
    /* to use until we have selected a mode.  (The BVH uses the DMQS  */
    /* information to make the decision for us at that point).  The   */
    /* function also sets up the values in the DDT which are directly */
    /* dependent on the mode selected and the aiXGAAdapter and        */
    /* ai2XGAAdapter structures.                                      */
    /******************************************************************/
    QueryAndSelectNativeMode();

    #else

    // set this value manually
    VRAMK    = (USHORT)(ai8514Adapter.lMemorySize / 1024);

    QueryAndSelectNativeMode();

    #endif //_8514

    /******************************************************************/
    /* Get the resolution, cursor type, default font and font         */
    /* directory from os2.ini                                         */
    /******************************************************************/
    GetConfigInfo(&xidUserConfig);

    /******************************************************************/
    /* Now we have the configuration, set up some globals.            */
    /******************************************************************/
    SWCursorForced = (xidUserConfig.achCursorType[0] == SOFTWARE_CURSOR);

#ifdef MATROX
    if (RunningOnMatrox())
    {
        SWCursorForced = TRUE;
    }
#endif /* MATROX */

    /******************************************************************/
    /* Set up variables used when manipulating the cursor.            */
    /* Note that the DDT values are set to the MAXIMUM width and      */
    /* height that the cursor definition may be, but the values of    */
    /* CurWidth and CurHeight may change with the size of the CURRENT */
    /* cursor (eg might be 32x32 or 40x40).                           */
    /******************************************************************/
    if (DDT.fScreenFlags & DM_HI_RES)
    {
        /**************************************************************/
        /* high res 8514 sized monitor (8514, Dallas, 8507)           */
        /**************************************************************/
        DDT.CursorWidth  = HIGHRESCURSORWIDTH;
        DDT.CursorHeight = HIGHRESCURSORHEIGHT;
    }
    else
    {
        /**************************************************************/
        /* VGA sized monitor (8503, 8512/3, PDP)                      */
        /**************************************************************/
        DDT.CursorWidth  = LOWRESCURSORWIDTH;
        DDT.CursorHeight = LOWRESCURSORHEIGHT;
    }

    /******************************************************************/
    /* Set up values in the bitmap header for Direct DCs and          */
    /* put the screen format in the dithered pattern bitmap header.   */
    /******************************************************************/
    DirectListEntry.Info.BitCount =
       NewPatternTable[PATSYM_DITHERED].Info.BitCount = DDT.BitCount;

    #ifdef BPP24
    if ( DDT.BitCount == 24 )
    {
        /**************************************************************/
        /* We do not set up the dithered pattern header here because  */
        /* we never dither at 24bpp.                                  */
        /**************************************************************/
        DirectListEntry.Info.HWFormat = TWENTYFOUR_BITS_PER_PEL;
    }
    else if ( DDT.BitCount == 16 )
    #else
    if ( DDT.BitCount == 16 )
    #endif
    {
        /**************************************************************/
        /* We do not set up the dithered pattern header here because  */
        /* we never dither at 16bpp.                                  */
        /**************************************************************/
        DirectListEntry.Info.HWFormat = SIXTEEN_BITS_PER_PEL;
    }
    else if ( DDT.BitCount == 8 )
    {
        NewPatternTable[PATSYM_DITHERED].Info.HWFormat =
        DirectListEntry.Info.HWFormat = EIGHT_BITS_PER_PEL;
    }
    else /* DDT.Bitcount == 4 */
    {
        NewPatternTable[PATSYM_DITHERED].Info.HWFormat =
        DirectListEntry.Info.HWFormat = FOUR_BITS_PER_PEL;
    }

    DirectListEntry.Info.Width    = DDT.ScreenWidth;
    DirectListEntry.Info.Height   = DDT.ScreenHeight;
    DirectListEntry.Info.HWHeight = DDT.ScreenHeight - (USHORT)1;
#ifdef VRAMPTR
    DirectListEntry.bm_cache_slot = BITMAP_NOT_CACHED;
#endif /* VRAMPTR */

#ifdef _8514
    Screen8514VisHeight = DDT.ScreenHeight;
    if ( DDT.BitCount < 24 ) {
       Screen8514VisWidth = DDT.ScreenWidth;
    }
    else
    {
       Screen8514VisWidth = DDT.ScreenWidth * 3;
    }
#endif

#ifdef MATROX
    if (RunningOnMatrox())
    {
        /**************************************************************/
        /* We have fiddled things so that Matrox says it is a 8515    */
        /* screen, on a card that supports 16bpp.  Thus the mode      */
        /* detailed in the DDT is 640 * 480.  However the actual      */
        /* memory arrangement is 1024 * 1024, and the format is       */
        /* assumed to be intel, not motorola.                         */
        /**************************************************************/
        DirectListEntry.Info.HWFormat &= ~MOTOROLA;
        DirectListEntry.Info.HWWidth   = 1023;
        DirectListEntry.BytesPerLine   = 1024 * 2;
    }
    else
    {
#endif /* MATROX */
        /**************************************************************/
        /* These are the normal XGA values                            */
        /**************************************************************/
        DirectListEntry.Info.HWWidth  = DDT.ScreenWidth - (USHORT)1;
        DirectListEntry.BytesPerLine  =
                (DDT.ScreenWidth * DDT.BitCount + (USHORT)7) / (USHORT)8;
#ifdef MATROX
    }
#endif /* MATROX */

    /******************************************************************/
    /* Get a pointer to the register to use for hardware polling -    */
    /* this will vary according to whether external polling is        */
    /* enabled or not.                                                */
    /******************************************************************/
    #ifndef   _8514
    pbHWPollRegister = HWPollRegisterAddress();

    /******************************************************************/
    /* Set up the XGA register pointer to point to the real XGA       */
    /* hardware registers.                                            */
    /******************************************************************/
    pXGARegs = pRealXGARegs = aiXGAAdapter.pMemRegBase;

    /******************************************************************/
    /* we also want the address of the IO registers                   */
    /******************************************************************/
    IOBase = aiXGAAdapter.usIORegBase;


    /******************************************************************/
    /* Set the initial value for the colour compare condition in the  */
    /* shadow registers (hardware register value will have been set   */
    /* by the xgaring0 code)                                          */
    /******************************************************************/
    ShadowXGARegs.ColCompCond = COLCOMP_ALWAYS;

    /******************************************************************/
    /* Store the address of the screen data. (The screen occurs       */
    /* right at the start of the VRAM).                               */
    /******************************************************************/
    DirectListEntry.BMPhys = aiXGAAdapter.ulVRAMBase;
    #else
    Shadow8514Regs.Mode.UnderPaint = MD_UP_FALSE;
    p8514Regs = &Shadow8514Regs;
    IOBase = ai8514Adapter.usIORegBase;
    DirectListEntry.BMPhys = ai8514Adapter.ulVRAMBase;
    #endif

#ifdef MATROX
    if (RunningOnMatrox())
    {
        /**************************************************************/
        /* Use software drawing to draw to VRAM.  Copy the direct     */
        /* list entry into our new VRAMBitmap structure               */
        /**************************************************************/
        VRAMBitmap = DirectListEntry;

        /**************************************************************/
        /* Get access to the screen bitmap in VRAM for this process.  */
        /**************************************************************/
        AccessVRAMBitmap();

        VRAMBitmap.BMPhys = 0;
    }
#endif /* MATROX */

    /******************************************************************/
    /* We need to set up a dummy bitmap header for use by INFO_DC's.  */
    /* This (for want of a better choice) is based on the screen.     */
    /******************************************************************/
    DummyInfoBitmap = DirectListEntry;

#ifdef SDBM20
    /******************************************************************/
    /* Create the PHUNK                                               */
    /******************************************************************/
    eddb_CreatePhunk();

#ifdef PALETTE_MGR
    /******************************************************************/
    /* We must initialise the UsePaletteMapping variable so that      */
    /* functions that are do not use palette mapping need not worry   */
    /* when they call the BitBlt sub-functions (eg. blttoDestination) */
    /******************************************************************/
    UsePaletteMapping = FALSE;
    /******************************************************************/
    /* Also want to indicate that we do not have a current palette    */
    /* mapping that is valid.                                         */
    /******************************************************************/
    CurrentMappingValid = FALSE;
#endif /* PALETTE_MGR */

#endif /* SDBM20 */

    /******************************************************************/
    /* Setup the font information.                                    */
    /******************************************************************/
    if (!SetupFontInformation())
    {
        goto FILLPDB_ERR_EXIT;
    }

    /******************************************************************/
    /* Set up the cursor information                                  */
    /******************************************************************/
    SetupCursorInformation();

    /******************************************************************/
    /* If we're on a P75 set vga mode with 24 rows, which stops it    */
    /* getting into a messy state.                                    */
    /******************************************************************/
    #ifndef _8514
    if ( plasma_status & PLASMA_ENABLED )
    {
       if ( !SwitchToP75VGAMode() )
       {
          goto FILLPDB_ERR_EXIT;
       }
    }
    #endif //_8514

    /******************************************************************/
    /* Now put the adapter into the mode we require.                  */
    /******************************************************************/
    if ( !SwitchToExtendedGraphicsMode() )
    {
       goto FILLPDB_ERR_EXIT;
    }

    /******************************************************************/
    /* Having set the mode we are using, get the instance data for    */
    /* the XGA being used for PM.                                     */
    /******************************************************************/
    #ifndef _8514
    fn_id = IO_GETINSTANCEDATA;
    ulDosReturn = DosDevIOCtl(ring0_handle,
                              XGA_CATEGORY,
                              GEN_FUNCTION,
                              (PVOID)&fn_id,
                              sizeof(fn_id),
                              NULL,
                              (PVOID)&InstanceData,
                              sizeof(InstanceData),
                              NULL );

    if ( ulDosReturn != NO_ERROR )
    {
        LogDosError(ulDosReturn);
        goto FILLPDB_ERR_EXIT;
    }
    #endif //_8514

#ifdef VVGA
    /******************************************************************/
    /* See if Virtual VGA operation is possible.                      */
    /******************************************************************/
    CheckForVirtualVGA();
#endif /* VVGA */

#ifdef _8514
    /* Start of new code for -             */

    /******************************************************************/
    /* Indicate that Virtual VGA operation is possible.               */
    /******************************************************************/

    vvdrq.vvd_offLatchByte = 0L;   /* offset of available latch storage */
    vvdrq.vvd_pfbDRQFlags  = 0L;   /* pointer to flags (see DRQ_* constants) */
    vvdrq.vvd_pfCtrlOwned  = 0L;   /* address of display.dll's fCtrlOwned flag */
    vvdrq.vvd_pfCtrlNotify = 0L;   /* address of display.dll's fCtrlNotify flag */
    vvdrq.vvd_nShadowRegs  = 0L;   /* # of registers to shadow */
    vvdrq.vvd_pShadowData  = 0L;   /* address of first entry in shadow list */

    #ifndef S3
    Notify_VDD( TRUE );
    #endif

    /* End of new code for -             */
#endif

    /******************************************************************/
    /* Create ring 0 callgates that are dependent on the DDT.         */
    /******************************************************************/
    #ifndef _8514
    CreateCallGates2();

    /******************************************************************/
    /* Ensure that the palettes contain the set of ISO compliant      */
    /* colours specified in the DMQS data.                            */
    /******************************************************************/
    MakePalettesISOCompliant();
    #endif

    /******************************************************************/
    /* Now rearange the palettes and generate the mapping tables      */
    /* needed for nearest color searches.  (We do this rearangement   */
    /* so that we will have an approximation of the         default   */
    /* system colors in the right place in the HW palette. )  This    */
    /* also means that PM CLR_ colors will mix and Rop better.        */
    /******************************************************************/
    FudgePalettesAndGenerateTables();

    /******************************************************************/
    /* Initialise the default Palette, the Physical and Logical       */
    /* Colour Tables and global variables used for colour             */
    /* according the format (or bitcount) of the screen.              */
    /******************************************************************/
    InitDefaultColorTables();

    /******************************************************************/
    /* Set up the AVIO information - cannot fail.                     */
    /******************************************************************/
    SetupAVIOInformation();

    /******************************************************************/
    /* initialize the QueryDevCaps values which could not be          */
    /* determined at compile time                                     */
    /******************************************************************/
    FillInCapsTable();

    /******************************************************************/
    /* Initialise VRAM with markers, patterns, etc.                   */
    /*                                                                */
    /* Actually this name is slightly misleading since this function  */
    /* also does some non VRAM initialization, so we still need to    */
    /* call it even on Matrox.                                        */
    /******************************************************************/
    InitialiseVRAM();

    /******************************************************************/
    /* Create and initialise the FontCacheInfo structure              */
    /******************************************************************/
    if ( !CreateFontCache() )
    {
        goto FILLPDB_ERR_EXIT;
    }

    /******************************************************************/
    /* Set up the pointer to the drawing functions table and set      */
    /* the soft draw flag for completeness - it should be zero on     */
    /* loading anyway                                                 */
    /******************************************************************/
    pDrawFunctions = (pDrawFunctionsTable)hardDrawTable ;
    softDrawInUse = 0 ;

    /******************************************************************/
    /* If we are at high resolution with 4bpp then adjust the         */
    /* default system colors to avoid hideous flickering due to       */
    /* dither patterns.                                               */
    /******************************************************************/
    #ifndef   _8514
    if ( (DDT.BitCount == 4) &&
         (DDT.ScreenWidth  == 1024) )
    {
        AdjustDefaultSysCols();
    }
    #endif

#ifdef SEAMLESS
#ifdef _8514
    /******************************************************************/
    /* Allocated a piece of tiled memory for use by multiple VDMs to  */
    /* allow orderly sharing of off-screen VRAM.                      */
    /******************************************************************/
    DosAllocSharedMem(&pWindowsSharedData, NULL, WINDOWS_PRIVATE_AREA_SIZE,
                      PAG_COMMIT | OBJ_GETTABLE | OBJ_TILE | PAG_READ | PAG_WRITE );
#endif /* _8514 */

    /******************************************************************/
    /* Initialise our seamless         capability.                    */
    /******************************************************************/
    InitialiseSeamless();
#endif /* SEAMLESS */

    /******************************************************************/
    /* return the PDB instance address                                */
    /******************************************************************/
#ifndef _8514
    DosClose(ring0_handle);
#endif
    ReleaseDriverSemaphore();
    return((ULONG)PDBInstance);


FILLPDB_ERR_EXIT:
    /******************************************************************/
    /* Return ERROR_NEG to indicate that an error has occured         */
    /******************************************************************/
#ifndef _8514
    if (ring0_handle != (HFILE)0)
    {
        DosClose(ring0_handle);
    }
#endif
    ReleaseDriverSemaphore();
    return(ERROR_NEG);
}

BOOL SetupFontInformation(VOID)
{
    USHORT               Result;
    COUNTRYCODE          ccCountryCode;
    COUNTRYINFO          ciCountryInfo;
    ULONG                ulBytesRead;
    CHAR                 achFailName[128];

    /******************************************************************/
    /* Assume a default codepage.                                     */
    /******************************************************************/
    usDefaultCodePage = 437;

    /******************************************************************/
    /* Now get the proper codepage if we can using DosGetCtryInfo     */
    /******************************************************************/
    ccCountryCode.country = ccCountryCode.codepage = 0;

    if (!DosQueryCtryInfo( sizeof(ciCountryInfo),
                           &ccCountryCode,
                           &ciCountryInfo,
                           &ulBytesRead ) )
    {
        usDefaultCodePage = ciCountryInfo.codepage;
    }

    /******************************************************************/
    /* Decide which system font we require                            */
    /******************************************************************/
    switch ( DDT.graphics_char_height )
    {
        case HI_RES_8515_GRAPHICS_CHAR_Y:
            ulSysFontId = 102;
            break;

        case HI_RES_8514_GRAPHICS_CHAR_Y:
            ulSysFontId = 101;
            break;

        case LO_RES_GRAPHICS_CHAR_Y:
            ulSysFontId = 100;
            break;

        default:
            /**********************************************************/
            /* We only cope with the above three fonts.               */
            /**********************************************************/
#ifdef FIREWALLS
            haltproc();
#endif /* FIREWALLS */
            ulSysFontId = 100;

    }

    /******************************************************************/
    /* Load the dll containing the fonts                              */
    /******************************************************************/
    Result = DosLoadModule(achFailName,
                           sizeof(achFailName),
                           RESOURCE_DLL,
                           &font_hmod);

    if ( Result != NO_ERROR )
    {
        DebugOutput("XGA: Unable to load font DLL\n\r");
        LogDosError(Result);
        return(FALSE);
    }

    /******************************************************************/
    /* Get the address of the font in resources                       */
    /*                                                                */
    /* - still need to do this here as EnableDC is called before      */
    /*   the default font is loaded by the engine from resources.     */
    /* EnableDC calls LocateFont (via set_dc_defaults) which accesses */
    /* pDefaultFont                                                   */
    /******************************************************************/
    Result = DosGetResource(font_hmod,
                            1000L,
                            ulSysFontId,
                            &pDefaultFont);

    if ( Result )
    {
        LOGDOSERR(NULL, "DosGetResource failed", FNULL, 0, Result);
        return(FALSE);
    }

    return(TRUE);
}

VOID SetupAVIOInformation(VOID)
{
    register ULONG       i;
    register ULONG       last_avio_font;

    /******************************************************************/
    /* Set up AVIO color lookup table.                                */
    /* We currently have a 256 color default palette, so we only set  */
    /* up this table.                                                 */
    /* We would like to set up the other tables here, but             */
    /* unfortunately the lower level color routines are written in    */
    /* such a way that you can only find the default color easily     */
    /* in the current default hardware palette                        */
    /*                                                                */
    /* The other tables will be set up as needed when the default     */
    /* palette size changes in palman.c                               */
    /******************************************************************/
    pAVIOColorXlate = AVIOXlate256;
    for (i=0; i < AVIO_PALETTE_SIZE; i++)
    {
        pAVIOColorXlate[i] =
                   NearestDirectDefaultPhysicalIndex(AVIOColorTable[i]);
    }

    DDT.NoOfAvioCellSizes = MAX_AVIO_FONTS_LOADED;

    /******************************************************************/
    /* Set up default AVIO font values.                               */
    /******************************************************************/
    if ( (DDT.fScreenFlags & DM_HI_RES) != 0 )
    {
        DefaultNormalFont = AvioDefaultFont[0].NormalFont;
        DefaultSmallFont  = AvioDefaultFont[0].SmallFont;
    }
    else /* lo-res */
    {
        DefaultNormalFont = AvioDefaultFont[1].NormalFont;
        DefaultSmallFont  = AvioDefaultFont[1].SmallFont;
    }

    /******************************************************************/
    /* NOW GET THE AVIO FONTS FROM RESOURCES !!!!                     */
    /* NB .rc file changes for pmformat fonts.                        */
    /* In this new version, avio fonts are PM format.  Removed code   */
    /* from eddevram.c which read AIformat fonts in.  PM format fonts */
    /* do not get written to, so can just use the selector returned   */
    /* by DosGetResource to access (Read-only!).                      */
    /* Make sure there are no AIformat references anywhere...         */
    /******************************************************************/

    /******************************************************************/
    /* Load the AVIO fonts from resources.                            */
    /******************************************************************/
    if ( DDT.ScreenWidth < HI_RES_WIDTH )
    {
      i = 0;
      last_avio_font = MAX_AVIO_FONTS_LOADED;
    }
    else
    {
      i = NO_OF_AVIO_FONTS - MAX_AVIO_FONTS_LOADED;
      last_avio_font = MAX_AVIO_FONTS_LOADED + i;
    }
    for ( ; i < last_avio_font; i++)
    {
        /**************************************************************/
        /* Load the font                                              */
        /**************************************************************/
        DosGetResource(font_hmod,
                       AvioBaseFont[i].ResourceType,
                       AvioBaseFont[i].ResourceName,
                       &(AvioBaseFont[i].pResourceData));
    }

}

#ifndef S3
VOID SetupCursorInformation(VOID)
{
    /******************************************************************/
    /* Make various h/w related values accessible to the cursor code. */
    /******************************************************************/
    #ifndef   _8514
    cursor_data.memory_registers = aiXGAAdapter.pMemRegBase;
    cursor_data.io_registers     = aiXGAAdapter.usIORegBase;
    cursor_data.polling_register = pbHWPollRegister;
    cursor_data.adapter_id       = aiXGAAdapter.AdapterID;
    #endif

    /******************************************************************/
    /* Specific values which describe the screen pixmap.              */
    /******************************************************************/
    cursor_data.screen_hw_format = DirectListEntry.Info.HWFormat;
    cursor_data.screen_hw_size   = (DirectListEntry.Info.HWHeight << 16) +
                                    DirectListEntry.Info.HWWidth;

#ifdef MATROX
    if (RunningOnMatrox())
    {
        ULONG       fn_id = IO_GLOBAL_ACCESS;
        ULONG       globaladdress;

        DosDevIOCtl( ring0_handle,
                     XGA_CATEGORY,
                     GEN_FUNCTION,
                     (PVOID)&fn_id,
                     sizeof(fn_id),  /* not passed to level 1 ring0 code */
                     NULL,           /* not passed to level 1 ring0 code */
                     (PVOID)&globaladdress,
                     sizeof(globaladdress),
                                     /* not passed to level 1 ring0 code */
                     NULL            /* not passed to level 1 ring0 code */
                   );

        cursor_data.screen_address = globaladdress;
    }
    else
    {
#endif /* MATROX */
        cursor_data.screen_address = DirectListEntry.BMPhys;
#ifdef MATROX
    }
#endif /* MATROX */

    /**************************************************************/
    /* assembler code also needs to know the defined size         */
    /* (the rectangular size within which the cursor was defined) */
    /* and various hardware sizes                                 */
    /**************************************************************/
    cursor_data.software_cursor.defnsize.x = DDT.CursorWidth;
    cursor_data.software_cursor.hwsize.x   = DDT.CursorWidth - (USHORT)1;
    cursor_data.software_cursor.defnsize.y = DDT.CursorHeight;
    cursor_data.software_cursor.hwsize.y   = DDT.CursorHeight - (USHORT)1;
#ifndef   _8514
    cursor_data.draw_sprite_width        = DDT.CursorWidth;
    cursor_data.draw_sprite_height       = DDT.CursorHeight;
#endif

    /******************************************************************/
    /* Set this to say that there is initially no valid saved cursor  */
    /* data to be restored by restore_software_cursor.                */
    /******************************************************************/
    cursor_data.software_cursor.coord.x = 0x8000;

    /******************************************************************/
    /* Are we forcing software cursors                                */
    /* or is the plasma enabled which always needs a software cursor  */
    /******************************************************************/
#ifndef   _8514
    if ( (plasma_status & PLASMA_ENABLED) ||
         SWCursorForced )
    {
        /**************************************************************/
        /* We require a software cursor.                              */
        /**************************************************************/
        cursor_data.cursor_status |= CURSOR_SOFTWARE;
    }
    else
    {
        /**************************************************************/
        /* The cursor will be handled by the hardware, so set the     */
        /* HW cursor colors in our structure.                         */
        /**************************************************************/

        /**************************************************************/
        /* Cursor is always black and something.                      */
        /**************************************************************/
        cursor_data.draw_sprite_col1.bGreen = 0x00;
        cursor_data.draw_sprite_col1.bRed   = 0x00;
        cursor_data.draw_sprite_col1.bBlue  = 0x00;

        if ( (DDT.fScreenFlags & DM_MONO) != 0 )
        {
            /**********************************************************/
            /* Monitor is mono so cursor is green and black           */
            /**********************************************************/
            cursor_data.draw_sprite_col2.bGreen = 0xff;
            cursor_data.draw_sprite_col2.bRed   = 0x00;
            cursor_data.draw_sprite_col2.bBlue  = 0x00;
        }
        else
        {
            /**********************************************************/
            /* Monitor is colour so cursor is white and black         */
            /**********************************************************/
            cursor_data.draw_sprite_col2.bGreen = 0xff;
            cursor_data.draw_sprite_col2.bRed   = 0xff;
            cursor_data.draw_sprite_col2.bBlue  = 0xff;
        }
    }
#else
    cursor_data.cursor_status |= CURSOR_SOFTWARE;
    SWCursorForced = TRUE;
#endif //_8514
}
#endif
