1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS - demos - sleep-1
3   File:     main.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-04-01#$
14   $Rev: 5208 $
15   $Author: yada $
16  *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 #include "data.h"
19 
20 static GXOamAttr oamBak[128];
21 
22 void    VBlankIntr(void);
23 void    ObjSet(int objNo, int x, int y, int charNo, int paletteNo);
24 
25 
26 //---- Return 0-9, A-F code for OBJ display
ObjChar(u32 cnt,int shift)27 inline int ObjChar(u32 cnt, int shift)
28 {
29     u32     d = (cnt >> shift) & 0xf;
30     return (int)((d < 10) ? '0' + d : 'A' + d - 10);
31 }
32 
33 
34 //---- Definitions, declarations for subthreads
35 #define STACK_SIZE  1024
36 #define THREAD_PRIO 20
37 
38 OSThread thread;
39 void    proc(void *arg);
40 
41 u64     stack[STACK_SIZE / sizeof(u64)];
42 
43 
44 //---- Display counter
45 static u32 count1;                     // For launch threads
46 static u32 count2;                     // For subthreads
47 
48 //================================================================================
49 //   Counter for launch threads is incremented and displayed.
50 //   If you press the A button, this thread will sleep for 1 second.
51 //   During that time a subthread will start.
52 //   Normally a subthread has a low priority, so it will not run.
53 /*---------------------------------------------------------------------------*
54   Name:         NitroMain
55 
56   Description:  Main.
57 
58   Arguments:    None.
59 
60   Returns:      None.
61  *---------------------------------------------------------------------------*/
NitroMain()62 void NitroMain()
63 {
64     //================ Initialization
65     OS_Init();
66 
67     OS_InitTick();
68     OS_InitAlarm();
69     OS_InitThread();
70 
71     GX_Init();
72 
73     //---- Start subthread
74     OS_CreateThread(&thread, proc, NULL, stack + STACK_SIZE / sizeof(u64), STACK_SIZE, THREAD_PRIO);
75     OS_WakeupThreadDirect(&thread);
76 
77 
78     //================ Settings
79     //---- All Power ON
80     GX_SetPower(GX_POWER_ALL);
81 
82     //----  Enable V-Blank interrupt
83     (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
84     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
85     (void)OS_EnableIrq();
86 
87     //---- V-Blank occurrence settings
88     (void)GX_VBlankIntr(TRUE);
89 
90     //---- Clear VRAM
91     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
92     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
93     (void)GX_DisableBankForLCDC();
94 
95     //---- OAM and palette clear
96     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
97     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
98 
99     //---- Set bank A for OBJ
100     GX_SetBankForOBJ(GX_VRAM_OBJ_128_A);
101 
102     //---- Set to graphics display mode
103     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
104 
105     //---- Set only OBJ display ON
106     GX_SetVisiblePlane(GX_PLANEMASK_OBJ);
107 
108     //---- Used with 32-KB OBJ in 2D mapping mode
109     GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_2D);
110 
111     //---- Data load
112     MI_DmaCopy32(3, sampleCharData, (void *)HW_OBJ_VRAM, sizeof(sampleCharData));
113     MI_DmaCopy32(3, samplePlttData, (void *)HW_OBJ_PLTT, sizeof(samplePlttData));
114 
115     //---- Move hidden OBJ off screen
116     MI_DmaFill32(3, oamBak, 0xc0, sizeof(oamBak));
117 
118     GX_DispOn();
119 
120     //================ Main loop
121     while (1)
122     {
123         u16     keyData;
124 
125         //---- Wait for V-Blank interrupt completion
126         OS_WaitVBlankIntr();
127 
128         //---- Load pad data
129         keyData = PAD_Read();
130 
131         //---- Increase count
132         count1++;
133 
134         //---- Display count
135         ObjSet(0, 50, 100, ObjChar(count1, 28), 2);
136         ObjSet(1, 60, 100, ObjChar(count1, 24), 2);
137         ObjSet(2, 70, 100, ObjChar(count1, 20), 2);
138         ObjSet(3, 80, 100, ObjChar(count1, 16), 2);
139         ObjSet(4, 90, 100, ObjChar(count1, 12), 2);
140         ObjSet(5, 100, 100, ObjChar(count1, 8), 2);
141         ObjSet(6, 110, 100, ObjChar(count1, 4), 2);
142         ObjSet(7, 120, 100, ObjChar(count1, 0), 2);
143 
144         ObjSet(8, 140, 100, ObjChar(count2, 28), 2);
145         ObjSet(9, 150, 100, ObjChar(count2, 24), 2);
146         ObjSet(10, 160, 100, ObjChar(count2, 20), 2);
147         ObjSet(11, 170, 100, ObjChar(count2, 16), 2);
148         ObjSet(12, 180, 100, ObjChar(count2, 12), 2);
149         ObjSet(13, 190, 100, ObjChar(count2, 8), 2);
150         ObjSet(14, 200, 100, ObjChar(count2, 4), 2);
151         ObjSet(15, 210, 100, ObjChar(count2, 0), 2);
152 
153 
154         //---- Sleep one second if the A button is pressed
155         if (keyData & PAD_BUTTON_A)
156         {
157             OS_Sleep(1000);
158         }
159     }
160 }
161 
162 //--------------------------------------------------------------------------------
163 //  Set OBJ
164 //
ObjSet(int objNo,int x,int y,int charNo,int paletteNo)165 void ObjSet(int objNo, int x, int y, int charNo, int paletteNo)
166 {
167     G2_SetOBJAttr((GXOamAttr *)&oamBak[objNo],
168                   x,
169                   y,
170                   0,
171                   GX_OAM_MODE_NORMAL,
172                   FALSE,
173                   GX_OAM_EFFECT_NONE, GX_OAM_SHAPE_8x8, GX_OAM_COLOR_16, charNo, paletteNo, 0);
174 }
175 
176 
177 //--------------------------------------------------------------------------------
178 //    V-Blank interrupt process
179 //
VBlankIntr(void)180 void VBlankIntr(void)
181 {
182     //---- OAM updating
183     DC_FlushRange(oamBak, sizeof(oamBak));
184     /* I/O register is accessed using DMA operation, so cache wait is not needed */
185     // DC_WaitWriteBufferEmpty();
186     MI_DmaCopy32(3, oamBak, (void *)HW_OAM, sizeof(oamBak));
187 
188     //---- Interrupt check flag
189     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
190 }
191 
192 //--------------------------------------------------------------------------------
193 //
194 //
proc(void * arg)195 void proc(void *arg)
196 {
197 #pragma unused( arg )
198 
199     while (1)
200     {
201         //---- Wait for V-Blank interrupt completion
202         OS_WaitVBlankIntr();
203 
204         //---- Increase count
205         count2++;
206     }
207 }
208 
209 /*====== End of main.c ======*/
210