#include int putchar(int c); #ifndef DISABLE_PRINTF static char temp[80]; static int _cvt(int val, char *buf, int radix) { #ifdef PRINTF_HEX_ONLY int c; int i; int nz=0; // if(val<0) // { // putchar('-'); // val=-val; // } if(val) { for(i=0;i<8;++i) { c=(val>>28)&0xf; val<<=4; if(c) nz=1; // Non-zero? Start printing then. if(c>9) c+='A'-10; else c+='0'; if(nz) // If we've encountered only zeroes so far we don't print. putchar(c); } } else putchar('0'); return(0); #else char *cp = temp; const char *digits="0123456789ABCDEF"; int length = 0; if(val<0) { putchar('-'); val=-val; } if (val == 0) { /* Special case */ *cp++ = '0'; } else { while (val) { unsigned int c; c=val%radix; *cp++ = digits[c]; val /= radix; } } while (cp != temp) { *buf++ = *--cp; length++; } *buf = '\0'; return (length); #endif } #define is_digit(c) ((c >= '0') && (c <= '9')) static char vpfbuf[sizeof(long long)*8]; static int _vprintf(const char *fmt, va_list ap) { unsigned int c; int sign; int *s2; char *cp=vpfbuf; int left_prec, right_prec, zero_fill, pad, pad_on_right, i, islong, islonglong; unsigned int val = 0; int res = 0, length = 0; int nextfmt; // Because we haven't implemented loadb from ROM yet, we can't use *++. // We work around this by reading 32 bits at a time and shift/masking the bytes // individually. // This is only necessary if using the hardware implementation of the // loadb/storeb instructions and running from BlockRAM. Loadb/storeb from external // RAM is implemented. s2=(int*)fmt; nextfmt=0; do { int i; int cs=*s2++; for(i=0;i<4;++i) { char tmp[2]; c=(cs>>24)&0xff; cs<<=8; if(c==0) return(res); if(nextfmt) // Have we encountered a %? { nextfmt=0; left_prec = right_prec = pad_on_right = islong = islonglong = 0; sign = '\0'; // Fetch value [numeric descriptors only] switch (c) { case 'd': case 'x': val = (long)va_arg(ap, unsigned int); break; default: break; } // Process output switch (c) { case 'd': length = _cvt(val, vpfbuf, 10); cp = vpfbuf; break; case 'x': length = _cvt(val, vpfbuf, 16); cp = vpfbuf; break; case 's': cp = va_arg(ap, char *); puts(cp); length = 0; break; case 'c': c = va_arg(ap, int /*char*/); putchar(c); res++; continue; default: putchar('%'); putchar(c); res += 2; continue; } while (length-- > 0) { c = *cp++; putchar(c); res++; } } else { if (c == '%') nextfmt=1; else { putchar(c); res++; } } } } while(c); } int small_printf(const char *fmt, ...) { va_list ap; int ret; va_start(ap, fmt); ret = _vprintf(fmt, ap); va_end(ap); return (ret); } #endif