1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS
3   File:     os_valarm.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  *---------------------------------------------------------------------------*/
18 #include <nitro.h>
19 
20 #define OSi_VHIGHT              HW_LCD_LINES
21 
22 #define OSi_VALARM_LATER        0
23 #define OSi_VALARM_NOW          1
24 #define OSi_VALARM_TIMEOUT      2
25 
26 //---- valarm queue
27 static struct OSiVAlarmQueue
28 {
29     OSVAlarm *head;
30     OSVAlarm *tail;
31 }
32 OSi_VAlarmQueue;
33 
34 
35 //---- flag for initialization or not
36 static u16 OSi_UseVAlarm = FALSE;
37 
38 //---- frame count
39 static s32 OSi_VFrameCount;
40 static s32 OSi_PreviousVCount;
41 
42 static void OSi_InsertVAlarm(OSVAlarm *alarm);
43 static void OSi_SetNextVAlarm(OSVAlarm *alarm);
44 static void OSi_AppendVAlarm(OSVAlarm *alarm);
45 static void OSi_VAlarmHandler(void *arg);
46 static int OSi_CompareVCount(OSVAlarm *alarm, s32 currentVCount, s32 currentVFrame);
47 static s32 OSi_GetVFrame(s32 vcount);
48 
49 
50 //----------------------------------------------------------------
51 //  arrange vcount
OSi_VCountArr(int count)52 static int OSi_VCountArr(int count)
53 {
54     while (count < 0)
55     {
56         count += OSi_VHIGHT;
57     }
58     while (count >= OSi_VHIGHT)
59     {
60         count -= OSi_VHIGHT;
61     }
62     return count;
63 }
64 
65 //----------------------------------------------------------------
66 //  subtruction for vcount (a-b)
67 #define OSi_VCountSub( a, b )  OSi_VCountArr( (int)((a) - (b)) )
68 
69 //----------------------------------------------------------------
70 //  check if a vcount is near to c vcount than b vcount
71 #define OSi_IsNearVCount( a, b, c ) ( ( OSi_VCountSub( (a), (c) )  < OSi_VCountSub( (b), (c) ) )? TRUE: FALSE )
72 
73 
74 //================================================================================
75 //        INITIALIZE/FINALIZE VALARM SYSTEM
76 //================================================================================
77 /*---------------------------------------------------------------------------*
78   Name:         OS_InitVAlarm
79 
80   Description:  Initialize v-alarm module
81 
82   Arguments:    None.
83 
84   Returns:      None.
85  *---------------------------------------------------------------------------*/
OS_InitVAlarm(void)86 void OS_InitVAlarm(void)
87 {
88     if (!OSi_UseVAlarm)
89     {
90         OSi_UseVAlarm = TRUE;
91 
92         //---- clear valarm list
93         OSi_VAlarmQueue.head = NULL;
94         OSi_VAlarmQueue.tail = NULL;
95 
96         //---- Vcount IRQ Disable
97         (void)OS_DisableIrqMask(OS_IE_V_COUNT);
98 
99         //---- init frame count
100         OSi_VFrameCount = 0;
101         OSi_PreviousVCount = 0;
102     }
103 }
104 
105 /*---------------------------------------------------------------------------*
106   Name:         OS_EndVAlarm
107 
108   Description:  end v-alarm system
109 
110   Arguments:    None
111 
112   Returns:      None
113  *---------------------------------------------------------------------------*/
OS_EndVAlarm(void)114 void OS_EndVAlarm(void)
115 {
116     OSIntrMode enabled;
117 
118     SDK_ASSERT(OSi_UseVAlarm);
119     enabled = OS_DisableInterrupts();
120 
121     //---- check if any valarm exists
122     if (OSi_UseVAlarm)
123     {
124         SDK_ASSERTMSG(!OSi_VAlarmQueue.head,
125                       "OS_EndVAlarm: Cannot end v-alarm system while using v-alarm.");
126         OSi_UseVAlarm = FALSE;
127     }
128 
129     (void)OS_RestoreInterrupts(enabled);
130 }
131 
132 /*---------------------------------------------------------------------------*
133   Name:         OS_IsVAlarmAvailable
134 
135   Description:  check v-alarm system is available
136 
137   Arguments:    None
138 
139   Returns:      if available, TRUE.
140  *---------------------------------------------------------------------------*/
OS_IsVAlarmAvailable(void)141 BOOL OS_IsVAlarmAvailable(void)
142 {
143     return OSi_UseVAlarm;
144 }
145 
146 //================================================================================
147 //        OPERATION OF VALARM LIST
148 //================================================================================
149 /*---------------------------------------------------------------------------*
150   Name:         OSi_InsertVAlarm
151 
152   Description:  Insert v-alarm. Needs to be called interrupts disabled.
153 
154   Arguments:    alarm        : pointer to v-alarm to be set
155 
156   Returns:      None.
157  *---------------------------------------------------------------------------*/
OSi_InsertVAlarm(OSVAlarm * alarm)158 static void OSi_InsertVAlarm(OSVAlarm *alarm)
159 {
160     OSVAlarm *prev;
161     OSVAlarm *next;
162 
163     //---- insert to list
164     for (next = OSi_VAlarmQueue.head; next; next = next->next)
165     {
166         //---- check 'alarm' should be after than 'next'.
167         if ((next->frame < alarm->frame) ||
168             (next->frame == alarm->frame) && (next->fire <= alarm->fire))
169         {
170             continue;
171         }
172 
173         prev = next->prev;
174 
175         //---- insert valarm before 'next'
176         //---- set alarm link
177         alarm->prev = prev;
178         alarm->next = next;
179 
180         //---- set next alarm link
181         next->prev = alarm;
182 
183         //---- set previous alarm link
184         if (prev)
185         {
186             prev->next = alarm;
187         }
188         else
189         {
190             OSi_VAlarmQueue.head = alarm;
191             OSi_SetNextVAlarm(alarm);
192         }
193 
194         return;
195     }
196 
197     //---- append valarm to tail
198     OSi_AppendVAlarm(alarm);
199 }
200 
201 /*---------------------------------------------------------------------------*
202   Name:         OSi_AppendVAlarm
203 
204   Description:  Append v-alarm. Needs to be called interrupts disabled.
205                 alarm is put into last position of list.
206 
207   Arguments:    alarm       pointer to v-alarm to be set
208 
209   Returns:      None.
210  *---------------------------------------------------------------------------*/
OSi_AppendVAlarm(OSVAlarm * alarm)211 static void OSi_AppendVAlarm(OSVAlarm *alarm)
212 {
213     OSVAlarm *prev = OSi_VAlarmQueue.tail;
214 
215     //---- set alarm link
216     alarm->prev = prev;
217     alarm->next = NULL;
218 
219     //---- fix tail link
220     OSi_VAlarmQueue.tail = alarm;
221 
222     //---- fix old last alarm link
223     if (prev)
224     {
225         prev->next = alarm;
226     }
227     else
228     {
229         OSi_VAlarmQueue.head = alarm;
230         OSi_SetNextVAlarm(alarm);
231     }
232 }
233 
234 /*---------------------------------------------------------------------------*
235   Name:         OSi_DetachAlarm
236 
237   Description:  detach head v-alarm. Needs to be called interrupts disabled.
238 
239   Arguments:    alarm       pointer to v-alarm to be detach
240 
241   Returns:      None.
242  *---------------------------------------------------------------------------*/
OSi_DetachVAlarm(OSVAlarm * alarm)243 static void OSi_DetachVAlarm(OSVAlarm *alarm)
244 {
245     OSVAlarm *prev;
246     OSVAlarm *next;
247 
248     if (!alarm)
249     {
250         return;
251     }
252 
253     prev = alarm->prev;
254     next = alarm->next;
255 
256     //---- fix next alarm link
257     if (next)
258     {
259         next->prev = prev;
260     }
261     else
262     {
263         OSi_VAlarmQueue.tail = prev;
264     }
265 
266     //---- fix previous alarm link
267     if (prev)
268     {
269         prev->next = next;
270     }
271     else
272     {
273         OSi_VAlarmQueue.head = next;
274     }
275 }
276 
277 //================================================================================
278 //        SET VALARM
279 //================================================================================
280 /*---------------------------------------------------------------------------*
281   Name:         OS_CreateVAlarm
282 
283   Description:  Create v-alarm
284 
285   Arguments:    alarm       pointer to v-alarm to be initialized
286 
287   Returns:      None.
288  *---------------------------------------------------------------------------*/
OS_CreateVAlarm(OSVAlarm * alarm)289 void OS_CreateVAlarm(OSVAlarm *alarm)
290 {
291     SDK_ASSERT(OSi_UseVAlarm);
292     SDK_ASSERT(alarm);
293 
294     alarm->handler = 0;
295     alarm->tag = 0;
296 
297     alarm->finish = FALSE;
298 }
299 
300 /*---------------------------------------------------------------------------*
301   Name:         OS_SetVAlarm
302 
303   Description:  Set v-alarm as a relative time
304 
305   Arguments:    alarm       pointer to v-alarm to be set
306                 count       count to fire
307                 delay       permissible range of delay
308                 handler     v-alarm handler to be called
309                 arg         argument of handler
310 
311   Returns:      None.
312  *---------------------------------------------------------------------------*/
OS_SetVAlarm(OSVAlarm * alarm,s16 count,s16 delay,OSVAlarmHandler handler,void * arg)313 void OS_SetVAlarm(OSVAlarm *alarm, s16 count, s16 delay, OSVAlarmHandler handler, void *arg)
314 {
315     OSIntrMode enabled = OS_DisableInterrupts();
316     s32     currentVCount;
317     s32     currentVFrame;
318 
319     //OS_Printf( "**OS_SetVAlarm alarm=%x count=%d\n", alarm, count);
320     SDK_ASSERT(OSi_UseVAlarm);
321     SDK_ASSERTMSG(handler, "OS_SetVAlarm: handler must not be NULL.");
322     if (!alarm || alarm->handler)
323     {
324 #ifndef SDK_FINALROM
325         OS_Panic("v-alarm could be already used.");
326 #else
327         OS_Panic("");
328 #endif
329     }
330 
331     //---- get current vframe and vcount
332     currentVCount = GX_GetVCount();
333     currentVFrame = OSi_GetVFrame(currentVCount);
334 
335     //---- clear periodic info
336     alarm->period = FALSE;
337 
338     //---- set fire time
339     alarm->fire = count;
340     alarm->frame = (u32)((count > currentVCount) ? currentVFrame : (currentVFrame + 1));
341 
342     //---- permissible range of delay
343     alarm->delay = delay;
344 
345     //---- set handler
346     alarm->handler = handler;
347     alarm->arg = arg;
348 
349     //---- cancel flag
350     alarm->canceled = FALSE;
351 
352     //---- insert periodic valarm
353     OSi_InsertVAlarm(alarm);
354 
355     (void)OS_RestoreInterrupts(enabled);
356 }
357 
358 /*---------------------------------------------------------------------------*
359   Name:         OS_SetPeriodicVAlarm
360 
361   Description:  set periodic v-alarm
362 
363   Arguments:    alarm          pointer to v-alarm to be set
364                 count          count to fire cyclicly
365                 delay          permissible range of delay
366                 handler        v-alarm handler to be called
367                 arg            argument of handler
368 
369   Returns:      None.
370  *---------------------------------------------------------------------------*/
OS_SetPeriodicVAlarm(OSVAlarm * alarm,s16 count,s16 delay,OSVAlarmHandler handler,void * arg)371 void OS_SetPeriodicVAlarm(OSVAlarm *alarm, s16 count, s16 delay, OSVAlarmHandler handler, void *arg)
372 {
373     OSIntrMode enabled = OS_DisableInterrupts();
374     s32     currentVCount;
375     s32     currentVFrame;
376 
377     SDK_ASSERT(OSi_UseVAlarm);
378     SDK_ASSERTMSG(handler, "OS_SetPeriodicVAlarm: handler must not be NULL\n");
379     SDK_ASSERTMSG(0 <= delay
380                   && delay <= OSi_VHIGHT,
381                   "OS_SetPeriodicVAlarm:  illegal permissible range of delay.");
382     if (!alarm || alarm->handler)
383     {
384 #ifndef SDK_FINALROM
385         OS_Panic("v-alarm could be already used.");
386 #else
387         OS_Panic("");
388 #endif
389     }
390 
391     //---- get current frame and vcount
392     currentVCount = GX_GetVCount();
393     currentVFrame = OSi_GetVFrame(currentVCount);
394 
395     //---- set periodic info
396     alarm->period = TRUE;
397 
398     //---- set fire time
399     alarm->fire = count;
400     alarm->frame = (u32)((count > currentVCount) ? currentVFrame : (currentVFrame + 1));
401 
402     //---- permissible range of delay
403     alarm->delay = delay;
404 
405     //---- set handler
406     alarm->handler = handler;
407     alarm->arg = arg;
408 
409     //---- cancel flag
410     alarm->canceled = FALSE;
411 
412     //---- insert periodic valarm
413     OSi_InsertVAlarm(alarm);
414 
415     (void)OS_RestoreInterrupts(enabled);
416 }
417 
418 /*---------------------------------------------------------------------------*
419   Name:         OSi_SetNextVAlarm
420 
421   Description:  set VCount
422 
423   Arguments:    alarm       pointer of v-alarm struct
424 
425   Returns:      None.
426  *---------------------------------------------------------------------------*/
OSi_SetNextVAlarm(OSVAlarm * alarm)427 static void OSi_SetNextVAlarm(OSVAlarm *alarm)
428 {
429     //---- set interrupt callback
430     OS_SetIrqFunction(OS_IE_V_COUNT, (void (*)())OSi_VAlarmHandler);
431 
432     //---- set vcount line
433     GX_SetVCountEqVal(alarm->fire);
434 
435     //---- set interrupt
436     GX_VCountEqIntr(TRUE);
437     (void)OS_EnableIrqMask(OS_IE_V_COUNT);
438 }
439 
440 //================================================================================
441 //        ALARM TAG
442 //================================================================================
443 /*---------------------------------------------------------------------------*
444   Name:         OS_SetVAlarmTag
445 
446   Description:  set tag which is used OS_CancelVAlarms
447 
448   Arguments:    alarm        alarm to be set tag
449                 tag          tagNo
450 
451   Returns:      None.
452  *---------------------------------------------------------------------------*/
OS_SetVAlarmTag(OSVAlarm * alarm,u32 tag)453 void OS_SetVAlarmTag(OSVAlarm *alarm, u32 tag)
454 {
455 #ifdef SDK_DEBUG
456     SDK_ASSERT(OSi_UseVAlarm);
457     SDK_ASSERT(alarm);
458     SDK_ASSERTMSG(tag > 0, "OSSetVAlarmTag: Tag must be >0.");
459 #else
460     if (tag == 0)
461     {
462         OS_Panic("");
463     }
464 #endif
465 
466     if (alarm)
467     {
468         alarm->tag = tag;
469     }
470 }
471 
472 //================================================================================
473 //        CANCEL VALARM
474 //================================================================================
475 /*---------------------------------------------------------------------------*
476   Name:         OS_CancelVAlarm
477 
478   Description:  Cancel v-alarm
479 
480   Arguments:    alarm       pointer to v-alarm to be canceled
481 
482   Returns:      None.
483  *---------------------------------------------------------------------------*/
OS_CancelVAlarm(OSVAlarm * alarm)484 void OS_CancelVAlarm(OSVAlarm *alarm)
485 {
486     OSIntrMode enabled = OS_DisableInterrupts();;
487 
488     SDK_ASSERT(OSi_UseVAlarm);
489     SDK_ASSERT(alarm);
490 
491     alarm->canceled = TRUE;
492     if (alarm->handler == NULL)
493     {
494         (void)OS_RestoreInterrupts(enabled);
495         return;
496     }
497 
498     //---- detach valarm
499     OSi_DetachVAlarm(alarm);
500 
501     //---- clear hander
502     alarm->handler = NULL;
503 
504     (void)OS_RestoreInterrupts(enabled);
505 }
506 
507 /*---------------------------------------------------------------------------*
508   Name:         OS_CancelAllVAlarms
509 
510   Description:  cancel all v-alarms
511 
512   Arguments:    None
513 
514   Returns:      None.
515  *---------------------------------------------------------------------------*/
OS_CancelAllVAlarms(void)516 void OS_CancelAllVAlarms(void)
517 {
518     OSIntrMode enabled;
519     OSVAlarm *alarm;
520     OSVAlarm *next;
521 
522     SDK_ASSERT(OSi_UseVAlarm);
523     enabled = OS_DisableInterrupts();
524 
525     for (alarm = OSi_VAlarmQueue.head, next = alarm ? alarm->next : NULL;
526          alarm; alarm = next, next = alarm ? alarm->next : NULL)
527     {
528         //---- cancel valarm
529         OS_CancelVAlarm(alarm);
530     }
531 
532     (void)OS_RestoreInterrupts(enabled);
533 }
534 
535 /*---------------------------------------------------------------------------*
536   Name:         OS_CancelVAlarms
537 
538   Description:  cancel v-alarms which have specified tag
539 
540   Arguments:    tag          tagNo. to be cancelled. not 0
541 
542   Returns:      None.
543  *---------------------------------------------------------------------------*/
OS_CancelVAlarms(u32 tag)544 void OS_CancelVAlarms(u32 tag)
545 {
546     OSIntrMode enabled = OS_DisableInterrupts();
547     OSVAlarm *alarm;
548     OSVAlarm *next;
549 
550 #ifdef SDK_DEBUG
551     SDK_ASSERT(OSi_UseVAlarm);
552     SDK_ASSERTMSG(tag > 0, "OSCancelVAlarms: Tag must be >0.");
553 #else
554     if (tag == 0)
555     {
556         OS_Panic("");
557     }
558 #endif
559 
560     for (alarm = OSi_VAlarmQueue.head, next = alarm ? alarm->next : NULL;
561          alarm; alarm = next, next = alarm ? alarm->next : NULL)
562     {
563         if (alarm->tag == tag)
564         {
565             //---- cancel valarm
566             OS_CancelVAlarm(alarm);
567         }
568     }
569 
570     (void)OS_RestoreInterrupts(enabled);
571 }
572 
573 //================================================================================
574 //        ALARM HANDLER
575 //================================================================================
576 /*---------------------------------------------------------------------------*
577   Name:         OSi_VAlarmHandler
578 
579   Description:  handler vcount interrupt
580 
581   Arguments:    not use
582 
583   Returns:      None.
584  *---------------------------------------------------------------------------*/
OSi_VAlarmHandler(void *)585 static void OSi_VAlarmHandler(void *)
586 {
587     OSVAlarm *alarm;
588     OSVAlarmHandler handler;
589     int     check;
590     s32     currentVCount;
591     s32     currentVFrame;
592 
593     //---- To be vcount-irq Disable
594     (void)OS_DisableIrqMask(OS_IE_V_COUNT);
595     GX_VCountEqIntr(FALSE);
596 
597     //---- set check flag vcount interrupt
598     OS_SetIrqCheckFlag(OS_IE_V_COUNT);
599 
600     //---- arrange vframe
601     // vcount '-1' for care of periodic alarm which interrupts in same line every frame
602     currentVCount = GX_GetVCountEqVal();
603     currentVFrame = OSi_GetVFrame(currentVCount - 1);
604 
605 
606     while (NULL != (alarm = OSi_VAlarmQueue.head))
607     {
608         //---- get current vcount and vframe
609         currentVCount = GX_GetVCount();
610         currentVFrame = OSi_GetVFrame(currentVCount);
611 
612         //---- compare current vcount with alarm fire vcount
613         check = OSi_CompareVCount(alarm, currentVFrame, currentVCount);
614 
615 #ifdef DEBUGPRINT
616         OS_Printf("[%d:%d %d] %d %d check=%d \n",
617                   alarm->arg, alarm->frame, alarm->fire, currentVFrame, currentVCount, check);
618 #endif
619 
620         switch (check)
621         {
622         case OSi_VALARM_LATER:
623             // Set next vcount interrupt
624             OSi_SetNextVAlarm(alarm);
625 
626             //
627             // Check if time is up (vcount == intrvcount) during setting next interrupt
628             //
629             if (alarm->fire != GX_GetVCount() || alarm->frame != currentVFrame)
630             {
631                 return;
632             }
633 
634             // Cancel next vcount interrupt
635             (void)OS_DisableIrqMask(OS_IE_V_COUNT);
636             GX_VCountEqIntr(FALSE);
637             (void)OS_ResetRequestIrqMask(OS_IE_V_COUNT);
638 
639             // Go through (no need 'break') to call valarm handler
640 
641         case OSi_VALARM_NOW:
642             //---- detach alarm
643             handler = alarm->handler;
644             OSi_DetachVAlarm(alarm);
645             alarm->handler = NULL;
646 
647             //---- call user valarm handler
648             if (handler)
649             {
650                 (handler) (alarm->arg);
651             }
652 
653             //---- move to tail or so
654             if (alarm->period && !alarm->canceled)
655             {
656                 alarm->handler = handler;
657                 alarm->frame = (u32)OSi_VFrameCount + 1;
658                 OSi_InsertVAlarm(alarm);
659             }
660             break;
661 
662         case OSi_VALARM_TIMEOUT:
663             //---- move to tail or so
664             OSi_DetachVAlarm(alarm);
665             alarm->frame = (u32)OSi_VFrameCount + 1;
666             OSi_InsertVAlarm(alarm);
667             break;
668 
669         }
670     }
671 }
672 
673 /*---------------------------------------------------------------------------*
674   Name:         OS_CompareVCount
675 
676   Description:  compare specified alarm vcount with current vcount.
677                 check if time is to fire. consider for delay
678 
679   Arguments:    alarm         : alarm to check
680                 currentVFrame : current vframe
681                 currentVCount : current vcount
682 
683   Returns:      OSi_VALARM_LATER    : there is enough time to fire next alarm, so do fire later
684                 OSi_VALARM_NOW      : it is time to fire alarm
685                 OSi_VALARM_TIMEOUT  : alarm time has passed already
686 
687  *---------------------------------------------------------------------------*/
OSi_CompareVCount(OSVAlarm * alarm,s32 currentVFrame,s32 currentVCount)688 static int OSi_CompareVCount(OSVAlarm *alarm, s32 currentVFrame, s32 currentVCount)
689 {
690     s32     delayVFrame;
691     s32     delayVCount;
692 
693     delayVFrame = currentVFrame - (s32)alarm->frame;    // get diff for safety against overflow
694     delayVCount = currentVCount - (s32)alarm->fire;
695 
696     //
697     // Check if having reached the time yet
698     //
699     if (delayVFrame < 0 || (delayVFrame == 0 && delayVCount < 0))
700     {
701         return OSi_VALARM_LATER;
702     }
703 
704     //
705     // Time is passed, execute alarm or timed out
706     //
707     if (delayVCount < 0)
708     {
709         delayVCount += OSi_VHIGHT;     // Care for looping vcount 263->0
710     }
711 
712     // Check if timeout or not
713     return (delayVCount <= alarm->delay) ? OSi_VALARM_NOW : OSi_VALARM_TIMEOUT;
714 }
715 
716 
717 /*---------------------------------------------------------------------------*
718   Name:         OS_GetVFrame
719 
720   Description:  Get current vframe. If need, increase frame count.
721 
722   Arguments:    vcount  : vcount
723 
724   Returns:      current vframe
725  *---------------------------------------------------------------------------*/
OSi_GetVFrame(s32 vcount)726 static s32 OSi_GetVFrame(s32 vcount)
727 {
728     OSIntrMode enabled = OS_DisableInterrupts();
729 
730     //---- count up vframe if need
731     if (vcount < OSi_PreviousVCount)
732     {
733         OSi_VFrameCount++;
734     }
735     OSi_PreviousVCount = vcount;
736 
737     (void)OS_RestoreInterrupts(enabled);
738     return OSi_VFrameCount;
739 }
740 
741 
742 
743 //================================================================================
744 //        FOR DEBUG
745 //================================================================================
746 /*---------------------------------------------------------------------------*
747   Name:         OS_DumpVAlarm
748 
749   Description:  Dump all valarm resisterd currently
750                 This is for debug function.
751 
752   Arguments:    None
753 
754   Returns:      None
755  *---------------------------------------------------------------------------*/
OS_DumpVAlarm(void)756 void OS_DumpVAlarm(void)
757 {
758     OSIntrMode enabled = OS_DisableInterrupts();
759     OSVAlarm *alarm;
760     OSVAlarm *next;
761 
762     OS_Printf("---------------- current vcount = %d\n", (s16)GX_GetVCount());
763     for (alarm = OSi_VAlarmQueue.head; alarm; alarm = next)
764     {
765         next = alarm->next;
766 
767         OS_Printf("%08x fire=%d:%d delay=%d arg=%2d prev=%08x next=%08x\n", alarm,
768                   alarm->frame, alarm->fire, alarm->delay, alarm->arg, alarm->prev, alarm->next);
769     }
770 
771     (void)OS_RestoreInterrupts(enabled);
772 }
773 
774 /*---------------------------------------------------------------------------*
775   Name:         OS_GetNumberOfVAlarm
776 
777   Description:  get number of valarm
778 
779   Arguments:    None
780 
781   Returns:      number of valarm
782  *---------------------------------------------------------------------------*/
OS_GetNumberOfVAlarm(void)783 int OS_GetNumberOfVAlarm(void)
784 {
785     OSIntrMode enabled = OS_DisableInterrupts();
786 	OSVAlarm* p = OSi_VAlarmQueue.head;
787 	int num = 0;
788 
789 	while(p)
790 	{
791 		num ++;
792 		p = p->next;
793 	}
794 
795     (void)OS_RestoreInterrupts(enabled);
796 	return num;
797 }
798 
799 /*---------------------------------------------------------------------------*
800   Name:         OS_GetVAlarmResource
801 
802   Description:  store resources of valarm to specified pointer
803 
804   Arguments:    resource       pointer to store thread resources
805 
806   Returns:      TRUE  ... success (always return this now)
807                 FALSE ... fail
808  *---------------------------------------------------------------------------*/
OS_GetVAlarmResource(OSVAlarmResource * resource)809 BOOL    OS_GetVAlarmResource(OSVAlarmResource *resource)
810 {
811 	resource->num = OS_GetNumberOfVAlarm();
812 
813 	return TRUE;
814 }
815