/* $Id: debug.c 562 2011-07-28 09:21:19Z rudi $ */ /****************************************************************************** * Jazz16 Physical Device Driver * Production code and toolkit sample * * (c) Copyright IBM Corporation 1993. All rights reserved * (c) Copyright Media Vision Corporation 1993, 1994. All rights reserved * * DISCLAIMER OF WARRANTIES. The following [enclosed] code is * sample code created by IBM Corporation and Media Vision Corporation. * It is provided to you solely for the purpose of assisting you in the * development of your applications. * The code is provided "AS IS", without warranty of any kind. * IBM and Media Vision shall not be liable for any damages arising out of * your use of the sample code, even if they have been advised of the * possibility of such damages. * ******************************************************************************* * * commdbg.c = debug routines to send data to COM: port * * This file contains routines to send debug information to COM: ports * during execution of device driver. * The routines provide 'C' printf like functions that send their output * to the serial port rather than stdout. * The calls to these routines are only called for debug versions of the * driver. See file debug.h for flags to turn on/off different debug options. * * MODIFICATION HISTORY: * DATE CHANGE DESCRIPTION * unknown Creation (Media Vision) * 07/30/93 Add headers for toolkit * 09/21/93 Header modifications ******************************************************************************/ #define INCL_NOPMAPI #define INCL_DOSERRORS // for ERROR_INVALID_FUNCTION #include #define CR 0x0d #define LF 0x0a #define LEADING_ZEROES 0x8000 #define SIGNIFICANT_FIELD 0x0007 BOOL fLineTerminate=TRUE; char hextab[]="0123456789ABCDEF"; #ifdef DEBUG //#define MAGIC_COMM_PORT 0x3f8 // pulled from word ptr 40:0 #define MAGIC_COMM_PORT 0x2f8 // pulled from word ptr 40:0 #define UART_DATA 0x00 // UART Data port #define UART_INT_ENAB 0x01 // UART Interrupt enable #define UART_INT_ID 0x02 // interrupt ID #define UART_LINE_CTRL 0x03 // line control registers #define UART_MODEM_CTRL 0x04 // modem control register #define UART_LINE_STAT 0x05 // line status register #define UART_MODEM_STAT 0x06 // modem status regiser #define UART_DIVISOR_LO 0x00 // divisor latch least sig #define UART_DIVISOR_HI 0x01h // divisor latch most sig #define DELAY nop #endif #ifdef DEBUG //--------------------------- CharOut - void CharOut(char c) { _asm { mov dx, MAGIC_COMM_PORT // address of PS/2's first COM port add dx, UART_LINE_STAT ReadyCheck: in al, dx // wait for comm port ready signal DELAY DELAY DELAY test al, 020h jz ReadyCheck // Send the character add dx, UART_DATA - UART_LINE_STAT mov al,c out dx, al DELAY DELAY DELAY } } #endif #ifdef DEBUG //------------------------- StringOut - void StringOut(char *DbgStr) { while (*DbgStr) CharOut(*DbgStr++); if (fLineTerminate) { CharOut(CR); // append carriage return, CharOut(LF); // linefeed } } #endif //-------------------- DecLongToASCII - char * DecLongToASCII(char *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))) { *StrPtr=(char)('0'+Digit); StrPtr++; } 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); } //-------------------- HexWordToASCII - //-------------------- HexLongToASCII - char * HexLongToASCII(char *StrPtr, ULONG wHexVal, USHORT Option) { BOOL fNonZero=FALSE; ULONG Digit; ULONG Power=0xF0000000; ULONG ShiftVal=28; while (Power) { Digit=(wHexVal & Power)>>ShiftVal; if (Digit) fNonZero=TRUE; if (Digit || fNonZero || (Option & LEADING_ZEROES) || ((Power==0x0F) && (fNonZero==FALSE))) *StrPtr++=hextab[Digit]; if (Power==0xF0000000) // 1 billion Power=0xF000000; else if (Power==0xF000000) Power=0xF00000; else if (Power==0xF00000) Power=0xF0000; else if (Power==0xF0000) Power=0xF000; else if (Power==0xF000) Power=0xF00; else if (Power==0xF00) Power=0xF0; else if (Power==0xF0) Power=0xF; else Power=0; ShiftVal-=4; } // end while return (StrPtr); } #ifdef DEBUG char BuildString[1024]; #endif // DEBUG //------------------------- PrintfOut - void _cdecl DPD(int level, char *DbgStr, ...) { #ifdef DEBUG char *BuildPtr=BuildString; char *pStr=(char *) DbgStr; char *SubStr; union { void *VoidPtr; USHORT *WordPtr; ULONG *LongPtr; ULONG *StringPtr; } Parm; USHORT wBuildOption; Parm.VoidPtr=(void *) &DbgStr; Parm.StringPtr++; // skip size of string pointer while (*pStr) { // don't overflow target if (BuildPtr >= (char *) &BuildString[1024-2]) break; switch (*pStr) { case '%': wBuildOption=0; pStr++; if (*pStr=='0') { wBuildOption|=LEADING_ZEROES; pStr++; } if (*pStr=='u') // always unsigned pStr++; if (*pStr=='#') pStr++; switch(*pStr) { case 'x': case 'X': case 'p': case 'P': BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; case 'd': BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; case 's': SubStr=(char *)*Parm.StringPtr; while (*BuildPtr++ = *SubStr++); Parm.StringPtr++; BuildPtr--; // remove the \0 pStr++; continue; case 'l': pStr++; switch (*pStr) { case 'x': case 'X': BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; case 'd': BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; } // end switch continue; // dunno what he wants case 0: continue; } // end switch break; case '\\': pStr++; switch (*pStr) { case 'n': *BuildPtr++=LF; pStr++; continue; case 'r': *BuildPtr++=CR; pStr++; continue; case 0: continue; break; } // end switch break; } // end switch *BuildPtr++=*pStr++; } // end while *BuildPtr=0; // cauterize the string StringOut((char *) BuildString); // print to comm port #endif //DEBUG } void _cdecl DPE(char *DbgStr, ...) { #ifdef DEBUG char *BuildPtr=BuildString; char *pStr = (char *) DbgStr; char *SubStr; union { void *VoidPtr; USHORT *WordPtr; ULONG *LongPtr; ULONG *StringPtr; } Parm; USHORT wBuildOption; Parm.VoidPtr=(void *) &DbgStr; Parm.StringPtr++; // skip size of string pointer while (*pStr) { // don't overflow target if (BuildPtr >= (char *) &BuildString[1024-2]) break; switch (*pStr) { case '%': wBuildOption=0; pStr++; if (*pStr=='0') { wBuildOption|=LEADING_ZEROES; pStr++; } if (*pStr=='u') // always unsigned pStr++; switch(*pStr) { case 'x': case 'X': BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; case 'd': BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; case 's': SubStr=(char *)*Parm.StringPtr; while (*BuildPtr++ = *SubStr++); Parm.StringPtr++; BuildPtr--; // remove the \0 pStr++; continue; case 'l': pStr++; switch (*pStr) { case 'x': case 'X': BuildPtr=HexLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; case 'd': BuildPtr=DecLongToASCII(BuildPtr, *Parm.LongPtr++,wBuildOption); pStr++; continue; } // end switch continue; // dunno what he wants case 0: continue; } // end switch break; case '\\': pStr++; switch (*pStr) { case 'n': *BuildPtr++=LF; pStr++; continue; case 'r': *BuildPtr++=CR; pStr++; continue; case 0: continue; break; } // end switch break; } // end switch *BuildPtr++=*pStr++; } // end while *BuildPtr=0; // cauterize the string StringOut((char *) BuildString); // print to comm port #endif //DEBUG }