/*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 = s3lacuna.c
 *
 * DESCRIPTIVE NAME = Chip specific PMI functions
 *
 *
 * VERSION = V2.1
 *
 * DATE
 *
 * DESCRIPTION PMI-file handler - Exported entry points
 *
 * FUNCTIONS
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#pragma langlvl(extended)
#include "ipmitype.h"
#include <conio.h>
/*****************************************************************************
 *
 *  FUNCTION NAME:      pfnSetS3Lacuna()
 *
 *  DESCRIPTIVE NAME:   Program the clock related registers based on the input data.
 *
 *  FUNCTION:
 *
 *  INPUT:              PVIDEO_ADAPTER - Pointer to current state of the adapter/mode
 *                      PREGS- Pointer to current register state
 *
 *  EXIT:               APIRET - return code
 *
 *  NOTES:              Program the S3864 adapters with ICD2061 clock chip
 *
 *  INTERNAL REFERENCES:
 *    ROUTINES:
 *
 *  EXTERNAL REFERENCES:
 *    ROUTINES:
 ****************************************************************************/
APIRET EXPENTRY  pfnSetS3Lacuna(PVIDEO_ADAPTER pAdapter,PREGS pRegs)
{
  ULONG rc = NO_ERROR;
  USHORT crtcport = (_inp(0x3cc) & 0x01) ? 0x3D4 : 0x3B4;
  BYTE r0, r1, r2;

  if (!(pAdapter->ModeInfo.usType & MODE_FLAG_GRAPHICS))
      return (ERROR_REFRESH_NOT_SUPPORTED);
  else
  {
    _outp(crtcport, 0x11);                   //yee dbug
    r0 = _inp(crtcport+1);
    _outp(crtcport+1, (r0 & 0x7F));

    switch(pAdapter->ModeInfo.usXResolution)
    {
      case 640:
         _outpw(crtcport, 0x0b06);
         _outpw(crtcport, 0xea10);
         _outpw(crtcport, 0x0b16);
         switch(pAdapter->ModeInfo.bBitsPerPixel)
         {
            case 8:
            case 4:
               _outpw(crtcport, 0x5f00);
               _outpw(crtcport, 0x8203);
               _outpw(crtcport, 0x5304);

               _outp(crtcport, 0x34);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0xef));

               _outp(crtcport, 0x43);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0x7f));

               _outp(crtcport, 0x5d);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0x80));

               _outp(crtcport, 0x5c);
               r0 = _inp(crtcport+1);

               switch(pAdapter->ModeInfo.bVrtRefresh)
               {
                  case 75:
                    _outp(crtcport+1, ((r0 & 0xcf) | 0x20));
                    _outpw(crtcport, 0x5204);
                    _outpw(crtcport, 0x9e05);
                    _outpw(crtcport, 0x8c11);
                    break;

                  case 72:
                    _outp(crtcport+1, ((r0 & 0xcf) | 0x20));
                    _outpw(crtcport, 0x6300);
                    _outpw(crtcport, 0x8603);
                    _outpw(crtcport, 0x9805);
                    _outpw(crtcport, 0x0606);
                    _outpw(crtcport, 0xe810);
                    _outpw(crtcport, 0x8b11);
                    _outpw(crtcport, 0x0616);
                    break;

                  case 60:
                  default:
                    _outp(crtcport+1, (r0 & 0xcf));
                    _outpw(crtcport, 0x9f05);
                    _outpw(crtcport, 0x8c11);
                    break;
               }
               break;

            case 16:
               _outpw(crtcport, 0xc300);
               _outpw(crtcport, 0x8603);
               _outpw(crtcport, 0xa404);
               _outpw(crtcport, 0x1c05);
               _outpw(crtcport, 0x0442);

               _outp(crtcport, 0x34);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0xef));

               _outp(crtcport, 0x43);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0x7f));

               _outp(crtcport, 0x5d);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0x80));

               _outp(crtcport, 0x5c);
               r0 = _inp(crtcport+1);

               switch(pAdapter->ModeInfo.bVrtRefresh)
               {
                  case 75:
                    _outp(crtcport+1, ((r0 & 0xcf) | 0x30));
                    _outpw(crtcport, 0x8c11);
                    break;

                  case 72:
                    _outp(crtcport+1, ((r0 & 0xcf) | 0x10));
                    _outpw(crtcport, 0xcb00);
                    _outpw(crtcport, 0x8e03);
                    _outpw(crtcport, 0xa604);
                    _outpw(crtcport, 0x1005);
                    _outpw(crtcport, 0x0606);
                    _outpw(crtcport, 0xe810);
                    _outpw(crtcport, 0x8b11);
                    _outpw(crtcport, 0x0616);
                    break;

                  case 60:
                  default:
                    _outp(crtcport+1, ((r0 & 0xcf) | 0x10));
                    _outpw(crtcport, 0x8c11);
                    _outpw(crtcport, 0x0042);
                    break;
               }
               break;

            case 24:
               _outpw(crtcport, 0x9100);
               _outpw(crtcport, 0x7701);
               _outpw(crtcport, 0x7702);
               _outpw(crtcport, 0x9203);
               _outpw(crtcport, 0x7b04);
               _outpw(crtcport, 0x0d05);
               _outpw(crtcport, 0x0742);

               _outp(crtcport, 0x34);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0xef));

               _outp(crtcport, 0x5d);
               r0 = _inp(crtcport+1);

               _outp(crtcport, 0x5c);
               r1 = _inp(crtcport+1);

               _outp(crtcport, 0x43);
               r2 = _inp(crtcport+1);

               switch(pAdapter->ModeInfo.bVrtRefresh)
               {
                  case 75:
                    _outp(crtcport+1, ((r2 & 0x7f) | 0x80));
                    _outpw(crtcport, 0x8c11);

                    _outp(crtcport, 0x5c);
                    _outp(crtcport+1, ((r1 & 0xcf) | 0x20));

                    _outp(crtcport, 0x5d);
                    _outp(crtcport+1, ((r0 & 0x80) | 0x00));
                    break;

                  case 72:
                    _outp(crtcport+1, ((r0 & 0x7f) | 0x00));
                    _outpw(crtcport, 0x3300);
                    _outpw(crtcport, 0xef01);
                    _outpw(crtcport, 0xef02);
                    _outpw(crtcport, 0x9503);
                    _outpw(crtcport, 0xf904);
                    _outpw(crtcport, 0x8805);
                    _outpw(crtcport, 0x0606);
                    _outpw(crtcport, 0xe810);
                    _outpw(crtcport, 0x8b11);
                    _outpw(crtcport, 0x0616);

                    _outp(crtcport, 0x5c);
                    _outp(crtcport+1, ((r1 & 0xcf) | 0x30));

                    _outp(crtcport, 0x5d);
                    _outp(crtcport+1, ((r0 & 0x80) | 0x01));
                    break;

                  case 60:
                  default:
                    _outp(crtcport+1, ((r0 & 0x7f) | 0x80));

                    _outpw(crtcport, 0x8c11);
                    _outpw(crtcport, 0x0442);

                    _outp(crtcport, 0x5c);
                    _outp(crtcport+1, ((r1 & 0xcf) | 0x20));

                    _outp(crtcport, 0x5d);
                    _outp(crtcport+1, ((r0 & 0x80) | 0x00));
                    break;
               }
               break;
         }
         break;

      case 800:
         _outpw(crtcport, 0x9806);
         _outpw(crtcport, 0x7c10);
         _outpw(crtcport, 0x9816);

         switch(pAdapter->ModeInfo.bBitsPerPixel)
         {
            case 8:
            case 4:
              _outpw(crtcport, 0x7d00);
              _outpw(crtcport, 0x8003);
              _outpw(crtcport, 0x6c04);
              _outpw(crtcport, 0x1b05);

               _outp(crtcport, 0x34);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0xef));

               _outp(crtcport, 0x5d);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0x80));

               _outp(crtcport, 0x5c);
               r0 = _inp(crtcport+1);

              switch(pAdapter->ModeInfo.bVrtRefresh)
              {
                 case 75:
                   _outp(crtcport+1, ((r0 & 0xcf) | 20)); //set CR5C
                   _outpw(crtcport, 0x8211);
                   break;

                 case 72:
                   _outp(crtcport+1, ((r0 & 0xcf) | 10)); //set CR5C
                   _outpw(crtcport, 0x8211);
                   break;

                 case 60:
                 default:
                   _outpw(crtcport, 0x7f00);
                   _outpw(crtcport, 0x8203);
                   _outpw(crtcport, 0x6a04);
                   _outpw(crtcport, 0x1a05);
                   _outpw(crtcport, 0x7206);
                   _outpw(crtcport, 0x5810);
                   _outpw(crtcport, 0x8c11);
                   _outpw(crtcport, 0x7216);
                   break;
              }
              break;

            case 16:
              _outpw(crtcport, 0xff00);
              _outpw(crtcport, 0x8203);
              _outpw(crtcport, 0xd604);
              _outpw(crtcport, 0x1405);
              _outpw(crtcport, 0x003c);
              _outpw(crtcport, 0x0642);

               _outp(crtcport, 0x43);
               r0 = _inp(crtcport+1);
               _outp(crtcport+1, (r0 & 0x7f));

               _outp(crtcport, 0x5d);
               r0 = _inp(crtcport+1);

               _outp(crtcport, 0x5c);
               r1 = _inp(crtcport+1);

               _outp(crtcport, 0x34);
               r2 = _inp(crtcport+1);

              switch(pAdapter->ModeInfo.bVrtRefresh)
              {
                 case 75:
                   _outp(crtcport+1, (r2 & 0x10)); //set CR34
                   _outpw(crtcport, 0x8211);
                   _outpw(crtcport, 0xeb3c);

                    _outp(crtcport, 0x5c);
                    _outp(crtcport+1, ((r1 & 0xcf) | 0x10));

                    _outp(crtcport, 0x5d);
                    _outp(crtcport+1, (r0 & 0x80));
                   break;

                 case 72:
                   _outp(crtcport+1, (r2 & 0x34)); //set CR34
                   _outpw(crtcport, 0x8211);

                    _outp(crtcport, 0x5c);
                    _outp(crtcport+1, (r1 & 0xcf));

                    _outp(crtcport, 0x5d);
                    _outp(crtcport+1, (r0 & 0x80));
                   break;

                 case 60:
                 default:
                   _outp(crtcport+1, (r2 & 0x34)); //set CR34
                   _outpw(crtcport, 0x0300);
                   _outpw(crtcport, 0x8603);
                   _outpw(crtcport, 0xd204);
                   _outpw(crtcport, 0x1205);
                   _outpw(crtcport, 0x7206);
                   _outpw(crtcport, 0x5810);
                   _outpw(crtcport, 0x8c11);
                   _outpw(crtcport, 0x7216);
                   _outpw(crtcport, 0x0242);

                    _outp(crtcport, 0x5c);
                    _outp(crtcport+1, ((r1 & 0xcf) | 0x30));

                    _outp(crtcport, 0x5d);
                    _outp(crtcport+1, ((r0 & 0x80) | 0x01));
                   break;
              }
              break;
         }
         break;

      case 1024:

         switch(pAdapter->ModeInfo.bBitsPerPixel)
         {
            case 8:
            case 4:
              _outpw(crtcport, 0xf507);
              _outpw(crtcport, 0x6009);
              _outpw(crtcport, 0xff12);
              _outpw(crtcport, 0xff15);

              _outp(crtcport,0x34);
              r0 = _inp(crtcport+1);
              _outp(crtcport+1, (r0 & 0xef));

              _outp(crtcport,0x43);
              r0 = _inp(crtcport+1);
              _outp(crtcport+1, (r0 & 0x7f));

              _outp(crtcport,0x5d);
              r0 = _inp(crtcport+1);
              _outp(crtcport+1, (r0 & 0x80));

              _outp(crtcport,0x5c);
              r0 = _inp(crtcport+1);

              switch(pAdapter->ModeInfo.bVrtRefresh)
              {
                 case 80:
                   _outp(crtcport+1, ((r1 & 0xcf) | 0x20)); //set CR5C
                   _outpw(crtcport, 0xa400);
                   _outpw(crtcport, 0x8703);
                   _outpw(crtcport, 0x8504);
                   _outpw(crtcport, 0x9305);
                   _outpw(crtcport, 0x2206);
                   _outpw(crtcport, 0x0210);
                   _outpw(crtcport, 0x8511);
                   _outpw(crtcport, 0x2216);
                   _outpw(crtcport, 0x0742);
                   break;

                 case 75:
                   _outp(crtcport+1, ((r1 & 0xcf) | 0x30)); //set CR5C
                   _outpw(crtcport, 0xab00);
                   _outpw(crtcport, 0x8e03);
                   _outpw(crtcport, 0x8504);
                   _outpw(crtcport, 0x8505);
                   _outpw(crtcport, 0x2406);
                   _outpw(crtcport, 0x0010);
                   _outpw(crtcport, 0x8811);
                   _outpw(crtcport, 0x2416);
                   _outpw(crtcport, 0x0542);
                   break;

                 case 72:
                   _outp(crtcport+1, ((r1 & 0xcf) | 0x20)); //set CR5C
                   _outpw(crtcport, 0xa500);
                   _outpw(crtcport, 0x8803);
                   _outpw(crtcport, 0x8204);
                   _outpw(crtcport, 0x8205);
                   _outpw(crtcport, 0x2506);
                   _outpw(crtcport, 0x0010);
                   _outpw(crtcport, 0x8811);
                   _outpw(crtcport, 0x2516);
                   _outpw(crtcport, 0x0542);
                   break;

                 case 70:
                   _outp(crtcport+1, ((r1 & 0xcf) | 0x10)); //set CR5C
                   _outpw(crtcport, 0xa100);
                   _outpw(crtcport, 0x8403);
                   _outpw(crtcport, 0x8404);
                   _outpw(crtcport, 0x9505);
                   _outpw(crtcport, 0x2406);
                   _outpw(crtcport, 0x0210);
                   _outpw(crtcport, 0x8811);
                   _outpw(crtcport, 0x2416);
                   _outpw(crtcport, 0x0542);
                   break;

                 case 60:
                   _outp(crtcport+1, (r1 & 0xcf)); //set CR5C
                   _outpw(crtcport, 0xa300);
                   _outpw(crtcport, 0x8603);
                   _outpw(crtcport, 0x8404);
                   _outpw(crtcport, 0x9505);
                   _outpw(crtcport, 0x2406);
                   _outpw(crtcport, 0x0210);
                   _outpw(crtcport, 0x8811);
                   _outpw(crtcport, 0x2416);
                   _outpw(crtcport, 0x0542);
                   break;

                   case 44:                   //interlace
                   default:
                   _outp(crtcport+1, ((r1 & 0xcf) | 0x30)); //set CR5C
                   _outpw(crtcport, 0x9900);
                   _outpw(crtcport, 0x9c03);
                   _outpw(crtcport, 0x8104);
                   _outpw(crtcport, 0x1705);
                   _outpw(crtcport, 0x9706);
                   _outpw(crtcport, 0x1f07);
                   _outpw(crtcport, 0x4009);
                   _outpw(crtcport, 0x8010);
                   _outpw(crtcport, 0x8411);
                   _outpw(crtcport, 0x7f12);
                   _outpw(crtcport, 0x8015);
                   _outpw(crtcport, 0x9616);
                   _outpw(crtcport, 0x403c);
                   _outpw(crtcport, 0x2142);
                   break;
              }
              break;

            case 16:            // execute from PMI file
              rc = ERROR_REFRESH_NOT_SUPPORTED;
              break;
         }
         break;

      case 1280:
         switch(pAdapter->ModeInfo.bBitsPerPixel)
         {
            case 8:
              switch(pAdapter->ModeInfo.bVrtRefresh)
              {
                 case 60:
                   _outpw(crtcport, 0xd300);
                   _outpw(crtcport, 0x9603);
                   _outpw(crtcport, 0xa104);
                   _outpw(crtcport, 0x1a05);
                   _outpw(crtcport, 0x1e06);
                   _outpw(crtcport, 0x5a07);
                   _outpw(crtcport, 0x8511);
                   _outpw(crtcport, 0xff15);
                   _outpw(crtcport, 0x1e16);
                   _outpw(crtcport, 0x0642);

                   _outp(crtcport, 0x43);
                   r0 = _inp(crtcport+1);
                   _outp(crtcport+1, (r0 & 0x7f));

                   _outp(crtcport, 0x5c);
                   r0 = _inp(crtcport+1);
                   _outp(crtcport+1, ((r0 & 0xcf) | 0x20));

                   _outp(crtcport, 0x5d);
                   r0 = _inp(crtcport+1);
                   _outp(crtcport+1, (r0 & 0x80));

                   _outpw(crtcport, 0x115e);
                   break;

                 case 53:
                 default:
                   _outpw(crtcport, 0xd200);
                   _outpw(crtcport, 0x9503);
                   _outpw(crtcport, 0xa304);
                   _outpw(crtcport, 0x0305);
                   _outpw(crtcport, 0x2306);
                   _outpw(crtcport, 0xb207);
                   _outpw(crtcport, 0x8611);
                   _outpw(crtcport, 0x0015);
                   _outpw(crtcport, 0x2216);
                   _outpw(crtcport, 0x4f42);

                   _outp(crtcport, 0x43);
                   r0 = _inp(crtcport+1);
                   _outp(crtcport+1, (r0 & 0x26));

                   _outp(crtcport, 0x5c);
                   r0 = _inp(crtcport+1);
                   _outp(crtcport+1, ((r0 & 0x40) | 0xcf));

                   _outp(crtcport, 0x5d);
                   r0 = _inp(crtcport+1);
                   _outp(crtcport+1, ((r0 & 0x00) | 0x80));

                   _outpw(crtcport, 0x005e);
                   break;
              }
              break;
         }
         break;

    }
  }               /* end MODE_FLAG_GRAPHICS test   */
  return rc;
}
