/*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.                                */
/*                                                                           */
/*****************************************************************************/
/**********************************************************************/
/*                                                                    */
/*   Module          = setmode.c                                      */
/*                                                                    */
/*   Description     = Display Device Driver functions                */
/*                     Set screen modes                               */
/*                                                                    */
/*   Function        = Contains routines which use VIOMODE structure  */
/*                     and so must be built using 16 bit headers.     */
/*                                                                    */
/*   Reference       = Winthorn Functional Specification              */
/*                     Device Driver Interface Specification          */
/*                     Display Device Driver Design Specification     */
/*                                                                    */
/*                                                                    */
/**********************************************************************/
#define INCL_WINPROGRAMLIST
#define INCL_AFI
#define INCL_DOSDEVICES

#define SEI_PMWIN           /* a      to stop pmsei.h being included */
/**********************************************************************/
/* NOTE: all LOGERRs have been removed because they need pmsei.h      */
/* to be include , and I can't get that to work with INCL_16          */
/**********************************************************************/

#include <eddinclt.h>
#include <edddtypt.h>
#include <eddetypt.h>
#include <eddqsres.h>
#include <eddesres.h>
#include <eddeextf.h>
#include <plasma.h>


#ifndef   _8514
extern ADAPTERINFO      _aiXGAAdapter;
extern ADAPTERINFO2     _ai2XGAAdapter;
extern BOOL             _plasma_status;
extern DDTType          _DDT;
VIOMODEINFO             _VioModeInfo;
#else
extern DDTType          DDT;
VIOMODEINFO             VioModeInfo;
#endif


/**********************************************************************/
/* SwitchToVGAMode                                                    */
/*                                                                    */
/* If the xga is the primary adapter, calls VIOSetMode to put the xga */
/* into vga mode 3.                                                   */
/**********************************************************************/
#ifndef   _8514
BOOL PASCAL _SwitchToVGAMode(VOID)
#else
BOOL SwitchToVGAMode(VOID)
#endif
{
   #ifndef   _8514
   if ( (_aiXGAAdapter.usFlags & XGA_PRIMARY_ADAPTER) != 0 )
   {
      _VioModeInfo.cb = 8;
      _VioModeInfo.fbType = 1;
      _VioModeInfo.color = 4;
      _VioModeInfo.col = 80;
      _VioModeInfo.row = 25;

      if (VioSetMode (&_VioModeInfo, 0L))
      {
//         LOGDOSERR(0,"VioSetMode error", FNULL, 0, 0);
         return(FALSE);
      }
   }
   #else


    VioModeInfo.cb = 8;
    VioModeInfo.fbType = 1;
    VioModeInfo.color = 4;
    VioModeInfo.col = 80;
    VioModeInfo.row = 25;

    DMS32CallBack( (PFN)SwitchToChosenMode );

   #endif

   return(TRUE);

} /* SwitchToVGAMode */

#ifndef   _8514
/**********************************************************************/
/* Sets the P75 VGA mode - same as VGA mode 3 but only 24 rows.       */
/**********************************************************************/
BOOL PASCAL _SwitchToP75VGAMode(VOID)
{
   _VioModeInfo.cb = 12;
   _VioModeInfo.fbType = 3;
   _VioModeInfo.color = 4;
   _VioModeInfo.col = 80;
   _VioModeInfo.row = 24;
   _VioModeInfo.hres = 640;
   _VioModeInfo.vres = 480;

   if (VioSetMode (&_VioModeInfo, 0L))
   {
//       LOGDOSERR(0,"VioSetMode error", FNULL, 0, 0);
       return(FALSE);
   }

   return(TRUE);

} /* SwitchToVGAMode */

#endif //_8514

/**********************************************************************/
/* Calls VIOSetMode to put the xga into extended graphics mode.       */
/**********************************************************************/
#ifndef   _8514
BOOL PASCAL _SwitchToExtendedGraphicsMode(VOID)
#else
BOOL SwitchToExtendedGraphicsMode(VOID)
#endif
{
    #ifndef   _8514
    if ( _plasma_status & PLASMA_ENABLED )
    {
        if ( !_SwitchToP75VGAMode() )
        {
            return(FALSE);
        }
    }

    _VioModeInfo.cb = 12;
    if ( MONO_DISPLAY(_ai2XGAAdapter) )
    {
        _VioModeInfo.fbType = 0xA;
    }

    else /* colour display */
    {
         _VioModeInfo.fbType = 0xB;
    }

    _VioModeInfo.color = (UCHAR)_DDT.BitCount;
    _VioModeInfo.col  = _DDT.ScreenWidth / _DDT.AlphaCellWidth;
    _VioModeInfo.row  = _DDT.ScreenHeight / _DDT.AlphaCellHeight;
    _VioModeInfo.hres = _DDT.ScreenWidth;
    _VioModeInfo.vres = _DDT.ScreenHeight;

    #else

    #ifndef   S3
    VioModeInfo.col  = 85;
    VioModeInfo.row  = 38;
    #else
    switch (DDT.ScreenWidth)
    {
        case HI_RES_WIDTH:
            VioModeInfo.col  = 128;
            VioModeInfo.row  = 48;
            break;
        case LO_RES_WIDTH:
            VioModeInfo.col  = 80;
            VioModeInfo.row  = 30;
            break;
        case RES_800_WIDTH:
            VioModeInfo.col  = 100;
            VioModeInfo.row  = 37;
            break;
        case RES_1280_WIDTH:
            VioModeInfo.col  = 160;
            VioModeInfo.row  = 64;
            break;
    }
    #endif

    VioModeInfo.fbType = VGMT_MAKEITWORK | VGMT_OTHER | VGMT_GRAPHICS;
    VioModeInfo.cb = 12;
    VioModeInfo.color = (UCHAR)DDT.BitCount;
    VioModeInfo.hres = DDT.ScreenWidth;
    VioModeInfo.vres = DDT.ScreenHeight;
    #endif


    #ifndef _8514
    if(VioSetMode (&_VioModeInfo, 0L))
    {
        //LOGDOSERR(0,"VioSetMode error", FNULL, 0, 0);
        return(FALSE);
    }
    else /* no VIO error */
    {
        return(TRUE);
    }
    #else


    DMS32CallBack( (PFN)SwitchToChosenMode );

    #ifdef S3
    // Turn off the display until we have cleared VRAM.
    // This prevents an unwanted display of data left over from any
    // full-screen sessions.  @RCW
    outp(0x3c4, 1);
    outp(0x3c5, (inp(0x3c5) | 0x20) );

    // Scan line Adjustments
    // Set the Scan Line Length
    if ( DDT.BitCount == 8 )
    {
       if ( DDT.ScreenWidth == RES_1280_WIDTH )
       {
            // 1280 scan line
          outp( 0x03d4 , 0x13 );
          outp( 0x03d5 , 0xA0 );
       }
       else
       {
            // 1k scan line
          outp( 0x03d4 , 0x13 );
          outp( 0x03d5 , 0x80 );
       }

    }
    else if ( DDT.BitCount == 16 )
    {
       switch ( DDT.ScreenWidth )
       {
       case HI_RES_WIDTH:
         // this will always be a 2k scan line
         outp( 0x03d4 , 0x13 );
         outp( 0x03d5 , 0x00 );
         outp( 0x03d4 , 0x51 );
         outp( 0x03d5 , ((inp( 0x03d5 ) & 0xCF) | 0x10 ));
         break;

       case RES_800_WIDTH:
         // 1600 scan line
         outp( 0x03d4 , 0x13 );
         outp( 0x03d5 , 0xC8 );
         outp( 0x03d4 , 0x50 );
         outp( 0x03d5 , 0x90 );
         outp( 0x03d4 , 0x51 );
         outp( 0x03d5 , (inp( 0x3d5 ) & 0xCF ));
         break;

       case LO_RES_WIDTH:
         // 1280 scan line
          outp( 0x03d4 , 0x13 );
          outp( 0x03d5 , 0xA0 );
          outp( 0x03d4 , 0x50 );
          outp( 0x03d5 , 0x50 );
       }
    }
    #ifdef   BPP24
    else if ( DDT.BitCount == 24 )
    {
       outp( 0x03d4 , 0x50 );
       outp( 0x03d5 , 0x00 );
       outp( 0x03d4 , 0x51 );
       outp( 0x03d5 , ((inp( 0x03d5 ) & 0xCF) | 0x10 ));
       outp( 0x03d4 , 0x13 );
       outp( 0x03d5 , 0x00 );
    }
    #endif

    // Turn off Linear Addressing.
    outp( 0x3d4, 0x58 );
    outp( 0x3d5, inp( 0x3d5) & 0xEF );

    // Clear the status flags.
    outp( 0x42E8, 0x0F );

    KlugeReset();

    // Turn the screen back on.  @RCW
    outp( 0x3c4, 1 );
    outp( 0x3c5, ( inp(0x3c5) & 0xDF ) );
    //Set sequencer index to 0 to avoid bus timing problems @DMS
    outp( 0x3c4, 0x00 );

    #endif


    return(TRUE);
    #endif

} /* SwitchToExtendedGraphicsMode */


#ifndef   _8514
VOID PASCAL _SwitchToChosenMode(VOID)
#else
VOID SwitchToChosenMode(VOID)
#endif
{
    #ifndef   _8514
    VioSetMode(&_VioModeInfo, 0L);
    #else
    if( Vio32SetMode(&VioModeInfo, 0L ) )
    {
       //@DMS put here at senja's request to emulate other svga drivers - yuck !!!
       critical_error:
       goto critical_error;
    }
    #endif
}

