⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdprintf.c

📁 marvell8385 GSPI开发驱动
💻 C
字号:
// vdPRINTF.C
//
#include "precomp.h"
#include <stdarg.h>
#include <conio.h>

unsigned int PmonTimedOut = FALSE;

#ifndef word
#define word unsigned short
#endif
#ifndef dword
#define dword unsigned long
#endif 
//#define DIRECT_TO_MONO
//#define DIRECT_TO_COM
#define DIRECT_TO_PARALLEL      // hard coded output to parrallel port
//#define DIRECT_TO_COLOR

#if defined(DEBUG) || DBG==1
int Init = 0;
#define CRonLF

void lcputhex( long x, int shift );
void lcputdec( unsigned x );
void _cdecl dputs( char *str );
void _cdecl dputc( int ch );



#ifdef DIRECT_TO_MONO
word *lpVideo = (word *)0xb0000;
int *lpCursor = (int *)0xb0fa0;
#endif

#ifdef DIRECT_TO_COM
#pragma intrinsic( outp )            
#pragma intrinsic( inp )            
//void commputc( int ch );

#define DEBUG_COM_PORT  1
//#define DEBUG_BAUD_RATE 115200
#define DEBUG_BAUD_RATE 57600
//#define DEBUG_BAUD_RATE 19200
#endif

#ifdef DIRECT_TO_PARALLEL
#pragma intrinsic( _outp )            
#pragma intrinsic( _inp )            
#define inp _inp
#define outp _outp
#define DEBUG_LPT_PORT  1
#define PBASE               0x3bc
//#define PBASE               0x378
//#define PBASE               0x278
#endif 

long locked = 0;

void dprintf(char *fmt, ...)
{
    char *ptr;
    va_list argp;
    unsigned tmp;

    if ( locked ) return;               // If locked, then loose debug till current thread is done.
    
    NdisInterlockedIncrement(&locked);      // take the lock.
    Init = 0;                           // reinit every time
    va_start(argp,fmt);

    ptr = fmt;                          //point to first char
    while( *ptr )                       //as long as we are not nulled
    {
        if ( *ptr == '%' )              //format char?
        {
            ptr++;                      //get to next char
            if ( *ptr == 'l' )          //double word ?
            {
                ptr++;                  // bump to next
                if ( *ptr == 'x' )
                {
                    lcputhex(va_arg(argp,long),28 );
                } 
                else if ( *ptr == 'd' || *ptr == 'u' )
                {
                    lcputdec(va_arg(argp,long));
                } else
                    continue;
            } else if ( *ptr == 'x' )   //q. use wants hex
            {
                lcputhex( (int)va_arg(argp,int),12 );            //send it as is
            } else if ( *ptr == 'p' )     //IO PORT (NEW ONE !!!!)
            {
                tmp =  va_arg(argp,unsigned); // get offset and save
                tmp &= 0x0fff;              // three bytes only
                lcputhex( tmp,8 );          // show offset
            } else if ( *ptr == 'v' )       // version, NEW ONE
            {
                tmp = va_arg(argp,unsigned short);    // get the whole thing
                lcputhex( tmp>>8,4);  // high word (bits+4)
                dputc('.');               // delimitor
                lcputhex( tmp&0x00ff,4);  // low word (bits+4)
            } else if ( *ptr == 'd'|| *ptr == 'u' )   //user wants integer decimal
            {
                lcputdec( (long)va_arg(argp,unsigned short) );            //send as is
            } else if ( *ptr == 's' )
            {
                dputs( va_arg(argp,char *) );
            } else if ( *ptr == 'c' )
            {
                dputc( va_arg(argp, char) );
            } else if ( *ptr == 'b' )
            {
                lcputhex( va_arg(argp,char),4 );
            }else if ( *ptr == 'g' )
            {
                int i;
                char *tmp = va_arg(argp, char *);
                lcputhex( (long)*((long *)tmp), 28);
                dputc(' ');
                tmp+=4;
                lcputhex( (unsigned short)*((unsigned short*)tmp), 12);
                dputc(' ');
                tmp+=2;
                lcputhex( (unsigned short)*((unsigned short*)tmp), 12);
                dputc(' ');
                tmp+=2;
                for(i=0;i<8;i++,tmp++)
                {
                    lcputhex( *tmp,4);
                    dputc(' ');
                }    
            } else
            {
                dputc(*ptr);
            }
        } else
        {
            dputc(*ptr);

#ifdef CRonLF
            if ( *ptr == '\n' )
                dputc('\r');
#endif
        }
        ptr++;
    }

    NdisInterlockedDecrement(&locked);      // take the lock.
}

void _cdecl dputs( char *str )
{
    while( *str )
    {
#ifdef CRonLF
        if ( *str == '\n')              // if character is new line
            dputc('\r');                // send a carridge return first
#endif CRonLF // end of Carridge return on Line Feed
        dputc( *str++ );
    }
            
}
void lcputhex( long hex, int shift )
{
    int val;
    for(;shift>=0;shift-=4)
    {
        val = (hex >> shift)&0x0f;      //get nibble shifted down
        if ( val < 10 )
            val += '0';                 //add offset to ascii zero
        else
            val += ('A'-10);            //add offset to get to ascii 'A'
        dputc((char)val);                      //output
    }
}
unsigned divisors[] ={ 1000000000,
                        100000000,
                         10000000,
                          1000000,
                           100000,
                            10000,
                             1000,
                              100,
                               10,
                                1,0 }; // zero terminates the list

void lcputdec( unsigned hex )
{
    unsigned i,leadzero = 0;
    unsigned digit;
    for(i=0;divisors[i];i++)
    {
        digit = hex / divisors[i];      // get the digit
        hex = hex % divisors[i];      // fix up remainder
        if ( digit )
        {
            dputc((char)(digit + '0'));
            leadzero = 1;
        } else if ( leadzero )
            dputc('0');
    }
    if (!leadzero)
        dputc('0');
}
void hd( unsigned char *hexdata, int count )
{
  int bytes=0;                              // bytes per line
  unsigned char *tmp;                        // tmp pointer

  if ( count > 256 )
    return;


  count = ( count + 16 ) & 0xfff0;           // round up to 8 words

  while( count ){                           // still got bytes left
    dprintf("\n\r%lx: ",hexdata);// print address of buffer
    tmp = hexdata;                          // get a copy of pointer
    for(bytes=0;bytes<16;bytes++)            //do a line
        dprintf("%b ",*tmp++);              //print hex value
    count -= 16;                             //8 words gone by
    hexdata += 16;                           //next paragraph
  }
    dprintf("\n\r");
  return;
}

#ifdef DIRECT_TO_MONO
void Scroll( void )
{
    dword *dest,*src;                   // move 32 bits at a time

    dest = (dword *)lpVideo;            // point to top of screen
    src = (dword *)( lpVideo + 80 );    // point to start of second line
    while ( src < (dword *)(lpVideo+2000) ) // do it till the end of screen
    {
        *dest++ = *src++;               // move dwords
    }
    dest = (dword *)(lpVideo+(2000-80)); // point to last line
    while( dest < (dword *)(lpVideo+2000) ) // do it to the end of the line
        *dest++ = (dword)0x07200720;      // double spaces
    return;
}
// this routine puts a single character at the next location on the screen
// and scrolls the screen if necessary
void _cdecl dputc( int ch )
{
    int cursor;
    if ( !Init )
    {
        if ( (*lpCursor == 0x07200720) ||
             (*lpCursor == 0x07000700) )
        {
            *lpCursor = 0;

            for (;Init < 2000;Init++)
            {
                *(lpVideo+Init++) = 0x0720;
            }
        }
        Init = 1;
    }        
    cursor = *lpCursor;    
    switch( ch )
    {
        case '\n':          // new line
            cursor += 80;  // get to it
            if ( cursor >= 2000 )
            {
                cursor -= 80;
                Scroll();
            }
            break;
        case '\r':          // return
            cursor = cursor - ( cursor % 80 );
            break;
        default:
            if ( ch & 0x80 )            // upper bit set?
            {
                ch &= 0x007f;           // mask upper byte and intensity bit
                ch |= 0x0f00;           // set high intensity
            }
            else
            {
                ch &= 0x007f;           // mask upper byte and intensity bit
                ch |= 0x0700;           // set up attribute for normal video
            }
            *(lpVideo+cursor) = (word)ch;// write character to display
            cursor++;
//            if ( (cursor % 80) == 70 )
//                cursor += 10;
            if ( cursor >= 2000 )
            {
                cursor -= 80;
                Scroll();
            }
            break;
    }
    *lpCursor = cursor;
}                        

void QuickC( int ch )
{
    int cursor;
    if ( !Init )
    {
        if ( *lpCursor == 0x07200720 )
        {
            *lpCursor = 0;

            for (;Init < 2000;Init++)
            {
                *(lpVideo+Init++) = 0x0720;
            }
        }
        Init = 1;
    }        
    cursor = *lpCursor;    
    ch &= 0x00ff;   // make sure upper word is null
    ch |= 0x0f00;   // set up attribute for BRIGHT video
    *(lpVideo+cursor) = (word)ch;// write character to display
    cursor++;
    if ( cursor >= 2000  )
    {
        cursor -= 80;
        Scroll();
    }
    *lpCursor = cursor;
}                        

#endif // end of DIRECT_TO_MONO

#ifdef DIRECT_TO_COM

int ports[] = {0,0x3f8,0x2f8,0x3e8,0x2e8,0};
int base;
int comm_fifo = 0;
int fifo_count = 0;
int init_port()
{

    word brlv = 0;                      // baud rate latch value

    base = ports[DEBUG_COM_PORT];

    while( !(inp(base+5) & 0x40) )
        ;                               // wait for serializer to drain

    outp( base+2, 0x01 );               // enable FIFO mode
    if ( (inp(base+2) & 0xc0) == 0xc0 ) // we have a FIFO
        comm_fifo = 1;                  // set flag to indicate to all
    outp( base+3, 0x80 );               // enable DLAB
    brlv = (word)(115200 / DEBUG_BAUD_RATE); // calulate divisor values
    outp( base+0,(brlv&0x00ff));        // write low byte
    outp( base+1,(brlv>>8) );           // write high byte
    outp( base+3,0x03);                 // 8 data, no parity, 1 stop

}


void commputc( int ch )
{
    if ( !Init )
    {
        Init = 1;
        init_port();
    }        
    if ( inp(base+5) & 0x20 )           // holding register empty?
        fifo_count = 0;                 // assume fifo empty
    if ( (fifo_count < 16) && comm_fifo)// we have room in the fifo
    {
        outp(base,ch);                  // xmit character
        fifo_count++;                   // bump count
        return;                         // we are done
    } else
    {
        while( !(inp(base+5) & 0x20) )  // wait for fifo to drain
            ;
        fifo_count = 1;
        outp(base,ch);
    }
}                        

//
// Used for sending a single character during a interrupt routine.
//
void QuickC( int ch )
{
    if ( !Init )
    {
        Init = 1;
        init_port();
    }        
    outp(base+0,ch);
    fifo_count++;
}                        

#endif // end of DIRECT_TO_COM

__inline int _cdecl stillDead ( )
{
   if ( PmonTimedOut == 1 ) 
   {
      if ( (inp(PBASE+1) & 0x40) == 0) // see if ACK is negated
        return TRUE;      
   }
   if ( PmonTimedOut == 2 )
   {
      if ( (inp(PBASE+1) & 0x40) != 0) // see if ACK is asserted
        return TRUE;      
   }
   return FALSE;
}
    
#ifdef DIRECT_TO_PARALLEL
void _cdecl dputc( int ch )
{
    int cnt;
//    if ( PmonTimedOut ) return; 

    cnt = 500000;
    while( (inp(PBASE+1) & 0x40) == 0)  // wait for ACK to be negated
    {
        if ( --cnt == 0 )
        {
            PmonTimedOut++;             // dying
        }
    }

    outp(PBASE,(char)ch);               // put char in output latch

    outp(PBASE+2,0x01);                 // strobe character
    cnt = 500000;
    while( (inp(PBASE+1) & 0x40) != 0)  // wait for ACK to be asserted
    {
        if ( --cnt == 0 )
        {
            PmonTimedOut++;             // Dead waiting for != 0
        }
    }
    outp(PBASE+2,0x00);                 // negate strobe
}

#endif // end of direct_to_parallel



#else // not in DEBUG
void  dprintf( char * fmt,... )
{
;
}
void  dputc( int ch )
{
;
}
void  dputs( char *str )
{
;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -