X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Fprintf_large.c;h=7d42abc25f3b79692bebd9ad9dab5a953be01505;hb=d7b30120ae115e8929d57e25038ca76dde13974e;hp=b5cfb5e7a07cbb32b51dfb7b7bc3027778c653e7;hpb=3b5dc7119c7a5d3760e4bef555ef4029a1f2712a;p=fw%2Fsdcc diff --git a/device/lib/printf_large.c b/device/lib/printf_large.c index b5cfb5e7..7d42abc2 100644 --- a/device/lib/printf_large.c +++ b/device/lib/printf_large.c @@ -24,17 +24,7 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#ifdef SDCC_STACK_AUTO - #ifdef ASM_ALLOWED - /* Eventually we should get rid of ASM_ALLOWED completely as it */ - /* prevents portability, clobbers this source and brings only 2% */ - /* optimization. A better alternative is a completely handcrafted */ - /* asm version if needed. */ - #undef ASM_ALLOWED - #endif -#endif - -#if defined(__ds390) +#if defined (SDCC_ds390) #define USE_FLOATS 1 #endif @@ -60,9 +50,21 @@ #ifdef toupper #undef toupper #endif +#ifdef tolower +#undef tolower +#endif +#ifdef islower +#undef islower +#endif +#ifdef isdigit +#undef isdigit +#endif //#define toupper(c) ((c)&=~0x20) #define toupper(c) ((c)&=0xDF) +#define tolower(c) ((c)|=0x20) +#define islower(c) ((unsigned char)c >= (unsigned char)'a' && (unsigned char)c <= (unsigned char)'z') +#define isdigit(c) ((unsigned char)c >= (unsigned char)'0' && (unsigned char)c <= (unsigned char)'9') typedef union { @@ -73,39 +75,61 @@ typedef union char *ptr; } value_t; -static const char memory_id[] = "IXCP-"; - #ifndef SDCC_STACK_AUTO static BOOL lower_case; static pfn_outputchar output_char; static void* p; + static value_t value; + static int charsOutputted; +#endif - #ifdef ASM_ALLOWED - static bool lsd; +/****************************************************************************/ - /* this one NEEDS to be in data */ - static data value_t value; - #else - static value_t value; - #endif +#ifdef SDCC_STACK_AUTO + #define OUTPUT_CHAR(c, p) { output_char (c, p); charsOutputted++; } +#else + #define OUTPUT_CHAR(c, p) _output_char (c) + static void _output_char( unsigned char c ) + { + output_char( c, p ); + charsOutputted++; + } #endif -/****************************************************************************/ +/*--------------------------------------------------------------------------*/ #ifdef SDCC_STACK_AUTO static void output_digit( unsigned char n, BOOL lower_case, pfn_outputchar output_char, void* p ) + { + register unsigned char c = n + (unsigned char)'0'; + + if (c > (unsigned char)'9') + { + c += (unsigned char)('A' - '0' - 10); + if (lower_case) + c += (unsigned char)('a' - 'A'); + } + output_char( c, p ); + } #else static void output_digit( unsigned char n ) -#endif { - output_char( n <= 9 ? '0'+n : - (lower_case ? n+(char)('a'-10) : n+(char)('A'-10)), p ); + register unsigned char c = n + (unsigned char)'0'; + + if (c > (unsigned char)'9') + { + c += (unsigned char)('A' - '0' - 10); + if (lower_case) + c = tolower(c); + } + _output_char( c ); } +#endif /*--------------------------------------------------------------------------*/ #ifdef SDCC_STACK_AUTO - #define OUTPUT_2DIGITS( B ) output_2digits( B, lower_case, output_char, p ) + #define OUTPUT_2DIGITS( B ) { output_2digits( B, lower_case, output_char, p ); charsOutputted += 2; } static void output_2digits( unsigned char b, BOOL lower_case, pfn_outputchar output_char, void* p ) { output_digit( b>>4, lower_case, output_char, p ); @@ -122,71 +146,47 @@ static const char memory_id[] = "IXCP-"; /*--------------------------------------------------------------------------*/ -#if defined ASM_ALLOWED -static void calculate_digit( unsigned char radix ) -{ - unsigned char i; - - for( i = 32; i != 0; i-- ) - { -_asm - clr c - mov a,_value+0 - rlc a - mov _value+0,a - mov a,_value+1 - rlc a - mov _value+1,a - mov a,_value+2 - rlc a - mov _value+2,a - mov a,_value+3 - rlc a - mov _value+3,a - mov a,_value+4 - rlc a - mov _value+4,a -_endasm; - if (radix <= value.byte[4] ) - { - value.byte[4] -= radix; - value.byte[0]++; - } - } -} -#elif defined SDCC_STACK_AUTO -static void calculate_digit( value_t* value, unsigned char radix ) +#if defined SDCC_STACK_AUTO +static void calculate_digit( value_t _AUTOMEM * value, unsigned char radix ) { - unsigned char i; + unsigned long ul = value->ul; + unsigned char _AUTOMEM * pb4 = &value->byte[4]; + unsigned char i = 32; - for( i = 32; i != 0; i-- ) + do { - value->byte[4] = (value->byte[4] << 1) | ((value->ul >> 31) & 0x01); - value->ul <<= 1; + *pb4 = (*pb4 << 1) | ((ul >> 31) & 0x01); + ul <<= 1; - if (radix <= value->byte[4] ) + if (radix <= *pb4 ) { - value->byte[4] -= radix; - value->ul |= 1; + *pb4 -= radix; + ul |= 1; } - } + } while (--i); + value->ul = ul; } #else static void calculate_digit( unsigned char radix ) { - unsigned char i; + register unsigned long ul = value.ul; + register unsigned char b4 = value.byte[4]; + register unsigned char i = 32; - for( i = 32; i != 0; i-- ) + do { - value.byte[4] = (value.byte[4] << 1) | ((value.ul >> 31) & 0x01); - value.ul <<= 1; + b4 = (b4 << 1); + b4 |= (ul >> 31) & 0x01; + ul <<= 1; - if (radix <= value.byte[4] ) + if (radix <= b4 ) { - value.byte[4] -= radix; - value.ul |= 1; + b4 -= radix; + ul |= 1; } - } + } while (--i); + value.ul = ul; + value.byte[4] = b4; } #endif @@ -204,24 +204,28 @@ static void calculate_digit( unsigned char radix ) #ifdef SDCC_STACK_AUTO #define OUTPUT_FLOAT(F, W, D, L, Z, S, P) output_float(F, W, D, L, Z, S, P, output_char, p) -static int output_float (float f, unsigned char reqWidth, - signed char reqDecimals, - BOOL left, BOOL zero, BOOL sign, BOOL space, - pfn_outputchar output_char, void* p) +static unsigned char +output_float (float f, unsigned char reqWidth, + signed char reqDecimals, + BOOL left, BOOL zero, BOOL sign, BOOL space, + pfn_outputchar output_char, void* p) +{ + unsigned char charsOutputted = 0; + char fpBuffer[128]; #else #define OUTPUT_FLOAT(F, W, D, L, Z, S, P) output_float(F, W, D, L, Z, S, P) -static int output_float (float f, unsigned char reqWidth, - signed char reqDecimals, - BOOL left, BOOL zero, BOOL sign, BOOL space) -#endif +static void +output_float (float f, unsigned char reqWidth, + signed char reqDecimals, + BOOL left, BOOL zero, BOOL sign, BOOL space) { - char negative=0; + xdata char fpBuffer[128]; +#endif //SDCC_STACK_AUTO + BOOL negative = 0; unsigned long integerPart; float decimalPart; - char fpBuffer[128]; char fpBI=0, fpBD; unsigned char minWidth, i; - int charsOutputted=0; // save the sign if (f<0) { @@ -237,26 +241,29 @@ static int output_float (float f, unsigned char reqWidth, for ( ; f < 1.0; exp--) f *=10.0; if (negative) { - output_char ('-', p); - charsOutputted++; + OUTPUT_CHAR ('-', p); } else { if (sign) { - output_char ('+', p); - charsOutputted++; + OUTPUT_CHAR ('+', p); } } +#ifdef SDCC_STACK_AUTO charsOutputted += OUTPUT_FLOAT(f, 0, reqDecimals, 0, 0, 0, 0); - output_char ('e', p); - charsOutputted++; +#else + OUTPUT_FLOAT(f, 0, reqDecimals, 0, 0, 0, 0); +#endif + OUTPUT_CHAR ('e', p); if (exp<0) { - output_char ('-', p); - charsOutputted++; + OUTPUT_CHAR ('-', p); exp = -exp; } - output_char ('0'+exp/10, p); - output_char ('0'+exp%10, p); - charsOutputted += 2; + OUTPUT_CHAR ('0'+exp/10, p); + OUTPUT_CHAR ('0'+exp%10, p); +#ifdef SDCC_STACK_AUTO return charsOutputted; +#else + return; +#endif //SDCC_STACK_AUTO } // split the float @@ -279,14 +286,19 @@ static int output_float (float f, unsigned char reqWidth, // fill buffer with the decimalPart (in normal order) fpBD=fpBI; - if (i=reqDecimals /* that's an assignment */) { - do { + + for (i=reqDecimals; i>1; i--) { decimalPart *= 10.0; // truncate the float integerPart=decimalPart; fpBuffer[fpBD++]='0' + integerPart; decimalPart-=integerPart; - } while (--i); + } + if (i) { + decimalPart *= 10.0; + // truncate the float + integerPart = decimalPart + 0.5; + fpBuffer[fpBD++] = '0' + integerPart; } minWidth=fpBI; // we need at least these @@ -298,93 +310,82 @@ static int output_float (float f, unsigned char reqWidth, if (zero) { if (negative) { - output_char('-', p); - charsOutputted++; + OUTPUT_CHAR('-', p); } else if (sign) { - output_char('+', p); - charsOutputted++; + OUTPUT_CHAR('+', p); } else if (space) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } while (reqWidth-->minWidth) { - output_char('0', p); - charsOutputted++; + OUTPUT_CHAR('0', p); } } else { while (reqWidth-->minWidth) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } if (negative) { - output_char('-', p); - charsOutputted++; + OUTPUT_CHAR('-', p); } else if (sign) { - output_char('+', p); - charsOutputted++; + OUTPUT_CHAR('+', p); } else if (space) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } } } else { if (negative) { - output_char('-', p); - charsOutputted++; + OUTPUT_CHAR('-', p); } else if (sign) { - output_char('+', p); - charsOutputted++; + OUTPUT_CHAR('+', p); } else if (space) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } } // output the integer part i=fpBI-1; do { - output_char (fpBuffer[i], p); - charsOutputted++; + OUTPUT_CHAR (fpBuffer[i], p); } while (i--); // ouput the decimal part if (reqDecimals) { - output_char ('.', p); - charsOutputted++; + OUTPUT_CHAR ('.', p); i=fpBI; while (reqDecimals--) { - output_char (fpBuffer[i++], p); - charsOutputted++; + OUTPUT_CHAR (fpBuffer[i++], p); } } if (left && reqWidth>minWidth) { while (reqWidth-->minWidth) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } } +#ifdef SDCC_STACK_AUTO return charsOutputted; +#else + return; +#endif //SDCC_STACK_AUTO } -#endif +#endif //USE_FLOATS int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list ap) { @@ -399,13 +400,11 @@ int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list #ifdef SDCC_STACK_AUTO BOOL lower_case; value_t value; + int charsOutputted; #endif -#ifndef ASM_ALLOWED BOOL lsd; -#endif unsigned char radix; - int charsOutputted; unsigned char width; signed char decimals; unsigned char length; @@ -420,7 +419,7 @@ int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list #endif // reset output chars - charsOutputted=0; + charsOutputted = 0; #ifdef SDCC_ds390 if (format==0) { @@ -437,10 +436,10 @@ int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list prefix_sign = 0; prefix_space = 0; signed_argument = 0; - radix = 0; char_argument = 0; long_argument = 0; float_argument = 0; + radix = 0; width = 0; decimals = -1; @@ -449,8 +448,7 @@ get_conversion_spec: c = *format++; if (c=='%') { - output_char(c, p); - charsOutputted++; + OUTPUT_CHAR(c, p); continue; } @@ -474,11 +472,13 @@ get_conversion_spec: goto get_conversion_spec; } - lower_case = islower(c); - if (lower_case) + if (islower(c)) { c = toupper(c); + lower_case = 1; } + else + lower_case = 0; switch( c ) { @@ -499,8 +499,11 @@ get_conversion_spec: goto get_conversion_spec; case 'C': - output_char( va_arg(ap,int), p ); - charsOutputted++; + if( char_argument ) + c = va_arg(ap,char); + else + c = va_arg(ap,int); + OUTPUT_CHAR( c, p ); break; case 'S': @@ -516,20 +519,23 @@ get_conversion_spec: #else length = strlen(PTR); #endif + if ( decimals == -1 ) + { + decimals = length; + } if ( ( !left_justify ) && (length < width) ) { width -= length; while( width-- != 0 ) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); } } - while ( *PTR ) + while ( (c = *PTR) && (decimals-- > 0)) { - output_char( *PTR++, p ); - charsOutputted++; + OUTPUT_CHAR( c, p ); + PTR++; } if ( left_justify && (length < width)) @@ -537,8 +543,7 @@ get_conversion_spec: width -= length; while( width-- != 0 ) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); } } break; @@ -546,28 +551,52 @@ get_conversion_spec: case 'P': PTR = va_arg(ap,ptr_t); -#ifdef SDCC_ds390 - output_char(memory_id[(value.byte[3] > 3) ? 4 : value.byte[3]], p ); - output_char(':', p); - output_char('0', p); - output_char('x', p); +#if defined (SDCC_ds390) + { + unsigned char memtype = value.byte[3]; + if (memtype > 0x80) + c = 'C'; + else if (memtype > 0x60) + c = 'P'; + else if (memtype > 0x40) + c = 'I'; + else + c = 'X'; + } + OUTPUT_CHAR(c, p); + OUTPUT_CHAR(':', p); + OUTPUT_CHAR('0', p); + OUTPUT_CHAR('x', p); OUTPUT_2DIGITS( value.byte[2] ); OUTPUT_2DIGITS( value.byte[1] ); OUTPUT_2DIGITS( value.byte[0] ); - charsOutputted += 10; -#else - output_char( memory_id[(value.byte[2] > 3) ? 4 : value.byte[2]], p ); - output_char(':', p); - output_char('0', p); - output_char('x', p); - if ((value.byte[2] != 0x00 /* DSEG */) && - (value.byte[2] != 0x03 /* SSEG */)) +#elif defined (SDCC_mcs51) + { + unsigned char memtype = value.byte[2]; + if (memtype > 0x80) + c = 'C'; + else if (memtype > 0x60) + c = 'P'; + else if (memtype > 0x40) + c = 'I'; + else + c = 'X'; + } + OUTPUT_CHAR(c, p); + OUTPUT_CHAR(':', p); + OUTPUT_CHAR('0', p); + OUTPUT_CHAR('x', p); + if ((c != 'I' /* idata */) && + (c != 'P' /* pdata */)) { OUTPUT_2DIGITS( value.byte[1] ); - charsOutputted += 2; } OUTPUT_2DIGITS( value.byte[0] ); - charsOutputted += 6; +#else + OUTPUT_CHAR('0', p); + OUTPUT_CHAR('x', p); + OUTPUT_2DIGITS( value.byte[1] ); + OUTPUT_2DIGITS( value.byte[0] ); #endif break; @@ -595,8 +624,7 @@ get_conversion_spec: default: // nothing special, just output the character - output_char( c, p ); - charsOutputted++; + OUTPUT_CHAR( c, p ); break; } @@ -606,8 +634,7 @@ get_conversion_spec: PTR=""; while (c=*PTR++) { - output_char (c, p); - charsOutputted++; + OUTPUT_CHAR (c, p); } // treat as long hex //radix=16; @@ -616,17 +643,20 @@ get_conversion_spec: //width=8; #else // ignore b and l conversion spec for now +#ifdef SDCC_STACK_AUTO charsOutputted += OUTPUT_FLOAT(value.f, width, decimals, left_justify, zero_padding, prefix_sign, prefix_space); -#endif +#else + OUTPUT_FLOAT(value.f, width, decimals, left_justify, + zero_padding, prefix_sign, prefix_space); +#endif //SDCC_STACK_AUTO +#endif //USE_FLOATS } else if (radix != 0) { // Apperently we have to output an integral type // with radix "radix" -#ifndef ASM_ALLOWED unsigned char store[6]; unsigned char _AUTOMEM *pstore = &store[5]; -#endif // store value in byte[0] (LSB) ... byte[3] (MSB) if (char_argument) @@ -668,21 +698,6 @@ get_conversion_spec: #else calculate_digit(radix); #endif -#if defined ASM_ALLOWED -_asm - jb _lsd,1$ - pop b ; b = - mov a,_value+4 ; a = - swap a - orl b,a ; b = - push b - sjmp 2$ -1$: - mov a,_value+4 ; a = - push acc -2$: -_endasm; -#else if (!lsd) { *pstore = (value.byte[4] << 4) | (value.byte[4] >> 4) | *pstore; @@ -692,7 +707,6 @@ _endasm; { *pstore = value.byte[4]; } -#endif length++; lsd = !lsd; } while( value.ul ); @@ -710,16 +724,14 @@ _endasm; { while ( width > (unsigned char) (length+1) ) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); width--; } } if (signed_argument) // this now means the original value was negative { - output_char( '-', p ); - charsOutputted++; + OUTPUT_CHAR( '-', p ); // adjust width to compensate for this character width--; } @@ -728,15 +740,13 @@ _endasm; // value > 0 if (prefix_sign) { - output_char( '+', p ); - charsOutputted++; + OUTPUT_CHAR( '+', p ); // adjust width to compensate for this character width--; } else if (prefix_space) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); // adjust width to compensate for this character width--; } @@ -746,8 +756,7 @@ _endasm; if (!left_justify) while ( width-- > length ) { - output_char( zero_padding ? '0' : ' ', p ); - charsOutputted++; + OUTPUT_CHAR( zero_padding ? '0' : ' ', p ); } else { @@ -762,22 +771,6 @@ _endasm; while( length-- ) { lsd = !lsd; -#ifdef ASM_ALLOWED -_asm - jb _lsd,3$ - pop acc ; a = - nop ; to disable the "optimizer" - push acc - swap a - anl a,#0x0F ; a = - sjmp 4$ -3$: - pop acc - anl a,#0x0F ; a = -4$: - mov _value+4,a -_endasm; -#else if (!lsd) { pstore++; @@ -787,27 +780,24 @@ _endasm; { value.byte[4] = *pstore & 0x0F; } -#endif #ifdef SDCC_STACK_AUTO output_digit( value.byte[4], lower_case, output_char, p ); + charsOutputted++; #else output_digit( value.byte[4] ); #endif - charsOutputted++; } if (left_justify) while (width-- > 0) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } } } else { // nothing special, just output the character - output_char( c, p ); - charsOutputted++; + OUTPUT_CHAR( c, p ); } }