* support/regression/ports/mcs51-xstack-auto/spec.mk: forgot -I(...)/mcs51
[fw/sdcc] / device / lib / printf_large.c
index cad0a0476f93a0b0d7e63b5d4a8a1680535ee3de..ba43fd546cb52ccbf93a8765cf46e7d3c0b022e5 100644 (file)
    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(SDCC_mcs51)
-  #if defined(SDCC_STACK_AUTO)
-    #if defined(SDCC_USE_XSTACK)
-      #define NEAR pdata
-    #else
-      //strange enough "idata" doesn't work
-      #define NEAR data
-    #endif
-  #elif defined(SDCC_MODEL_LARGE)
-    #define NEAR xdata
-  #else
-    #define NEAR data
-  #endif
-#else
-  #define NEAR
-#endif
-
 #if defined(__ds390)
 #define USE_FLOATS 1
 #endif
@@ -60,6 +33,7 @@
 #include <ctype.h>
 #include <stdio.h>
 #include <stdbool.h>
+#include <sdcc-lib.h>
 
 #define PTR value.ptr
 
@@ -95,15 +69,7 @@ static const char memory_id[] = "IXCP-";
   static BOOL lower_case;
   static pfn_outputchar output_char;
   static void* p;
-
-  #ifdef ASM_ALLOWED
-    static bool   lsd;
-
-    /* this one NEEDS to be in data */
-    static data value_t value;
-  #else
-    static value_t value;
-  #endif
+  static value_t value;
 #endif
 
 /****************************************************************************/
@@ -138,39 +104,7 @@ 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
+#if defined SDCC_STACK_AUTO
 static void calculate_digit( value_t* value, unsigned char radix )
 {
   unsigned char i;
@@ -231,7 +165,7 @@ static int output_float (float f, unsigned char reqWidth,
                          BOOL left, BOOL zero, BOOL sign, BOOL space)
 #endif
 {
-  char negative=0;
+  BOOL negative=0;
   unsigned long integerPart;
   float decimalPart;
   char fpBuffer[128];
@@ -295,14 +229,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
@@ -416,9 +355,7 @@ int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list
   BOOL   lower_case;
   value_t value;
 #endif
-#ifndef ASM_ALLOWED
   BOOL   lsd;
-#endif
 
   unsigned char radix;
   int charsOutputted;
@@ -532,6 +469,10 @@ get_conversion_spec:
 #else
         length = strlen(PTR);
 #endif
+        if ( decimals == -1 )
+        {
+          decimals = length;
+        }
         if ( ( !left_justify ) && (length < width) )
         {
           width -= length;
@@ -542,7 +483,7 @@ get_conversion_spec:
           }
         }
 
-        while ( *PTR )
+        while ( *PTR  && (decimals-- > 0))
         {
           output_char( *PTR++, p );
           charsOutputted++;
@@ -639,15 +580,17 @@ get_conversion_spec:
       {
         // Apperently we have to output an integral type
         // with radix "radix"
-#ifndef ASM_ALLOWED
         unsigned char store[6];
-        unsigned char NEAR *pstore = &store[5];
-#endif
+        unsigned char _AUTOMEM *pstore = &store[5];
 
         // store value in byte[0] (LSB) ... byte[3] (MSB)
         if (char_argument)
         {
           value.l = va_arg(ap,char);
+          if (!signed_argument)
+          {
+            value.l &= 0xFF;
+          }
         }
         else if (long_argument)
         {
@@ -656,6 +599,10 @@ get_conversion_spec:
         else // must be int
         {
           value.l = va_arg(ap,int);
+          if (!signed_argument)
+          {
+            value.l &= 0xFFFF;
+          }
         }
 
         if ( signed_argument )
@@ -676,21 +623,6 @@ get_conversion_spec:
 #else
           calculate_digit(radix);
 #endif
-#if defined ASM_ALLOWED
-_asm
-  jb   _lsd,1$
-  pop  b                ; b = <lsd>
-  mov  a,_value+4       ; a = <msd>
-  swap a
-  orl  b,a              ; b = <msd><lsd>
-  push b
-  sjmp 2$
-1$:
-  mov  a,_value+4       ; a = <lsd>
-  push acc
-2$:
-_endasm;
-#else
           if (!lsd)
           {
             *pstore = (value.byte[4] << 4) | (value.byte[4] >> 4) | *pstore;
@@ -700,11 +632,9 @@ _endasm;
           {
             *pstore = value.byte[4];
           }
-#endif
           length++;
           lsd = !lsd;
-        } while( (value.byte[0] != 0) || (value.byte[1] != 0) ||
-                 (value.byte[2] != 0) || (value.byte[3] != 0) );
+        } while( value.ul );
 
         if (width == 0)
         {
@@ -771,22 +701,6 @@ _endasm;
         while( length-- )
         {
           lsd = !lsd;
-#ifdef ASM_ALLOWED
-_asm
-  jb   _lsd,3$
-  pop  acc              ; a = <msd><lsd>
-  nop                   ; to disable the "optimizer"
-  push acc
-  swap a
-  anl  a,#0x0F          ; a = <msd>
-  sjmp 4$
-3$:
-  pop  acc
-  anl  a,#0x0F          ; a = <lsd>
-4$:
-  mov  _value+4,a
-_endasm;
-#else
           if (!lsd)
           {
             pstore++;
@@ -796,7 +710,6 @@ _endasm;
           {
             value.byte[4] = *pstore & 0x0F;
           }
-#endif
 #ifdef SDCC_STACK_AUTO
           output_digit( value.byte[4], lower_case, output_char, p );
 #else