/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft Corporation, 1989                                 */
/* 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.                                */
/*                                                                           */
/*****************************************************************************/
/*****************************************************************************
 *
 * SOURCE FILE NAME = SVGASRHW.C
 *
 * DESCRIPTIVE NAME = Save/Restore Hardware.
 *
 *
 * VERSION      V2.0
 *
 * DATE
 *
 * DESCRIPTION  Super VGA specific routines to Save/Restore the hardware state.
 *
 * FUNCTIONS
 *
 * NOTES        NONE
 *
 * STRUCTURES   NONE
 *
 * EXTERNAL REFERENCES
 *
 *              NONE
 *
 * EXTERNAL FUNCTIONS
 *
 *              NONE
 *
*/


#define  INCL_BASE                     /* ALL of OS/2 Base                  */
#define  INCL_DOSDEVICES               /* Device specific, ring 2 support   */
#define  INCL_OS2STD                   /* Needed for NULL definition in     */
                                       /* OS2STD.H                          */
#include <os2.h>
#include <memory.h>
#include "svgatype.h"

/*
**      Externals
*/

extern PVIDEOMODE pModes;
/*extern FPHWCOMMAND pHWLockData;                         -gone-            */
extern FPHWCOMMAND pHWUnLockData;                               /*          */
extern OEMSVGAINFO SVGAHardware;                                /*          */
extern OEMINFO OEMHardware;                                     /*          */

extern SHORT FAR WDPanelOn( VOID );                             /*          */
extern VOID FAR WDSetPanelClk( VOID );                          /*          */

USHORT FAR HardwareColor(VOID);

VOID EXPENTRY AccessRegister(PREGADDRESS,USHORT,PBYTE);
VOID EXPENTRY AccessVideoEnable(USHORT,USHORT,USHORT FAR *);
VOID PASCAL FAR AccessCLUT(USHORT,PREGDATA);
VOID PASCAL FAR SetDiamondClk(USHORT,USHORT,USHORT);   /*            */  /*            */
VOID PASCAL FAR SetNumber9Clk(USHORT);                 /*            */

/***************************************************************************
 *
 * FUNCTION NAME =  SaveRestoreCLUT()
 *
 * DESCRIPTION   = SaveRestoreCLUT is called to save or restore the CLUT
 *                 state.
 *
 * INPUT         = ENVIRONMENT far *Environment
 *                 USHORT Direction  ( GET(for SAVE) or SET(for RESTORE) )
 *
 * OUTPUT        = Hardware state is saved or restored to or from the
 *                 environment buffer.
 *
 * RETURN-NORMAL = NONE
 * RETURN-ERROR  = NONE
 *
 **************************************************************************/

void PASCAL near SaveRestoreCLUT(PENVIRONMENT Environment,USHORT Direction)
{
  REGDATA RegData;

  RegData.FirstEntry = 0;
  RegData.DataArea = (PBYTE)&Environment->LookupTable[0];
  RegData.NumEntries = 256;            /* All registers */
  AccessCLUT(Direction, &RegData);

  /*
  ** If the current CLUT is equivalent to SumCLUT set NO_CLR_BRST in fbtype
  */

  if ((Direction == SET) && ((Environment->ModeData.fbType&MODE_FLAG_NOT_MONO)
     == MODE_FLAG_NOT_MONO))
  {

    /*
    ** We are looking for any monochrome CLUT, not a particular one.  The
    ** characteristic of a monochrome palette is the same intensity for
    ** red, green, and blue in each row.
    */

    register irow = 0;

    while ((irow < 256) && (Environment->LookupTable[irow].Red ==
       Environment->LookupTable[irow].Green) &&
       (Environment->LookupTable[irow].Red == Environment->LookupTable[irow].Blue))
      irow++;

    /*
    ** If loop completed, assume black & white
    */

    if (irow == 256)
      Environment->ModeData.fbType |= MODE_FLAG_NO_CLR_BRST;

  }

}

/***************************************************************************
 *
 * FUNCTION NAME =  SaveRestoreHW()
 *
 * DESCRIPTION   = SaveRestoreHW is called to save or restore the hardware
 *                 state.
 *
 * INPUT         = ENVIRONMENT far *Environment
 *                 USHORT Direction  ( GET(for SAVE) or SET(for RESTORE) )
 *
 * OUTPUT        = Hardware state is saved or restored to or from the
 *                 environment buffer.
 *
 * RETURN-NORMAL = NONE
 * RETURN-ERROR  = NONE
 *
 **************************************************************************/

void PASCAL near SaveRestoreHW(PENVIRONMENT Environment,USHORT Direction)
{
  USHORT ColorMode;
  USHORT VideoEnable;

  ColorMode = (Direction == SET)?(USHORT)(Environment->ModeData.fbType
     &MODE_FLAG_NOT_MONO):HardwareColor();
                        /* Turn the video signal off to reduce snow */
  VideoEnable = 0;
  AccessVideoEnable(ColorMode, SET, &VideoEnable);

  /*           
  ** New command list is created whenever a ModeSet without the
  ** HARDWARE flag is set. If an environment to be saved had only
  ** a SetMode with the HARDWARE flag set, then the command list
  ** will be created here. The command list is disposed of either
  ** by a subsequent mode set or by Terminate Env.
  */
  if (!Environment->pCmdData)
    SVGACopyCmdList(pModes[Environment->ModeIndex].pHWSetModeData,
                    &Environment->pCmdData);

  if (pHWUnLockData)
    ExecCommands(pHWUnLockData);

  if (Direction == SET)
  {

  /*
  ** Set Diamond SpeedStar specific external clock bits
  */

    if (OEMHardware.Manufacturer == DIAMOND_MANUFACTURER)       /*          */  /*            */
      SetDiamondClk(Environment->ModeData.hres,
                    Environment->ModeData.fbType,
                    Environment->ModeData.color);               /*          */  /*            */

    ExecCommands(Environment->pCmdData);

    if( (SVGAHardware.AdapterType == WESTERNDIG_ADAPTER)        /*          */
        && ((SVGAHardware.ChipType == WESTERNDIG_WD9024_CHIP)   /*          */
            || (SVGAHardware.ChipType == WESTERNDIG_WD9026_CHIP)/*          */
            || (SVGAHardware.ChipType == WESTERNDIG_WD9026_CHIP)/*          */
            )                                                   /*          */
        /* It's a laptop! Are external only modes disallowed?*/ /*          */
        && WDPanelOn())                                         /*          */
      WDSetPanelClk();                                          /*          */

  }
  else
  {
    SVGAXlatCmdList(Environment->pCmdData, SAVE);
    ExecCommands(Environment->pCmdData);
    SVGAXlatCmdList(Environment->pCmdData, RESTORE);
  }

  /*
  ** Save/Restore the color lookup table
  */

  if(!(pModes[Environment->ModeIndex].fbType&MODE_FLAG_GRAPHICS) ||
     (pModes[Environment->ModeIndex].color <= 8))            /*            */  /*            */
    SaveRestoreCLUT(Environment, Direction);

/*if (pHWLockData)
      ExecCommands(pHWLockData);                                             */

  /*
  ** Set Number Nine specific external clock bits                                       
  ** after setting the mode                                                 
  */
  if (Direction == SET)
    if (OEMHardware.Manufacturer == NUMBER9_MANUFACTURER)
      if ((Environment->ModeData.fbType & 0x02) ||     /* graphics mode      */
          (Environment->ModeData.hres == 1056) ||      /* 132 cols text      */
          (Environment->ModeData.hres == 1188))
        SetNumber9Clk(Environment->ModeData.hres);

  /*
  ** Turn the video signal back on if Env flag is set
  */

  if (Environment->VideoEnable)
  {
    VideoEnable = 1;                               /* Turn video on  */
    AccessVideoEnable(ColorMode, SET, &VideoEnable);
  }

}
