#include "biosdem.h" /* big bug on %d !! * printf for the lcd inside it */ #include #include #include /* * doprnt for PIC. Supports: * * %d decimal * %u unsigned * %o octal * %x hex (lower case) * %X hex (upper case) * %s string * %c character * * On the 14 bit PICS only: * Field widths and precision are supported (precision is significant * only for %s), including variable width, e.g. %*s * * Optionally (on 14 bitters) * * %ld long decimal * %lx long hex (lower case) * %lX long hex (upper case) * %lo long octal * * Even more optionally: * * %f float (really double) - field with and precision supported * %e float - scientific format * */ #ifdef __FLOAT #define __LONG 1 /* float requires long */ #endif #ifdef __LONG #define INT long #else #define INT short #endif /* variable globale */ #ifdef _PIC16 bank3 far char __printf_it_temp[16+1]; bank3 far char * bank3 __printf_it_where ; #else bank3 char __printf_it_temp[16+1]; bank3 char * bank3 __printf_it_where ; #endif bank3 char __printf_it_c; bank3 va_list __printf_it_ap; bank3 unsigned char __printf_it_sign; bank3 unsigned char __printf_it_prec; bank3 unsigned INT __printf_it_i; bank3 unsigned char __printf_it_retval; #ifdef __FLOAT bank3 unsigned long __printf_it_frac; bank3 unsigned long __printf_it_over; bank3 unsigned char __printf_it_digs; #endif #ifndef _PIC12 bank3 signed char __printf_it_width; #else #define __printf_it_width __printf_it_sign #endif #define pputch(c) (++__printf_it_retval, _IT_lcd_putchar(__printf_it_c)) unsigned char #ifdef _PIC16 _IT_lcd_printf( const char * f, ...) #else _IT_lcd_printf( const char * f, ...) #endif { __printf_it_where = __printf_it_temp; __printf_it_retval = 0; va_start(__printf_it_ap, f); while(__printf_it_c = *f++) if(__printf_it_c != '%') pputch(__printf_it_c); else { __printf_it_prec = 255; #ifndef _PIC12 __printf_it_width = 0; #endif __printf_it_sign = 0; loop: switch(__printf_it_c = *f++) { case 0: if(__printf_it_where) *__printf_it_where = 0; return __printf_it_retval; #ifndef _PIC12 case '*': __printf_it_width = va_arg(__printf_it_ap, int); goto loop; #if __LONG case 'l': __printf_it_sign |= 0x80; goto loop; #endif #endif case 'd': __printf_it_sign++; goto decimal; case 'x': case 'X': __printf_it_prec += 8; case 'o': __printf_it_prec -= 2; case 'u': decimal: { unsigned INT __printf_it_j; #if __LONG if(__printf_it_sign & 0x80) __printf_it_i = va_arg(__printf_it_ap, unsigned INT); else #endif __printf_it_i = va_arg(__printf_it_ap, int); if(__printf_it_sign & 1) { if((INT)__printf_it_i < 0) { __printf_it_i = -__printf_it_i; #ifndef _PIC12 __printf_it_width--; #endif } else __printf_it_sign = 0; } else { #if __LONG if(!(__printf_it_sign & 0x80)) __printf_it_i = (unsigned short)__printf_it_i; #endif __printf_it_sign = 0; } __printf_it_prec -= 255-10; putint: __printf_it_c = (unsigned INT)__printf_it_i % __printf_it_prec; *(unsigned INT *)&__printf_it_i /= __printf_it_prec; __printf_it_j = 1; while(__printf_it_j <= __printf_it_i) { __printf_it_j *= __printf_it_prec; #ifndef _PIC12 __printf_it_width--; #endif } #ifndef _PIC12 while(--__printf_it_width > 0) #if __FLOAT pputch(__printf_it_sign & 4 ? '0' : ' '); #else pputch(' '); #endif #endif if(__printf_it_sign & 1) pputch('-'); while(__printf_it_j /= __printf_it_prec) { __printf_it_width = (__printf_it_i/__printf_it_j)%__printf_it_prec; if(__printf_it_width > 9) __printf_it_width += 'A'-'0'-10; pputch(__printf_it_width+'0'); } if(__printf_it_c > 9) __printf_it_c += 'A'-'0'-10; pputch(__printf_it_c+'0'); #if __FLOAT if(__printf_it_sign & 2) { pputch('.'); __printf_it_i = __printf_it_frac; __printf_it_sign = 4; __printf_it_width = __printf_it_digs; __printf_it_prec = 10; goto putint; } #endif } break; #if __FLOAT case 'f': { double __printf_it_flt; __printf_it_flt = va_arg(__printf_it_ap, double); if(__printf_it_prec > 6) __printf_it_prec = 6; __printf_it_digs = __printf_it_prec; __printf_it_sign = 0; if(__printf_it_flt < 0) { __printf_it_sign = 1; __printf_it_flt = -__printf_it_flt; } if(__printf_it_digs == 0) { __printf_it_i = (unsigned long)(__printf_it_flt+0.5); __printf_it_prec = 10; goto putint; /* put as integer - no dot */ } __printf_it_width -= __printf_it_digs+1; __printf_it_i = (unsigned long)__printf_it_flt; __printf_it_flt -= (double)__printf_it_i; __printf_it_sign |= 2; __printf_it_over = 1; do { __printf_it_flt *= 10.0; __printf_it_over *= 10; } while(--__printf_it_prec); __printf_it_flt += 0.5; __printf_it_frac = (unsigned long)__printf_it_flt; /* adjust whole if frac pt. overflows */ if(__printf_it_frac >= __printf_it_over) { __printf_it_frac -= __printf_it_over; __printf_it_i++; } __printf_it_prec = 10; goto putint; } #endif case 'c': #ifndef _PIC12 while(__printf_it_width > 1) { pputch(' '); __printf_it_width--; } #endif __printf_it_c = va_arg(__printf_it_ap, int); pputch(__printf_it_c); continue; case 's': { const char * x; x = va_arg(__printf_it_ap, const char *); #ifndef _PIC12 __printf_it_c = 0; while(x[__printf_it_c]) __printf_it_c++; if(__printf_it_c < __printf_it_prec) __printf_it_prec = __printf_it_c; while(__printf_it_width > __printf_it_prec) { pputch(' '); __printf_it_width--; } while(__printf_it_prec--) { __printf_it_c = *x++; pputch(__printf_it_c); } #else while(__printf_it_c = *x++) pputch(__printf_it_c); #endif continue; } #ifndef _PIC12 case '.': if(*f == '*') { __printf_it_prec = va_arg(__printf_it_ap, int); f++; } else { __printf_it_prec = *f++ - '0'; __printf_it_c = *f; if(__printf_it_c >= '0' && __printf_it_c <= '9') { __printf_it_prec = __printf_it_prec*10 + __printf_it_c - '0'; f++; } } goto loop; default: if(__printf_it_c >= '0' && __printf_it_c <= '9') { __printf_it_width = __printf_it_width * 10 + __printf_it_c - '0'; goto loop; } #else default: #endif pputch(__printf_it_c); continue; } } if(__printf_it_where) *__printf_it_where = 0; return __printf_it_retval; }