/*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.                                */
/*                                                                           */
/*****************************************************************************/
/************************************************************************
 *
 * SOURCE FILE NAME = VVIBM.C
 *
 * DESCRIPTIVE NAME = Virtual Video IBM Specific Processing
 *
 *
 * VERSION = V2.1
 *
 * DATE      04/30/93
 *
 * DESCRIPTION  This module contains all accelerator specific SVGA code and data.
 *
 *
 * FUNCTIONS
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/


#define  IO8BIT           /* CL386 Version 6.00.054 FLAG:              */
#include <mvdm.h>
#include <vvd.h>
#include <vvdp.h>

#ifdef   VDDSTRICT
MODNAME = __FILE__;
#endif
#define  INCL_DOSERRORS
#include <bseerr.h>


#pragma  BEGIN_SWAP_DATA
/*
**     Externals
*/
extern ULONG ulSVGAChipType;
extern SA8514INFO sA8514Info;
extern STRAPREGINFO sA8514TrapRegInfo[];
extern PLE pleXGAOperatingMode;
extern PLE pleXGAApertureCtrl;
extern PLE pleXGAApertureIndx;

CHAR pszIBMAdapterName [] = "IBM" ;                             /*          */

PCHAR ppszIBMChipNames [MAX_IBM_CHIP] =                         /*          */
{  /* As produced by SVGA.EXE! */                               /*          */
  "IBMSVGA",                                                    /*          */
};                                                              /*          */

IOH iohXGAbreg [2] =                    /* 21xy */
{
  {
    NULL,
  },
  {
    &VVReadIBMRegistersBgnd,                                    /*          */
    &VVWriteIBMRegistersBgnd,                                   /*          */
  },
};

IOH iohXGAOperatingMode [2] =           /* 21x0 */              /*          */
{                                                               /*          */
  {                                                             /*          */
    NULL,                                                       /*          */
  },                                                            /*          */
  {                                                             /*          */
    &VVReadIBMRegistersBgnd,                                    /*          */
    &VVWriteIBMOperatingModeBgnd,                               /*          */
  },                                                            /*          */
};                                                              /*          */

IOH iohXGAApertureCtrl [2] =            /* 21x1 */
{
  {
    NULL,                                                       /*          */
    &VVWriteIBMApertureCtrlFgnd,                                /*          */
  },
  {
    &VVReadIBMRegistersBgnd,                                    /*          */
    &VVWriteIBMApertureCtrlBgnd,                                /*          */
  },
};

IOH iohXGAApertureIndx [2] =            /* 21x8 */              /*          */
{                                                               /*          */
  {                                                             /*          */
    NULL,                                                       /*          */
  },                                                            /*          */
  {                                                             /*          */
    &VVReadIBMRegistersBgnd,                                    /*          */
    &VVWriteIBMApertureIndxBgnd,                                /*          */
  },
};

#define WS(x) ((PVOID)(&VDMData.VdmSVGA.aregXGAData [x]))
#define RW_INDX (PORTF_NOTVALIDSVGAPORT | WRITE_INDX | READ_INDX | R_EQ_W)     /*            */
#define RW_MANY (PORTF_NOTVALIDSVGAPORT | WRITE_MANY | READ_MANY | R_EQ_W)     /*            */

PLE apleXGA [AXGA_TOTAL] =
{
  {{/*x00*/0x2100, WS(0x00), WS(0x00), RW_MANY, iohXGAOperatingMode}, 0, NULL},
  {{/*x01*/0x2101, WS(0x01), WS(0x01), RW_MANY, iohXGAApertureCtrl}, 0, NULL},
  {{/*x02*/0x2102, WS(0x02), WS(0x02), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x03*/0x2103, WS(0x03), WS(0x03), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x04*/0x2104, WS(0x04), WS(0x04), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x05*/0x2105, WS(0x05), WS(0x05), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x06*/0x2106, WS(0x06), WS(0x06), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x07*/0x2107, WS(0x07), WS(0x07), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x08*/0x2108, WS(0x08), WS(0x08), RW_MANY, iohXGAApertureIndx}, 0, NULL},
  {{/*x09*/0x2109, WS(0x09), WS(0x09), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x0a*/0x210a, WS(0x0a), WS(0x0a), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x0b*/0x210b, WS(0x0b), WS(0x0b), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x0c*/0x210c, WS(0x0c), WS(0x0c), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x0d*/0x210d, WS(0x0d), WS(0x0d), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x0e*/0x210e, WS(0x0e), WS(0x0e), RW_MANY, iohXGAbreg}, 0, NULL},
  {{/*x0f*/0x210f, WS(0x0f), WS(0x0f), RW_MANY, iohXGAbreg}, 0, NULL},
};

ULONG ulIBMXGAInstance = 0x2100;                                /*          */

#pragma  END_SWAP_DATA

#pragma  BEGIN_SWAP_CODE

/***************************************************************************
 *
 * FUNCTION NAME = vvIBMEditTables()
 *
 * DESCRIPTION   = Called once to do SVGA-specific initialisation
 *
 * INPUT         =
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 **************************************************************************/
VOID PRIVENTRY vvIBMEditTables( VOID )
{
  UINT usIndex;
  BYTE bSave, bData;                                            /*          */
  BOOL bFound;                                                  /*          */

  /*
  **  We need to find the current instance of the XGA/IBMSVGA
  */

  for( bFound = FALSE, ulIBMXGAInstance = 0x2180;               /*          */
       !bFound && ((ulIBMXGAInstance -= 0x0010) > 0x2100);      /*          */
       )                                                        /*          */
  {                                                             /*          */
    apleXGA [AXGA_OPERATING_MODE].sTrapBRegInfo.portTrap =      /*          */
      ulIBMXGAInstance;                                         /*          */
    bSave = vvInput( INVALID_HVDM,                              /*          */
                     &apleXGA [AXGA_OPERATING_MODE] );          /*          */
    if( !(bSave & 0xea) )                                       /*          */
    {                                                           /*          */
      vvOutput( INVALID_HVDM,                                   /*          */
                &apleXGA [AXGA_OPERATING_MODE],                 /*          */
                (BYTE) (bSave ^ 0xea) );                        /*          */
      bData = vvInput( INVALID_HVDM,                            /*          */
                       &apleXGA [AXGA_OPERATING_MODE] );        /*          */
      vvOutput( INVALID_HVDM,                                   /*          */
                &apleXGA [AXGA_OPERATING_MODE],                 /*          */
                bSave );                                        /*          */
      bFound = (bData == bSave);        /* Constant bits! */    /*          */
    }                                                           /*          */
  }                                                             /*          */
  for( usIndex = AXGA_OPERATING_MODE;                           /*          */
       usIndex < AXGA_TOTAL;                                    /*          */
       usIndex++ )                                              /*          */
  {                                                             /*          */
    apleXGA [usIndex].sTrapBRegInfo.portTrap &= ~0xFFF0;        /*          */
    apleXGA [usIndex].sTrapBRegInfo.portTrap |=
      ulIBMXGAInstance;
    /*
    ** vvPMIPortToPPLE enables all appropriate trap list entries
    ** by removing NOTRAP flag when port found in trapreg list!
    */
    /*!!So remove this & change SVGA.EXE as needed */           /*          */
    apleXGA [usIndex].sTrapBRegInfo.fTrapType &= ~ PORTF_NOTVALIDSVGAPORT;      /*            */
  }                                                             /*          */
}

/***************************************************************************
 *
 * FUNCTION NAME = vvIBMSetBank()
 *
 * DESCRIPTION   = Set IBM bank register
 *
 * INPUT         = hvdm
 *                 ulBank
 *                 fSetWriteBank
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

VOID PRIVENTRY vvIBMSetBank(
  HVDM hvdm,
  ULONG ulBank,
  BOOL fSetWriteBank )
{
  register PVDMDATA pvd = pVDMData(hvdm);                       /*          */
  register BYTE bOperMode;

  fSetWriteBank;                                 /* shut the compiler up    */
  if( pvd->mstateVideo == MEMORY_GRFX256 )                      /*          */
  {
    /*!!Is this really necessary? Why? */                       /*          */
    bOperMode = vvInput( hvdm,
                         &apleXGA [AXGA_OPERATING_MODE] );
    if (bOperMode & 0x10 )
    {
      /* Reset VGA address enable on Speedway */
      /* to allow bank setting in ext mode transfer */
      bOperMode &= 0xfe;
      vvOutput( hvdm,
                &apleXGA [AXGA_OPERATING_MODE],
                bOperMode );
    }
  }
  vvOutput( hvdm,
            &apleXGA [AXGA_APERTURE_INDEX],
            (BYTE)ulBank );
}

/***************************************************************************
 *
 * FUNCTION NAME = vvIBMGetBank()
 *
 * DESCRIPTION   = Get IBM bank register
 *
 *
 * INPUT         = hvdm
 *                 fGetWriteBank
 *
 * OUTPUT        = ulBank
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

ULONG PRIVENTRY vvIBMGetBank(
  HVDM hvdm,
  BOOL fGetWriteBank )
{
  fGetWriteBank;                                 /* shut the compiler up    */
  return( vvInput( hvdm,
                   &apleXGA [AXGA_APERTURE_INDEX] )
          & 0x0f );
}
/***********************************************************************
 *
 * FUNCTION NAME = vvIBMUpdateModeData()
 *
 * DESCRIPTION   = Update current mode state variables which
 *                 having the accelerator on affects.
 *                 Do not change anything which is already calculated
 *                 correctly by vvUpdateModeData and vvUpdateScreenState.
 *                 Usually there is little or nothing to update.
 *
 * INPUT         = hvdm -> VDM
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL = NONE
 * RETURN-ERROR  = NONE
 *
 * CALLED BY
 *      vvIBMUpdateModeData
 *
 ***********************************************************************/
VOID    PRIVENTRY vvIBMUpdateModeData(                  /*            */
  HVDM hvdm )
{
  register PVDMDATA pvd = pVDMData( hvdm );
  if((pvd->mstateVideo == MEMORY_GRFX256) &&
     (pvd->                                            
       VdmSVGA.aregXGAData [AXGA_OPERATING_MODE]
      & 0x10))                                          
  pvd->flVDMXVideo |= VDMX_ENHANCEDMODE;

}

#pragma  END_SWAP_CODE

#pragma  BEGIN_SWAP_DATA

SSVGAINFO sIBMAdapterInfo =                                     /*          */
{
  { /* SVGAINFO */                                              /*          */
    { /* SEGAINFO */
      { /* SCGAINFO */
        &vvEGAAdjustedPort,
        &vvCGAStartAddr,
        &vvEGAOddEvenMode,
        &vvEGAHighResMode,
        &vvEGAHorzDspEnd,
        &vvEGAHorzLogEnd,
        &vvVGAVertDspEnd,
        &vvVGABitsPerPixel,
        &vvVGAPrepareSetMode,                                   /*          */
      },
      &vvEGAPackedMode,
      &vvVGAVertLineCmp,
    },
    &vvVGADacSave,                                              /*          */
    &vvVGADacRestore,                                           /*          */
  },                                                            /*          */
  &vvIBMEditTables,                                             /*          */
  &vvVGAInterlaced,
  &vvVGAUpdateIoState,
  &vvVGARestoreIoState,
  &vvIBMSetBank,
  &vvIBMGetBank,
  &vvVGAFixSetMode,
  &vvVGAFixSetBgnd,
  &vvVGAWriteGDCDataFgnd,
  &vvVGAReadSEQDataBgnd,
  &vvVGAWriteSEQDataBgnd,
  &vvVGADacRS2Clear,                                            /*          */
  &vvVGADacRS2Set,                                              /*          */
  &vvVGADacRS3,                                                 /*          */
  &sA8514Info.sAcceleratorInfo,
  pszIBMAdapterName,
  MAX_IBM_CHIP,
  ppszIBMChipNames,
  &vvIBMUpdateModeData,                                         /*            */
};

#pragma  END_SWAP_DATA
