1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - libraries - OS
3   File:     os_printf.c
4 
5   Copyright 2003-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #include        <nitro.h>
18 #include        <nitro/dbghost.h>
19 
20 //---------------- For IS-NITRO-DEBUGGER
21 #ifdef          SDK_LINK_ISD
22 # pragma warn_extracomma off
23 # include       <isdbglib.h>           // Has extra comma in enum
24 # pragma warn_extracomma reset
25 #else
26 void    ISDPrint(const char *);
27 #endif
28 
29 //---------------- For IS-TWL-DEBUGGER
30 #ifdef          SDK_LINK_ISTD
31 # pragma warn_extracomma off
32 # include       <istdbglib.h>          // Has extra comma in enum
33 # pragma warn_extracomma reset
34 #else
35 void    ISTDPrintEx(int console, const char *);
36 #endif
37 //---- Print output
38 #ifdef SDK_ARM9
39 #define OSi_PRINT_OUTPUT        (*(u8*)HW_PRINT_OUTPUT_ARM9)
40 #define OSi_PRINT_ERR_OUTPUT    (*(u8*)HW_PRINT_OUTPUT_ARM9ERR)
41 #else
42 #define OSi_PRINT_OUTPUT        (*(u8*)HW_PRINT_OUTPUT_ARM7)
43 #define OSi_PRINT_ERR_OUTPUT    (*(u8*)HW_PRINT_OUTPUT_ARM7ERR)
44 #endif
45 
46 #ifndef SDK_FINALROM
47 static char common_buffer[256];        // Thread unsafe, but less use of stack
48 #endif
49 
50 #if !defined(SDK_FINALROM) && defined(SDK_NO_MESSAGE)
51 #undef OSi_Warning
52 #undef OSi_TWarning
53 #undef OSi_Panic
54 #undef OSi_TPanic
55 void    OSi_Warning(const char *file, int line, const char *fmt, ...);
56 void    OSi_TWarning(const char *file, int line, const char *fmt, ...);
57 void    OSi_Panic(const char *file, int line, const char *fmt, ...);
58 void    OSi_TPanic(const char *file, int line, const char *fmt, ...);
59 #endif /* SDK_NO_MESSAGE */
60 
61 
62 /*---------------------------------------------------------------------------*
63   Name:         OS_PutChar
64                 OS_FPutChar
65 
66   Description:  Puts a letter for debug console.
67 
68   Arguments:    console: Output window
69                 c: Char code, should be 0x01-0xff
70 
71   Returns:      None.
72  *---------------------------------------------------------------------------*/
73 #ifndef SDK_FINALROM
OS_PutChar(char c)74 SDK_WEAK_SYMBOL void OS_PutChar(char c)
75 {
76 	OS_FPutChar((int)OSi_PRINT_OUTPUT, c);
77 }
78 
OS_FPutChar(int console,char c)79 SDK_WEAK_SYMBOL void OS_FPutChar(int console, char c)
80 {
81     char    str[2];
82 
83     str[0] = c;
84     str[1] = '\0';
85 
86     // Because of no putchar-type function on ISDebugger library,
87     // use 'putstring' for a single letter outputting
88     OS_FPutString(console, str);
89 }
90 #endif
91 
92 /*---------------------------------------------------------------------------*
93   Name:         OS_FPutString
94 
95   Description:  put a string to debug console.
96                 console port are automatically switched depends on emu/hw
97 
98   Arguments:    console : output window
99                 str: String
100 
101   Returns:      None.
102  *---------------------------------------------------------------------------*/
103 static void OS_PutStringDefault(const char* str);
104 static void OS_FPutStringInit(int console, const char *str);
105 
106 #ifndef SDK_FINALROM
107 static void OS_FPutStringDummy(int console, const char *str);
108 static void OS_FPutStringAris(int console, const char *str);
109 static void OS_FPutStringISD(int console, const char *str);
110 static void OS_FPutStringISTD(int console, const char *str);
111 #ifdef  SDK_ARM7
112 static void OS_FPutStringPrnSrv(int console, const char *str);
113 #endif
114 #endif
115 
116 #ifndef SDK_FINALROM
117 void    (*OS_PutString)  (const char *str) = OS_PutStringDefault;
118 void    (*OS_FPutString) (int console, const char *str) = OS_FPutStringInit;
119 void    (*OSi_FuncTerminate) (void) = OS_Terminate;
120 //----  Hook function
121 static OSFPutStringHookType  OSi_FPutStringHook = NULL;
122 #endif
123 
124 
125 /*---------------------------------------------------------------------------*
126   Name:         OS_PutStringDefault
127   Description:  OS_PutString initializer
128  *---------------------------------------------------------------------------*/
OS_PutStringDefault(const char * str)129 static void OS_PutStringDefault(const char* str)
130 {
131 #pragma unused(str)
132 #ifndef SDK_FINALROM
133     OS_FPutString(OS_PRINT_OUTPUT_CURRENT, str);
134 #endif
135 }
136 
137 /*---------------------------------------------------------------------------*
138   Name:         OS_FPutStringInit
139   Description:  OS_FPutString initializer
140  *---------------------------------------------------------------------------*/
OS_FPutStringInit(int console,const char * str)141 static void OS_FPutStringInit(int console, const char *str)
142 {
143 #ifndef SDK_FINALROM
144     OSIntrMode intr = OS_DisableInterrupts();
145 	u32 consoleType = OS_GetConsoleType();
146 
147     OS_FPutString = OS_FPutStringDummy;
148 
149 #ifdef  SDK_ARM9
150 	//---- ARM9
151     if ( consoleType & OS_CONSOLE_ENSATA )
152     {
153         OS_FPutString = OS_FPutStringAris;
154     }
155     else if ( consoleType & OS_CONSOLE_TWLDEBUGGER )
156 	{
157 		OS_FPutString = OS_FPutStringISTD;
158 	}
159 	else if ( consoleType & OS_CONSOLE_ISDEBUGGER )
160 	{
161 #ifndef SDK_TWLLTD
162 		OS_FPutString = OS_FPutStringISD;
163 #endif
164 	}
165 #else
166 	//---- ARM7
167     if ( consoleType & OS_CONSOLE_TWLDEBUGGER )
168     {
169 		OS_FPutString = OS_FPutStringISTD;
170 	}
171 	else
172 	{
173         OS_FPutString = OS_FPutStringPrnSrv;
174 	}
175 #endif
176 
177     OS_FPutString(console, str);
178 
179     (void)OS_RestoreInterrupts(intr);
180 
181 #else
182 #pragma unused(console, str)
183 #endif
184 }
185 
186 /*---------------------------------------------------------------------------*
187   Name:         OS_FPutStringDummy
188   Description:  dummy OS_FPutString. do nothing.
189  *---------------------------------------------------------------------------*/
OS_FPutStringDummy(int console,const char * str)190 static void OS_FPutStringDummy(int console, const char *str)
191 {
192 #pragma unused(console, str)
193 #ifndef SDK_FINALROM
194 	if ( OSi_FPutStringHook )
195 	{
196 		OSi_FPutStringHook(OS_FPUTSTRING_DUMMY, console, str);
197 	}
198 #endif
199 }
200 
201 /*---------------------------------------------------------------------------*
202   Name:         OS_FPutStringAris
203   Description:  OS_FPutString for software simulator called ARIS
204  *---------------------------------------------------------------------------*/
205 #ifndef SDK_FINALROM
206 #ifdef  SDK_CW_WARNOFF_SAFESTRB
207 #include <nitro/code32.h>
208 #endif
OS_FPutStringAris(int console,const char * str)209 static void OS_FPutStringAris(int console, const char *str)
210 {
211     char    c;
212 
213 	if ( console == OS_PRINT_OUTPUT_CURRENT )
214 	{
215 		console = (int)OSi_PRINT_OUTPUT;
216 	}
217 	else if ( console == OS_PRINT_OUTPUT_ERROR )
218 	{
219 		console = (int)OSi_PRINT_ERR_OUTPUT;
220 	}
221 
222 	if ( console != OS_PRINT_OUTPUT_NONE )
223 	{
224 		while ('\0' != (c = *str))
225 		{
226 			reg_OS_EMU_CONSOLE_OUT = (u8)c; // Console out
227 			str++;
228 		}
229 		if ( OSi_FPutStringHook )
230 		{
231 			OSi_FPutStringHook(OS_FPUTSTRING_ARIS, console, str);
232 		}
233 	}
234 }
235 #ifdef  SDK_CW_WARNOFF_SAFESTRB
236 #include <nitro/codereset.h>
237 #endif
238 #endif
239 
240 /*---------------------------------------------------------------------------*
241   Name:         OS_FPutStringISD
242   Description:  OS_FPutString for hardware emulator called IS Debugger
243  *---------------------------------------------------------------------------*/
244 #ifndef SDK_FINALROM
OS_FPutStringISD(int console,const char * str)245 static void OS_FPutStringISD(int console, const char *str)
246 {
247     // ISDPrint initialize process
248     OS_InitLock();
249 
250 	if ( console == OS_PRINT_OUTPUT_CURRENT )
251 	{
252 		console = (int)OSi_PRINT_OUTPUT;
253 	}
254 	else if ( console == OS_PRINT_OUTPUT_ERROR )
255 	{
256 		console = (int)OSi_PRINT_ERR_OUTPUT;
257 	}
258 
259 	if ( console != OS_PRINT_OUTPUT_NONE )
260 	{
261 		ISDPrint(str);
262 		if ( OSi_FPutStringHook )
263 		{
264 			OSi_FPutStringHook(OS_FPUTSTRING_ISD, console, str);
265 		}
266 	}
267 }
268 #endif
269 
270 /*---------------------------------------------------------------------------*
271   Name:         OS_FPutStringISTD
272   Description:  OS_FPutString for hardware emulator called IS TWL Debugger
273  *---------------------------------------------------------------------------*/
274 #ifndef SDK_FINALROM
OS_FPutStringISTD(int console,const char * str)275 static void OS_FPutStringISTD(int console, const char *str)
276 {
277     // ISTDPrintEx initialize process
278     OS_InitLock();
279 
280 	if ( console == OS_PRINT_OUTPUT_CURRENT )
281 	{
282 		console = (int)OSi_PRINT_OUTPUT;
283 	}
284 	else if ( console == OS_PRINT_OUTPUT_ERROR )
285 	{
286 		console = (int)OSi_PRINT_ERR_OUTPUT;
287 	}
288 
289 	if ( console != OS_PRINT_OUTPUT_NONE )
290 	{
291 		ISTDPrintEx(console, str);
292 		if ( OSi_FPutStringHook )
293 		{
294 			OSi_FPutStringHook(OS_FPUTSTRING_ISTD, console, str);
295 		}
296 	}
297 }
298 #endif
299 
300 
301 /*---------------------------------------------------------------------------*
302   Name:         OS_VPrintf/OS_TVPrintf
303 
304   Description:  Prints formatted strings (vprintf version).
305 
306   Arguments:    fmt: Format string
307                 vlist: Parameters
308 
309   Returns:      None.
310  *---------------------------------------------------------------------------*/
311 // If you want to use "vsnprintf()" in ARM7, define SDK_USE_VSNPRINTF.
312 // "vsnprintf()" is able to print float format but the code size become hugely bigger.
313 // #define SDK_USE_VSNPRINTF
314 
315 #ifndef SDK_FINALROM
316 #if     defined(SDK_ARM9) || defined(SDK_USE_VSNPRINTF)
OS_VPrintf(const char * fmt,va_list vlist)317 SDK_WEAK_SYMBOL void OS_VPrintf(const char *fmt, va_list vlist)
318 {
319 	OS_VFPrintf(OS_PRINT_OUTPUT_CURRENT, fmt, vlist);
320 }
OS_VFPrintf(int console,const char * fmt,va_list vlist)321 SDK_WEAK_SYMBOL void OS_VFPrintf(int console, const char *fmt, va_list vlist)
322 {
323     (void)vsnprintf(common_buffer, sizeof(common_buffer), fmt, vlist);
324     OS_FPutString(console, common_buffer);
325 }
326 #else
OS_VPrintf(const char * fmt,va_list vlist)327 SDK_WEAK_SYMBOL void OS_VPrintf(const char *fmt, va_list vlist)
328 {
329     OS_TVFPrintf(OS_PRINT_OUTPUT_CURRENT, fmt, vlist);
330 }
OS_VFPrintf(int console,const char * fmt,va_list vlist)331 SDK_WEAK_SYMBOL void OS_VFPrintf(int console, const char *fmt, va_list vlist)
332 {
333     OS_TVFPrintf(console, fmt, vlist);
334 }
335 #endif
OS_TVPrintf(const char * fmt,va_list vlist)336 SDK_WEAK_SYMBOL void OS_TVPrintf(const char *fmt, va_list vlist)
337 {
338 	OS_TVFPrintf(OS_PRINT_OUTPUT_CURRENT, fmt, vlist);
339 }
OS_TVFPrintf(int console,const char * fmt,va_list vlist)340 SDK_WEAK_SYMBOL void OS_TVFPrintf(int console, const char *fmt, va_list vlist)
341 {
342     (void)OS_VSNPrintf(common_buffer, sizeof(common_buffer), fmt, vlist);
343     OS_FPutString(console, common_buffer);
344 }
OS_TVPrintfEx(const char * fmt,va_list vlist)345 SDK_WEAK_SYMBOL void OS_TVPrintfEx(const char *fmt, va_list vlist)
346 {
347 	OS_TVFPrintfEx(OS_PRINT_OUTPUT_CURRENT, fmt, vlist);
348 }
OS_TVFPrintfEx(int console,const char * fmt,va_list vlist)349 SDK_WEAK_SYMBOL void OS_TVFPrintfEx(int console, const char *fmt, va_list vlist)
350 {
351     (void)OS_VSNPrintfEx(common_buffer, sizeof(common_buffer), fmt, vlist);
352     OS_FPutString(console, common_buffer);
353 }
354 #endif
355 
356 /*---------------------------------------------------------------------------*
357   Name:         OS_Printf/OS_TPrintf/OS_TPrintfEx
358                 OS_FPrintf/OS_TFPrintf/OS_TFPrintfEx
359 
360   Description:  Prints formatted strings.
361 
362   Arguments:    console: Output window
363                 fmt: Format string
364                 ...   and parameters
365 
366   Returns:      None.
367  *---------------------------------------------------------------------------*/
368 #ifndef SDK_FINALROM
OS_Printf(const char * fmt,...)369 SDK_WEAK_SYMBOL void OS_Printf(const char *fmt, ...)
370 {
371     va_list vlist;
372 
373     va_start(vlist, fmt);
374     OS_VFPrintf(OS_PRINT_OUTPUT_CURRENT, fmt, vlist);
375     va_end(vlist);
376 }
377 
OS_FPrintf(int console,const char * fmt,...)378 SDK_WEAK_SYMBOL void OS_FPrintf(int console, const char *fmt, ...)
379 {
380     va_list vlist;
381 
382     va_start(vlist, fmt);
383     OS_VFPrintf(console, fmt, vlist);
384     va_end(vlist);
385 }
386 
OS_TPrintf(const char * fmt,...)387 SDK_WEAK_SYMBOL void OS_TPrintf(const char *fmt, ...)
388 {
389     va_list vlist;
390 
391     va_start(vlist, fmt);
392     OS_TVFPrintf(OS_PRINT_OUTPUT_CURRENT, fmt, vlist);
393     va_end(vlist);
394 }
395 
OS_TFPrintf(int console,const char * fmt,...)396 SDK_WEAK_SYMBOL void OS_TFPrintf(int console, const char *fmt, ...)
397 {
398     va_list vlist;
399 
400     va_start(vlist, fmt);
401     OS_TVFPrintf(console, fmt, vlist);
402     va_end(vlist);
403 }
404 
OS_TPrintfEx(const char * fmt,...)405 SDK_WEAK_SYMBOL void OS_TPrintfEx(const char *fmt, ...)
406 {
407     va_list vlist;
408 
409     va_start(vlist, fmt);
410     OS_TVFPrintfEx(OS_PRINT_OUTPUT_CURRENT, fmt, vlist);
411     va_end(vlist);
412 }
413 
OS_TFPrintfEx(int console,const char * fmt,...)414 SDK_WEAK_SYMBOL void OS_TFPrintfEx(int console, const char *fmt, ...)
415 {
416     va_list vlist;
417 
418     va_start(vlist, fmt);
419     OS_TVFPrintfEx(console, fmt, vlist);
420     va_end(vlist);
421 }
422 #endif
423 
424 
425 /*---------------------------------------------------------------------------*
426   Name:         OSi_Warning / OSi_TWarning
427 
428   Description:  Prints warning message.
429 
430   Arguments:    file: Filename of warning location
431                 line: Line number of warning location
432                 fmt: Format string
433                 ...   and parameters
434 
435   Returns:      None.
436  *---------------------------------------------------------------------------*/
437 #ifndef SDK_FINALROM
OSi_Warning(const char * file,int line,const char * fmt,...)438 SDK_WEAK_SYMBOL void OSi_Warning(const char *file, int line, const char *fmt, ...)
439 {
440     va_list vlist;
441 
442     va_start(vlist, fmt);
443     OS_FPrintf(OS_PRINT_OUTPUT_ERROR, "%s:%d Warning:", file, line);
444     OS_VFPrintf(OS_PRINT_OUTPUT_ERROR, fmt, vlist);
445     OS_FPrintf(OS_PRINT_OUTPUT_ERROR, "\n");
446     va_end(vlist);
447 }
448 
449 
OSi_TWarning(const char * file,int line,const char * fmt,...)450 SDK_WEAK_SYMBOL void OSi_TWarning(const char *file, int line, const char *fmt, ...)
451 {
452     va_list vlist;
453 
454     va_start(vlist, fmt);
455     OS_TPrintf("%s:%d Warning:", file, line);
456     OS_TVPrintf(fmt, vlist);
457     OS_TPrintf("\n");
458     va_end(vlist);
459 }
460 #endif
461 
462 /*---------------------------------------------------------------------------*
463   Name:         OSi_Panic/OSi_TPanic
464 
465   Description:  Prints panic message and halt CPU.
466 
467   Arguments:    file: Filename of panic location
468                 line: Line number of panic location
469                 fmt: Format string
470                 ...   and parameters
471 
472   Returns:      None.
473  *---------------------------------------------------------------------------*/
474 #ifndef SDK_FINALROM
OSi_Panic(const char * file,int line,const char * fmt,...)475 SDK_WEAK_SYMBOL void OSi_Panic(const char *file, int line, const char *fmt, ...)
476 {
477     va_list vlist;
478 
479     va_start(vlist, fmt);
480     (void)OS_DisableInterrupts();
481     OS_FPrintf(OS_PRINT_OUTPUT_ERROR, "%s:%d Panic:", file, line);
482     OS_VFPrintf(OS_PRINT_OUTPUT_ERROR, fmt, vlist);
483     OS_FPrintf(OS_PRINT_OUTPUT_ERROR, "\n");
484     OSi_FuncTerminate();               // Never Returns
485 }
486 
OSi_TPanic(const char * file,int line,const char * fmt,...)487 SDK_WEAK_SYMBOL void OSi_TPanic(const char *file, int line, const char *fmt, ...)
488 {
489     va_list vlist;
490 
491     va_start(vlist, fmt);
492     (void)OS_DisableInterrupts();
493     OS_TPrintf("%s:%d Panic:", file, line);
494     OS_TVPrintf(fmt, vlist);
495     OS_TPrintf("\n");
496     OSi_FuncTerminate();               // Never Returns
497 }
498 #endif
499 
500 /*---------------------------------------------------------------------------*
501   Name:         OSi_FWarning / OSi_TFWarning
502 
503   Description:  Prints warning message.
504 
505   Arguments:    console: Output window
506                 file: Filename of warning location
507                 line: Line number of warning location
508                 fmt: Format string
509                 ...   and parameters
510 
511   Returns:      None.
512  *---------------------------------------------------------------------------*/
513 #ifndef SDK_FINALROM
OSi_FWarning(int console,const char * file,int line,const char * fmt,...)514 SDK_WEAK_SYMBOL void OSi_FWarning(int console, const char *file, int line, const char *fmt, ...)
515 {
516     va_list vlist;
517 
518     va_start(vlist, fmt);
519     OS_FPrintf(console, "%s:%d Warning:", file, line);
520     OS_VFPrintf(console, fmt, vlist);
521     OS_FPrintf(console, "\n");
522     va_end(vlist);
523 }
524 
525 
OSi_TFWarning(int console,const char * file,int line,const char * fmt,...)526 SDK_WEAK_SYMBOL void OSi_TFWarning(int console, const char *file, int line, const char *fmt, ...)
527 {
528     va_list vlist;
529 
530     va_start(vlist, fmt);
531     OS_TFPrintf(console, "%s:%d Warning:", file, line);
532     OS_TVFPrintf(console, fmt, vlist);
533     OS_TFPrintf(console, "\n");
534     va_end(vlist);
535 }
536 #endif
537 
538 /*---------------------------------------------------------------------------*
539   Name:         OSi_FPanic/OSi_TFPanic
540 
541   Description:  Prints panic message and halts CPU.
542 
543   Arguments:    file: Filename of panic location
544                 line: Line number of panic location
545                 fmt: Format string
546                 ...   and parameters
547 
548   Returns:      None.
549  *---------------------------------------------------------------------------*/
550 #ifndef SDK_FINALROM
OSi_FPanic(int console,const char * file,int line,const char * fmt,...)551 SDK_WEAK_SYMBOL void OSi_FPanic(int console, const char *file, int line, const char *fmt, ...)
552 {
553     va_list vlist;
554 
555     va_start(vlist, fmt);
556     (void)OS_DisableInterrupts();
557     OS_FPrintf(console, "%s:%d Panic:", file, line);
558     OS_VFPrintf(console, fmt, vlist);
559     OS_FPrintf(console, "\n");
560     OSi_FuncTerminate();               // Never Returns
561 }
562 
OSi_TFPanic(int console,const char * file,int line,const char * fmt,...)563 SDK_WEAK_SYMBOL void OSi_TFPanic(int console, const char *file, int line, const char *fmt, ...)
564 {
565     va_list vlist;
566 
567     va_start(vlist, fmt);
568     (void)OS_DisableInterrupts();
569     OS_TFPrintf(console, "%s:%d Panic:", file, line);
570     OS_TVFPrintf(console, fmt, vlist);
571     OS_TFPrintf(console, "\n");
572     OSi_FuncTerminate();               // Never Returns
573 }
574 #endif
575 
576 /*---------------------------------------------------------------------------*
577   Name:         OS_InitPrintServer
578 
579   Description:  Initializes print server.
580                 - This code should be called before OS_InitLock()
581                 - OS_InitLock() are also called from OS_Init()
582 
583   Arguments:    None.
584 
585   Returns:      None.
586  *---------------------------------------------------------------------------*/
587 #ifdef   SDK_ARM9
588 #ifndef  SDK_FINALROM
OS_InitPrintServer(void)589 void OS_InitPrintServer(void)
590 {
591     OSPrintServerBuffer *p;
592 
593     // First, allocate buffer and register it.
594     OS_InitArena();
595     p = OS_AllocFromSharedArenaHi(sizeof(OSPrintServerBuffer), 4);
596     p->in = p->out = 0UL;
597     PXI_SetComponentParam((u32)p);
598 }
599 #endif //SDK_FINALROM
600 #endif //SDK_ARM9
601 
602 
603 /*---------------------------------------------------------------------------*
604   Name:         OS_PrintServer
605 
606   Description:  Prints a string comes from ARM7 via shared memory.
607 
608   Arguments:    str: String
609 
610   Returns:      None.
611  *---------------------------------------------------------------------------*/
612 #ifdef   SDK_ARM9
613 #ifndef  SDK_FINALROM
614 #include <nitro/code32.h>              // To access 'common_buffer' via cache
OS_PrintServer(void)615 void OS_PrintServer(void)
616 {
617     OSPrintServerBuffer *p;
618     register OSPrintWChar word;
619 
620     u32     in, out;
621     int     i;
622 
623     p = (OSPrintServerBuffer *)PXI_GetComponentParam();
624 
625     //---- If print buffer isn't set up, do nothing.
626     if (!p)
627     {
628         return;
629     }
630 
631     out = p->out;
632     in = p->in;
633 
634     while (in != out)
635     {
636         i = 0;
637 
638         while (in != out && i < sizeof(common_buffer) - 3)
639         {
640             word.s = p->buffer[out].s;
641             if (word.c[0])
642             {
643                 common_buffer[i++] = word.c[0]; // store via cache
644 
645                 if (word.c[1])
646                 {
647                     common_buffer[i++] = word.c[1];     // store via cache
648                 }
649             }
650             out++;
651             if (out >= OS_PRINTSRV_WCHARSIZE)
652                 out = 0;
653         }
654         common_buffer[i] = '\0';       // store via cache
655         OS_FPutString(OS_PRINT_OUTPUT_CURRENT, common_buffer);
656     }
657 
658     // tell finished
659     p->out = out;
660 }
661 
662 #include <nitro/codereset.h>
663 #endif //SDK_FINALROM
664 #endif //SDK_ARM9
665 
666 
667 /*---------------------------------------------------------------------------*
668   Name:         OS_FPutStringPrnSrv
669 
670   Description:  Sends string to ARM9 via shared memory.
671 
672   Arguments:    console: Output window
673                 str: String to be sent
674 
675   Returns:      None.
676  *---------------------------------------------------------------------------*/
677 #ifdef  SDK_ARM7
OS_FPutStringPrnSrv(int console,const char * str)678 static void OS_FPutStringPrnSrv(int console, const char *str)
679 {
680 #pragma unused(console, str)
681 #ifndef  SDK_FINALROM
682     OSPrintServerBuffer *p;
683     register OSPrintWChar word;
684 
685     u32     in, in_tmp, out;
686     u32     isOdd;
687 
688 	if ( console == OS_PRINT_OUTPUT_NONE )
689 	{
690 		return;
691 	}
692 
693     p = (OSPrintServerBuffer *)PXI_GetComponentParam();
694     in = p->in;
695     out = p->out;
696     isOdd = ((u32)str) & 1;
697 
698     while (1)
699     {
700         in_tmp = in + 1;
701         if (in_tmp >= OS_PRINTSRV_WCHARSIZE)
702             in_tmp = 0;
703         if (out == in_tmp)
704             break;                     // Buffer full, then exit
705 
706         if (isOdd)
707         {
708             p->buffer[in].s = word.s = (u16)((*(u16 *)(str - 1)) & 0xff00);
709             str++;
710             isOdd = 0UL;
711             if (!word.c[1])
712                 break;
713             in = in_tmp;
714         }
715         else
716         {
717             p->buffer[in].s = word.s = *(u16 *)str;
718             str += 2;
719             if (!word.c[0])
720                 break;
721             in = in_tmp;
722             if (!word.c[1])
723                 break;
724         }
725     }
726     p->in = in;
727 #endif //SDK_FINALROM
728 }
729 #endif //SDK_ARM7
730 
731 
732 #if defined(SDK_CW_WARNOFF_SAFESTRB)
733 #include <nitro/code32.h>
734 #endif
735 
736 /* inner function for sized-buffer output */
737 typedef struct dst_string_tag
738 {
739     size_t  len;
740     char   *cur;
741     char   *base;
742 }
743 dst_string;
744 
string_put_char(dst_string * p,char c)745 static void string_put_char(dst_string * p, char c)
746 {
747     if (p->len > 0)
748         *p->cur = c, --p->len;
749     ++p->cur;
750 }
751 
string_fill_char(dst_string * p,char c,int n)752 static void string_fill_char(dst_string * p, char c, int n)
753 {
754     if (n > 0)
755     {
756         size_t  i, k = p->len;
757         if (k > (size_t) n)
758             k = (size_t) n;
759         for (i = 0; i < k; ++i)
760             p->cur[i] = c;
761         p->len -= k;
762         p->cur += n;
763     }
764 }
765 
string_put_string(dst_string * p,const char * s,int n)766 static void string_put_string(dst_string * p, const char *s, int n)
767 {
768     if (n > 0)
769     {
770         size_t  i, k = p->len;
771         if (k > (size_t) n)
772             k = (size_t) n;
773         for (i = 0; i < k; ++i)
774             p->cur[i] = s[i];
775         p->len -= k;
776         p->cur += n;
777     }
778 }
779 
780 /*---------------------------------------------------------------------------*
781   Name:         OS_SPrintf
782 
783   Description:  Equal to 'OS_VSPrintf' except argument style.
784 
785   Arguments:    dst: Destination buffer
786                 fmt: Format string
787 
788   Returns:      Length of the generated string.
789  *---------------------------------------------------------------------------*/
OS_SPrintf(char * dst,const char * fmt,...)790 SDK_WEAK_SYMBOL int OS_SPrintf(char *dst, const char *fmt, ...)
791 {
792     int     ret;
793     va_list va;
794     va_start(va, fmt);
795     ret = OS_VSPrintf(dst, fmt, va);
796     va_end(va);
797     return ret;
798 }
799 
800 /*---------------------------------------------------------------------------*
801   Name:         OS_VSPrintf
802 
803   Description:  Equal to 'OS_VSNPrintf' except buffer size argument.
804 
805   Arguments:    dst: Destination buffer
806                 fmt: Format string
807                 vlist: Parameters
808 
809   Returns:      Length of the generated string.
810  *---------------------------------------------------------------------------*/
OS_VSPrintf(char * dst,const char * fmt,va_list vlist)811 SDK_WEAK_SYMBOL int OS_VSPrintf(char *dst, const char *fmt, va_list vlist)
812 {
813     return OS_VSNPrintf(dst, 0x7FFFFFFF, fmt, vlist);
814 }
815 
816 /*---------------------------------------------------------------------------*
817   Name:         OS_SNPrintf
818 
819   Description:  Equal to 'OS_VSNPrintf' except argument style.
820 
821   Arguments:    dst: Destination buffer
822                 len: Destination buffer size
823                 fmt: Format string
824 
825   Returns:      Length of the generated string (except '\0').
826                 if(result < len),
827                   put NUL in dst[result].
828                 else if(len > 0),
829                   put NUL in dst[len - 1].
830                 else,
831                   do nothing.
832  *---------------------------------------------------------------------------*/
OS_SNPrintf(char * dst,size_t len,const char * fmt,...)833 SDK_WEAK_SYMBOL int OS_SNPrintf(char *dst, size_t len, const char *fmt, ...)
834 {
835     int     ret;
836     va_list va;
837     va_start(va, fmt);
838     ret = OS_VSNPrintf(dst, len, fmt, va);
839     va_end(va);
840     return ret;
841 }
842 
843 /*---------------------------------------------------------------------------*
844   Name:         OS_VSNPrintf
845 
846   Description:  small-size vsnprintf which is similar to 'vsnprintf'
847                 without following supports.
848                 * CodeWarrior Extensions (#s)
849                 * MSL AltiVec Extensions (v, vh, vl, hv, lv, @)
850                 * indexed argments (%m$, *m$)
851                 * floating-point
852                 * wchar_t
853 
854   Note:         '+' and '#' do not work, MSL's sprintf().
855                 to keep same result, they are no implement.
856                 { // example
857                   char buf[5];
858                   sprintf(buf, "%-i\n", 45);  // "45"  (OK)
859                   sprintf(buf, "%0i\n", 45);  // "45"  (OK)
860                   sprintf(buf, "% i\n", 45);  // " 45" (OK)
861                   sprintf(buf, "%+i\n", 45);  // "%+i" ("+45" expected)
862                   sprintf(buf, "%#x\n", 45);  // "%#x" ("0x2d" expected)
863                   // but, this works correctly!
864                   sprintf(buf, "% +i\n", 45); // "+45" (OK)
865                 }
866 
867   Arguments:    dst: Destination buffer
868                 len: Destination buffer size
869                 fmt: Format string
870                 vlist: Parameters
871 
872   Returns:      Length of the generated string (except '\0').
873                 if(result < len),
874                   put NUL in dst[result].
875                 else if(len > 0),
876                   put NUL in dst[len - 1].
877                 else,
878                   do nothing.
879  *---------------------------------------------------------------------------*/
OS_VSNPrintf(char * dst,size_t len,const char * fmt,va_list vlist)880 SDK_WEAK_SYMBOL int OS_VSNPrintf(char *dst, size_t len, const char *fmt, va_list vlist)
881 {
882     return STD_TVSNPrintf(dst, len, fmt, vlist);
883 }
884 
885 /*---------------------------------------------------------------------------*
886   Name:         OS_VSNPrintfEx
887 
888   Description:  OS_VSNPrintfEx is an addition of binary output to OS_VSNPrintfEx.
889 
890   Arguments:    dst: Destination buffer
891                 len: Destination buffer size
892                 fmt: Format string
893                 vlist: Parameters
894 
895   Returns:      Length of the generated string (except '\0').
896                 if(result < len),
897                   put NUL in dst[result].
898                 else if(len > 0),
899                   put NUL in dst[len - 1].
900                 else,
901                   do nothing.
902  *---------------------------------------------------------------------------*/
OS_VSNPrintfEx(char * dst,size_t len,const char * fmt,va_list vlist)903 SDK_WEAK_SYMBOL int OS_VSNPrintfEx(char *dst, size_t len, const char *fmt, va_list vlist)
904 {
905     char    buf[24];
906     int     n_buf;
907     char    prefix[2];
908     int     n_prefix;
909 
910     const char *s = fmt;
911 
912     dst_string str;
913     str.len = len, str.cur = str.base = dst;
914 
915     while (*s)
916     {
917         if ((unsigned int)(((unsigned char)*s ^ 0x20) - 0xA1) < 0x3C)
918         {
919             /* Shift JIS character */
920             string_put_char(&str, *s++);
921             if (*s)
922                 string_put_char(&str, *s++);
923         }
924         else if (*s != '%')
925         {
926             /* normal ASCII character */
927             string_put_char(&str, *s++);
928         }
929         else
930         {
931             /* output with format */
932             enum
933             {
934                 flag_blank = 000001,   /* ' ' */
935                 flag_plus = 000002,    /* '+' */
936                 flag_sharp = 000004,   /* '#' */
937                 flag_minus = 000010,   /* '-' */
938                 flag_zero = 000020,    /* '0' */
939                 flag_l1 = 000040,      /* "l" */
940                 flag_h1 = 000100,      /* "h" */
941                 flag_l2 = 000200,      /* "ll" */
942                 flag_h2 = 000400,      /* "hh" */
943                 flag_unsigned = 010000, /* 'o', 'u', ... */
944                 flag_binary = 020000,  /* 'b' */
945                 flag_colon = 040000,   /* ':' */
946                 flag_end
947             };
948             int     flag = 0, width = 0, precision = -1, radix = 10;
949             char    hex_char = 'a' - 10;
950             const char *p_start = s;
951             /* flags */
952             for (;;)
953             {
954                 switch (*++s)
955                 {
956                 case '+':
957                     if (s[-1] != ' ')
958                         break;
959                     flag |= flag_plus;
960                     continue;
961                 case ' ':
962                     flag |= flag_blank;
963                     continue;
964                 case '-':
965                     flag |= flag_minus;
966                     continue;
967                 case '0':
968                     flag |= flag_zero;
969                     continue;
970                 case ':':
971                     flag |= flag_colon;
972                     continue;
973                 }
974                 break;
975             }
976             /* Width */
977             if (*s == '*')
978             {
979                 ++s, width = va_arg(vlist, int);
980                 if (width < 0)
981                     width = -width, flag |= flag_minus;
982             }
983             else
984             {
985                 while ((*s >= '0') && (*s <= '9'))
986                     width = (width * 10) + *s++ - '0';
987             }
988             /* precision */
989             if (*s == '.')
990             {
991                 ++s, precision = 0;
992                 if (*s == '*')
993                 {
994                     ++s, precision = va_arg(vlist, int);
995                     if (precision < 0)
996                         precision = -1;
997                 }
998                 else
999                 {
1000                     while ((*s >= '0') && (*s <= '9'))
1001                         precision = (precision * 10) + *s++ - '0';
1002                 }
1003             }
1004             /* Options */
1005             switch (*s)
1006             {
1007             case 'h':
1008                 if (*++s != 'h')
1009                     flag |= flag_h1;
1010                 else
1011                     ++s, flag |= flag_h2;
1012                 break;
1013             case 'l':
1014                 if (*++s != 'l')
1015                     flag |= flag_l1;
1016                 else
1017                     ++s, flag |= flag_l2;
1018                 break;
1019             }
1020 
1021             /* type */
1022             switch (*s)
1023             {
1024             case 'd':                 /* signed decimal */
1025             case 'i':                 /* signed decimal */
1026                 goto put_integer;
1027             case 'o':                 /* unsigned octal */
1028                 radix = 8;
1029                 flag |= flag_unsigned;
1030                 goto put_integer;
1031             case 'u':                 /* unsigned decimal */
1032                 flag |= flag_unsigned;
1033                 goto put_integer;
1034             case 'X':                 /* unsigned hexadecimal */
1035                 hex_char = 'A' - 10;
1036                 goto put_hexadecimal;
1037             case 'x':                 /* unsigned hexadecimal */
1038                 goto put_hexadecimal;
1039             case 'p':                 /* pointer */
1040                 /* equal to code warrior */
1041                 flag |= flag_sharp;
1042                 precision = 8;
1043                 goto put_hexadecimal;
1044 
1045             case 'C':                 /* unicode-character */
1046                 flag |= flag_l1;
1047             case 'c':                 /* character */
1048                 if (precision >= 0)
1049                     goto put_invalid;
1050                 {
1051                     int     c = va_arg(vlist, int);
1052                     width -= 1;
1053                     if (flag & flag_minus)
1054                     {
1055                         if (flag & flag_l1)
1056                         {
1057                             char    dst[2];
1058 
1059                             if (STD_ConvertCharUnicodeToSjis(dst, (u16)c) == 1)
1060                             {
1061                                 string_put_char(&str, dst[0]);
1062                             }
1063                             else
1064                             {
1065                                 string_put_string(&str, dst, 2);
1066                             }
1067                         }
1068                         else
1069                         {
1070                             string_put_char(&str, (char)c);
1071                         }
1072                         string_fill_char(&str, ' ', width);
1073                     }
1074                     else
1075                     {
1076                         char    pad = (char)((flag & flag_zero) ? '0' : ' ');
1077                         string_fill_char(&str, pad, width);
1078 
1079                         if (flag & flag_l1)
1080                         {
1081                             char    dst[2];
1082 
1083                             if (STD_ConvertCharUnicodeToSjis(dst, (u16)c) == 1)
1084                             {
1085                                 string_put_char(&str, dst[0]);
1086                             }
1087                             else
1088                             {
1089                                 string_put_string(&str, dst, 2);
1090                             }
1091                         }
1092                         else
1093                         {
1094                             string_put_char(&str, (char)c);
1095                         }
1096                     }
1097                     ++s;
1098                 }
1099                 break;
1100 
1101             case 'S':                 /* unicode-string */
1102                 flag |= flag_l1;
1103             case 's':                 /* string */
1104                 {
1105                     int     n_buf = 0;
1106                     const char *p_buf = va_arg(vlist, const char *);
1107 
1108                     if (precision < 0)
1109                     {
1110                         while (p_buf[n_buf])
1111                         {
1112                             if (flag & flag_l1)
1113                             {
1114                                 n_buf += 2;
1115                             }
1116                             else
1117                             {
1118                                 ++n_buf;
1119                             }
1120                         }
1121                     }
1122                     else
1123                     {
1124                         while ((n_buf < precision) && p_buf[n_buf])
1125                         {
1126                             if (flag & flag_l1)
1127                             {
1128                                 n_buf += 2;
1129                             }
1130                             else
1131                             {
1132                                 ++n_buf;
1133                             }
1134                         }
1135                     }
1136                     if (flag & flag_l1)
1137                     {
1138                         n_buf /= 2;
1139                     }
1140                     width -= n_buf;
1141                     if (flag & flag_minus)
1142                     {
1143                         if (flag & flag_l1)
1144                         {
1145                             u16    *w_buf = (u16 *)p_buf;
1146                             char    dst[2];
1147 
1148                             while (n_buf--)
1149                             {
1150                                 if (STD_ConvertCharUnicodeToSjis(dst, *w_buf) == 1)
1151                                 {
1152                                     string_put_char(&str, dst[0]);
1153                                 }
1154                                 else
1155                                 {
1156                                     string_put_string(&str, dst, 2);
1157                                 }
1158                                 w_buf++;
1159                             }
1160                         }
1161                         else
1162                         {
1163                             string_put_string(&str, p_buf, n_buf);
1164                         }
1165                         string_fill_char(&str, ' ', width);
1166                     }
1167                     else
1168                     {
1169                         char    pad = (char)((flag & flag_zero) ? '0' : ' ');
1170                         string_fill_char(&str, pad, width);
1171 
1172                         if (flag & flag_l1)
1173                         {
1174                             u16    *w_buf = (u16 *)p_buf;
1175                             char    dst[2];
1176 
1177                             while (n_buf--)
1178                             {
1179                                 if (STD_ConvertCharUnicodeToSjis(dst, *w_buf) == 1)
1180                                 {
1181                                     string_put_char(&str, dst[0]);
1182                                 }
1183                                 else
1184                                 {
1185                                     string_put_string(&str, dst, 2);
1186                                 }
1187                                 w_buf++;
1188                             }
1189                         }
1190                         else
1191                         {
1192                             string_put_string(&str, p_buf, n_buf);
1193                         }
1194                     }
1195                     ++s;
1196                 }
1197                 break;
1198 
1199             case 'B':                 /* binary */
1200                 hex_char = 'A' - 10;
1201             case 'b':                 /* binary */
1202                 {
1203                     int     n_buf = width;
1204                     int     count = 0;
1205                     char   *p_buf = va_arg(vlist, char *);
1206                     int     column_count;
1207 
1208                     if (n_buf <= 0)
1209                     {
1210                         n_buf = 1;
1211                     }
1212                     if (precision == 0)
1213                     {
1214                         precision = -1;
1215                     }
1216                     column_count = precision;
1217 
1218                     while (1)
1219                     {
1220                         char    left_char, right_char;
1221                         int     left = ((p_buf[count] & 0xF0) >> 4);
1222                         int     right = (p_buf[count] & 0x0F);
1223 
1224                         left_char = (char)((left < 10) ? (left + '0') : (left + hex_char));
1225                         right_char = (char)((right < 10) ? (right + '0') : (right + hex_char));
1226 
1227                         string_put_char(&str, left_char);
1228                         string_put_char(&str, right_char);
1229 
1230                         count++;
1231 
1232                         if (count >= n_buf)
1233                             break;
1234 
1235                         if (column_count > 0)
1236                         {
1237                             --column_count;
1238                         }
1239 
1240                         if (column_count == 0)
1241                         {
1242                             string_put_char(&str, '\n');
1243                             if ((flag & flag_blank) && !(flag & flag_minus))
1244                             {
1245                                 string_put_char(&str, ' ');
1246                             }
1247                             column_count = precision;
1248                         }
1249                         else if (flag & flag_colon)
1250                         {
1251                             string_put_char(&str, ':');
1252                         }
1253                         else if (flag & flag_blank)
1254                         {
1255                             string_put_char(&str, ' ');
1256                         }
1257                     }
1258                     ++s;
1259                 }
1260                 break;
1261 
1262             case 'n':                 /* store the number of output */
1263                 {
1264                     int     pos = str.cur - str.base;
1265                     if (flag & flag_h2)
1266                         ;
1267                     else if (flag & flag_h1)
1268                         *va_arg(vlist, signed short *) = (signed short)pos;
1269                     else if (flag & flag_l2)
1270                         *va_arg(vlist, u64 *) = (u64)pos;
1271                     else
1272                         *va_arg(vlist, signed int *) = (signed int)pos;
1273                 }
1274                 ++s;
1275                 break;
1276 
1277             case '%':                 /* output '%' */
1278                 if (p_start + 1 != s)
1279                     goto put_invalid;
1280                 string_put_char(&str, *s++);
1281                 break;
1282 
1283             default:                  /* invalid type */
1284                 goto put_invalid;
1285 
1286               put_invalid:
1287                 string_put_string(&str, p_start, s - p_start);
1288                 break;
1289 
1290               put_hexadecimal:
1291                 radix = 16;
1292                 flag |= flag_unsigned;
1293               put_integer:
1294                 {
1295                     u64     val = 0;
1296                     n_prefix = 0;
1297 
1298                     if (flag & flag_minus)
1299                         flag &= ~flag_zero;
1300                     if (precision < 0)
1301                         precision = 1;
1302                     else
1303                         flag &= ~flag_zero;
1304 
1305                     if (flag & flag_unsigned)
1306                     {
1307                         if (flag & flag_h2)
1308                             val = va_arg(vlist, unsigned char);
1309                         else if (flag & flag_h1)
1310                             val = va_arg(vlist, unsigned short);
1311                         else if (flag & flag_l2)
1312                             val = va_arg(vlist, u64);
1313                         else
1314                             val = va_arg(vlist, unsigned long);
1315                         flag &= ~(flag_plus | flag_blank);
1316                         if (flag & flag_sharp)
1317                         {
1318                             if (radix == 16)
1319                             {
1320                                 if (val != 0)
1321                                 {
1322                                     prefix[0] = (char)(hex_char + (10 + 'x' - 'a'));
1323                                     prefix[1] = '0';
1324                                     n_prefix = 2;
1325                                 }
1326                             }
1327                             else if (radix == 8)
1328                             {
1329                                 prefix[0] = '0';
1330                                 n_prefix = 1;
1331                             }
1332                         }
1333                     }
1334                     else
1335                     {
1336                         if (flag & flag_h2)
1337                             val = va_arg(vlist, char);
1338                         else if (flag & flag_h1)
1339                             val = va_arg(vlist, short);
1340                         else if (flag & flag_l2)
1341                             val = va_arg(vlist, u64);
1342                         else
1343                             val = va_arg(vlist, long);
1344                         if ((val >> 32) & 0x80000000)
1345                         {
1346                             val = ~val + 1;
1347                             prefix[0] = '-';
1348                             n_prefix = 1;
1349                         }
1350                         else
1351                         {
1352                             if (val || precision)
1353                             {
1354                                 if (flag & flag_plus)
1355                                 {
1356                                     prefix[0] = '+';
1357                                     n_prefix = 1;
1358                                 }
1359                                 else if (flag & flag_blank)
1360                                 {
1361                                     prefix[0] = ' ';
1362                                     n_prefix = 1;
1363                                 }
1364                             }
1365                         }
1366                     }
1367                     n_buf = 0;
1368                     switch (radix)
1369                     {
1370                     case 8:
1371                         while (val != 0)
1372                         {
1373                             int     d = (int)(val & 0x07);
1374                             val >>= 3;
1375                             buf[n_buf++] = (char)(d + '0');
1376                         }
1377                         break;
1378                     case 10:
1379                         if ((val >> 32) == 0)
1380                         {
1381 #if defined(SDK_CW) || defined(SDK_RX) || defined(__MWERKS__)
1382 #pragma optimize_for_size off
1383 #endif
1384                             u32     v = (u32)val;
1385                             while (v != 0)
1386                             {
1387                                 // If the operation is division of a u32 and a constant, the compiler automatically converts it to addition using magic numbers
1388                                 //
1389                                 u32     r = v / 10;
1390                                 int     d = (int)(v - (r * 10));
1391                                 v = r;
1392                                 buf[n_buf++] = (char)(d + '0');
1393                             }
1394                         }
1395                         else
1396                         {
1397                             while (val != 0)
1398                             {
1399                                 u64     r = val / 10;
1400                                 int     d = (int)(val - (r * 10));
1401                                 val = r;
1402                                 buf[n_buf++] = (char)(d + '0');
1403                             }
1404                         }
1405                         break;
1406                     case 16:
1407                         while (val != 0)
1408                         {
1409                             int     d = (int)(val & 0x0f);
1410                             val >>= 4;
1411                             buf[n_buf++] = (char)((d < 10) ? (d + '0') : (d + hex_char));
1412                         }
1413                         break;
1414                     }
1415                     if ((n_prefix > 0) && (prefix[0] == '0'))
1416                     {
1417                         n_prefix = 0;
1418                         buf[n_buf++] = '0';
1419                     }
1420                 }
1421                 goto put_to_stream;
1422 
1423               put_to_stream:
1424                 {
1425                     int     n_pad = precision - n_buf;
1426                     if (flag & flag_zero)
1427                     {
1428                         if (n_pad < width - n_buf - n_prefix)
1429                             n_pad = width - n_buf - n_prefix;
1430                     }
1431                     if (n_pad > 0)
1432                         width -= n_pad;
1433                     width -= n_prefix + n_buf;
1434                     if (!(flag & flag_minus))
1435                         string_fill_char(&str, ' ', width);
1436                     while (n_prefix > 0)
1437                         string_put_char(&str, prefix[--n_prefix]);
1438                     string_fill_char(&str, '0', n_pad);
1439                     while (n_buf > 0)
1440                         string_put_char(&str, buf[--n_buf]);
1441                     if (flag & flag_minus)
1442                         string_fill_char(&str, ' ', width);
1443                     ++s;
1444                 }
1445                 break;
1446             }
1447         }
1448     }
1449 
1450     if (str.len > 0)
1451         *str.cur = '\0';
1452     else if (len > 0)
1453         str.base[len - 1] = '\0';
1454     return str.cur - str.base;
1455 }
1456 
1457 
1458 #if defined(SDK_CW_WARNOFF_SAFESTRB)
1459 #include <nitro/codereset.h>
1460 #endif
1461 
1462 //================================================================================
1463 //              Set output of print (for IS-TWL-DEBUGGER)
1464 //================================================================================
1465 #ifndef SDK_FINALROM
1466 #ifdef  SDK_LINK_ISTD
1467 /*---------------------------------------------------------------------------*
1468   Name:         OS_SetPrintOutput
1469 
1470   Description:  Specifies the output window OS_Printf uses.
1471                 This is only for IS-TWL-DEBUGGER.
1472 
1473   Arguments:    proc : processor
1474                          OS_PRINT_OUTPUT_PROC_ARM9     : ARM9
1475                          OS_PRINT_OUTPUT_PROC_ARM7     : ARM7
1476                          OS_PRINT_OUTPUT_PROC_ARM9ERR  : ARM9 for error
1477                          OS_PRINT_OUTPUT_PROC_ARM7ERR  : ARM7 for error
1478                 num: Window number (0-3)
1479 
1480   Returns:      None.
1481  *---------------------------------------------------------------------------*/
OS_SetPrintOutput(OSPrintOutputProc proc,int num)1482 void OS_SetPrintOutput( OSPrintOutputProc proc, int num )
1483 {
1484     SDK_ASSERT( (0<=num && num<=OS_PRINT_OUTPUT_WINDOW_MAX) || num==OS_PRINT_OUTPUT_NONE );
1485     SDK_ASSERT( 0<=(int)proc && (int)proc<=OS_PRINT_OUTPUT_PROC_ARM7ERR );
1486 	*(u8*)(HW_PRINT_OUTPUT_ARM9 + proc) = (u8)num;
1487 }
1488 #endif
1489 #endif
1490 
1491 //================================================================================
1492 //              FPutString hook
1493 //================================================================================
1494 #ifndef SDK_FINALROM
1495 /*---------------------------------------------------------------------------*
1496   Name:         OS_SetFPutStringHook
1497 
1498   Description:  Sets hook function in FPutString.
1499 
1500   Arguments:    func : hook function
1501 
1502   Returns:      None.
1503  *---------------------------------------------------------------------------*/
OS_SetFPutStringHook(OSFPutStringHookType func)1504 void OS_SetFPutStringHook( OSFPutStringHookType func )
1505 {
1506 	OSi_FPutStringHook = func;
1507 }
1508 
1509 /*---------------------------------------------------------------------------*
1510   Name:         OS_GetFPutStringHook
1511 
1512   Description:  get hook function in FPutString
1513 
1514   Arguments:    None.
1515 
1516   Returns:      hook function
1517  *---------------------------------------------------------------------------*/
OS_GetFPutStringHook(void)1518 OSFPutStringHookType OS_GetFPutStringHook(void)
1519 {
1520 	return OSi_FPutStringHook;
1521 }
1522 #endif
1523 
1524 //================================================================================
1525 //              DUMMY PRINT (stub for FINALROM)
1526 //================================================================================
1527 #ifdef SDK_FINALROM
1528 #ifdef OS_Printf
1529 #undef OS_Printf
1530 #endif
1531 void    OS_Printf(const char *fmt, ...);
OS_Printf(const char * fmt,...)1532 void OS_Printf(const char *fmt, ...)
1533 {
1534 #pragma unused( fmt )
1535 }
1536 #endif
1537