/*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 = vmint15.c
 *
 * DESCRIPTIVE NAME = Virtual Mouse Device Driver Int 15h Pointer Services
 *
 *
 * VERSION =   V2.0
 *
 * DATE        09/20/91
 *
 * DESCRIPTION This module contains the VMD's Int 15h pointer services. 
 *             
 *
 * FUNCTIONS    
 *      vmInt15Hook()            Int 15h processing and dispatch
 *      vmInt15EnableDisable()   Int 15h Enable or Disable (function 0)
 *      vmInt15Reset()           Int 15h Reset pointing device (function 1)
 *      vmInt15SetSampleRate()   Int 15h Set Sample Rate  (function 2)
 *      vmInt15SetResolution()   Int 15h Set Resolution (function 3)
 *      vmInt15ReadDeviceType()  Int 15h Read Device Type (function 4)
 *      vmInt15Init()            Int 15h Initialize (function 5)
 *      vmInt15ExtCommand()      Int 15h Extended Commands (function 6)
 *      vmInt15FarCallInit()     Int 15h DD Far Call Initialization (FUNC 7)
 *
 *
 * ENTRY POINTS: 
 *
 * DEPENDENCIES:  
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/
#define  INCL_MI
#include "vmdp.h"

#ifdef   VDDSTRICT
MODNAME = __FILE__;
#endif

/*
**    External References
*/

#pragma  BEGIN_SWAP_CODE

 /***************************************************************************
 *
 * FUNCTION NAME  :  vmInt15Hook() 
 *
 * DESCRIPTION    :  Int 15h processing and dispatch
 *
 *  Verifies the given Int 15h request is for us, and then dispatches
 *  to the appropriate worker routine.
 *
 *  INPUT         :
 *                    pcrf -> VDM register frame
 *
 *  OUTPUT        :
 *                  EMULATED
 *                      TRUE
 *                  NOT EMULATED
 *                      FALSE (pass control to next VDD and/or ROM)
 *  USES          :
 *                  32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                  VDM Task-time
 *
 *  PSEUDO-CODE   :                                 REFERENCES
 *      if a valid function request
 *          route to the correpsonding handler;
 ***************************************************************************/

BOOL HOOKENTRY vmInt15Hook( register PCRF pcrf )
{
  AssertTRUE(VDMData.fScrInit);
  if (AH(pcrf) == 0xc2)
  {
    switch (AL(pcrf))
    {
      case 0 :
        vmInt15EnableDisable(pcrf);
        break;
      case 1 :
        vmInt15Reset(pcrf);
        break;
      case 2 :
        vmInt15SetSampleRate(pcrf);
        break;
      case 3 :
        vmInt15SetResolution(pcrf);
        break;
      case 4 :
        vmInt15ReadDeviceType(pcrf);
        break;
      case 5 :
        vmInt15Init(pcrf);
        break;
      case 6 :
        vmInt15ExtCommand(pcrf);
        break;
      case 7 :
        vmInt15FarCallInit(pcrf);
        break;
      default  :
        AH(pcrf) = 1;                 /* Invalid function call               */
        break;
    }                                 /* end switch                          */
    VDHPopInt();                      /* ignore ROM BIOS                     */

    /*
    ** Now update the carry flag accordingly.
    ** NOTE: The carry flag MUST be updated after the VDHPopInt call
    */

    if (AH(pcrf))
      FL(pcrf) = (USHORT)(FL(pcrf)|F_CARRY);  /* error encountered           */
    else
      FL(pcrf) = (USHORT)(FL(pcrf)&~F_CARRY); /* no error encountered        */
    return  TRUE;                             /* Don't chain to next VDD     */
  } 
  else
  {
    return  FALSE;                       /* Let other VDDs or ROM BIOS handle*/
  } 
}                                             /* vmInt15Hook                 */

 /****************************************************************************
 *
 * FUNCTION NAME :  vmInt15EnableDisable() 
 *
 * DESCRIPTION   :  Int 15h Enable or Disable (function 0)
 *
 *      This routine is used to either enable or disable the calling
 *      of the registered subroutine. The registered subroutine is
 *      called on every event when we are in the enabled state.
 *
 *  INPUT         :
 *                   pcrf -> VDM register frame
 *  OUTPUT        :
 *                        EMULATED
 *                            ALWAYS
 *  USES          :
 *                   32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                   VDM Task-time
 *
 *  PSEUDO-CODE   :                                 REFERENCES
 *
 ****************************************************************************/

BOOL PRIVENTRY vmInt15EnableDisable(register PCRF pcrf)
{
  if ( BH (pcrf) == 0 )
  {                                   /* Disable                             */
    if ( VDMData.mstates.int15info.ii_SubAddr != NULL )
    {
      VDMData.mstates.int15info.ii_fstatus &= 0xdf;
      AH(pcrf) = 0;
    } 
    else
      AH(pcrf) = 3;                   /* Interface Error                     */
  } 
  else
    if ( BH(pcrf) == 1 )
    {                                 /* Enable                              */
      if ( VDMData.mstates.int15info.ii_SubAddr != NULL )
      {
        VDMData.mstates.int15info.ii_fstatus |= 0x20;
        AH(pcrf) = 0;
      } 
      else
        AH(pcrf) = 5;                 /* No far call installed               */
    } 
}                                      /* vmInt15EnableDisable               */

 /***************************************************************************
 *
 * FUNCTION NAME  : vmInt15Reset() 
 *
 * DESCRIPTION    :  Int 15h Reset pointing device (function 1)
 *
 *      This routine is used to reset the pointing device to its
 *      original state. The original state is as follows:
 *
 *      int15info.ii_fstatus = 0  where;
 *
 *       Bit         Meaning
 *       ---         -------
 *        0          0 - right button up   1 - right button down
 *        1          0 - reserved
 *        2          0 - left button up    1 - left button down
 *        3          0 - reserved
 *        4          0 - 1:1 scaling       1 - 2:1 scaling
 *        5          0 - Disabled          1 - Enabled
 *        6          0 - Stream Mode       1 - Remote Mode
 *        7          0 - reserved
 *
 *      int15info.ii_srate = 64h  (100 reports per second)
 *
 *      int15info.ii_res = 02h  where;
 *
 *       02H =  4 counts per millimeter
 *
 *
 *  INPUT         :
 *                   pcrf -> VDM register frame
 *  OUTPUT        :
 *                    EMULATED
 *                     ALWAYS
 *  USES          :
 *                  32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                    VDM Task-time
 *
 *  PSEUDO-CODE   :                                 REFERENCES
 *
 ****************************************************************************/

BOOL PRIVENTRY vmInt15Reset(register PCRF pcrf)
{
  VDMData.mstates.int15info.ii_fstatus = 0;
  VDMData.mstates.int15info.ii_srate = 0x64; /* 100 reports per second       */
  VDMData.mstates.int15info.ii_res = 2;      /* 4 counts per millimeter      */
  BH(pcrf) = 0;                              /* return device ID             */
  AH(pcrf) = 0;

    /*
    ** WARNING - The documentation states that the BL register
    ** is modified upon return.         determinnes if a mouse is
    ** installed by issueing this call and checking for no carry.
    ** If the call succeeded         then checks to see if BL has
    ** been modified. I'm returning the exact same value that DOS
    ** returns. 8/30/91
    */

  BL(pcrf) = 0xaa;                    /* Modify this reg                     */
}                                     /* vmInt15Reset                        */

 /***************************************************************************
 *
 *  FUNCTION NAME : vmInt15SetSampleRate() 
 *
 *  DESCRIPTION   : Int 15h Set Sample Rate  (function 2)
 *
 *  INPUT         :
 *                    pcrf -> VDM register frame
 *                   
 *                    BH(pcrf) = Sample rate value
 *                   
 *                     00H =  10  reports per second
 *                     01H =  20  reports per second
 *                     02H =  40  reports per second
 *                     03H =  60  reports per second
 *                     04H =  80  reports per second
 *                     05H =  100 reports per second
 *                     06H =  200 reports per second
 *
 *  OUTPUT        :
 *                   EMULATED
 *                       ALWAYS
 *  USES          :
 *                   32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                        VDM Task-time
 *
 *  PSEUDO-CODE   :                                  REFERENCES
 *
 ****************************************************************************/

BOOL PRIVENTRY vmInt15SetSampleRate ( register PCRF pcrf )
{
  switch (BH(pcrf))
  {
    case 0 :
      VDMData.mstates.int15info.ii_srate = 10;
      break;
    case 1 :
      VDMData.mstates.int15info.ii_srate = 20;
      break;
    case 2 :
      VDMData.mstates.int15info.ii_srate = 40;
      break;
    case 3 :
      VDMData.mstates.int15info.ii_srate = 60;
      break;
    case 4 :
      VDMData.mstates.int15info.ii_srate = 80;
      break;
    case 5 :
      VDMData.mstates.int15info.ii_srate = 100;
      break;
    case 6 :
      VDMData.mstates.int15info.ii_srate = 200;
      break;
    default  :
      AH(pcrf) = 2;                   /* Invalid Input                       */
      return  FALSE;
  } 
  AH(pcrf) = 0;
}                                      /* vmInt15SetSampleRate               */

 /***************************************************************************
 *
 * FUNCTION NAME  : vmInt15SetResolution() 
 *
 * DESCRIPTION    :  Int 15h Set Resolution (function 3) 
 *
 * INPUT          :
 *                  pcrf -> VDM register frame
 *                  
 *                  BH(pcrf) = Resolution value
 *                  
 *                   00H =  1 counts per millimeter
 *                   01H =  2 counts per millimeter
 *                   02H =  4 counts per millimeter
 *                   03H =  8 counts per millimeter
 *
 * OUTPUT         :
 *                   EMULATED
 *                       ALWAYS
 *  USES          :
 *                   32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                   VDM Task-time
 *
 *  PSEUDO-CODE   :                                 REFERENCES
 *****************************************************************************/

BOOL PRIVENTRY vmInt15SetResolution(register PCRF pcrf)
{
  if (BH(pcrf) < 4)
  {
    VDMData.mstates.int15info.ii_res = BH(pcrf);
    AH(pcrf) = 0;
  } 
  else
    AH(pcrf) = 2;                     /* Invalid Input                       */
}                                      /* vmInt15SetResolution               */

/*****************************************************************************
 *
 * FUNCTION NAME  : vmInt15ReadDeviceType() 
 *
 * DESCRIPTION    :  Int 15h Read Device Type (function 4) 
 *
 * INPUT          :
 *                   pcrf -> VDM register frame
 * OUTPUT         :
 *                  EMULATED
 *                      ALWAYS
 *  USES          :
 *                  32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                   VDM Task-time
 *
 *  PSEUDO-CODE   :                                 REFERENCES
 *****************************************************************************/

BOOL PRIVENTRY vmInt15ReadDeviceType(register PCRF pcrf)
{
  BH(pcrf) = 0;                       /* Device ID                           */
  AH(pcrf) = 0;
}                                      /* vmInt15ReadDeviceType              */

 /*****************************************************************************
 *
 * FUNCTION NAME : vmInt15Init() 
 *
 * DESCRIPTION   :  Int 15h Initialize (function 5)  
 *
 * INPUT  :
 *                  pcrf -> VDM register frame
 *                
 *                  BH(pcrf) = Data Packet Size
 *                
 *                   00H =  Reserved
 *                   01H =  1 byte
 *                   02H =  2 bytes
 *                   03H =  3 bytes
 *                   04H =  4 bytes
 *                   05H =  5 bytes
 *                   06H =  6 bytes
 *                   07H =  7 bytes
 *                   08H =  8 bytes
 *                
 *                  If a valid data packet size is given the pointing device
 *                  is set back to its original state. The original state is
 *                  as follows:
 *                
 *                  int15info.ii_fstatus = 0  where;
 *                
 *                   Bit         Meaning
 *                   ---         -------
 *                    0          0 - right button up   1 - right button down
 *                    1          0 - reserved
 *                    2          0 - left button up    1 - left button down
 *                    3          0 - reserved
 *                    4          0 - 1:1 scaling       1 - 2:1 scaling
 *                    5          0 - Disabled          1 - Enabled
 *                    6          0 - Stream Mode       1 - Remote Mode
 *                    7          0 - reserved
 *                
 *                  int15info.ii_srate = 64h  (100 reports per second)
 *                
 *                  int15info.ii_res = 02h  where;
 *                
 *                   02H =  4 counts per millimeter
 *                
 *
 * OUTPUT         :
 *                   EMULATED
 *                  ALWAYS
 *  USES          :
 *                  32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                   VDM Task-time
 *
 *  PSEUDO-CODE   :                                  REFERENCES
 *****************************************************************************/

BOOL PRIVENTRY vmInt15Init(register PCRF pcrf)
{
  if ((BH(pcrf) < 9) && (BH(pcrf) > 0))
  {
    VDMData.mstates.int15info.ii_fstatus = 0;
    VDMData.mstates.int15info.ii_srate = 0x64;  /* 100 reports per second    */
    VDMData.mstates.int15info.ii_res = 2;       /* 4 counts per millimeter   */
    AH(pcrf) = 0;
  } 
  else
    AH(pcrf) = 2;                               /* Invalid Input             */
}                                               /* vmInt15Init               */

 /****************************************************************************
 *
 * FUNCTION NAME  : vmInt15ExtCommand() 
 *
 * DESCRIPTION    : Int 15h Extended Commands (function 6) 
 *
 * INPUT          :
 *                  pcrf -> VDM register frame
 * OUTPUT         :
 *                  EMULATED
 *                     ALWAYS
 *  USES          :
 *                  32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT       :
 *                   VDM Task-time
 *
 *  PSEUDO-CODE   :                                  REFERENCES
 *****************************************************************************/

BOOL PRIVENTRY vmInt15ExtCommand(register PCRF pcrf)
{
  switch (BH(pcrf))
  {
    case 0 :
      break;
    case 1 :
      VDMData.mstates.int15info.ii_fstatus &= 0xf7;/* 1:1 scaling            */
      break;
    case 2 :
      VDMData.mstates.int15info.ii_fstatus |= 0x08;/* 2:1 scaling            */
      break;
    default  :
      AH(pcrf) = 1;                   /* Invalid function call               */
      return  FALSE;
  } 
  BL(pcrf) = VDMData.mstates.int15info.ii_fstatus;
  CL(pcrf) = VDMData.mstates.int15info.ii_res;
  DL(pcrf) = VDMData.mstates.int15info.ii_srate;
  AH(pcrf) = 0;
}                                      /* vmInt15ExtCommand                  */

 /*****************************************************************************
 *
 * FUNCTION NAME  : vmInt15FarCallInit()
 *
 * DESCRIPTION    : Int 15h DD Far Call Initialization (function 7) 
 *
 * INPUT          :
 *                    pcrf -> VDM register frame
 * OUTPUT         :
 *                   EMULATED
 *                       ALWAYS
 *  USES          :
 *                   32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT
 *                   VDM Task-time
 *
 *  PSEUDO-CODE                                     REFERENCES
 *****************************************************************************/

BOOL PRIVENTRY vmInt15FarCallInit(register PCRF pcrf)
{
  SEGMENTOF32(VDMData.mstates.int15info.ii_SubAddr) = ES(pcrf);
  OFFSETOF32(VDMData.mstates.int15info.ii_SubAddr) = BX(pcrf);
  AH(pcrf) = 0;
}                                      /* vmInt15FarCallInit                 */
#pragma  END_SWAP_CODE
