]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/triton/v2_0/include/dprintf.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / hal / arm / xscale / triton / v2_0 / include / dprintf.c
1 //     Full Function UART        
2 #define FFRBR      ( 0x40100000 )          // Receive Buffer Register (read only)     
3 #define FFTHR      ( 0x40100000 )          // Transmit Holding Register (write only)     
4 #define FFIER      ( 0x40100004 )          // Interrupt Enable Register (read/write)     
5 #define FFIIR      ( 0x40100008 )          // Interrupt ID Register (read only)     
6 #define FFFCR      ( 0x40100008 )          // FIFO Control Register (write only)     
7 #define FFLCR      ( 0x4010000C )          // Line Control Register (read/write)     
8 #define FFMCR      ( 0x40100010 )          // Modem Control Register (read/write)     
9 #define FFLSR      ( 0x40100014 )          // Line Status Register (read only)     
10 #define FFMSR      ( 0x40100018 )          // Modem Status Register (read only)     
11 #define FFSPR      ( 0x4010001C )          // Scratch Pad Register (read/write)     
12 #define FFDLL      ( 0x40100000 )          // baud divisor lower byte (read/write)     
13 #define FFDLH      ( 0x40100004 )          // baud divisor higher byte (read/write)     
14 #define FFISR      ( 0x40100020 )          // slow Infrared Select Register (read/write)     
15
16
17 #define ANY_DISP_SEG 0x8000      // Set if should be displayed as segmented
18
19 #define FALSE 0
20 #define TRUE 1
21
22 typedef unsigned long DWORD;
23 typedef unsigned short WORD;
24 typedef unsigned char  BYTE;
25
26 typedef int BOOL;
27
28
29 typedef void    *   PVOID;
30 typedef DWORD   *   PDWORD;
31 typedef WORD    *   PWORD;
32 typedef BYTE    *   PBYTE;
33 typedef BOOL    *   PBOOL;
34 typedef char    *   PSTR;
35 typedef const char *    PCSTR;
36
37 typedef WORD     ROMWORD;
38 typedef DWORD    ROMDWORD;
39 typedef BYTE     ROMBYTE;
40 typedef char     ROMCHAR;
41 typedef PCSTR    PROMCHAR;
42
43
44 typedef void (* WRITECHAR)(BYTE);
45
46
47
48 //
49 // Address structure for printf %la and ScanAddress:
50 //
51 typedef struct {
52     WORD     Flags;
53     WORD     MemSpace;
54     DWORD    LinearAddress;
55     PVOID    SegAddress;
56 } AnyAddress, * FPANYADDRESS;
57
58
59 int
60 tolower( int value) {
61         if (value >= 'A' && value <='Z') 
62                 return (value + 0x20);
63         else
64                 return value;
65 }
66
67
68
69 static void iprintf(char * format, ...);    // Internal printf
70
71 static WRITECHAR writechar;
72
73 /*
74 ** define global storage for the sprint routine
75 */
76 char sprintbuf[1024];
77 unsigned short sbindex;
78
79
80
81
82 static void output_char(unsigned char data) {
83         while(!((*(volatile unsigned long int *)FFLSR) & 0x40)); // wait here for fifo not full
84         *(volatile unsigned long int *)FFTHR = (unsigned long int) data;
85 }
86
87
88
89
90 /////////////////////////////////////////////////////////////////////////
91 // FillSpaces() prints out a given number of spaces or zeroes
92 //
93 static void FillSpaces(int Size, BOOL DoIt, BOOL FillZero)
94 {
95     if (DoIt)
96         while (Size-- >0)
97             writechar((char) (FillZero ? '0' : ' '));
98 }
99
100 /////////////////////////////////////////////////////////////////////////
101 // HexDigit() returns the correct hexadecimal digit for a number
102 //
103 char HexDigit(DWORD value, char UpperLower)
104 {
105     if (value < 10)
106         return (char)(value + '0');
107
108     return (char)(value-10 + 'A' + UpperLower - 'X');
109 }
110
111 /////////////////////////////////////////////////////////////////////////
112 // PrintAddress prints a standard (segment:offset) or long address.
113 // It is an internal routine used by printf.
114 //
115 static void PrintAddress(PDWORD param, BOOL Long, WORD StringIndex)
116 {
117     static BYTE string0[] = "%04X:%04lX";
118     static BYTE string1[] = "%04x:%04lx";
119     static BYTE string2[] = "%01X/%07lX";
120     static BYTE string3[] = "%01x/%07lx";
121
122     static BYTE * strings[] = {string0,string1,string2,string3};
123
124     FPANYADDRESS a;
125
126     DWORD LinearAddress = param[0];
127     DWORD  MemSpace      = param[1];
128     WORD  SegValue;
129
130     if (Long)
131     {
132         a = (FPANYADDRESS)*((PDWORD)param);
133         LinearAddress = a->LinearAddress;
134         MemSpace      = a->MemSpace;
135         SegValue      = 0;
136
137         if ((a->Flags & ANY_DISP_SEG) == 0)
138             StringIndex += 2;
139         else
140         {
141             MemSpace = ((WORD)(LinearAddress >> 4) - SegValue);
142             MemSpace &= 0xF000;
143             MemSpace +=  SegValue;
144             LinearAddress -= ((DWORD)MemSpace << 4);
145         }
146     }
147     iprintf(strings[StringIndex],MemSpace,LinearAddress);
148 }
149
150 /////////////////////////////////////////////////////////////////////////
151 // Minimal printf implementation.  Supports:
152 //  % [-] [0] [<length>] [l] [s|c|x|i|d|u]
153 //
154 //  -     == Left justify
155 //  0     == Fill field with zeroes
156 // length == Minimum field width
157 //  l     == Doubleword for x|i|d|u
158 //  s     == string pointer
159 //  c     == single character
160 //  x     == hex number
161 //  i,d   == signed decimal number
162 //  u     == unsigned number
163 //  a     == address (segment:offset)
164 //  la    == long address (AnyAddress type)
165 //
166 void vpprintf(WRITECHAR outroutine, PCSTR * ptrptr)
167 {
168     static BYTE Percent[]      = "%";
169     static BYTE PercentQuery[] = "%???";
170     static BYTE NullMsg[]      = "";
171
172     PCSTR ptr     = *ptrptr;
173     PDWORD param   = (PDWORD)(ptrptr+1);
174     BOOL ZeroFill;
175     int  MinWidth;
176     BOOL Long;
177     enum {ParseIncomplete, ParseString, ParseNum, ParsePercent,
178                    ParseAddress, ParseNonsense} ParseType;
179     BOOL LeftJustify;
180     PSTR sPtr;
181     WORD NumBase;
182     BOOL Signed;
183     char ch;
184     char NumString[16];          // Holds largest number
185
186     writechar = outroutine;
187
188     for (;;)
189     {
190         switch (ch = *(ptr++))
191         {
192             case 0:
193                return;
194             case '%':
195                 ZeroFill = FALSE;
196                 MinWidth = 0;
197                 Long = FALSE;
198                 LeftJustify = FALSE;
199                 sPtr = 0;
200                 NumBase = 10;
201                 Signed = FALSE;
202                 ParseType = ParseIncomplete;
203                 while (ParseType == ParseIncomplete)
204                     switch (tolower(ch = *(ptr++)))
205                     {
206                         case 0:
207                             ptr--;
208                             ParseType = ParseNonsense;
209                             break;
210                         case '-':
211                             LeftJustify = TRUE;
212                             break;
213                         case '0':
214                         case '1':
215                         case '2':
216                         case '3':
217                         case '4':
218                         case '5':
219                         case '6':
220                         case '7':
221                         case '8':
222                         case '9':
223                             MinWidth = MinWidth*10 + ch - '0';
224                             if (MinWidth == 0)
225                                 ZeroFill = TRUE;
226                             break;
227                         case 'l':
228                             Long = TRUE;
229                             break;
230                         case 'c':
231                             sPtr = (PSTR)(param++);
232                             sPtr[1] = 0;
233                             ParseType = ParseString;
234                             break;
235                         case 's':
236                             sPtr = (PSTR)param[0];
237                             param ++;
238                             ParseType = ParseString;
239                             break;
240                         case 'x':
241                             NumBase = 16;
242                             ParseType = ParseNum;
243                             break;
244                         case 'd':
245                         case 'i':
246                             Signed = TRUE;
247                         case 'u':
248                             ParseType = ParseNum;
249                             break;
250                         case 'a':
251                             ParseType = ParseAddress;
252                             break;
253                         case '%':
254                             ParseType = ParsePercent;
255                             break;
256                         default:
257                             ParseType = ParseNonsense;
258                             break;
259                     }
260                 switch (ParseType)
261                 {
262                     case ParsePercent:
263                         sPtr = (PSTR)Percent;
264                         break;
265                     case ParseNonsense:
266                         sPtr = (PSTR)PercentQuery;
267                         break;
268
269                     case ParseAddress:
270                         MinWidth -= 9;
271                         FillSpaces(MinWidth,!LeftJustify,ZeroFill);
272                         PrintAddress(param,Long,(WORD)(ch=='a'));
273                         sPtr = (PSTR)NullMsg;
274                         param += 2;
275                         break;
276
277                     case ParseNum:
278                     {
279                         DWORD value;
280 /*
281 **  The following modification made to support the Microsoft 32 bit
282 **  compiler (which is required because the MaCraigor API uses a
283 **  DLL, which is only supported by the 32 bit compiler).
284 **
285 **  The 16 bit compiler aligns stack parameters as 16 bit words.  Thus
286 **  a byte value passed as a parameter to the printf will be padded by
287 **  a zero  to take up one word on the stack.  The else statement below
288 **  would correctly get the byte value and then bump the parameter pointer
289 **  past the pad char to point at the next parameter.
290 **
291 **  But in the 32 bit compiler, parameters are passed as DWORDs, or unsigned
292 **  longs, and take up 32 bits on the stack.  Thus, the if(Long) is
293 **  always true for the purposes of incrementing the param pointer.  param
294 **  is of type LPWORD, so one increment moves it by two bytes.
295 */
296 //                        if (Long)
297 //                        {
298                             value = *((PDWORD)param);
299                             param ++;
300 //                        }
301 //                        else
302 //                            value = *(((LPWORD)param)++);
303                         if (Signed)
304                         {
305                             Signed = (value >= (0x8000UL << (16*Long)));
306                             if (Signed)
307                             {
308                                 value = 0-value;
309                                 if (!Long)
310                                     value &= 0x7FFF;
311                             }
312                         }
313
314                         sPtr = &NumString[sizeof(NumString)];
315                         *(--sPtr) = 0;
316                         do {
317                             *(--sPtr) = HexDigit(value % NumBase,ch);
318                             value /= NumBase;
319                         } while (value > 0);
320                         if (Signed)
321                             *(--sPtr) = '-';
322                     }
323                 }
324                 MinWidth -= strlen(sPtr);
325                 FillSpaces(MinWidth,!LeftJustify,ZeroFill);
326                 while (*sPtr != 0)
327                     writechar(*(sPtr++));
328                 FillSpaces(MinWidth,LeftJustify,FALSE);
329                 break;
330
331             default:
332                 writechar(ch);
333                                 // if this was a line feed, also add a Carriage return
334                                 if(ch == 0xa) writechar(0xd);
335                 break;
336         }
337     }
338 }
339
340 /////////////////////////////////////////////////////////////////////////
341 //   iprintf - Internal printf for recursion, doesn't alter writechar
342 //
343 static void iprintf(char * format, ...)
344 {
345     vpprintf(writechar,(PCSTR *)&format);
346 }
347
348 /////////////////////////////////////////////////////////////////////////
349 //   printf - 
350 //
351 void dprintf(char * format, ...)
352 {
353     vpprintf(output_char,(PCSTR *)&format);
354 }
355
356 /* character write routine for sprintf */
357 void putspbuf(char data)
358 {
359         sprintbuf[sbindex++] = data;
360 }
361 /////////////////////////////////////////////////////////////////////////
362 //   sprintf - 
363 //
364 void sprintf(char * buffer, char * format, ...)
365 {
366         sbindex = 0;
367     vpprintf((WRITECHAR)putspbuf,(PCSTR *)&format);
368         putspbuf(0);
369         strcpy(buffer,sprintbuf);
370 }