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