/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/*****************************************************************************\
**
** SOURCE FILE NAME = ASM2C.C
**
** DESCRIPTIVE NAME = Contains convert asm routines.
**
**
** VERSION = V1.0
**
** DATE        05/18/94
**
** DESCRIPTION This module contains routines that were in asm converted
**             to C.  Most are math functions.  The conversion was done
**             for porting to PowerPC
**
**
** FUNCTIONS   frmul
**             LongXFixed
**             LongMulFixed
**             fxmultiply
**             dofdiv
**             iqdiv
**             frdiv
**             BigMulDiv
**             frsqrt
**             frVectLength
**             ulNormalize
**             CopyAndNormalize
**             FractionToDecimal
**             utl_memcopy
**             LongShiftRight
**             szIsEqual
**
**
** NOTES
**
**
** STRUCTURES
**
** EXTERNAL REFERENCES
**
** EXTERNAL FUNCTIONS
**
*/

/*            */
#define  INCL_GPIBITMAPS
#define  INCL_VMANDDI
#define  INCL_GREALL
#define  INCL_DDIPATHS
#define  INCL_GRE_DEVICESURFACE
#define  INCL_DOSSEMAPHORES
#include <os2.h>
#define  PASCAL
#define  FAR
#define  INCL_DDIMISC
#define  INCL_GREALL
#include <ddi.h>
#include <pmddi.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "inc\pspagtun.h"

extern FIXED _System doimul( PQWORD, FIXED, FIXED );
extern ULONG _System dodiv( PQWORD, FIXED );

#define LMAX 0xFFFFFFFF
#define MATRIX_ROUNDOFF 0x8000

/* Also in prddct.h */
typedef struct _MATRIX
{
    FIXED   mx_fxM11;
    FIXED   mx_fxM12;
    FIXED   mx_fxM21;
    FIXED   mx_fxM22;
    LONG    mx_lM41;
    LONG    mx_lM42;
    SHORT  mx_usfracM41;
    SHORT  mx_usfracM42;
    SHORT  mx_flags;
    SHORT  mx_unused;
} MATRIX, *PMATRIX;

/*****************************************************************************\
**
** FUNCTION: frmul
**
** DESCRIPTION: Multiplies two fixed numbers returning a fixed.
**
** PARAMETERS: Two fixed (long) numbers to be multiplied
**
** RETURNS: FIXED result
**
\*****************************************************************************/

FIXED frmul( FIXED l1, FIXED l2 )
{
  ULONG f1, f2;

  f1 = l1 & 0x0000FFFF;   /* Fraction part of l1 */
  f2 = l2 & 0x0000FFFF;   /* Fraction part of l2 */
  l1 = l1 >> 16;          /* Interger part of l1 */
  l2 = l2 >> 16;          /* Interger part of l2 */

  return  ((l1 * l2) << 16 ) +  /* Mult integer parts and scale up */
          (l1 * f2)          +  /* Cross Product */
          (f1 * l2)          +  /* Cross Product */
          ((f1 * f2) >> 16 ) ;  /* Fraction parts scale */

}


/*****************************************************************************\
**
** FUNCTION: FixedXLong
**
**
** DESCRIPTION: Multiplies a fixed and long returning a long.  This saves
**              2 shifts converting long to and from Fixed and the
**              function is simpler than frmul.
**              Method:
**              ( long X fixed_fraction ) then shift off fraction add
**              in long X fixed_integer
**
** PARAMETERS: A long and a fixed
** RETURNS: Long result - truncated not rounded
**
\*****************************************************************************/

LONG LongXFixed( LONG l, FIXED fx )
{
  return ( ( l * ( fx & 0x0000FFFF ) ) >> 16 )  +  ( l * ( fx >> 16 ) );
}


/*****************************************************************************\
**
** FUNCTION: LongMulFixed
**
** DESCRIPTION: Multiplies a fixed and long returning a long. Note -
**              There is rounding
**
** PARAMETERS: LONG, FIXED, pointer to LONG
**
** RETURNS: Over Flow flag.
**
\*****************************************************************************/

SHORT LongMulFixed( LONG lNum, FIXED fxNum, PLONG plAns )
{
  LONG lAns;
  LONG lFrac;

  USHORT usSigns = 0;

  lAns = lNum * ( fxNum >> 16 );                 /* This is long x fixed_int */
    /* long x fract rounded */
  lFrac = (( lNum * ( fxNum & 0x0000FFFF ) ) + 0x8000 ) >> 16;
  *plAns = lAns + lFrac;

#if 0
//   Note the only way in asm file for overflow is by adding a carry bit in to
//   edx. Since a long x fixed_int can't overflow in the quad result you will
//   not get an overflow.
//
///*
//** compute the sign of product
//** 0 or 2 is pos, 1 is neg
//*/
//if ( lNum < 0 )
//  usSigns = 1;
//if ( fxNum < 0 )
//  usSigns += 1;
//
//if ( ( usSigns == 1 && *plAns >= 0 ) ||   /* Neg expected, pos result */
//     ( usSigns != 1 && *plAns <  0 ) )    /* Pos expected, neg result */
//  return 0;
#endif

  return 1;
}


/*****************************************************************************\
**
** FUNCTION: fxmultiply
**
** DESCRIPTION: Multiplies two fixed numbers returning a fixed. The passed QUAD
**              is filled in with the quad intermediate result.  The Overflow
**              flag is always zero
**
** PARAMETERS: Pointer to QWORD,Two fixed (long) numbers to be multiplied
**             ptr to overflow flag.
**
** RETURNS: FIXED result
**
\*****************************************************************************/

FIXED fxmultiply( PQWORD qw, FIXED l1, FIXED l2, PULONG ulOFlag )
{
  ULONG f1, f2;
  LONG t;
  QWORD q;

  *ulOFlag = 0L;          /* Flag is always zero */

#if  PPC

  f1 = l1 & 0x0000FFFF;   /* Fraction part of l1 */
  f2 = l2 & 0x0000FFFF;   /* Fraction part of l2 */
  l1 = l1 >> 16;          /* Interger part of l1 */
  l2 = l2 >> 16;          /* Interger part of l2 */

  q.ulHi = l1 * l2;       /* High Quad is int1 X int2 */
  q.ulLo = f1 * f2;       /* Low Quad is fract1 X fract2 */

  t = l1 * f2;            /* Cross Product        */
  q.ulHi +=  t  >> 16;    /* Add high part to int */
  t  <<= 16;
  q.ulLo += (ULONG)t;       /* Low part to fract  */
  if ( q.ulLo < (ULONG)t )  /* Check for overflow */
  {
    q.ulHi++;
  }

  t = f1 * l2;            /* Cross product 2 same as above */
  q.ulHi +=  t  >> 16;
  t  <<= 16;
  q.ulLo += (ULONG)t;
  if ( q.ulLo < (ULONG)t )
  {
    q.ulHi++;
  }

  qw->ulLo = q.ulLo;      /* Copy over */
  qw->ulHi = q.ulHi;

  t = ( q.ulHi << 16 ) + ( q.ulLo >> 16 );    /* Return the low of quad int */

#else

  doimul( qw, l1, l2 );                       /* Call asm stub to do multiply */
  t = ( qw->ulHi << 16 ) + ( qw->ulLo >> 16 );  /* Return the low of quad int */
                                                /* high of quad fract         */
#endif


  return t;

}


#if PPC

/*****************************************************************************\
**
** FUNCTION: dofdiv
**
** DESCRIPTION: Does a floating divide of a QWORD by a long
**
** PARAMETERS:  PARM1: pointer to QWORD
**              PARM2: ULONG denominator
**
** NOTES   Use for PowerPC only - some Intel machines might not have floating
**         point unit resulting in costly simulation
**
** RETURNS:  LONG result
**
\*****************************************************************************/

LONG _Optlink dofdiv( PQWORD qNum, ULONG ulDenom )
{
  typedef long double LD;
  #define K ((LD)4294967296.0)  //0x100000000 for shifting longs

  LD x;

  x = (LD)(qNum->ulLo) + ( (LD)(qNum->ulHi) * K );  //Move quad into long dbl
  x = x / (LD)ulDenom;                              //Divide it

  qNum->ulLo = (ULONG)x;                      //Only interested in first "long"
//qNum->ulHi = (ULONG)( x / K );                Not used...

  return qNum->ulLo;
}

#endif

/*****************************************************************************\
**
** FUNCTION: iqdiv
**
** DESCRIPTION: Divides a Quad by a long returning a fixed.
**
** PARAMETERS: Quad numerator, LONG/FIXED denominator ptr to remainder, ptr to
**             Overflow flag.
**
**             Note: Since no one uses the remainder it is set to 0.
**
** ALGORITHM:     quad/fixed  = qInt x 2**32 + qFrac / fixed
**                since 2**32 can't be represented in a long so we change it to:
**                (qInt x (LMAX+1) + qFrac) / fixed =
**                                         (qInt x LMAX + qInt + qFrac) / fixed
**                Since it's possible for qInt + qFrac to overflow a long we
**                get the sum = qInt+qFrac.  If the sum is less < qFrac there is
**                an overflow so inc qInt.
**                The algorithm continues as follows:
**                Q1, R1  = LMAX        / fixed
**                Q2, R2  = (R1 x qInt) / fixed
**                Q3, R3  = (sum + R2)  / fixed
**                Quotient = (Q1 x qInt) + Q2 + Q3
**                The remainder is R3 but not actually calculated since it's
**                not needed
**
**
** RETURNS: FIXED result
**
** CHANGES/MODIFICATION
**
** @96713 - 12-12-94  mjones - signs for iqdiv() needed some correction.
**          Defect revealed  with -1 / 1 and  -1 / .707
\*****************************************************************************/

FIXED _Optlink iqdiv( QWORD qNum, FIXED denom, PULONG pulRem, PULONG pulOFlag )
{

  ULONG Quo1, Quo2, Quo3;
  ULONG Rem1, Rem2;
  ULONG Sum,Quotient;
  SHORT sign = 1;
  SHORT NumSign = 1;

  /*
  ** Change to ABS values
  */
  if ( denom < 0 )
  {
    sign = -1;
    denom = 0 - denom;
  }

  if ( (LONG)qNum.ulHi < 0 )
  {
    sign *= -1;
    NumSign = -1;

    qNum.ulHi = ~qNum.ulHi;     /* NOT Quad Hi */

    qNum.ulLo = 0 - qNum.ulLo;  /* NEG Quad lo */

    if ( qNum.ulLo == 0 )
       qNum.ulHi -= -1;           // @96713
  }

  /*
  ** Check for major overflow - no need dividing by absolute numbers
  */

  if ( (ULONG)qNum.ulHi >= (ULONG)denom )
  {
    *pulOFlag = 1;
    return sign * 0x00010000;    // @96713
  }

#if PPC
// This algorithm gives close but not exact results.  Since PowerPCs have
// a floating point processor it is better (and more accurate) to use it.
// This code is left in case it might be needed later.
//
//  Sum = (ULONG)qNum.ulHi + (ULONG)qNum.ulLo;
//  if ( Sum < (ULONG)qNum.ulLo )
//  { /* Potential Overflow */
//    Sum++;
//    qNum.ulHi = (ULONG)qNum.ulHi + 1;
//  }
//
//  Quo1 = LMAX / (ULONG)denom;
//  Rem1 = LMAX % (ULONG)denom;
//
//  Rem1 *= qNum.ulHi;
//
//  Quo2 = Rem1 / (ULONG)denom;
//  Rem2 = Rem1 % (ULONG)denom;
//
//  Rem2 += Sum;
//
//  Quo3 = Rem2 / (ULONG)denom;
//
///**** Not used *********************************\
//* *pulRem =  (Rem2  % (ULONG)denom ) * NumSign;
//\***********************************************/
//
//  Quotient = ( Quo1 * (ULONG)qNum.ulHi ) + Quo2 + Quo3;

  Quotient = dofdiv( &qNum, denom );

#else

  Quotient = dodiv( &qNum, denom );

#endif

  *pulRem = *pulOFlag = 0;
  return (FIXED)Quotient * sign;

}


/*****************************************************************************\
**
** FUNCTION: frdiv
**
** DESCRIPTION: Divides two fixed numbers returning a fixed.
**
** PARAMETERS: Two fixed (long) numbers to be multiplied
**
** RETURNS: FIXED result
**
\*****************************************************************************/

FIXED frdiv( FIXED num, FIXED denom )
{
  QWORD qNum;
  ULONG ulRem;
  ULONG ulOFlag;

  qNum.ulHi = num >> 16;
  qNum.ulLo = (ULONG)num << 16;

  return ( iqdiv( qNum, denom, &ulRem, &ulOFlag ) );

}


/*****************************************************************************\
**
** FUNCTION: BigMulDiv
**
** DESCRIPTION: Multiplies the first two fixed parms then divides result by
**              third
**
** PARAMETERS: Two fixed (long) numbers to be multiplied followed by divisor
**
** RETURNS: FIXED result
**
\*****************************************************************************/

FIXED BigMulDiv( FIXED f1, FIXED f2, FIXED f3 )
{
  QWORD qRes;
  ULONG ulOFlag;
  ULONG ulRem;

  fxmultiply( &qRes, f1, f2, &ulOFlag );
  return ( iqdiv( qRes, f3, &ulRem, &ulOFlag ) );
}


/*****************************************************************************\
**
** FUNCTION: frsqrt
**
** DESCRIPTION: Calculates the square root of a FIXED number
**              third
**
** PARAMETERS: A FIXED number
**
** RETURNS: FIXED result
**
\*****************************************************************************/

FIXED frsqrt ( FIXED i )
{
  LONG  j = 0;
  LONG  y;
  ULONG sqrtx_small;
  LONG  sqrtx;
  LONG  sqx;

  if ( i == 0L )
    return( 0L );

  sqx = i;
  if (i < 0x10000)
  {
    if (i < 0x1000)
    {
      if (i < 0x200)
      {
        if (i < 0x80)
        {
          if (i < 0x20)
            sqrtx_small = 0x2d4;
          else
            if (i < 0x40)
              sqrtx_small = 0x6d4;
            else
              sqrtx_small = 0xf50;
        }
        else
          if (i < 0x100)
            sqrtx_small = 0xda8;
          else
            sqrtx_small = 0x1350;
      }
      else
      {
        if (i < 0x400)
          sqrtx_small = 0x1b50;
        else
          if (i < 0x800)
            sqrtx_small = 0x26a0;
          else
            sqrtx_small = 0x36a0;
      }
    }
    else
    {
      if (i < 0x4000)
      {
        if (i < 0x2000)
          sqrtx_small = 0x4d41;
        else
          sqrtx_small = 0x6d41;
      }
      else
      {
        if (i < 0x8000)
          sqrtx_small = 0x9a82; /* (sqx >> 7) + 0x40; */
        else
          sqrtx_small = 0xda82; /* (sqx >> 1) + 0x8000; */
      }
    }
    sqx <<= 16;
    sqrtx_small = ((sqx / sqrtx_small) + sqrtx_small) >> 1;
    sqrtx_small = ((sqx / sqrtx_small) + sqrtx_small) >> 1;
    sqrtx_small = ((sqx / sqrtx_small) + sqrtx_small) >> 1;
    sqrtx = (LONG)sqrtx_small;
  }
  else
  {
    if (i < 0x1000000)
    {
      if (i < 0x100000)
      {
        if (i < 0x40000)
        {
          if (i < 0x20000)
            sqrtx = 0x135;
          else
            sqrtx = 0x1b5;
        }
        else
          if (i < 0x80000)
            sqrtx = 0x26a;
          else
            sqrtx = 0x36a;

      }
      else  /* i > 0x1000000 */
      {
        if (i < 0x400000)
        {
          if (i < 0x200000)
            sqrtx = 0x4d4;
          else
            sqrtx = 0x6d4;
        }
        else
          if (i < 0x800000)
            sqrtx = 0x9a8;
          else
            sqrtx = 0xda8;
      }
    }
    else /* i > 0x1000000 */
    {
      if (i < 0x10000000)
      {
        if (i < 0x4000000)
        {
          if (i < 0x2000000)
            sqrtx = 0x1350;
          else
            sqrtx = 0x1b60;
        }
        else
          if (i < 0x8000000)
            sqrtx = 0x26a0;
          else
            sqrtx = 0x36a0;
      }
      else  /* i > 0x10000000 */
      {
        if (i < 0x40000000)
        {
          if (i < 0x20000000)
            sqrtx = 0x4d41;
          else
            sqrtx = 0x6d41;
        }
        else
          sqrtx = 0x9a82;
      }
    }

    sqrtx = ((sqx / sqrtx) + sqrtx) >> 1;
    sqrtx = ((sqx / sqrtx) + sqrtx) >> 1;
    y = i - (sqrtx * sqrtx);
    sqrtx = (sqrtx << 8) + (((y << 12) / sqrtx) >> 5);
  }
  return ( (FIXED)sqrtx );
}


/*****************************************************************************\
**
** FUNCTION: frVectLength
**
** DESCRIPTION: Compute the length of a vector given the X and Y components as
**              fixed point numbers. Return the square root as a fixed point
**              value.
**
** PARAMETERS: Two FIXED numbers
**
** RETURNS: FIXED result
**
\*****************************************************************************/

FIXED frVectLength( FIXED f1, FIXED f2 )
{

  QWORD qF1Squared;
  QWORD qF2Squared;
  QWORD qSum;
  ULONG ulOFlag;
  FIXED fSum;
  FIXED fRes;

  fxmultiply( &qF1Squared, f1, f1, &ulOFlag );   /* Square the first fixed  */
  fxmultiply( &qF2Squared, f2, f2, &ulOFlag );   /* Square the second fixed */

  qSum.ulHi = qF1Squared.ulHi + qF2Squared.ulHi;
  if ( ( qSum.ulLo = qF1Squared.ulLo + qF2Squared.ulLo ) < qF2Squared.ulLo )
  { /* Check for overflow */
    qSum.ulHi++;
  }

  if ( qSum.ulHi <= 0x00007FFF )
  {
    fSum = (( qSum.ulHi << 16 ) + ( qSum.ulLo >> 16 ));
  }
  else
    if ( qSum.ulHi <= 0x0000FFFF )
    {
      fSum = (( qSum.ulHi << 16 ) + ( qSum.ulLo >> 16 )) >> 2 ;
    }
    else
    {
      fSum = qSum.ulHi;
    }

  fRes = frsqrt ( fSum );

  if ( qSum.ulHi > 0x0000FFFF )
  {
    fRes = fRes << 8;
  }
  else
    if ( qSum.ulHi > 0x00007FFF )
    {
      fRes = fRes << 1;
    }

  return fRes;
}


/*****************************************************************************\
**
** FUNCTION: ulNormalize
**
** DESCRIPTION: Return the number of shifts needed to shift the
**              the passed ULONG number so that the highest order bit is 1
**
** NOTE:        If the number is zero then zero will be returned.
**
** INPUT         = ulNum
**
** RETURN-NORMAL = number of shifts
**
** RETURN-ERROR  = NONE
**
\*****************************************************************************/

LONG ulNormalize( ULONG ulNum )
{
  SHORT i;
  ULONG mask;

  if ( ulNum == 0 )
    return 0;

  if ( ulNum < 0x10000 )
  { /* Nothing in High part start looking in low 16 */
    i = 16;
    mask = 0x8000;
  }
  else
  {
    i = 0;
    mask = 0x80000000;
  }

  while ( ! (mask & ulNum ))
  {
    mask >>= 1;
    i++;
  }
  return i;
}


/*****************************************************************************\
**
** FUNCTION: CopyAndNormalize
**
** DESCRIPTION:
**
**
** NOTE:
**
** INPUT         = ulNum
**
** RETURN-NORMAL = NONE
**
** RETURN-ERROR  = NONE
**
\*****************************************************************************/

VOID CopyAndNormalize( PXFORM pXform, PMATRIX pMatrix )
{
  MATRIX mx;
  LONG  dxax, cxbx;
  USHORT uFlags;

  if ( pMatrix == NULL )
    return;

  /*
  ** move the XFORM
  */
  memcpy( &mx, pXform, sizeof( XFORM ) );

  /*
  ** Set the fractions to 1/2.  This will let us avoid an extra roundoff
  ** step when actually doing a transform.  On the other hand, we have
  ** to be careful to remember these when doing invert_matrix and
  ** combine_xform.
  */
  mx.mx_usfracM41 =  mx.mx_usfracM42 = MATRIX_ROUNDOFF;

  /*
  ** clear the flags
  */
  mx.mx_flags =  mx.mx_unused = 0;

  /*
  ** check for a simple rotation
  */
  if ( mx.mx_fxM11 == 0 &&
       mx.mx_fxM22 == 0 )
  {
    /*
    ** set the simple and exchange bits
    */
    mx.mx_flags |=  MATRIX_SIMPLE + MATRIX_XY_EXCHANGE;

    /* pick up the X multiplier in DX:AX and the Y multiplier in CX:BX */
    dxax = mx.mx_fxM12;
    cxbx = mx.mx_fxM21;
  }
  else
  {
    /*
    ** check for scaling case
    */
    if (( mx.mx_fxM12 == 0 ) &&
        ( mx.mx_fxM21 == 0 ) )
    {
      /*
      ** set the simple bit
      */
      mx.mx_flags |=  MATRIX_SIMPLE;

      /* pick up the X multiplier in DX:AX and the Y multiplier in CX:BX */
      cxbx = mx.mx_fxM22;
      dxax = mx.mx_fxM11;
    }
    else
      goto have_mx_flags;
  }

  /*
  ** see if it's all units
  */
  if ( ( LOUSHORT( dxax ) | LOUSHORT( cxbx ) ) == 0 )
  {
    uFlags = MATRIX_UNITS;

    if ( dxax < 0 )
    {
      dxax = -( dxax >> 16 );
      uFlags |= MATRIX_X_NEGATE;
    }

    if ( cxbx < 0 )
    {
      cxbx = -( cxbx >> 16 );
      uFlags |= MATRIX_Y_NEGATE;
    }

    if ( ( cxbx - 1 ) == 0 &&
         ( dxax - 1 ) == 0  )
    {
      mx.mx_flags |= uFlags;
    }
  }
have_mx_flags:

  /*
  ** check for a translation
  */
  if ( mx.mx_lM41 != 0 ||
       mx.mx_lM42 != 0 )
  {
    mx.mx_flags |= MATRIX_TRANSLATION;
  }

  *pMatrix = mx;

  return;
}


/*****************************************************************************\
**
** FUNCTION: FractionToDecimal
**
** DESCRIPTION: Converts the fraction of a fixed number to the base 10 ASCII
**              equivalent
**
** INPUT         = ptr to char buf, low half of fixed number
**
** RETURN-NORMAL = Count of significant digits.
**
** RETURN-ERROR  = NONE
**
\*****************************************************************************/

SHORT _System FractionToDecimal( PCHAR pBuf, USHORT usFract )
{
  SHORT i;
  SHORT sSignif = 0;
  ULONG ulNum = usFract;


  for ( i = 1; i <= 5; i++ )
  {
    ulNum *= 10;
    if ( ( *pBuf = ( ulNum >> 16 ) + '0' ) != '0' )
      sSignif = i;
    pBuf++;
    ulNum &= 0xFFFF;
  }

  return sSignif;
}


/*****************************************************************************\
**
** FUNCTION: utl_memcopy
**
** DESCRIPTION: Passthru to C memcpy
**
** INPUT         = ptr to dest, ptr to source, count
**
** RETURN-NORMAL = Void
**
** RETURN-ERROR  = NONE
**
\*****************************************************************************/

VOID _System utl_memcopy( PBYTE pbDest, PBYTE pbSrc, USHORT usCount )
{
  memcpy( pbDest, pbSrc, usCount );

  return;

}


/*****************************************************************************\
**
** FUNCTION: LongShiftRight
**
** DESCRIPTION: Shifts a long value to the right by specified count
**
** INPUT         = Ulong target, amount
**
** RETURN-NORMAL = Ulong - shifted value
**
** RETURN-ERROR  = NONE
**
\*****************************************************************************/

ULONG _System LongShiftRight( ULONG ulValue, SHORT sAmount )
{
  return ( ulValue >> sAmount );
}


/*****************************************************************************\
**
** FUNCTION: szIsEqual
**
** DESCRIPTION: Compares two strings.
**
** INPUT         = ptr to string 1, ptr to sting 2
**
** RETURN-NORMAL = Bool - True if equal, False if not
**
** RETURN-ERROR  = NONE
**
\*****************************************************************************/

BOOL _System szIsEqual( PSZ pszStr1, PSZ pszStr2 )
{
  if ( ! strcmp( pszStr1, pszStr2 ) )
    return TRUE;
  else
    return FALSE;
}

