/*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 = VDHMAIN.c
 *
 * DESCRIPTIVE NAME = Base video device handlers - Initialization,
 *                                                 Save/Restore &
 *                                                 Get/FreePhysBuf
 *
 *
 * VERSION      V2.0
 *
 * DATE
 *
 * DESCRIPTION  This source is compiled conditionally to produce 5
 *              distinct video device handlers ( dynalink libraries )
 *              for support of either MPA, CGA, EGA, VGA/PS2 adapter, or
 *              8514/A display adapters.  The video device handlers
 *              each consist of hardware dependent functions, which are
 *              invoked directly by the OS/2 base video subsystem.
 *
 *              To direct the compiler to build each video device handler,
 *              a unique symbol must be defined via the '-D' compile
 *              switch for each one.  These symbols are:
 *              -DVDHMPA for the MPA video device handler (VDHMPA.DLL)
 *              -DVDHCGA for the CGA video device handler (VDHCGA.DLL)
 *              -DVDHEGA for the EGA video device handler (VDHEGA.DLL)
 *              -DVDHVGA for the VGA and PS/2 adapter VDH (VDHVGA.DLL)
 *              -DVDH8514A for the BGA video device handler (VDH8514A.DLL)
 *
 * FUNCTIONS    DevEnable
 *              InitEnv, SaveEnv, RestoreEnv
 *              RetConfigInfo
 *              GetPhysBuf, FreePhysBuf
 *
 * NOTES        NONE
 *
 * STRUCTURES   NONE
 *
 * EXTERNAL REFERENCES
 *              DosOpen,  DosGetHugeShift
 *              DosAllocSeg, DosFreeSeg
 *              SaveRegs, RestoreRegs
 *              ExamineConfig, SetHWMode
 *              SaveRestorePVB, SaveRestoreHW
 *              PhysToUVirt, FreePhysToUVirt
 *
 * EXTERNAL FUNCTIONS
 *
 *              NONE
 *
*/

/*
 +----------------------------------------------------------------------------+
 |  Include files                                                             |
 +----------------------------------------------------------------------------+
*/
#define INCL_BASE               /* ALL of OS/2 Base                */
#define INCL_DOSDEVICES         /* Device specific, ring 2 support */
#include <os2.h>

#include "vdhctl.h"             /* Conditional compilation control */
#include "vdh.h"                /* Type definitions                */
#include "vdhdata.h"            /* Global data                     */
#include "fntcalls.h"           /* FNTCALLS definition             */   //J-TS00
#include "memhelp.h"            /* MEMHELP interface definition    */   //J-TS00
#include "vgaemu.h"             /* VGA text emulation buffer       */   //J-TS00

/*
 +----------------------------------------------------------------------------+
 |  Externally defined global variables                                       |
 +----------------------------------------------------------------------------+
*/
extern CLUTDATA far ColorCLUT;
extern CLUTDATA far MonoCLUT;

extern USHORT SVGAPresent;                                              //@drw
extern USHORT PASCAL NEAR GetSVGAConfig(VOID);                          //@drw

extern USHORT  BvscbSel[];          // BVSCB Selector                   J-KK1127
extern USHORT  HardwareScroll;      /* hardware scroll option */        //J-TS00

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: DevEnable                                          */
/*                                                                      */
/*  DESCRIPTIVE NAME: Initialize call vector table                      */
/*                                                                      */
/*  FUNCTION: DevEnable is called via the Presentation Manager DDI      */
/*            interface.  The entry points of all VDH routines are      */
/*            appropriately entered into the call vector table.         */
/*            In addition, display adapter configuration is verified.   */
/*                                                                      */
/*  ENTRY POINT: DevEnable                                              */
/*    LINKAGE:   CALL FAR                                               */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR * Parameter2  ( far pointer to parameter 2 packet )  */
/*                      FAR *Flags                                      */
/*                      FAR *CallVectorTable                            */
/*             FAR * Parameter1  ( far pointer to parameter 1 packet )  */
/*                      ULONG EngineVersion ( Graphics engine ver. )    */
/*                      ULONG TableSize ( Length of call table )        */
/*             ULONG Subfunction ( Enable subfunction )                 */
/*             FAR *CallVectorTable[] ( BVS's table of entry points )   */
/*         (Referenced)                                                 */
/*             VDHEntryPoint[] (global data - table of entry points )   */
/*             HugeShift (global data - huge shift value)               */
/*             hScreenDD (global data - screen device driver handle)    */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Entries in VDHEntryPoint table are copied to           */
/*                  CallVectorTable                                     */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_BAD_ADAPTER or                           */
/*                   DosGetHugeShift error or                           */
/*                   DosOpen error or                                   */
/*                   PMERR_DEV_FUNC_NOT_INSTALLED                       */
/*                                                                      */
/*  EFFECTS: Huge shift value is saved in HugeShift                     */
/*           Screen device driver handle is saved in hScreenDD          */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: DosGetHugeShift, DosOpen, ExamineConfig                 */
/*              SaveRegs, RestoreRegs                                   */
/*    DATA:     hScreenDD       (Global nonshared): handle to SCREEN$   */
/*              HugeShift       (Global shared): from DosGetHugeShift   */
/*              VDHEntryPoint[] (Global shared): table of entry points  */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY DevEnable( Parm2, Parm1, Subfunction )
DEV_PARM2 far *Parm2;
DEV_PARM1 far *Parm1;
ULONG Subfunction;
{
USHORT rc,
       j,
       One = 1,
       ActionTaken;
ULONG i;
    UCHAR *val;                                                         //J-TS00V

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

rc = NO_ERROR;                          /* Initialize to successful */

if ( (Subfunction != FnFillInitDevBlock) &&     /* @T15 */
     (Subfunction != FnFillLogicalDevBlock) ) {
    rc = PMERR_DEV_FUNC_NOT_INSTALLED;

} else {

/*----------------------------------------------------------------------*/
/*  Get handle to SCREEN$ for later use of IOCtls cat 3, funcs 70 & 71  */
/*----------------------------------------------------------------------*/

    if (!hScreenDD) {               /* SCREEN$ not yet open, @S15*/
        rc = DosOpen( SCREENDD_NAME, (PHFILE)&hScreenDD,
            (PUSHORT)&ActionTaken, NO_SIZE, NO_ATTRIBUTES, OPEN_IF_EXISTS,
            NO_INHERIT+DENY_NONE+READ_WRITE, RESERVED_LONG ); /*@T5,@T15,@S15*/
    }                               /*@S15*/

    if ( Subfunction == FnFillInitDevBlock )  /* Only One Time          J-KKJ1*/
        FIRST_RETCONFIG = TRUE; /*Means Following RetConfigInfo is First. J-KK*/

    if (!rc && FIRST_INIT) {            /*@T21,@S15*/
        FIRST_INIT = FALSE;             /*@T15*/

/*
 +----------------------------------------------------------------------------+
 |  Get huge shift value for later use during save/rest of display buffer     |
 +----------------------------------------------------------------------------+
*/
        if ( !(rc = DosGetHugeShift( (PUSHORT)&HugeShift )) ) {
            HugeShift = One << HugeShift;

/*
 +----------------------------------------------------------------------------+
 |  Verify presence of adapter and record adapter configuration for           |
 |  later use by RetConfigInfo and RetROMFontInfo                             |
 +----------------------------------------------------------------------------+
*/



/*
 +----------------------------------------------------------------------------+
 |  We need to check hardware scroll option.                                  |
 +----------------------------------------------------------------------------+
*/
    if (!DosScanEnv(ENV_VAR_PROTECTHS, (PSZ *)&val)) {
        if (strcmp(val, STR_PROTECT_HS_ON) == 0)
            HardwareScroll = PROTECT_HS_ON;
        if (strcmp(val, STR_PROTECT_HS_LC) == 0)
            HardwareScroll = PROTECT_HS_LC;
        if (strcmp(val, STR_PROTECT_HS_OFF) == 0)
            HardwareScroll = PROTECT_HS_OFF;
    }

/*
 +----------------------------------------------------------------------------+
 |  We need the call vector to RetConfigInfo in the VGA VDH (if it's there)   |
 |  ( This vector must be accessible prior to the call to ExamineConfig() )   |
 +----------------------------------------------------------------------------+
*/
// Device Chaining is determined by the satatetemt in "CONFIG.SYS".      J-KKJ1
//  SET VIDEO_DEVICES = VIO_VGA                                          J-KKJ1
//  SET VIO_VGA = DEVICE(VDHVGA,VDHVGA2)    ===> Device Chaining         J-KKJ1
//     or                                                                J-KKJ1
//  SET VIO_VGA = DEVICE(VDHVGA2)           ===> Not Device Chaining     J-KKJ1

            if ( Parm2->CallVectorTable[FnReturnConfigInfo] == 0 )    /*J-KKJ1*/
                   VGA_PRESENT = 0;      /* Device Chaining Disable     J-KKJ1*/
            else   VGA_PRESENT = 1;      /* Device Chaining Enable      J-KKJ1*/


            if ( VGA_PRESENT )    /* For Device Chaining J-KKJ */
                (USHORT far *)ChainedCallVectorTable[FnChainedRetConfigInfo] =
                                 Parm2->CallVectorTable[FnReturnConfigInfo];

            SVGAPresent = GetSVGAConfig();

            if ( !( rc = ExamineConfig() ) ) {

#ifdef  XVIO
//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Allocate Common Data Area to Communication with Xvio.           J-KK0929  Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
              if (!(rc = DosAllocSeg( sizeof( COMMONAREA ) * 16,    /*J-KK0929*/
                                      (PSEL)&CommonSelector,        /*J-KK0929*/
                                      2 ))) {   /* Shareable */     /*J-KK0929*/
#endif
/*
 +----------------------------------------------------------------------------+
 |  Copy all VDH entry points that are supported for this adapter             |
 |  to BVS's call table for this adapter                                      |
 +----------------------------------------------------------------------------+
*/
                for ( i = FnTextBufferUpdate, j = FnChainedBufUpdate;
                    (i <= FnGetLVBInfo) && (i < Parm1->TableSize); i++, j++ ) { /* @P1 */

                    if ( VDHEntryPoint[j] != UNSUPPORTED_FUNCTION ) {
/*
 +----------------------------------------------------------------------------+
 |  Save a copy of the call vector table for chaining                         |
 +----------------------------------------------------------------------------+
*/
                       if ( VGA_PRESENT )    /* For Device Chaining J-KKJ */
                            (USHORT far *)ChainedCallVectorTable[j] =
                                Parm2->CallVectorTable[i];
/*
 +----------------------------------------------------------------------------+
 |  Change the current entry in the call vector table                         |
 +----------------------------------------------------------------------------+
*/
                        Parm2->CallVectorTable[i] = VDHEntryPoint[j];
                    }
                }

// ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
// Ί Get Valid Code Page.                                          J-KK1002   Ί
// ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
                GetCodePage();      /*@C10*/
#ifdef  XVIO
              }
#endif
            }
        }
    }
    if ( rc ) {
        DosClose(hScreenDD);        /* @T5 */
    }
}

/*RestoreRegs();*/ /*@B14*/              /* Restore registers and flags */
return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: InitEnv                                            */
/*                                                                      */
/*  DESCRIPTIVE NAME: Initialize environment                            */
/*                                                                      */
/*  FUNCTION: InitEnv is called by BVS to initialize the video          */
/*            environment during the creation of a new session.  This   */
/*            includes initializing the adapter hardware and/or the     */
/*            environment buffer.                                       */
/*                                                                      */
/*  ENTRY POINT: InitEnv                                                */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 257 )   */
/*                                                                      */
/*  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                */
/*             ULONG Function ( Call vector table entry = 257 )         */
/*         (Referenced)                                                 */
/*             Modes[] (global data - table of supported video modes )  */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Environment buffer is initialized                      */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: If requested, display adapter hardware is initialized to   */
/*           highest resolution mode supported.                         */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: SetHWMode, SetEnvMode                                   */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY InitEnv( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_INITENV far *ParmBlock;
ULONG Function;
{
USHORT rc,
       SaveFlags,    /*J-KKJ*/
       i, j;
COUNTRYCODE CCode;          /* Country Code */                      /*J-KK0821*/

#ifdef  XVIO
USHORT         xrc;                                                 /*J-KK0822*/
XVS_INITIALIZE Xvio;                                                /*J-KK0804*/
XVS_SUSPEND    XvioSusp;                                            /*J-KK0822*/
XVS_RESUME     XvioResm;                                            /*J-KK0822*/
XVS_SETMODE    XvioMode;                                            /*J-KK0822*/
XVS_SETCP      XvioCP;
XVS_SETSTATE   XvioState;                                           /*J-KK0928*/
#endif

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

rc = ERROR_VIO_INVALID_PARMS;                          /* Initialize to error */

if ( ( Function == FnInitializeEnvironment )        && /* Valid function request */
     ( ParmBlock->Length >= sizeof( VDH_INITENV ) ) && /* Valid packet length */
     ( ParmBlock->Flags  <= VALID_INITENV_FLAG )    && /* Valid flags         */
     SEG( Environment ) ) {                            /* Environment passed  */

  rc = NO_ERROR;                                /* Initialize no error */

//--------------------------------------------
// Initialize VGA text emulation video buffer
//--------------------------------------------
  InitVideoBuff();                                                      //J-TS00

//--------------------------------------------
// Initialize mouse pointer draw device driver
//--------------------------------------------
  InitPointer(ParmBlock->SessionNum & 0x000F);                          //J-TS00

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Initialize BvscbSel                                         J-KK1127      Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
//@2KK0531  BvscbSel[ParmBlock->SessionNum] = 0;
     Environment->SessionNum = ParmBlock->SessionNum & 0x000F;        //@2KK0531
     BvscbSel[Environment->SessionNum] = 0;                           //@2KK0531

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Set Environment Buffer ID                                   J-KK1120      Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
  Environment->EnvBuffID = 0x4C4C5546L;  // "FULL"

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Get Seesion Number                                          J-KK0925      Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
//@2KK0531  Environment->SessionNum = ParmBlock->SessionNum;             /*J-KK0925*/

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Initialize LVB Selector                                     J-KK1026      Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
  Environment->LVB_Selector = 0;                               //J-KK1026

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Initialize First_Grid_Color Field                           J-KK0119      Ί
//Ί   This field is used at only Epoch Mono Mode.                             Ί
//Ί   When VioSetState ( Grid Color Set ) is called in Epoch Mono Mode,       Ί
//Ί   this field becomes FALSE.                                               Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
  Environment->First_Grid_Color = TRUE;                        //J-KK0119

#ifdef  XVIO
//-----------------------------------------------------------------
// BXVS Call Initialize
//-----------------------------------------------------------------
  Xvio.Length    = sizeof(Xvio);
  Xvio.Reserve   = NoOption;                                        //@XVIO
  Xvio.Session   = (UCHAR)Environment->SessionNum;                  /*J-KK0926*/
  Xvio.CommonSel = CommonSelector;                                  /*J-KK0929*/
  Xvio.Option    = XVS_Always_CallFNT;                              /*J-KK1005*/
  rc = XVIOVDHIF( XvsInitialize, (PUSHORT)&Xvio);
  if ( rc ) {                                     // Error !!!         J-KK0122
     rc = ERROR_VIO_INTERNAL_RESOURCE;            //                   J-KK0122
     return( rc );                                //                   J-KK0122
  } /* endif */                                   //                   J-KK0122
#endif

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Get Environment Flags                                                     Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
  Environment->EnvFlags = DEFAULT_ENVFLAGS;     /*D198*/
  if ( ParmBlock->Flags & INITENV_3xBOX ) {     /*D198*/             /* @B6 */
      Environment->EnvFlags |= ENVFLAG_3xBOX;   /*D198*/
  }

// Check Process Code Page by DBCSEv vector.                          J-KK0821
//  If CP = SBCS, then Initialize Environment by SBCS & Enable VGA
//                else DBCS & VGA2.

  CCode.country = CCode.codepage = 0;                               /*J-KK0822*/
  rc = DosGetDBCSEv( DBCSEvBuffSize,                                /*J-KK0822*/
                     (COUNTRYCODE far *)&CCode,                     /*J-KK0822*/
            (unsigned char far *)&Environment->DBCSEvBuff[0]);      //J-KK1017

/*
 +----------------------------------------------------------------------------+
 |  If VDHVGA.DLL has been successfully installed, call InitEnv in VDHVGA.DLL |
 |  Otherwise, initialize to an 8514/A graphics mode and hope for the best    |
 +----------------------------------------------------------------------------+
*/

  FIRST_RETCONFIG = FALSE;          /* Flag Off: RetConfig is Not First J-KKJ*/

  Environment->NATIVE_MODE = TRUE;

  if (( Environment->DBCSEvBuff[0] == 0) &&                         //J-KK1017
      ( Environment->DBCSEvBuff[1] == 0) &&                         //J-KK1017
        VGA_PRESENT ) {                                             /*J-KK0822*/

           /* Process CP=SBCS */

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

    Environment->NATIVE_MODE = FALSE; /* To VGA Mode *              /*J-KK0821*/

    rc = ChainedVDHInitEnv(                                         /*J-KK0821*/
                (ENVIRONMENT far *)&Environment->VGAEnvironment,    /*J-KK0821*/
                            ParmBlock, Function );                  /*J-KK0821*/

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0822*/
// BXVS Call SetMode ( U.S. Video Mode )                            /*J-KK0822*/
//------------------------------------------------------------------/*J-KK0822*/
    XvioMode.Length    = sizeof(XvioMode);                          /*J-KK0822*/
    XvioMode.Option    = Resume;
    if ( ParmBlock->Flags & UPDATE_HARDWARE )                       //J-KK0213
      XvioMode.Option |= FG_Session;                                //J-KK0213
    XvioMode.HWMode    = -1;                                        /*J-KK0822*/
    XvioMode.Session   = (UCHAR)Environment->SessionNum;            /*J-KK0926*/
    xrc = XVIOVDHIF( XvsSetMode, (PUSHORT)&XvioMode);               /*J-KK0822*/
#endif

  } else {  /* Process CP=DBCS */                                   /*J-KK0821*/

    if ( !( ParmBlock->Flags & INITENV_3xBOX ) &&   // Not 3xBox    //J-KK1023
            VGA_PRESENT ) {                                         //J-KK1023

      SaveFlags = ParmBlock->Flags;                 /*??? Save Flags  J-KKJ*/
      ParmBlock->Flags &= ~(USHORT)UPDATE_HARDWARE; /*??? Reset Flags J-KK0206*/

      rc = ChainedVDHInitEnv( (ENVIRONMENT far *)&Environment->VGAEnvironment,
                              ParmBlock, Function );

      ParmBlock->Flags = SaveFlags;                 /*??? Restore Flags J-KKJ*/

    } /* Initialize for VDHVGA J-KKJ1*/

  } /* For DBCS/SBCS CP Handling */                                 /*J-KK0821*/

/*
 +----------------------------------------------------------------------------+
 |  Initialize 1st word in environment buf to point to VioSetMode structure   |
 |  ( This offset is relative to the begining of the environment buffer )     |
 +----------------------------------------------------------------------------+
*/
  Environment->ModeDataOFF = OFFSET( Environment->ModeData ) -
                             OFFSET( Environment->ModeDataOFF );

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί Initialize code page ID & option in Japan Unique struct.                  Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
  if ( ParmBlock->Flags & INITENV_3xBOX ) {       // 3xBox           //J-KK1023
            Environment->CodePageID = 932;        // Always CP = 932 //J-KK1023
            Environment->Option = 0;              // Initialize      //J-KK0111
  } else {                                        // Not 3xBox       //J-KK1023

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Initialize JapamDataArea.FormatChanged Arae                         J-KK  Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
    Environment->FormatChanged = FALSE;                             //J-KK1017

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Set JapanDataArea.Option                                         J-KK1005 Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
// Default meaning of Attribute MSB for Atlas Text mode is Blinking.

    Environment->Option = Blink_State + Always_FNTCall ;            /*J-KK1005*/

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Get Current Process CodePage                                    .   J-KK  Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ

    DosGetCp( 0x2, (PUSHORT)&Environment->CodePageID, (PUSHORT)&i );  /*J-KK0822*/

  }                                               // Not 3xBox      //J-KK1023

#ifdef  XVIO
//------------------------------------------------------------------/*J-KK0822*/
// BXVS Call SetCP                                                  /*J-KK0822*/
//------------------------------------------------------------------/*J-KK0822*/
  XvioCP.Length   = sizeof(XvioCP);
  XvioCP.Option   = Suspend+Resume;
  XvioCP.CodePage = Environment->CodePageID;
  XvioCP.Session  = (UCHAR)Environment->SessionNum;                 /*J-KK0926*/
  xrc = XVIOVDHIF( XvsSetCP , (PUSHORT)&XvioCP );
#endif

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Initialize Configuaration Data                              J-KKJ         Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ

  Environment->DisplayType     = VideoHardware.display;                 //J-TS00
  Environment->DisplayAdapter  = TYPE_VGA;                              //J-TS00
  Environment->MemorySize      = VideoHardware.memory;                  //J-TS00
  Environment->PartialSaveSize = 80 * 25 * 2;                           //J-TS00
  Environment->MaxFullSaveSize = 38400 * 4;                             //J-TS00

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Initialize User Font Flag.                                       J-KK1002 Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ

  Environment->UserFont        = 0;            /* None of User Font */

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Initialize Misc Values for VDHINFO.                         J-KKJ         Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ

   Environment->Overscan = 0;                                  /*J-KKJ*/
   Environment->Underscore = 0;                                /*J-KKJ*/
   Environment->VideoEnable = 0;                               /*J-KKJ*/

/*
 +----------------------------------------------------------------------------+
 |  Initialize video mode to highest resolution 80x25 color text supported    |
 +----------------------------------------------------------------------------+
*/
  SetEnvMode( VideoHardware.popupMode, /* Initialize mode data structure  @T39*/
              Environment, (ENVIRONMENT far *)NULL, 1 );                /*@T70*/
/*
 +----------------------------------------------------------------------------+
 |  Shadow cursor attribute outside of register shadow - register contains    |
 |  one bit indicating hidden or visible.  Use this to retrieve exact non -1  |
 |  cursor attribute ( cursor attribute: -1 = hidden, other = non-hidden )    |
 +----------------------------------------------------------------------------+
*/
  Environment->CursorAttribute = 0;                             /* Not hidden */

/*
 +----------------------------------------------------------------------------+
 |  For VGA, the Screen Off bit (b5) of the Miscellaneous Output Register     |
 |  is used to enable/disable the video signal.  For all other adapters, the  |
 |  Attribute registers are used and a query references this shadow           |
 +----------------------------------------------------------------------------+
  @C21  Use Attribute regs for all including VGA
*/
  Environment->VideoEnable = 1;                                   /* Enabled */

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Special Handling for EPOCH Mono Text Mode                      J-KK0905   Ί
//Ί   Store Default FG and FGH Color Data                                      Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ

    Environment->Hardware.Fore_Color = 0x02;                            //J-TS00
    Environment->Hardware.Fore_Int   = 0x3f;                            //J-TS00

/*
 +----------------------------------------------------------------------------+
 |  Initialize mode to highest resolution 80x25 color text                    |
 |           ( This includes the setting of the appropriate ROM font )        |
 |  If foreground, SetHWMode will set the hardware. By passing the            |
 |  environment, SetHWMode will shadow also shadow the registers.             |
 +----------------------------------------------------------------------------+
*/

  if (( Environment->DBCSEvBuff[0] == 0) &&                         //J-KK1017
      ( Environment->DBCSEvBuff[1] == 0) &&                         //J-KK1017
        VGA_PRESENT ) {                                             /*J-KK0822*/
           /* Process CP=SBCS */                                    /*J-KK0821*/

    SaveFlags = ParmBlock->Flags;                  /* Save Flags */ /*J-KK0821*/
    ParmBlock->Flags &= ~(USHORT)UPDATE_HARDWARE;  /* Reset Flags *//*J-KK0206*/
    SetHWMode( VideoHardware.popupMode, ParmBlock->Flags, Environment ); /*@T39*/
    ParmBlock->Flags = SaveFlags;                 /* Restore Flags*//*J-KK0821*/

  } else {   /* Process CP=DBCS */                                  /*J-KK0821*/

    SetHWMode( VideoHardware.popupMode, ParmBlock->Flags, Environment ); /*@T39*/

  }

/*
 +----------------------------------------------------------------------------+
 |  Initialize the scrollable text region of the screen.                @P1   |
 |  Note that in all cases the entire screen is the scrollable region.  @P1   |
 +----------------------------------------------------------------------------+
*/
  Environment->ScrollRect.Left = 0;                             /*      @P1 */
  Environment->ScrollRect.Top = 0;                              /*      @P1 */
  Environment->ScrollRect.Right = Environment->ModeData.col - 1; /*     @P1 */
  Environment->ScrollRect.Bottom = Environment->ModeData.row - 1; /*    @P1 */
  Environment->AttrBufSize = 1;                                 /*      @P1 */
  Environment->AttrBuf[0] = DefaultAttribute[0];                /*      @P1 */
  Environment->AttrBuf[1] = DefaultAttribute[1];                /*      @P1 */
  Environment->AttrBuf[2] = DefaultAttribute[2];                /*      @P1 */

#ifdef  XVIO
//-----------------------------------------------------------------   J-KK0928
// BXVS Call SetState
//-----------------------------------------------------------------
  XvioState.Length    = sizeof(XvioState);
  XvioState.Option    = Suspend+Resume;
  XvioState.BlinkHInt = (Environment->Option & Blink_State) ? 0 : 1;  //J-KK1017
  XvioState.NonScrRow = Environment->ModeData.row -
                        Environment->ScrollRect.Bottom - 1 ;
  XvioState.NonScrCol = Environment->ScrollRect.Right;
  XvioState.Session   = (UCHAR)Environment->SessionNum;
  xrc = XVIOVDHIF( XvsSetState, (PUSHORT)&XvioState );
#endif

}

/*RestoreRegs();*/ /*@B14*/             /* Restore registers and flags */
return( rc );
}

/**********************  START OF SPECIFICATIONS  **********************/
/*                                                                     */
/*  SUBROUTINE NAME: SaveEnv                                           */
/*                                                                     */
/*  DESCRIPTIVE NAME: Save environment                                 */
/*                                                                     */
/*  FUNCTION: SaveEnv is called by BVS prior to a screen switch        */
/*            in order to preserve the display adapter hardware state  */
/*            and/or the full or partial display buffer.               */
/*                                                                     */
/*  ENTRY POINT: SaveEnv                                               */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 258 )  */
/*                                                                     */
/*  INPUT: (Passed on stack)                                           */
/*             FAR *Environment ( Environment buffer for the session ) */
/*             FAR *ParmBlock                                          */
/*                     USHORT Length = length of this packet           */
/*                     USHORT Flags  = 2 - Hardware state              */
/*                                     4 - Full display buffer         */
/*                                     8 - Partial display buffer      */
/*                     USHORT PVBHugeSEL = 1st huge selector for PVB   */
/*             ULONG Function ( Call vector table entry = 258 )        */
/*                                                                     */
/*  EXIT-NORMAL: AX = 0                                                */
/*               Hardware state and/or display buffer is saved in      */
/*                 environment buffer                                  */
/*                                                                     */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                           */
/*                                                                     */
/*  EFFECTS: If 3xBox save, the BIOS data area for video is either     */
/*           referenced or modified to reflect the current state.      */
/*                                                                     */
/*  INTERNAL REFERENCES:                                               */
/*    ROUTINES: NONE                                                   */
/*                                                                     */
/*  EXTERNAL REFERENCES:                                               */
/*    ROUTINES: BIOSData, SaveRestorePVB, SaveRestoreHW                */
/*                                                                     */
/***********************  END OF SPECIFICATIONS  ***********************/
USHORT EXPENTRY SaveEnv( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_SAVEREST far *ParmBlock;
ULONG Function;
{
USHORT     rc,
           EnvBufferPassed;
REGDATA    RegData;
REGADDRESS RegAddress;
ULONG      BufSize;
USHORT     SaveFlag;                                                    //J-TS00V

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

/*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                 ) {                                   /*J-KKJ*/
                                                             /* VGA Mode J-KKJ*/
    SaveFlag = ParmBlock->Flags;                                        //J-TS00V
    if ( ParmBlock->Flags & SAVEREST_PARTPVB ) {                        //J-TS00V
        ParmBlock->Flags &= ~SAVEREST_PARTPVB;                          //J-TS00V
        ParmBlock->Flags |=  SAVEREST_FULLPVB;                          //J-TS00V
    }                                                                   //J-TS00V
    rc = ChainedVDHSaveEnv( (ENVIRONMENT far *)&Environment->VGAEnvironment,
                            ParmBlock, Function              );        /*J-KKJ*/
                                                                       /*J-KKJ*/
    ParmBlock->Flags = SaveFlag;                                        //J-TS00V

} else {                                                /* ATLAS Mode    J-KKJ*/

if ( ( Function == FnSaveEnvironment ) &&               /* Valid function request */
     ( ParmBlock->Length >= MinSLen_SaveRestoreEnv ) && /* Valid packet length */
       ParmBlock->Flags                          &&     /* An option specified */
    !( ParmBlock->Flags & ~VALID_SAVEREST_FLAG ) &&     /* No illegal options  */
    !( ( ParmBlock->Flags & SAVEREST_FULLPVB )   &&
       ( ParmBlock->Flags & SAVEREST_PARTPVB ) ) &&      /* Not part and full   */
    !( ( ParmBlock->Length < sizeof( VDH_SAVEREST ) ) && /* PVB and no selector */
       ( ParmBlock->Flags & (SAVEREST_FULLPVB+SAVEREST_PARTPVB) ) ) &&
     EnvBufferPassed ) {

#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

  rc = NO_ERROR;                                       /* Initialize no error */

  if ( ParmBlock->Flags & SAVEREST_HARDWARE ) {
/*
 +----------------------------------------------------------------------------+
 |  If hardware is not write-only, read it and copy to the env buffer         |
 |    and, if 3xBox being saved, to the BIOS data area                        |
 |  Otherwise, if 3xBox being saved, copy info from BIOS data area            |
 |    to the environment buffer                                               |
 +----------------------------------------------------------------------------+
*/

/*
 +----------------------------------------------------------------------------+
 |  Read registers into environment buffer                                    |
 +----------------------------------------------------------------------------+
*/
    SaveRestoreHW( Environment, GET );

#ifdef  XVIO                                                        //J-EA44
//------------------------------------------------------------------/*J-EA44*/
// BXVS Call HIDE                                                   /*J-EA44*/
//------------------------------------------------------------------/*J-EA44*/
  XvioHide.Length   = sizeof(XvioHide);                             //J-EA44
  XvioHide.Option   = NoOption;                                     //J-KKB19
  XvioHide.Session  = (UCHAR)Environment->SessionNum;               //J-EA44
  XvioHide.StartRow = 0;                                            //J-EA44
  XvioHide.EndRow   = ( Environment->SessionNum == 2 ) ?  // For Real Mode  //J-EA44
                        Environment->ScrollRect.Bottom : -1;        //J-EA44
  xrc = XVIOVDHIF( XvsHide, (PUSHORT)&XvioHide );                   //J-EA44
#endif                                                              //J-EA44

  }


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

  }

}       /* VGA Mode J-KKJ*/

/*RestoreRegs();*/ /*@B14*/              /* Restore registers and flags */
return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: RestoreEnv                                         */
/*                                                                      */
/*  DESCRIPTIVE NAME: Restore environment                               */
/*                                                                      */
/*  FUNCTION: RestoreEnv is called by BVS following a screen switch     */
/*            in order to restore the display adapter hardware state    */
/*            and/or the full or partial display buffer.                */
/*                                                                      */
/*  ENTRY POINT: RestoreEnv                                             */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 259 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = 2 - Hardware state               */
/*                                     4 - Full display buffer          */
/*                                     8 - Partial display buffer       */
/*                     USHORT PVBHugeSEL = 1st huge selector for PVB    */
/*             ULONG Function ( Call vector table entry = 259 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Hardware state and/or display buffer is restored       */
/*                 using info from environment buffer.                  */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: If 3xBox save, the BIOS data area for video is             */
/*           modified to reflect the current state.                     */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: BIOSData, SaveRestorePVB, SaveRestoreHW                 */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY RestoreEnv( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_SAVEREST far *ParmBlock;
ULONG Function;
{
USHORT rc,
       VideoState,                                                      /*@C21*/
       VideoOn,                                                         /*@C21*/
       ColorMode,                                                       /*@C21*/
       EnvBufferPassed;
USHORT SaveFlag;                                                        //J-TS00V

#ifdef  XVIO
USHORT      xrc;                                                    /*J-KK1114*/
XVS_SUSPEND XvioSusp;                                               /*J-KK1114*/
XVS_RESUME  XvioResm;                                               /*J-KK1114*/
XVS_REDRAW  XvioRedraw;                                             /*J-KK1128*/
XVS_SETMODE XvioMode;                                               /*@KK0529*/
#endif

/*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               ) {                                     /*J-KKJ*/
                                                       /* VGA Mode */  /*J-KKJ*/
#ifdef  XVIO
//------------------------------------------------------------------//@KK0529
// BXVS Call SetMode ( U.S. Video Mode )                            //@KK0529
//------------------------------------------------------------------//@KK0529
  XvioMode.Length    = sizeof(XvioMode);                            //@KK0529
  XvioMode.Option    = Suspend+Resume;                              //@KK0529
  if ( ParmBlock->Flags & SAVEREST_HARDWARE )                       //@KK0529
    XvioMode.Option |= FG_Session;                                  //@KK0529
  XvioMode.HWMode    = -1;                                          //@KK0529
  XvioMode.Session   = (UCHAR)Environment->SessionNum;              //@KK0529
  xrc = XVIOVDHIF( XvsSetMode, (PUSHORT)&XvioMode );                //@KK0529
#endif

  SaveFlag = ParmBlock->Flags;                                          //J-TS00V
  if ( ParmBlock->Flags & SAVEREST_PARTPVB ) {                          //J-TS00V
      ParmBlock->Flags &= ~SAVEREST_PARTPVB;                            //J-TS00V
      ParmBlock->Flags |=  SAVEREST_FULLPVB;                            //J-TS00V
  }                                                                     //J-TS00V
  rc = ChainedVDHRestoreEnv(                                           /*J-KKJ*/
                    (ENVIRONMENT far *)&Environment->VGAEnvironment,   /*J-KKJ*/
                     ParmBlock, Function );                            /*J-KKJ*/
  ParmBlock->Flags = SaveFlag;                                          //J-TS00V
                                                                       /*J-KKJ*/
} else {                                               /* ATLAS Mode *//*J-KKJ*/

if ( ( Function == FnRestoreEnvironment ) &&            /* Valid function request */
     ( ParmBlock->Length >= MinSLen_SaveRestoreEnv ) && /* Valid packet length */
       ParmBlock->Flags                          &&     /* An option specified */
    !( ParmBlock->Flags & ~VALID_SAVEREST_FLAG ) &&     /* No illegal options  */
    !( ( ParmBlock->Flags & SAVEREST_FULLPVB )   &&
       ( ParmBlock->Flags & SAVEREST_PARTPVB ) ) &&      /* Not part and full   */
    !( ( ParmBlock->Length < sizeof( VDH_SAVEREST ) ) && /* PVB and no selector */
       ( ParmBlock->Flags & (SAVEREST_FULLPVB+SAVEREST_PARTPVB) ) ) &&
     EnvBufferPassed ) {

  rc = NO_ERROR;                                       /* Initialize no error */

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

/*
 +----------------------------------------------------------------------------+
 |  Turn off the Video Signal                                             @C21|
 +----------------------------------------------------------------------------+
*/
  VideoState = Environment->VideoEnable;                                /*@C21*/
  Environment->VideoEnable = 0;                                         /*@C21*/

  ColorMode = HardwareColor();        /* color/mono mode               @C21*/
  VideoOn = 0;                                                          /*@C21*/
  AccessVideoEnable( ColorMode, SET, &VideoOn );                        /*@C21*/

//ΙΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝ»
//Ί  Notify FNTCALL of changing Session.                             J-KK0206  Ί
//ΘΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΝΌ
    rc = FNTCHGSG( Environment->SessionNum, FNT_SCREEN_GROUP_OLD );

  if ( ParmBlock->Flags & SAVEREST_HARDWARE )
/*
 +----------------------------------------------------------------------------+
 |  Output environment buffer to registers                                    |
 +----------------------------------------------------------------------------+
*/
    SaveRestoreHW( Environment, SET );

  if ( ParmBlock->Flags & ( SAVEREST_FULLPVB | SAVEREST_PARTPVB ) )
/*
 +----------------------------------------------------------------------------+
 |  Restore partial or full display buffer                                    |
 +----------------------------------------------------------------------------+
*/
//---------------------------------------------------------------------/*J-KKJ*/
// In OS/2-J, PVB is restored from LVB.                                /*J-KKJ*/
//---------------------------------------------------------------------/*J-KKJ*/
         rc = RestoreLVB( ParmBlock, Environment );                    /*J-KKJ*/

/*
 +----------------------------------------------------------------------------+
 |  Turn the Video Signal ON if it was on previously                      @C21|
 +----------------------------------------------------------------------------+
*/
  if ( VideoState ) {                                                   /*@C21*/
     AccessVideoEnable( ColorMode, SET, &VideoState );                  /*@C21*/
     Environment->VideoEnable = 1;                                      /*@C21*/
  }                                                                     /*@C21*/

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

  }

}               /* VGA Mode J-KKJ*/

/*RestoreRegs();*/ /*@B14*/              /* Restore registers and flags */
return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: RetConfigInfo                                      */
/*                                                                      */
/*  DESCRIPTIVE NAME: Return video adapter configuration information    */
/*                                                                      */
/*  FUNCTION: RetConfigInfo is called by BVS to identify the current    */
/*            display adapter.                                          */
/*                                                                      */
/*  ENTRY POINT: RetConfigInfo                                          */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 260 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = 0 ( reserved )                   */
/*                     FAR *ConfigData = VioGetConfig structure         */
/*             ULONG Function ( Call vector table entry = 260 )         */
/*         (Referenced)                                                 */
/*                                                                      */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               Configuration data is returned to caller               */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: If the length of ConfigData does not exactly fit a         */
/*           parameter, the length is adjusted and returned.            */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY RetConfigInfo( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_CONFIG far *ParmBlock;
ULONG Function;
{
USHORT rc,workvar;

VDHCONFIGINFO far *pReqConfig;          /* Reduce level of indirection, @S8 */
unsigned register ReqConfigLen;         /* Eliminate segment loading, @S8 */

USHORT EnvComplete;             /*J-KKJ*/
USHORT EnvSize;                 //J-KK1120
VDH_CONFIG    ParmBlockVGA;                                             //J-TS00
static VDHCONFIGINFO ReqConfigVGA;                                      //J-TS00
USHORT VGAOrgConf = FALSE;                                              //J-TS00

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

rc = ERROR_VIO_INVALID_PARMS;                         /* Initialize to error    */

//-------------------------------------------------------------------------
// Check Environment Buffer Size
// Environment Buffer Size is Enough ?
//
//         The logic to check if the environment buffer has been
//         initialized as follows.
//
//          1) Environment Buffer must have an enough size.
//          2) EnvBuffID must be "FULL".
//          3) ModeDataOFF must be a correct value.
//
//-------------------------------------------------------------------------

if ((EnvSize=GetLimit(SEG(Environment)))
                >= sizeof(ENVIRONMENT)-1 &&    // Enough Size        @IDS
    Environment->EnvBuffID == 0x4C4C5546L &&   // ID == "FULL"       @KK0406
    Environment->ModeDataOFF ==                // Offset is matched. @KK0406
     (OFFSET( Environment->ModeData)-OFFSET(Environment->ModeDataOFF)) ) //@KK0406

      EnvComplete = TRUE;                                           /*J-KK0908*/
else                                                                /*J-KK0908*/
      EnvComplete = FALSE;                                          /*J-KK0908*/

#ifdef  J_INSTALL                                                       //J-TS00V
      EnvComplete = FALSE;                                              //J-TS00V
#endif  //J_INSTALL                                                     //J-TS00V

//------------------------------------------------------------------
// Check whitch VDH must return the configuration information
//------------------------------------------------------------------

if ( !FIRST_RETCONFIG &&    /* First Entry to this routine */       /*J-KKJ*/
     VGA_PRESENT &&                                                 /*J-KKJ*/
     SEG( Environment ) &&                                          /*J-KKJ*/
     EnvComplete &&         /* Environment Enough Size */           /*J-KK0908*/
     !Environment->NATIVE_MODE ) {                                  /*J-KKJ*/

  ReqConfigLen = ParmBlock->ConfigDataPTR->cb;      // Save Request Cb  J-KK1019

  rc = ChainedVDHRetConfigInfo(                                      /*J-KKJ*/
                    (ENVIRONMENT far *)&Environment->VGAEnvironment, /*J-KKJ*/
                    ParmBlock, Function );                           /*J-KKJ*/

  if ( !rc &&                                       // No Error        J-KK1019
//J-TS100391       ( ReqConfigLen != Config_Return_Length )) {  // Req. Cb Not 2   J-KK1019
        ( ReqConfigLen >= MinDLen_Config_HWBufLen )) { // Length>=HWBUfLen //J-TS100391
    ParmBlock->ConfigDataPTR->HWBufferSize += sizeof( ENVIRONMENT ); /*J-KKJ*/
  } /* endif */                                     //                 J-KK1019

} else {

  if ( ( Function == FnReturnConfigInfo )            && /* Valid function request */
       ( ParmBlock->Length >= sizeof( VDH_CONFIG ) ) && /* Valid packet length    */
       ( !ParmBlock->Flags ) ) {                        /* Valid flags            */

    rc = NO_ERROR;                                       /* Initialize no error */

    ReqConfigLen = (pReqConfig = ParmBlock->ConfigDataPTR)->cb; /*@S8*/

    if ( ReqConfigLen > sizeof(VDHCONFIGINFO) ) { /*@S25*/
       ReqConfigLen = MinDLen_Config_Memory;      /*@S25*/
    }                                             /*@S25*/

    if ( ( ReqConfigLen < MinDLen_Config_Adapter ) &&  /* @@A */
         ( ReqConfigLen != Config_Return_Length ) )    /* @@A */
       rc = ERROR_VIO_INVALID_LENGTH;                                  /* @@A */

/*
 +----------------------------------------------------------------------------+
 |  Structure length of 2 means set structure length and return               |
 +----------------------------------------------------------------------------+
*/
    else if ( ReqConfigLen == Config_Return_Length )
      ReqConfigLen = sizeof( VDHCONFIGINFO );

    else {
                /*                                   */                 //J-TS00
                /* Get BVHVGA, BVHSVGA configuration */                 //J-TS00
                /*                                   */                 //J-TS00
        if ( VGA_PRESENT && SVGAPresent ) {                             //J-TS00
            ParmBlockVGA.Length        = sizeof(VDH_CONFIG);            //J-TS00
            ParmBlockVGA.Flags         = 0;                             //J-TS00
            ParmBlockVGA.ConfigDataPTR = &ReqConfigVGA;                 //J-TS00
            ReqConfigVGA.cb            = sizeof(VDHCONFIGINFO);         //J-TS00
            rc = ChainedVDHRetConfigInfo(                               //J-TS00
                    NULL, &ParmBlockVGA, FnReturnConfigInfo );          //J-TS00
            if (!rc)                                                    //J-TS00
                VGAOrgConf = TRUE;                                      //J-TS00
        }                                                               //J-TS00
/*
 +----------------------------------------------------------------------------+
 |  Adapter types:                                                            |
 |                 0 - MPA                   4 - IBM Japan G                  |
 |                 1 - CGA                   5 - IBM Japan H                  |
 |                 2 - EGA                   6 - IBM Japan ST                 |
 |                 3 - VGA or PS/2 adapter   7 - 8514/A                       |
 +----------------------------------------------------------------------------+
*/

#ifdef  J_INSTALL                                                       //J-TS00V
      pReqConfig->adapter = (VideoHardwareJ.Display == NoDisplay) ?     //J-TS00V
                            TYPE_VGA : TYPE_ATLAS;                      //J-TS00V
#else   //J_INSTALL                                                     //J-TS00V
      pReqConfig->adapter = ( EnvComplete ) ?                       /*J-KK0825*/
                    Environment->DisplayAdapter : TYPE_VGA;         /*J-KK0825*/ //J-TS00
#endif  //J_INSTALL                                                     //J-TS00V

      if ( ReqConfigLen < MinDLen_Config_Display )
        ReqConfigLen = MinDLen_Config_Adapter;
      else {
/*
 +----------------------------------------------------------------------------+
 |  Display types:                                                            |
 |                 0 - 5151 mono             5 - IBM Japan 5550 mono          |
 |                 1 - 5153 color            6 - IBM Japan 5550 color         |
 |                 2 - 5154 enhanced         7 - IBM Japan 5570 color         |
 |                 3 - 8503 mono             8 - IBM Japan 5570 full page     |
 |                 4 - 8512/8513 color       9 - 8514 color                   |
 +----------------------------------------------------------------------------+
*/
        pReqConfig->display = ( EnvComplete ) ?                       /*J-KK0825*/
                                Environment->DisplayType :            /*J-KK0825*/
                                VideoHardware.display;                //J-TS00

        if ( ReqConfigLen < MinDLen_Config_Memory )
          ReqConfigLen = MinDLen_Config_Display;
        else {
/*
 +----------------------------------------------------------------------------+
 |  Video memory size:                                                        |
 |    VGA or PS/2 adapter:  256k                                              |
 |    EGA:                  64k, 128k, 192k, 256k                             |
 |    CGA:                  64k                                               |
 |    MPA:                  4k                                                |
 |    8514/A:               512k, 1MB                                         |
 +----------------------------------------------------------------------------+
*/
          pReqConfig->cbMemory = ( EnvComplete ) ?                    /*J-KK0825*/
                                   Environment->MemorySize :          /*J-KK0825*/
                                   VideoHardware.memory;              //J-TS00

          if (VGAOrgConf &&                                             //J-TS00
              (pReqConfig->cbMemory < ReqConfigVGA.cbMemory))           //J-TS00
            pReqConfig->cbMemory = ReqConfigVGA.cbMemory;               //J-TS00

          if ( ReqConfigLen < MinDLen_Config_ConfigNum )
            ReqConfigLen = MinDLen_Config_Memory;
          else {
/*
 +----------------------------------------------------------------------------+
 |  Configuration number: always return unknown                               |
 +----------------------------------------------------------------------------+
*/
            pReqConfig->Configuration = UNKNOWN;

            if ( ReqConfigLen < MinDLen_Config_Version )
              ReqConfigLen = MinDLen_Config_ConfigNum;
            else {
/*
 +----------------------------------------------------------------------------+
 |  Video device driver version number                                        |
 +----------------------------------------------------------------------------+
*/
              pReqConfig->DeviceDriver = DeviceDriver;

              if ( ReqConfigLen < MinDLen_Config_Flag )
                ReqConfigLen = MinDLen_Config_Version;
              else {
/*
 +----------------------------------------------------------------------------+
 |  Configuration flag: xxxxxxxb  1 = Power-up display                        |
 +----------------------------------------------------------------------------+
*/
                pReqConfig->Flags = ConfigFlag;

                if ( ReqConfigLen < MinDLen_Config_HWBufLen )
                  ReqConfigLen = MinDLen_Config_Flag;
                else {
/*
 +----------------------------------------------------------------------------+
 |  Size of hardware state buffer                                             |
 +----------------------------------------------------------------------------+
*/
                  pReqConfig->HWBufferSize = sizeof( ENVIRONMENT );

/*
 +----------------------------------------------------------------------------+
 |  If the VDHVGA is there, allocate enough room to tack its environment      |
 |  buffer onto the end of the VDH8514A environment buffer.                   |
 +----------------------------------------------------------------------------+
*/
                  if ( VGA_PRESENT )
                    pReqConfig->HWBufferSize += VGAConfigData.HWBufferSize;


                  if ( ReqConfigLen < MinDLen_Config_FullSaveSz )
                    ReqConfigLen = MinDLen_Config_HWBufLen;
                  else {
/*
 +----------------------------------------------------------------------------+
 |  Size of entire physical display buffer for the current mode (page 0 only) |
 +----------------------------------------------------------------------------+
*/
                    pReqConfig->FullSaveSize =  ( EnvComplete ) ?     /*J-KK0825*/
                        Environment->MaxFullSaveSize :                /*J-KK0825*/
                        38400L * 4L;              /* VGA mode 12 */   //J-TS00

                    if (VGAOrgConf &&                                               //J-TS00
                        (pReqConfig->FullSaveSize < ReqConfigVGA.FullSaveSize))     //J-TS00
                        pReqConfig->FullSaveSize = ReqConfigVGA.FullSaveSize;       //J-TS00

                    if ( ReqConfigLen < MinDLen_Config_PartSaveSz )
                      ReqConfigLen = MinDLen_Config_FullSaveSz;
                    else {
/*
 +----------------------------------------------------------------------------+
 |  Size of entire physical display buffer for the popup mode (page 0 only)   |
 +----------------------------------------------------------------------------+
*/
                      pReqConfig->PartSaveSize =  ( EnvComplete ) ?     /*J-KK0825*/
                        Environment->PartialSaveSize : PartialSaveSize; /*J-KK0825*/

                      if (VGAOrgConf &&                                               //J-TS00
                          (pReqConfig->PartSaveSize < ReqConfigVGA.PartSaveSize))     //J-TS00
                          pReqConfig->PartSaveSize = ReqConfigVGA.PartSaveSize;       //J-TS00

                      if ( ReqConfigLen < MinDLen_Config_EMAdapter )
                        ReqConfigLen = MinDLen_Config_PartSaveSz;
                      else {
/*
 +----------------------------------------------------------------------------+
 |  Emulated adapter type and offset its offset in ConfigData structure       |
 +----------------------------------------------------------------------------+
*/
                        pReqConfig->EMAdaptersOFF =
                                OFFSET( pReqConfig->LEMAdapterdata ) -    /*@C33*/
                                OFFSET( pReqConfig->cb );

                                         /* length of Emulated adapter data @C33*/
                        pReqConfig->LEMAdapterdata = 1;                   /*@C33*/
/*
 +----------------------------------------------------------------------------+
 |  Emulated adapter types:                                                   |
 |              b0 - MPA adapter         b3 - VGA or PS/2 adapter             |
 |              b1 - CGA adapter         b7 - 8514/A adapter                  |
 |              b2 - EGA adapter                                              |
 +----------------------------------------------------------------------------+
*/

                        pReqConfig->EMAdapters = EMULATE_TYPE_VGA +     /*J-KKJ*/
                                                 EMULATE_TYPE_ATLAS ;   /*J-KKJ*/

                        if ( ReqConfigLen < MinDLen_Config_EMDisplay )
                          ReqConfigLen = MinDLen_Config_EMAdapter;
                        else {
/*
 +----------------------------------------------------------------------------+
 |  Emulated display type and offset its offset in ConfigData structure       |
 +----------------------------------------------------------------------------+
*/
                          pReqConfig->EMDisplaysOFF =
                                       OFFSET( pReqConfig->LEMDisplaydata ) - /*@C33*/
                                       OFFSET( pReqConfig->cb );

                                         /* length of Emulated display data @C33*/
                          pReqConfig->LEMDisplaydata = 1;               /*@C33*/
/*
 +----------------------------------------------------------------------------+
 |  Emulated display types:                                                   |
 |                b0 - 5151 mono            b3 - 8503 mono                    |
 |                b1 - 5153 color           b4 - 8512/8513 color              |
 |                b2 - 5154 enhanced        b9 - 8514 color                   |
 +----------------------------------------------------------------------------+
*/
                          pReqConfig->EMDisplays = EmDisp_VGA +         /*J-KKJ*/
                                                   EmDisp_Mono74 ;      //J-KK1106
                          if ( VideoHardware.display == Color8512_8513 )  //J-TS00
                            pReqConfig->EMDisplays += EmDisp_Colo74 ;   //J-KK1106

                          ReqConfigLen = MinDLen_Config_EMDisplay;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  if (!rc) {                              /*@S8*/
      pReqConfig->cb = ReqConfigLen;      /*@S8*/
  }                                       /*@S8*/

}                       /* VGA Mode J-KKJ*/

/*RestoreRegs();*/ /*@B14*/              /* Restore registers and flags */
return( rc );
}

#ifndef J_INSTALL                                                       //J-TS00
/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: GetPhysBuf                                         */
/*                                                                      */
/*  DESCRIPTIVE NAME: Get LDT selector to physical display buffer       */
/*                                                                      */
/*  FUNCTION: GetPhysBuf is called by BVS in order to obtain an LDT     */
/*            selector by which to address the display buffer           */
/*            corresponding to the current mode or the mode specified.  */
/*                                                                      */
/*  ENTRY POINT: GetPhysBuf                                             */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 275 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags                                     */
/*                     FAR *PhysBufData = VioGetPhysBuf structure       */
/*             ULONG Function ( Call vector table entry = 275 )         */
/*         (Referenced)                                                 */
/*             MemoryMaps[] (Table of memory map info for each mode)    */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               An LDT selector to the PVB is returned to caller       */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: NONE                                                       */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: PhysToUVirt                                             */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY GetPhysBuf( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_GETPVB far *ParmBlock;
ULONG Function;
{
USHORT rc,
       i,
       Mode,
       AmountAllocated,
       EnvBufferPassed;
ULONG  PVB_TOP, PVB_BOTTOM,
       PVBLen, NOT_ALLOCATED;
FarAddress PVB, Temp;                                                   /*@T30*/
ENVIRONMENT far *TempEnv;
SEL Selector;
USHORT far *ReturnDataArea;

USHORT return_alt_selectors;                                            /*@B29*/      /*@B29*/
USHORT use_ALT_VIOPHYSBUF;                                              /*@B29*/

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

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

 return_alt_selectors = FALSE;                                           /*@B29*/

 rc = ERROR_VIO_PTR;                                   /* LDTSelector not passed */

 if ( ( Function == FnGetPhysBuf )                  && /* Valid function request */
      ( ParmBlock->Length >= sizeof( VDH_GETPVB ) ) && /* Valid structure length */
      ( ParmBlock->Flags <= 1 ) ) {                    /* Valid flags            */

   EnvBufferPassed = SEG( Environment );               /* Non-zero = TRUE        */

   if ( ParmBlock->PVBDataPTR->cb == 0L && ParmBlock->PVBDataPTR->pBuf != 0L ) {

     rc = ERROR_VIO_INVALID_PARMS;                                      //J-TS00
     }
   else {
     if ( ParmBlock->PVBDataPTR->cb != 0L ) {
       PVBLen = ParmBlock->PVBDataPTR->cb;
       PVB_BOTTOM = (ULONG)(PVB.FullAddress = ParmBlock->PVBDataPTR->pBuf);
       PVB_TOP    = PVB_BOTTOM + PVBLen - 1L;

       if ( ( (PVB_BOTTOM >= MIN_PVB_BOTTOM)  && (PVB_TOP <= MAX_PVB_TOP)  )
         ) rc = NO_ERROR; /* This passes the A0000 to BFFFF text, say it's OK */
       else                                   /*@B68*/
           rc = ERROR_VIO_INVALID_PARMS;      /*@B68*/

 /*
  +----------------------------------------------------------------------------+
  |  Return selector list in the passed PhysBuf data structure                 |
  +----------------------------------------------------------------------------+
 */
       ReturnDataArea = (USHORT far *)&ParmBlock->PVBDataPTR->asel[0];
       }
     }

   use_ALT_VIOPHYSBUF = FALSE;                                           /*@B29*/
   if (ReturnDataArea == (USHORT far *)&(((ALT_VIOPHYSBUF far *)(ParmBlock->PVBDataPTR->pBuf))->asel[0])){ /*@B29*/
     use_ALT_VIOPHYSBUF = TRUE;                                          /*@B29*/
     }

   if ( !rc )
     for ( i = 0, NOT_ALLOCATED = PVBLen; NOT_ALLOCATED; i++ ) {
       if ( NOT_ALLOCATED > 0xFFFFL+1L ) {
         AmountAllocated = 0;                      /* Allocate maximum ( 64K ) */
         NOT_ALLOCATED -= 64L * 1024L;
         rc = PhysToUVirt( PVB, &Temp, AmountAllocated );        /*@B31*/
         PVB.part.Selector += 1;                                 /*@B31*/
         }
       else {
         AmountAllocated = (USHORT)NOT_ALLOCATED;         /* Allocate the rest */
         NOT_ALLOCATED = 0L;
         rc = PhysToUVirt( PVB, &Temp, AmountAllocated );        /*@B31*/
        }

    /* rc = PhysToUVirt( PVB, &Temp, AmountAllocated );  */              /*@T30*//*@B31*/
    /* ReturnDataArea[i] = Temp.part.Selector;*/ // BUGBUG -- JeffPar    /*@T30*//*@B29*/

       if (use_ALT_VIOPHYSBUF == TRUE){                                  /*@B29*/
         ((ALT_VIOPHYSBUF far *)(ParmBlock->PVBDataPTR->pBuf))->cb = ((2*(i+1))+2); /*@B28*/
         if (return_alt_selectors == TRUE)                               /*@B29*/
            ReturnDataArea[i] = Temp.part.Selector;                      /*@B29*/
       }                                                                 /*@B29*/
       else
         ReturnDataArea[i] = Temp.part.Selector;   // BUGBUG -- JeffPar    /*@T30*/

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

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: FreePhysBuf                                        */
/*                                                                      */
/*  DESCRIPTIVE NAME: Deallocate LDT selector                           */
/*                                                                      */
/*  FUNCTION: FreePhysBufe is called by BVS in order to deallocate an   */
/*            LDT selector which was previously used to address the     */
/*            physical display buffer.                                  */
/*                                                                      */
/*  ENTRY POINT: FreePhysBuf                                            */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 276 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = 0 ( reserved )                   */
/*                     USHORT LDTSelector = selector to deallocate      */
/*             ULONG Function ( Call vector table entry = 276 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               An LDT selector to the PVB is deallocated              */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: NONE                                                       */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: FreePhysToUVirt                                         */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY FreePhysBuf( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_FREEPVB far *ParmBlock;
ULONG Function;
{
USHORT rc;

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

if ( ( Function == FnFreePhysBuf )                  && /* Valid function request */
     ( ParmBlock->Length >= sizeof( VDH_FREEPVB ) ) && /* Valid structure length */
      !ParmBlock->Flags ) {                            /* Valid flags            */
  FreePhysToUVirt( ParmBlock->LDTSelector );
  rc = NO_ERROR;                                       /* Signal no error        */
  }
else
  rc = ERROR_VIO_INVALID_PARMS;                        /* LDTSelector not passed */

/*RestoreRegs();*/ /*@B14*/              /* Restore registers and flags */
return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: PrintScreen                                        */
/*                                                                      */
/*  DESCRIPTIVE NAME: Print Screen                                      */
/*                                                                      */
/*  FUNCTION: Print the contents of screen.                             */
/*                                                                      */
/*  ENTRY POINT: PrintScreen                                            */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 277 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags                                     */
/*                     USHORT LVBSelector = LVB selector                */
/*                     USHORT PrinterHandle = printer handle            */
/*             ULONG Function ( Call vector table entry = 277 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*               The contents of screen is printed out.                 */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  EFFECTS: NONE                                                       */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY PrintScreen( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_PRINT far *ParmBlock;
ULONG Function;
{
USHORT rc;

    if ( SEG( Environment ) &&
         !Environment->NATIVE_MODE &&
         VGA_PRESENT               ) {
                                                        /* VGA Mode */
        rc = ChainedVDHPrintScreen(
                       (ENVIRONMENT far *)&Environment->VGAEnvironment,
                        ParmBlock, Function );

    } else {                                            /* ATLAS Mode */

          rc = JVDHPRTSC( Environment, ParmBlock, Function );

    }

    return( rc );
}
#endif  //J_INSTALL                                                     //J-TS00

//* J-KKJ **************  START OF SPECIFICATIONS  ***********************/
//*                                                                      */
//*  SUBROUTINE NAME: BufferUpdate                       J-KKJ           */
//*                                                                      */
//*  DESCRIPTIVE NAME: Buffer Update Routine                             */
//*                                                                      */
//*  FUNCTION: BufferUpdate                                              */
//*                                                                      */
//*  ENTRY POINT: BufferUpdate                                           */
//*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 260 )   */
//*                                                                      */
//*  INPUT: (Passed on stack)                                            */
//*             FAR *Environment ( Environment buffer for the session )  */
//*             FAR *ParmBlock                                           */
//*                     USHORT Length = length of this packet            */
//*                     USHORT Flags  = 0 ( reserved )                   */
//*                     FAR *ConfigData = VioGetConfig structure         */
//*             ULONG Function ( Call vector table entry = 260 )         */
//*         (Referenced)                                                 */
//*             MemorySize (global data - amount of video memory)        */
//*                                                                      */
//*  EXIT-NORMAL: AX = 0                                                 */
//*               BufferUpadte                                           */
//*                                                                      */
//*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
//*                                                                      */
//*  INTERNAL REFERENCES:                                                */
//*    ROUTINES: NONE                                                    */
//*                                                                      */
//*  EXTERNAL REFERENCES:                                                */
//*    ROUTINES: NONE                                                    */
//*                                                                      */
//***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY BufferUpdate( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_BUFUP far *ParmBlock;
ULONG Function;
{
USHORT rc;

    if ( SEG( Environment ) &&
         !Environment->NATIVE_MODE &&
         VGA_PRESENT               ) {
                                                        /* VGA Mode */
        rc = ChainedVDHBufferUpdate(
                       (ENVIRONMENT far *)&Environment->VGAEnvironment,
                        ParmBlock, Function );

    } else {                                            /* ATLAS Mode */

        rc = JBUFFERUPDATE( Environment, ParmBlock, Function );

    }                                                   /* VGA Mode */

    return( rc );
}

/**********************  START OF SPECIFICATIONS  ***********************/
/*                                                                      */
/*  SUBROUTINE NAME: CloseEnv                                           */
/*                                                                      */
/*  DESCRIPTIVE NAME: Close environment                                 */
/*                                                                      */
/*  FUNCTION: CloseEnv is called by BVS to close the video              */
/*            environment during the termination of session.            */
/*                                                                      */
/*  ENTRY POINT: CloseEnv                                               */
/*    LINKAGE:   CALL FAR ( via BVS-DDI call vector table entry 276 )   */
/*                                                                      */
/*  INPUT: (Passed on stack)                                            */
/*             FAR *Environment ( Environment buffer for the session )  */
/*             FAR *ParmBlock                                           */
/*                     USHORT Length = length of this packet            */
/*                     USHORT Flags  = all zero                         */
/*                     USHORT LVBSel = LVB selector                     */
/*             ULONG Function ( Call vector table entry = 276 )         */
/*                                                                      */
/*  EXIT-NORMAL: AX = 0                                                 */
/*                                                                      */
/*  EXIT-ERROR: AX = ERROR_VIO_INVALID_PARMS                            */
/*                                                                      */
/*  INTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/*  EXTERNAL REFERENCES:                                                */
/*    ROUTINES: NONE                                                    */
/*                                                                      */
/***********************  END OF SPECIFICATIONS  ************************/
USHORT EXPENTRY CloseEnv( Environment, ParmBlock, Function )
ENVIRONMENT far *Environment;
VDH_CLOSEENV far *ParmBlock;
ULONG Function;
{
//  ClosePointer(Environment->SessionNum);
}

USHORT near InitVideoBuff()
{
    HFILE fd;
    USHORT action;
    USHORT rc = NO_ERROR;
    struct ParamAllocBuff AllocBuff;
    extern struct VGATextEmulationBuffer *VideoBuff;

    if (VideoBuff != NULL)
        return NO_ERROR;
                                        // get video buffer
    if (rc = DosOpen(MEMHELP_PDD_NAME, &fd, &action,
                     0L, 0, 0x0001, 0x00c2, 0L))
        return rc;

    AllocBuff.BuffLen = sizeof(struct VGATextEmulationBuffer);

    if (rc = DosDevIOCtl(NULL, &AllocBuff, FUNC_ALLOC_BUFF, CAT_MEMHELP, fd)) {
        DosClose(fd);
        return rc;
    }

    DosClose(fd);

    VideoBuff = MAKEP(AllocBuff.BuffSel, 0);
    VideoBuff->APAStart = 0xa0000;
                                // Initialize mouse pointer draw device driver
    return rc;
}

USHORT near InitPointer(SessionID)
USHORT SessionID;
{
    HFILE fh;
    USHORT action, rc;
    struct {
        USHORT length;
        struct VGATextEmulationBuffer far *VideoBuff;
    } data;
    extern struct VGATextEmulationBuffer *VideoBuff;

    if (InitPointerDone)
        return NO_ERROR;

    rc = DosOpen("POINTER$", &fh, &action, 0L, 0, 0x0001, 0x00c2, 0L);
    if (!rc) {
        data.length    = sizeof(data);
        data.VideoBuff = VideoBuff;
        rc |= DosDevIOCtl(&data, NULL, 0x7f, 3, fh);
        rc |= DosClose(fh);
    }

    if (!rc)
        InitPointerDone = TRUE;

    return rc;
}

USHORT near CheckInstanceData()
{
    USHORT  rc = 0, ActionTaken;

    if (!hScreenDD) {               /* SCREEN$ not yet open */

        rc = DosOpen( SCREENDD_NAME,
                      (PHFILE)&hScreenDD,
                      (PUSHORT)&ActionTaken,
                      NO_SIZE,
                      NO_ATTRIBUTES,
                      OPEN_IF_EXISTS,
                      NO_INHERIT+DENY_NONE+READ_WRITE,
                      RESERVED_LONG );
    }

    return rc;
}

USHORT near strcmp(s, d)
UCHAR *s, *d;
{
    for (;*s && *d;)
        if ((*s++ | 0x20) != (*d++ | 0x20))
            return 1;
    return ((*s | 0x20) != (*d | 0x20));
}
