/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1992 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 source code is provided to you solely for       */
/*    the purpose of assisting you in your development of OS/2 device        */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Developer Connection Device Driver       */
/*    Source Kit for OS/2. This Copyright statement may not be removed.      */
/*                                                                           */
/*****************************************************************************/
/*
*
*/
/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  RSCDEBUG.C                                            */
/*                                                                            */
/*   DESCRIPTIVE NAME: IBMRSCSI Debug routines                                */
/*                                                                            */
/*   FUNCTION: Print out debug information and verbose mode information       */
/*                                                                            */
/*   NOTES:                                                                   */
/*                                                                            */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:   VPrint6x                                                 */
/*                   DBGPrint6x                                               */
/*                                                                            */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer      Comment                                 */
/*  ----    --------  ----------      -------                                 */
/*          01/11/23  VJ              Initial Version                         */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/
#include "rsc.h"


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME: VPrint6x                                           */
/*                                                                    */
/* DESCRIPTIVE NAME:  Verbose mode print                              */
/*                                                                    */
/* FUNCTION:  Makes string for verbose printing                       */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:  VPrint6x                                             */
/*     LINKAGE:  FAR                                                  */
/*                                                                    */
/* INPUT:  PSZ s      - string parameter                              */
/*         ULONG par1 - numeric parameter                             */
/*         ULONG par2 - numeric parameter                             */
/*         ULONG par3 - numeric parameter                             */
/*         ULONG par4 - numeric parameter                             */
/*         ULONG par5 - numeric parameter                             */
/*         ULONG par6 - numeric parameter                             */
/*                                                                    */
/*                                                                    */
/* EXIT-NORMAL:  n/a                                                  */
/*                                                                    */
/* EXIT-ERROR:   n/a                                                  */
/*                                                                    */
/* EFFECTS: gpVRB->pVerboseMsg -  message storage                      */
/*                                                                    */
/* INTERNAL REFERENCES:                                               */
/*    ROUTINES:         DBGPrint6x                                    */
/*                                                                    */
/* EXTERNAL REFERENCES:                                               */
/*    ROUTINES:         DevHelp_Save_Message                          */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/

VOID  FAR VPrint6x(  PSZ s, 
                     ULONG par1, 
                     ULONG par2, 
                     ULONG par3, 
                     ULONG par4, 
                     ULONG par5, 
                     ULONG par6)
{

   if (gpVRB->VerboseMode == NO_VERBOSE)
      return;

   gpVRB->pVerboseMsg = (PSZ)gpVRB->VerboseMsg;

   gpVRB->IsVPrint = TRUE;

   DBGPrint6x(s, par1, par2, par3, par4, par5, par6);

   *gpVRB->pVerboseMsg = 0;

   gpVRB->IsVPrint = FALSE;

   gpVRB->MsgTable.MsgStrings[0] = (PSZ)gpVRB->VerboseMsg;

   DevHelp_Save_Message( (NPBYTE) &gpVRB->MsgTable );

}  // VPrint6x END

#pragma  optimize("cegl",off)

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:   WriteChar                                       */
/*                                                                    */
/* DESCRIPTIVE NAME:  Write Char                                      */
/*                                                                    */
/* FUNCTION:  This function writes character to the com port          */
/*                                                                    */
/* NOTES:  Used for output to the debug terminal, usually COM2        */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:  WriteChar                                            */
/*     LINKAGE:  NEAR                                                 */
/*                                                                    */
/* INPUT: CHAR c -character to printout                               */
/*                                                                    */
/* EXIT-NORMAL: n/a                                                   */
/*                                                                    */
/* EXIT-ERROR: n/a                                                    */
/*                                                                    */
/* EFFECTS:                                                           */
/*                                                                    */
/* INTERNAL REFERENCES: none                                          */
/*    ROUTINES:                                                       */
/*                                                                    */
/* EXTERNAL REFERENCES:                                               */
/*    ROUTINES:        inp8                                           */
/*                     outp8                                          */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
VOID WriteChar(CHAR c)
{
   if (!(gRSCFlags&FF_INIT_COMPLETE) && gpVRB->IsVPrint)
   {
      if (gpVRB->pVerboseMsg != (PSZ)&gpVRB->VerboseMsg[sizeof(gpVRB->VerboseMsg)-1])
      {
         *gpVRB->pVerboseMsg++=c;
      }
   }
   else
   {
      UCHAR  readyByte;
      int    maxWait = 2000;
      int    uartLineStat = COMM_PORT + UART_LINE_STAT;
      int    uartData = COMM_PORT;

      // Wait for com port ready
      do
      {
         inp8(uartLineStat, readyByte);
         if (readyByte & 0x20)
         {
            break;
         }
      } while (maxWait--);

      // Send the character
      outp8(uartData, c);
   }
   return;
} // WriteChar END

#pragma  optimize("",on)

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  DecWordToASCII                                   */
/*                                                                    */
/* DESCRIPTIVE NAME:  DecWordToASCII                                  */
/*                                                                    */
/* FUNCTION: Converts decimal word number to the ascii string         */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:    DecWordToASCII                                     */
/*     LINKAGE:   NEAR                                                */
/*                                                                    */
/* INPUT: PSZ StrPtr, USHORT wDecVal, USHORT Option                   */
/*                                                                    */
/* EXIT-NORMAL: PSZ ptr to the ascii string created is returned       */
/*                                                                    */
/* EXIT-ERROR:  n/a                                                   */
/*                                                                    */
/* EFFECTS:                                                           */
/*                                                                    */
/* INTERNAL REFERENCES:                                               */
/*    ROUTINES:        WriteChar                                      */
/*                                                                    */
/* EXTERNAL REFERENCES: none                                          */
/*    ROUTINES:                                                       */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
PSZ DecWordToASCII(PSZ StrPtr, USHORT wDecVal, USHORT Option)
{
   BOOL fNonZero=FALSE;
   USHORT  Digit;
   USHORT  Power=10000;

   while (Power)
   {
      Digit=0;
      while (wDecVal >=Power)                   //Digit=wDecVal/Power;
      {
         Digit++;
         wDecVal-=Power;
      }

      if (Digit)
         fNonZero=TRUE;

      if (Digit ||
          fNonZero ||
          (Option & LEADING_ZEROES) ||
          ((Power==1) && (fNonZero==FALSE)))
      {
         WriteChar((CHAR)('0'+Digit));
      }

      if (Power==10000)
         Power=1000;
      else if (Power==1000)
         Power=100;
      else if (Power==100)
         Power=10;
      else if (Power==10)
         Power=1;
      else
         Power=0;
   } // end while

   return (StrPtr);

} // DecWordToASCII END

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME: DecLongToASCII                                    */
/*                                                                    */
/* DESCRIPTIVE NAME: DecLongToASCII                                   */
/*                                                                    */
/* FUNCTION:  Converts decimal long number to  the ascii string       */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:   DecLongToASCII                                      */
/*     LINKAGE:   NEAR                                                */
/*                                                                    */
/* INPUT: PSZ StrPtr, ULONG lDecVal, USHORT Option                    */
/*                                                                    */
/* EXIT-NORMAL: PSZ ptr to the ascii string is returned               */
/*                                                                    */
/* EXIT-ERROR:  n/a                                                   */
/*                                                                    */
/* EFFECTS:                                                           */
/*                                                                    */
/* INTERNAL REFERENCES:                                               */
/*    ROUTINES:         WriteChar                                     */
/*                                                                    */
/* EXTERNAL REFERENCES: none                                          */
/*    ROUTINES:                                                       */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
PSZ DecLongToASCII(PSZ StrPtr, ULONG lDecVal, USHORT Option)
{
   BOOL    fNonZero=FALSE;
   ULONG   Digit;
   ULONG   Power=1000000000;                      // 1 billion

   while (Power)
   {
      Digit=0;                                                                        // Digit=lDecVal/Power
      while (lDecVal >=Power)                   // replaced with while loop
      {
         Digit++;
         lDecVal-=Power;
      }

      if (Digit)
         fNonZero=TRUE;

      if (Digit ||
          fNonZero ||
          (Option & LEADING_ZEROES) ||
          ((Power==1) && (fNonZero==FALSE)))
      {
         WriteChar((CHAR)('0'+Digit));
      }

      if (Power==1000000000)                    // 1 billion
         Power=100000000;
      else if (Power==100000000)
         Power=10000000;
      else if (Power==10000000)
         Power=1000000;
      else if (Power==1000000)
         Power=100000;
      else if (Power==100000)
         Power=10000;
      else if (Power==10000)
         Power=1000;
      else if (Power==1000)
         Power=100;
      else if (Power==100)
         Power=10;
      else if (Power==10)
         Power=1;
      else
         Power=0;
   }
   return (StrPtr);

} // DecLongToASCII END

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  HexWordToASCII                                   */
/*                                                                    */
/* DESCRIPTIVE NAME:  Hexadecimal to ASCII                            */
/*                                                                    */
/* FUNCTION:  Converts hexadecimal word value to the ascii string     */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT: HexWordToASCII                                        */
/*     LINKAGE: NEAR                                                  */
/*                                                                    */
/* INPUT: PSZ StrPtr, USHORT wHexVal, USHORT Option                   */
/*                                                                    */
/* EXIT-NORMAL: PSZ to the string creted is returned                  */
/*                                                                    */
/* EXIT-ERROR:                                                        */
/*                                                                    */
/* EFFECTS:                                                           */
/*                                                                    */
/* INTERNAL REFERENCES:                                               */
/*    ROUTINES:         WriteChar                                     */
/*                                                                    */
/* EXTERNAL REFERENCES: none                                          */
/*    ROUTINES:                                                       */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
PSZ HexWordToASCII(PSZ StrPtr, USHORT wHexVal, USHORT Option)
{
   BOOL fNonZero=FALSE;
   USHORT Digit;
   USHORT Power = 0xF000;
   USHORT  ShiftVal=12;
   CHAR     hexStr;

   while (Power)
   {
      Digit=(wHexVal & Power)>>ShiftVal;
      if (Digit)
         fNonZero=TRUE;

      if (Digit || fNonZero || (Option & LEADING_ZEROES) ||
          ((Power==0x0F) && (fNonZero==FALSE)))
      {
         if (Digit<=9)
            hexStr=(CHAR)('0'+Digit);
         else
            hexStr=(CHAR)('A'+Digit-10);
         WriteChar(hexStr);
      }

      Power>>=4;
      ShiftVal-=4;
   } // end while

   return (StrPtr);
} // HexWordToASCII END


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  StrPrint                                         */
/*                                                                    */
/* DESCRIPTIVE NAME: StrPrint                                         */
/*                                                                    */
/* FUNCTION: Formats and prints out string with parameters            */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:  StrPrint                                             */
/*     LINKAGE: NEAR                                                  */
/*                                                                    */
/* INPUT:   PSZ    DbgStr - string for format and output              */
/*          ULONG  arg1 - argument 1                                  */
/*          ULONG  arg2 - argument 2                                  */
/*          ULONG  arg3 - argument 3                                  */
/*          ULONG  arg4 - argument 4                                  */
/*          ULONG  arg5 - argument 5                                  */
/*          ULONG  arg6 - argument 6                                  */
/*                                                                    */
/*                                                                    */
/* EXIT-NORMAL:  always                                               */
/*                                                                    */
/* EXIT-ERROR:  n/a                                                   */
/*                                                                    */
/* EFFECTS:                                                           */
/*                                                                    */
/* INTERNAL REFERENCES:                                               */
/*    ROUTINES:      HexWordToASCII                                   */
/*                   DecWordToASCII                                   */
/*                   DecLongToASCII                                   */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/* EXTERNAL REFERENCES:                                               */
/*    ROUTINES:      HexLongToASCII                                   */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
VOID StrPrint(PSZ    DbgStr,
              ULONG  arg1,
              ULONG  arg2,
              ULONG  arg3,
              ULONG  arg4,
              ULONG  arg5,
              ULONG  arg6) 
{
   PSZ          BuildPtr=NULL;
   PSZ          pStr=DbgStr;
   PSZ          SubStr;
   USHORT       wBuildOption;
   ULONG        args[NUM_ARGS];
   int          curArg = 0;

   args[0] = arg1;
   args[1] = arg2;
   args[2] = arg3;
   args[3] = arg4;
   args[4] = arg5;
   args[5] = arg6;
   args[6] = 0L;

   while (*pStr)
   {
      // don't overflow args
      if (curArg >= NUM_ARGS)
      {
         break;
      }

      switch (*pStr)
      {
      case '%':
         wBuildOption=0;
         pStr++;
         if (*pStr=='0')
         {
            wBuildOption|=LEADING_ZEROES;
            pStr++;
         }
         if (*pStr=='u')                                                         // always unsigned
            pStr++;

         switch (*pStr)
         {
         case 'x':
            BuildPtr=HexWordToASCII(BuildPtr, (USHORT)args[curArg++],wBuildOption);
            pStr++;
            continue;

         case 'd':
            BuildPtr=DecWordToASCII(BuildPtr, (USHORT)args[curArg++],wBuildOption);
            pStr++;
            continue;

         case 's':
            for (SubStr = (PSZ)args[curArg++]; *SubStr; SubStr++)
               WriteChar((CHAR)(*SubStr));
            pStr++;
            continue;

         case 'l':
            pStr++;
            switch (*pStr)
            {
            case 'x':
               BuildPtr=HexLongToASCII(BuildPtr, (ULONG)args[curArg++],wBuildOption);
               pStr++;
               continue;

            case 'd':
               BuildPtr=DecLongToASCII(BuildPtr, (ULONG)args[curArg++],wBuildOption);
               pStr++;
               continue;
            } // end switch
            continue;                        // dunno what he wants

         case 0:
            continue;
         } // end switch
         break;

      case '\\':
         pStr++;
         switch (*pStr)
         {
         case 'n':
            WriteChar(LF);
            pStr++;
            continue;

         case 'r':
            WriteChar(LF);
            pStr++;
            continue;

         case 0:
            continue;
            break;
         } // end switch

         break;
      } // end switch

      WriteChar(*pStr);
      pStr++;
   } // end while

} // StrPrint END


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  DBGPrint6x                                       */
/*                                                                    */
/* DESCRIPTIVE NAME: Dedug Print                                      */
/*                                                                    */
/* FUNCTION: This function prints debug prefix and formatted string   */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT: DBGPrint6x                                            */
/*     LINKAGE: FAR                                                   */
/*                                                                    */
/* INPUT:    PSZ    pFormatStr - string for the output.               */
/*           ULONG  arg1   - argument 1                               */
/*           ULONG  arg2   - argument 2                               */
/*           ULONG  arg3   - argument 3                               */
/*           ULONG  arg4   - argument 4                               */
/*           ULONG  arg5   - argument 5                               */
/*           ULONG  arg6   - argument 6                               */
/*                                                                    */
/* EXIT-NORMAL:  ALWAYS                                               */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS:   NONE                                                    */
/*                                                                    */
/* INTERNAL REFERENCES:                                               */
/*    ROUTINES:         StrPrint                                      */
/*                                                                    */
/* EXTERNAL REFERENCES: none                                          */
/*    ROUTINES:                                                       */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
#pragma  optimize("cegl",off)

VOID FAR DBGPrint6x( PSZ    pFormatStr,
                     ULONG  arg1,
                     ULONG  arg2,
                     ULONG  arg3,
                     ULONG  arg4,
                     ULONG  arg5,
                     ULONG  arg6)
{
   USHORT   flags;  // here we'll save flags
   USHORT   oldes;  // and ES segment value

   _asm
   {
      pushf
      pop   flags

      pusha
      mov oldes, es
   }

   CLI();

#ifdef DEBUG
   /* Print Debug prefix message, if it is not verbose output to the screen */
   if ( gRSCFlags&FF_INIT_COMPLETE || !gpVRB->IsVPrint)
      StrPrint((PSZ)DBGPrefix,0,0,0,0,0,0);
#endif

   StrPrint( pFormatStr, arg1, arg2, arg3, arg4, arg5, arg6);

   if (flags&EFLAGS_IF)
   {
      STI();
   }

   _asm{
      popa
      mov  es, oldes
   }
} /* DBGPrint6x END */
#pragma  optimize("",on)

