/*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 = VDHPALET.c
 *
 * DESCRIPTIVE NAME = Base video device handlers - Color Lookup/Palette
 *
 *
 * VERSION      V2.0
 *
 * DATE
 *
 * DESCRIPTION  This source file contains VDH entry points which
 *              get/set the color lookup table and palette registers.
 *              and get/set palette registers.
 *
 *  NOTE:       These routines execute as ring 2 conforming
 *
 * FUNCTIONS    GetColorLookup,  SetColorLookup
 *              GetPaletteReg,   SetPaletteReg
 *
 * NOTES        NONE
 *
 * STRUCTURES   NONE
 *
 * EXTERNAL REFERENCES
 *              SaveRegs, RestoreRegs
 *              AccessHardware, AccessCLUT
 *              PhysToUVirt, FreePhysToUVirt
 *
 * EXTERNAL FUNCTIONS
 *
 *              NONE
 *
*/

/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Include files                                                             Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
#define INCL_BASE               /* ALL of OS/2 Base                */
#include <os2.h>

#include "vdhctl.h"             /* Conditional compilation control */
#include "vdh.h"                /* Type definitions                */

/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Externally defined global variables                                       Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
extern VIDEOMODE  Modes[];                  /* Supported modes                */
extern MEMORYMAPS MemoryMaps[];             /* Memory map info for each mode  */
extern short HugeShift;                     /* Huge shift value               */
extern USHORT IStart;                       /* Mode table start index         */
extern UCHAR READABLE;
extern ULONG PartialSaveSize;   /* Room required to save entire PVB in the popup mode */
extern USHORT VGA_PRESENT;      /* TRUE if VGA VDH has been installed */
extern USHORT (APIENTRY *ChainedCallVectorTable[MaxFn])();           /* @T24 */
extern USHORT EpoPalette[], CnvPalette[];                               //J-TS00

/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Parameters to ring 2 routines                                             Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
extern UCHAR CRTReg1;
extern UCHAR CRTReg2;
extern UCHAR PelHeightFixup;
extern UCHAR ScreenRemainder;
extern CLUTDATA far ColorCLUT;
extern CLUTDATA far MonoCLUT;
extern CLUTDATA far SumCLUT;

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: GetColorLookup                                     */
/*                                                                      */
/*  DESCRIPTIVE NAME: Get color lookup table                            */
/*                                                                      */
/*  FUNCTION: GetColorLookup is called by BVS to return a specified     */
/*            portion of the current color lookup table settings        */
/*                                                                      */
/*  ENTRY POINT: GetColorLookup                                         */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 263 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = 0 - Environment buffer only      */
/*                                     1 - Hardware also                */
/*                     CLUTDATA far *LookupTable ( 0x00 - 0xFF )        */
/*                                     UCHAR Red                        */
/*                                     UCHAR Green                      */
/*                                     UCHAR Blue                       */
/*                     USHORT   FirstEntry                              */
/*                     USHORT   NumEntries                              */
/*             ULONG Function ( Call vector table entry = 263 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Portion of CLUT requested is returned                  */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: If hardware specified and hardware is readable, the        */
/*           environment buffer is updated, if passed.                  */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: AccessCLUT                                              */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY GetColorLookup( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_CLUT far *ParmBlock;
ULONG Function;
{
USHORT rc,
       EnvBufferPassed;
int    i, j;

#ifdef  XVIO
USHORT      xrc;                                                    /*J-KK0804*/
XVS_SUSPEND XvioSusp;                                               /*J-KK0804*/
XVS_RESUME  XvioResm;                                               /*J-KK0804*/
#endif

rc = ERROR_VIO_INVALID_PARMS;                          /* Initialize to error */
EnvBufferPassed = SEG( Environment );                  /* Non-zero = TRUE     */

if ( EnvBufferPassed &&                                                /*J-KKJ*/
     !Environment->NATIVE_MODE &&                                      /*J-KKJ*/
     VGA_PRESENT )   {              /* VGA Mode */                     /*J-KKJ*/
                                                                       /*J-KKJ*/
    rc = ChainedVDHGetColorLookup(                                     /*J-KKJ*/
                    (ENVIRONMENT far *)&Environment->VGAEnvironment,   /*J-KKJ*/
                    ParmBlock, Function );                             /*J-KKJ*/
                                                                       /*J-KKJ*/
} else {        /* ATLAS Mode */                                       /*J-KKJ*/

if ( ( Function == FnGetColorLookupTable ) &&          /* Valid function request */
     ( ParmBlock->Length >= sizeof( VDH_CLUT ) ) &&    /* Valid packet length */
     ( ParmBlock->Flags  <= 1  )           &&          /* Valid flags         */
     ( ParmBlock->NumEntries )             &&          /* Non-zero amount     */
     ( ParmBlock->FirstEntry  <= 0xFF )    &&          /* Valid first entry   */
     ( ParmBlock->FirstEntry + ParmBlock->NumEntries <= 0xFF+1 ) &&
     ( EnvBufferPassed || ( ParmBlock->Flags & UPDATE_HARDWARE ) ) ) {

/*----------------------------------------------------------------------*/
/*  If requesting application is running in foreground,                 */
/*    - Return hardware value                                           */
/*    - Otherwise return environment buffer value                       */
/*  If requesting application is running in background,                 */
/*    - Return environment buffer value                                 */
/*     ( report error if environment buffer was not passed )            */
/*----------------------------------------------------------------------*/

  rc = NO_ERROR;                        /* Initialize no error */

/*----------------------------------------------------------------------*/
/*  Get CLUT values directly from the hardware                          */
/*----------------------------------------------------------------------*/

  if ( ParmBlock->Flags & UPDATE_HARDWARE ) {

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0804*/
// BXVS Call Suspend                                                /*J-KK0804*/
//------------------------------------------------------------------/*J-KK0804*/
     XvioSusp.Length  = sizeof(XvioSusp);                           /*J-KK0804*/
     XvioSusp.Reserve = NoOption;                                   //@XVIO
     XvioSusp.Session = (UCHAR)Environment->SessionNum;             /*J-KK0926*/
     xrc = XVIOVDHIF( XvsSuspend, (PUSHORT)&XvioSusp );             /*J-KK0804*/
#endif

/*
 +----------------------------------------------------------------------------+
 |  Get CLUT values directly from the hardware                                |
 +----------------------------------------------------------------------------+
*/
     AccessCLUT( GET, &ParmBlock->LookupTable ); /* ring 2 callgate */

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0804*/
// BXVS Call Resume                                                 /*J-KK0804*/
//------------------------------------------------------------------/*J-KK0804*/
     XvioResm.Length  = sizeof(XvioResm);                           /*J-KK0804*/
     XvioResm.Reserve = NoOption;                                   //@XVIO
     XvioResm.Session = (UCHAR)Environment->SessionNum;             /*J-KK0926*/
     xrc = XVIOVDHIF( XvsResume, (PUSHORT)&XvioResm );              /*J-KK0804*/
#endif

/*----------------------------------------------------------------------*/
/*  Copy CLUT values from caller's parmeter area to the env buffer      */
/*----------------------------------------------------------------------*/

     if ( EnvBufferPassed ) {
        for (i= ParmBlock->FirstEntry, j= 0; j < ParmBlock->NumEntries; i++, j++) {
           Environment->LookupTable[i].Red = ParmBlock->LookupTable[j].Red;
           Environment->LookupTable[i].Green = ParmBlock->LookupTable[j].Green;
           Environment->LookupTable[i].Blue  = ParmBlock->LookupTable[j].Blue;
        }
     }

  } else {                              /* Caller in background */

/*----------------------------------------------------------------------*/
/*  Copy CLUT values from env buffer to caller's parameter area         */
/*----------------------------------------------------------------------*/

     for (i= ParmBlock->FirstEntry, j= 0; j < ParmBlock->NumEntries; i++, j++) {
        ParmBlock->LookupTable[j].Red   = Environment->LookupTable[i].Red;
        ParmBlock->LookupTable[j].Green = Environment->LookupTable[i].Green;
        ParmBlock->LookupTable[j].Blue  = Environment->LookupTable[i].Blue;
     }

  }

}
}                                                                       //J-TS00
return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: SetColorLookup                                     */
/*                                                                      */
/*  DESCRIPTIVE NAME: Set color lookup table                            */
/*                                                                      */
/*  FUNCTION: SetColorLookup is called by BVS to set a specified        */
/*            portion of the color lookup table settings                */
/*                                                                      */
/*  ENTRY POINT: SetColorLookup                                         */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 264 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = 0 - Environment buffer only      */
/*                                     1 - Hardware also                */
/*                     CLUTDATA far *LookupTable ( 0x00 - 0xFF )        */
/*                                     UCHAR Red                        */
/*                                     UCHAR Green                      */
/*                                     UCHAR Blue                       */
/*                     USHORT   FirstEntry                              */
/*                     USHORT   NumEntries                              */
/*             ULONG Function ( Call vector table entry = 264 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Portion of CLUT requested is set                       */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: AccessCLUT                                              */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY SetColorLookup( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_CLUT far *ParmBlock;
ULONG Function;
{
USHORT rc,
       i, j,
       EnvBufferPassed;

#ifdef  XVIO
USHORT      xrc;                                                    /*J-KK0804*/
XVS_SUSPEND XvioSusp;                                               /*J-KK0804*/
XVS_RESUME  XvioResm;                                               /*J-KK0804*/
#endif

rc = ERROR_VIO_INVALID_PARMS;                          /* Initialize to error */
EnvBufferPassed = SEG( Environment );                  /* Non-zero = TRUE     */

if ( EnvBufferPassed &&                                                /*J-KKJ*/
     !Environment->NATIVE_MODE &&                                      /*J-KKJ*/
     VGA_PRESENT ) {                /* VGA Mode */                     /*J-KKJ*/
                                                                       /*J-KKJ*/
    rc = ChainedVDHSetColorLookup(                                     /*J-KKJ*/
             (ENVIRONMENT far *)&Environment->VGAEnvironment,          /*J-KKJ*/
              ParmBlock, Function );                                   /*J-KKJ*/
                                                                       /*J-KKJ*/
} else {        /* ATLAS Mode */                                       /*J-KKJ*/

if ( ( Function == FnSetColorLookupTable ) &&          /* Valid function request */
     ( ParmBlock->Length >= sizeof( VDH_CLUT ) ) &&    /* Valid packet length */
     ( ParmBlock->Flags  <= 1  )           &&          /* Valid flags         */
     ( ParmBlock->NumEntries )             &&          /* Non-zero amount     */
     ( ParmBlock->FirstEntry  <= 0xFF )    &&          /* Valid first entry   */
     ( ParmBlock->FirstEntry + ParmBlock->NumEntries <= 0xFF+1 ) &&
     ( EnvBufferPassed || ( ParmBlock->Flags & UPDATE_HARDWARE ) ) ) {

/*----------------------------------------------------------------------*/
/*  Parameters are valid - Update environment buffer if it was passed   */
/*                       - Update hardware if in foreground             */
/*----------------------------------------------------------------------*/

  rc = NO_ERROR;                        /* Initialize no error */

/*----------------------------------------------------------------------*/
/*  Copy CLUT values from caller's parmeter area to the env buffer      */
/*----------------------------------------------------------------------*/

  if ( EnvBufferPassed ) {
      for (i= ParmBlock->FirstEntry, j= 0; j < ParmBlock->NumEntries; i++, j++) {
        Environment->LookupTable[i].Red   = ParmBlock->LookupTable[j].Red;
        Environment->LookupTable[i].Green = ParmBlock->LookupTable[j].Green;
        Environment->LookupTable[i].Blue  = ParmBlock->LookupTable[j].Blue;
      }
  }

  if ( ParmBlock->Flags & UPDATE_HARDWARE ) {

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0804*/
// BXVS Call Suspend                                                /*J-KK0804*/
//------------------------------------------------------------------/*J-KK0804*/
      XvioSusp.Length  = sizeof(XvioSusp);                          /*J-KK0804*/
      XvioSusp.Reserve = NoOption;                                  //@XVIO
      XvioSusp.Session = (UCHAR)Environment->SessionNum;            /*J-KK0926*/
      xrc = XVIOVDHIF( XvsSuspend, (PUSHORT)&XvioSusp );            /*J-KK0804*/
#endif

/*----------------------------------------------------------------------*/
/*  Set CLUT registers directly on the hardware                         */
/*----------------------------------------------------------------------*/
      AccessCLUT( SET, &ParmBlock->LookupTable ); /* ring 2 callgate */

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0804*/
// BXVS Call Resume                                                 /*J-KK0804*/
//------------------------------------------------------------------/*J-KK0804*/
      XvioResm.Length  = sizeof(XvioResm);                          /*J-KK0804*/
      XvioResm.Reserve = NoOption;                                  //@XVIO
      XvioResm.Session = (UCHAR)Environment->SessionNum;            /*J-KK0926*/
      xrc = XVIOVDHIF( XvsResume, (PUSHORT)&XvioResm );             /*J-KK0804*/
#endif

  }

}
}                                                                       //J-TS00
return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: GetPaletteReg                                      */
/*                                                                      */
/*  DESCRIPTIVE NAME: Get palette registers                             */
/*                                                                      */
/*  FUNCTION: GetPaletteReg is called by BVS to return the specified    */
/*            portion of the palette registers.  If the request         */
/*            specifies hardware and the hardware is readable, the      */
/*            actual hardware setting will be read and returned.        */
/*            Otherwise the returned information will be taken from     */
/*            the environment buffer, if it has been passed.            */
/*                                                                      */
/*  ENTRY POINT: GetPaletteReg                                          */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 273 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = 0 - Environment buffer only      */
/*                                     1 - Hardware also                */
/*                     FAR *PaletteBuffer                               */
/*                     USHORT   FirstEntry                              */
/*                     USHORT   NumEntries                              */
/*             ULONG Function ( Call vector table entry = 273 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Requested palette registers are returned               */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: If hardware specified and hardware is readable, the        */
/*           environment buffer is updated, if passed.                  */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: AccessHardware                                          */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY GetPaletteReg( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_PALETTE far *ParmBlock;
ULONG Function;
{
USHORT rc,
       ColorMode,                                                       /*@C21*/
       VideoOn,                                                         /*@C21*/
       EnvBufferPassed;
int    i, j;
REGADDRESS RegAddress;
USHORT mode;                                                            //J-TS00
USHORT palettes[16];                                                    //J-TS00
REGDATA2 PaletteBuffer;                                                 //J-TS00

/*SaveRegs();*/ /*@B14*/                      /* Preserve registers and flags */

rc = ERROR_VIO_INVALID_PARMS;                          /* Initialize to error */
EnvBufferPassed = SEG( Environment );                  /* Non-zero = TRUE     */

if ( EnvBufferPassed &&                                                /*J-KKJ*/
     !Environment->NATIVE_MODE &&                                      /*J-KKJ*/
     VGA_PRESENT ) {                /* VGA Mode */                     /*J-KKJ*/

    rc = ChainedVDHGetPaletteReg(                                      /*J-KKJ*/
                (ENVIRONMENT far *)&Environment->VGAEnvironment,       /*J-KKJ*/
                ParmBlock, Function );                                 /*J-KKJ*/
                                                                       /*J-KKJ*/
} else {        /* ATLAS Mode */                                       /*J-KKJ*/

if ( ( Function == FnGetPaletteRegisters ) &&          /* Valid function request */
     ( ParmBlock->Length >= sizeof( VDH_PALETTE ) ) && /* Valid packet length */
     ( ParmBlock->Flags  <= 1  )                &&     /* Valid flags         */
     ( EnvBufferPassed || ( ParmBlock->Flags & UPDATE_HARDWARE ) ) )
//rc = ERROR_VIO_INVALID_LENGTH;                                        @T59

if ( ( ParmBlock->PaletteBuffer.NumEntries )    &&     /* Non-zero amount     */
     ( ParmBlock->PaletteBuffer.FirstEntry  <= 0x0F ) && /* Valid first entry   */
     ( ParmBlock->PaletteBuffer.FirstEntry + ParmBlock->PaletteBuffer.NumEntries <= 0x0F+1 ) ) {

  rc = NO_ERROR;                                       /* Initialize no error */

/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  If requesting application is running in foreground,                       Ί
 Ί    - Return hardware value if hardware can be read                         Ί
 Ί    - Otherwise return environment buffer value                             Ί
 Ί     ( report error if write-only hardware and no env buffer passed )       Ί
 Ί  If requesting application is running in background,                       Ί
 Ί    - Return environment buffer value                                       Ί
 Ί     ( report error if environment buffer was not passed )                  Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
  if ( (ParmBlock->Flags & UPDATE_HARDWARE) && READABLE ) {

/*
 +----------------------------------------------------------------------------+
 |  Get palette values directly from the hardware                             |
 |  Accessing the Attribute regs resets the VideoEnable status so have    @C21|
 |  to reset it if it was ON before the call                              @C21|
 +----------------------------------------------------------------------------+
*/

    ColorMode = HardwareColor();       /* color/mono mode ( hardware )    @C21*/
    if ( EnvBufferPassed )                                              /*@C21*/
       VideoOn = Environment->VideoEnable;                              /*@C21*/
    else                                                                /*@C21*/
       AccessVideoEnable( ColorMode, GET, &VideoOn );                   /*@C21*/

    RegAddress.AddressPort = AttAddressPort;
    RegAddress.DataPort    = AttDataReadPort;
    RegAddress.ColorAdjust = NONE;
    RegAddress.Flags       = Attributes_CMD;


    PaletteBuffer.DataArea   = palettes;                                //J-TS00
    PaletteBuffer.FirstEntry = 0;                                       //J-TS00
    PaletteBuffer.NumEntries = 16;                                      //J-TS00

    AccessHardware( &RegAddress, WORDS, HardwareColor(), GET,           //J-TS00
                    (REGDATA far *)&PaletteBuffer );                    //J-TS00

    if ( VideoOn )                                                      /*@C21*/
       AccessVideoEnable( ColorMode, SET, &VideoOn );                   /*@C21*/

    if ( EnvBufferPassed )
/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Copy palette values from caller's parmeter area to the env buffer         Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
      for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0; j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)
        Environment->Hardware.Attributes.Regs.Palettes[i] = (UCHAR)palettes[i]; //J-TS00

    }
  else {
/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Requesting application is running in the background                       Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/

    if ( EnvBufferPassed )
/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Copy palette values from env buffer to caller's parameter area            Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
      for (i= 0; i < 16; i++)                                           //J-TS00
        palettes[i] = (USHORT)Environment->Hardware.Attributes.Regs.Palettes[i]; //J-TS00
    else
      rc = ERROR_VIO_INVALID_PARMS;    /* Not FG OR write-only, no env buffer */
    }

    if ( rc == NO_ERROR ) {                                                  //J-TS00
      mode = EnvBufferPassed ? Environment->ModeIndex                        //J-TS00
                             : ModeIndex_ATLASCO80VGA;                       //J-TS00
      if ( mode == ModeIndex_EPOCHMONO80 ) {                                 //J-TS00
            /* In EPOCH mono mode, only a few palettes are valid. */         //J-TS00
        for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                   //J-TS00
                    j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)       //J-TS00
            ParmBlock->PaletteBuffer.DataArea[j] = ( i == 4 ) ?              //J-TS00
                                (USHORT)Environment->GridColor :             //J-TS00
                                ( EpoPalette[i] != 0xFF ) ?                  //J-TS00
                                    palettes[CnvPalette[EpoPalette[i]]] : 0; //J-TS00
                                                                             //J-TS00
      } else if ( mode == ModeIndex_EPOCHCOLR80 ) {                          //J-TS00
            /* In EPOCH color mode, only palette #4 is valid & the color */  //J-TS00
            /* is grid color.                                            */  //J-TS00
        for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                   //J-TS00
                    j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)       //J-TS00
            ParmBlock->PaletteBuffer.DataArea[j] = ( i == 4 ) ?              //J-TS00
                                (USHORT)Environment->GridColor : 0;          //J-TS00
                                                                             //J-TS00
      } else if ( mode <= ModeIndex_ATLASCOMMON ) {                          //J-TS00
            /* In DBCS VGA & COMMON mode, palette values are */              //J-TS00
            /* simply copied.                                */              //J-TS00
        for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                   //J-TS00
             j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)              //J-TS00
          ParmBlock->PaletteBuffer.DataArea[j] = palettes[i];                //J-TS00
                                                                             //J-TS00
      } else {                                                               //J-TS00
            /* In ATLAS 3bytes mode, palette registers are crossed. */       //J-TS00
            /* So the values must be re-crossed.                    */       //J-TS00
        for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                   //J-TS00
             j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)              //J-TS00
          ParmBlock->PaletteBuffer.DataArea[j] = palettes[CnvPalette[i]];    //J-TS00
      }                                                                      //J-TS00
    }                                                                        //J-TS00

  }

}                       /* VGA Mode J-KKJ*/
/*RestoreRegs();*/ /*@B14*/              /* Restore registers and flags */
return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: SetPaletteReg                                      */
/*                                                                      */
/*  DESCRIPTIVE NAME: Set palette registers                             */
/*                                                                      */
/*  FUNCTION: SetPaletteReg is called by BVS to set the specified       */
/*            portion of the palette registers.  If the request         */
/*            specifies hardware the hardware and the environment       */
/*            buffer, if passed, will be updated.  Otherwise just the   */
/*            environment buffer, if passed, will be updated.           */
/*                                                                      */
/*  ENTRY POINT: SetPaletteReg                                          */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 274 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = 0 - Environment buffer only      */
/*                                     1 - Hardware also                */
/*                     FAR *PaletteBuffer                               */
/*                     USHORT   FirstEntry                              */
/*                     USHORT   NumEntries                              */
/*             ULONG Function ( Call vector table entry = 274 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Requested palette registers are set                    */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: AccessHardware                                          */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY SetPaletteReg( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_PALETTE far *ParmBlock;
ULONG Function;
{
USHORT rc,
       i, j,
       ColorMode,
       VideoOn,                                                         /*@C21*/
       EnvBufferPassed;
REGADDRESS RegAddress;

USHORT mode;                                                            //J-TS00
USHORT palettes[16];                                                    //J-TS00
REGDATA2 PaletteBuffer;                                                 //J-TS00

#ifdef  XVIO
USHORT      xrc;                                                    /*J-KK0804*/
XVS_SUSPEND XvioSusp;                                               /*J-KK0804*/
XVS_RESUME  XvioResm;                                               /*J-KK0804*/
#endif

/*SaveRegs();*/ /*@B14*/                      /* Preserve registers and flags */

rc = ERROR_VIO_INVALID_PARMS;                          /* Init to error   */
EnvBufferPassed = SEG( Environment );                  /* Non-zero = TRUE     */

if ( EnvBufferPassed &&                                                /*J-KKJ*/
     !Environment->NATIVE_MODE &&                                      /*J-KKJ*/
     VGA_PRESENT  )   {                /* VGA Mode */                  /*J-KKJ*/
                                                                       /*J-KKJ*/
    rc = ChainedVDHSetPaletteReg(                                      /*J-KKJ*/
                    (ENVIRONMENT far *)&Environment->VGAEnvironment,   /*J-KKJ*/
                     ParmBlock, Function );                            /*J-KKJ*/
                                                                       /*J-KKJ*/
} else {        /* ATLAS Mode */                                       /*J-KKJ*/

if ( ( Function == FnSetPaletteRegisters ) &&          /* Valid function request */
     ( ParmBlock->Length >= sizeof( VDH_PALETTE ) ) && /* Valid packet length */
     ( ParmBlock->Flags  <= 1  )             &&        /* Valid flags         */
     ( ParmBlock->PaletteBuffer.FirstEntry  <= 0x0F ) &&  /* @@A valid 1st ntry*/
     ( EnvBufferPassed || ( ParmBlock->Flags & UPDATE_HARDWARE ) ) )
//rc = ERROR_VIO_INVALID_LENGTH;                                        @T59

if ( ( ParmBlock->PaletteBuffer.NumEntries ) &&        /* Non-zero amount     */
     ( ParmBlock->PaletteBuffer.FirstEntry + ParmBlock->PaletteBuffer.NumEntries <= 0x0F+1 ) ) {

  rc = NO_ERROR;                                       /* Initialize no error */

/* First of all, get current palette setting */                         //J-TS00
  if ( ParmBlock->Flags & UPDATE_HARDWARE ) {                           //J-TS00
/*                                                                      //J-TS00
 +---------------------------------------------------------------------+//J-TS00
 |  Get palette values directly from the hardware                      |//J-TS00
 |  Accessing the Attribute regs resets the VideoEnable status so have |//J-TS00
 |  to reset it if it was ON before the call                           |//J-TS00
 +---------------------------------------------------------------------+//J-TS00
*/                                                                      //J-TS00
    ColorMode = HardwareColor();     /* color/mono mode ( hardware ) */ //J-TS00
    if ( EnvBufferPassed )                                              //J-TS00
      VideoOn = Environment->VideoEnable;                               //J-TS00
    else                                                                //J-TS00
      AccessVideoEnable( ColorMode, GET, &VideoOn );                    //J-TS00
                                                                        //J-TS00
    RegAddress.AddressPort = AttAddressPort;                            //J-TS00
    RegAddress.DataPort    = AttDataReadPort;                           //J-TS00
    RegAddress.ColorAdjust = NONE;                                      //J-TS00
    RegAddress.Flags       = Attributes_CMD;                            //J-TS00
                                                                        //J-TS00
    PaletteBuffer.DataArea   = palettes;                                //J-TS00
    PaletteBuffer.FirstEntry = 0;                                       //J-TS00
    PaletteBuffer.NumEntries = 16;                                      //J-TS00
                                                                        //J-TS00
    AccessHardware( &RegAddress, WORDS, HardwareColor(), GET,           //J-TS00
                    (REGDATA far *)&PaletteBuffer );                    //J-TS00
                                                                        //J-TS00
    if ( VideoOn )                                                      //J-TS00
      AccessVideoEnable( ColorMode, SET, &VideoOn );                    //J-TS00
  } else if ( EnvBufferPassed ) {                                       //J-TS00
    for (i = 0; i < 16; i++)                                            //J-TS00
      palettes[i] = Environment->Hardware.Attributes.Regs.Palettes[i];  //J-TS00
  }                                                                     //J-TS00
                                                                        //J-TS00
/* Next, copy passed palettes */                                        //J-TS00
  if ( rc == NO_ERROR ) {                                               //J-TS00
    mode = EnvBufferPassed ? Environment->ModeIndex                     //J-TS00
                           : ModeIndex_ATLASCO80VGA;                    //J-TS00
    if ( mode == ModeIndex_EPOCHMONO80 ) {                              //J-TS00
          /* In EPOCH mono mode, only a few palettes are valid. */      //J-TS00
      for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                //J-TS00
                  j < ParmBlock->PaletteBuffer.NumEntries; i++, j++) {  //J-TS00
        if (( i == 4 ) && EnvBufferPassed ) {                           //J-TS00
          Environment->GridColor = ParmBlock->PaletteBuffer.DataArea[j] //J-TS00
                                 & 0x0F;                                //J-TS00
          SetGridDrawColor(Environment->GridColor);                     //J-TS00
          Environment->First_Grid_Color = FALSE;                        //J-TS00
                                                                        //J-TS00
        } else if ( EpoPalette[i] != 0xFF ) {                           //J-TS00
          palettes[CnvPalette[EpoPalette[i]]] =                         //J-TS00
                            ParmBlock->PaletteBuffer.DataArea[j];       //J-TS00
                                                                        //J-TS00
          if (( i == 2 ) && EnvBufferPassed )                           //J-TS00
            Environment->Hardware.Fore_Color =                          //J-TS00
                        (UCHAR)ParmBlock->PaletteBuffer.DataArea[j];    //J-TS00
                                                                        //J-TS00
          else if (( i == 3 ) && EnvBufferPassed )                      //J-TS00
            Environment->Hardware.Fore_Int   =                          //J-TS00
                        (UCHAR)ParmBlock->PaletteBuffer.DataArea[j];    //J-TS00
        }                                                               //J-TS00
      }                                                                 //J-TS00
                                                                        //J-TS00
    } else if ( mode == ModeIndex_EPOCHCOLR80 ) {                       //J-TS00
          /* In EPOCH color mode, only palette #4 is valid */           //J-TS00
          /* the color is grid color.                      */           //J-TS00
      for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                //J-TS00
                  j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)    //J-TS00
        if (( i == 4 ) && EnvBufferPassed ) {                           //J-TS00
          Environment->GridColor = ParmBlock->PaletteBuffer.DataArea[j] //J-TS00
                                 & 0x0F;                                //J-TS00
          SetGridDrawColor(Environment->GridColor);                     //J-TS00
        }                                                               //J-TS00
                                                                        //J-TS00
    } else if ( mode <= ModeIndex_ATLASCOMMON ) {                       //J-TS00
          /* In DBCS VGA & COMMON mode, palette values are */           //J-TS00
          /* simply copied.                                */           //J-TS00
      for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                //J-TS00
           j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)           //J-TS00
        palettes[i] = ParmBlock->PaletteBuffer.DataArea[j];             //J-TS00
                                                                        //J-TS00
    } else {                                                            //J-TS00
          /* In ATLAS 3bytes mode, palette registers are crossed. */    //J-TS00
          /* So the values must be re-crossed.                    */    //J-TS00
      for (i= ParmBlock->PaletteBuffer.FirstEntry, j= 0;                //J-TS00
           j < ParmBlock->PaletteBuffer.NumEntries; i++, j++)           //J-TS00
        palettes[CnvPalette[i]] = ParmBlock->PaletteBuffer.DataArea[j]; //J-TS00
    }                                                                   //J-TS00
  }                                                                     //J-TS00

/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Parameters are valid - Update environment buffer if it was passed         Ί
 Ί                       - Update hardware if in foreground                   Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
  if ( EnvBufferPassed ) {
/*
 ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
 Ί  Copy palette values from caller's parmeter area to the env buffer         Ί
 ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
*/
      for (i= 0; i < 16; i++)                                           //J-TS00
        Environment->Hardware.Attributes.Regs.Palettes[i]               //J-TS00
                = (UCHAR)palettes[i];                                   //J-TS00

    }

  if ( ParmBlock->Flags & UPDATE_HARDWARE ) {

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0804*/
// BXVS Call Suspend                                                /*J-KK0804*/
//------------------------------------------------------------------/*J-KK0804*/
    XvioSusp.Length  = sizeof(XvioSusp);                            /*J-KK0804*/
    XvioSusp.Reserve = NoOption;                                    //@XVIO
    XvioSusp.Session = (UCHAR)Environment->SessionNum;              /*J-KK0926*/
    xrc = XVIOVDHIF( XvsSuspend, (PUSHORT)&XvioSusp );              /*J-KK0804*/
#endif

/*
 +----------------------------------------------------------------------------+
 |  Set palette values directly from the hardware                             |
 |  Accessing the Attribute regs resets the VideoEnable status so have    @C21|
 |  to reset it if it was ON before the call                              @C21|
 +----------------------------------------------------------------------------+
*/
    RegAddress.AddressPort = AttAddressPort;
    RegAddress.DataPort    = AttDataWritePort;
    RegAddress.ColorAdjust = NONE;
    RegAddress.Flags       = Attributes_CMD;

    ColorMode = HardwareColor(); /* color/mono mode ( hardware ) */

    if ( EnvBufferPassed )                                              /*@C21*/
       VideoOn = Environment->VideoEnable;                              /*@C21*/
    else                                                                /*@C21*/
         AccessVideoEnable( ColorMode, GET, &VideoOn );                 /*@C21*/

    PaletteBuffer.DataArea   = palettes;                                //J-TS00
    PaletteBuffer.FirstEntry = 0;                                       //J-TS00
    PaletteBuffer.NumEntries = 16;                                      //J-TS00
                                                                        //J-TS00
    AccessHardware( &RegAddress, WORDS, ColorMode, SET,                 //J-TS00
                    (REGDATA far *)&PaletteBuffer );                    //J-TS00

    if ( VideoOn )                                                      /*@C21*/
       AccessVideoEnable( ColorMode, SET, &VideoOn );                   /*@C21*/
    }

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0804*/
// BXVS Call Resume                                                 /*J-KK0804*/
//------------------------------------------------------------------/*J-KK0804*/
    XvioResm.Length  = sizeof(XvioResm);                            /*J-KK0804*/
    XvioResm.Reserve = NoOption;                                    //@XVIO
    XvioResm.Session = (UCHAR)Environment->SessionNum;              /*J-KK0926*/
    xrc = XVIOVDHIF( XvsResume, (PUSHORT)&XvioResm );               /*J-KK0804*/
#endif

  }

}               /* VGA Mode J-KKJ*/
/*RestoreRegs();*/ /*@B14*/                    /* Restore registers and flags */
return( rc );
}
