1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS - demos - mutex-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: 5205 $
15 $Author: yada $
16 *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18
19 void VBlankIntr(void);
20 void ObjSet(int objNo, int x, int y, int charNo, int paletteNo);
21
22 static GXOamAttr oamBak[128];
23 extern const u16 samplePlttData[16][16];
24 extern const u32 sampleCharData[8 * 0x100];
25
26 //---- Thread
27 #define STACK_SIZE 1024
28 #define THREAD1_PRIO 1
29 #define THREAD2_PRIO 2
30 OSThread thread1;
31 OSThread thread2;
32 u64 stack1[STACK_SIZE / sizeof(u64)];
33 u64 stack2[STACK_SIZE / sizeof(u64)];
34 void proc1(void *p1);
35 void proc2(void *p1);
36
37 OSMutex mutex;
38
39 void common(u32 val);
40
41 //================================================================================
42 /*---------------------------------------------------------------------------*
43 Name: NitroMain
44
45 Description: Main.
46
47 Arguments: None.
48
49 Returns: None.
50 *---------------------------------------------------------------------------*/
NitroMain(void)51 void NitroMain(void)
52 {
53 //================ Initialization
54 OS_Init();
55 //---- GX Initialization
56 GX_Init();
57
58 //================ Create Mutex
59 OS_InitMutex(&mutex);
60
61 //================ Start thread
62 OS_InitThread();
63 OS_CreateThread(&thread1, proc1, NULL, stack1 + STACK_SIZE / sizeof(u64), STACK_SIZE,
64 THREAD1_PRIO);
65 OS_CreateThread(&thread2, proc2, NULL, stack2 + STACK_SIZE / sizeof(u64), STACK_SIZE,
66 THREAD2_PRIO);
67 OS_WakeupThreadDirect(&thread1);
68 OS_WakeupThreadDirect(&thread2);
69
70 //================ Settings
71 //---- All Power ON
72 GX_SetPower(GX_POWER_ALL);
73
74 //---- Enable V-Blank interrupt
75 (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
76 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
77 (void)OS_EnableIrq();
78
79 //---- V-Blank occurrence settings
80 (void)GX_VBlankIntr(TRUE);
81
82 //---- Clear VRAM
83 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
84 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
85 GX_SetBankForLCDC(0);
86
87 //---- OAM and palette clear
88 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
89 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
90
91
92 //---- Set bank A for OBJ
93 GX_SetBankForOBJ(GX_VRAM_OBJ_128_A); // Assign bank A onto OBJ
94
95 //---- Set to graphics display mode
96 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
97
98 //---- Set only OBJ display ON
99 GX_SetVisiblePlane(GX_PLANEMASK_OBJ);
100
101 //---- Used with 32-KB OBJ in 2D mapping mode
102 GX_SetOBJVRamModeChar(GX_OBJVRAMMODE_CHAR_2D);
103
104 //================ Data load
105 MI_DmaCopy32(3, sampleCharData, (void *)HW_OBJ_VRAM, sizeof(sampleCharData));
106 MI_DmaCopy32(3, samplePlttData, (void *)HW_OBJ_PLTT, sizeof(samplePlttData));
107
108 GX_DispOn();
109
110 //================ Main loop
111 while (1)
112 {
113 u16 keyData;
114
115 //---- Wait for V-Blank interrupt completion
116 OS_WaitVBlankIntr();
117
118 //---- Move hidden OBJ off screen
119 MI_DmaFill32(3, oamBak, 0xc0, sizeof(oamBak));
120
121 //---- Load pad data
122 keyData = PAD_Read();
123
124 //---- Display pad information as OBJ
125 ObjSet(0, 180, 95, 'A', (keyData & PAD_BUTTON_A) ? 1 : 2);
126 }
127 }
128
129 //--------------------------------------------------------------------------------
130 // Set OBJ
131 //
ObjSet(int objNo,int x,int y,int charNo,int paletteNo)132 void ObjSet(int objNo, int x, int y, int charNo, int paletteNo)
133 {
134 G2_SetOBJAttr((GXOamAttr *)&oamBak[objNo],
135 x,
136 y,
137 0,
138 GX_OAM_MODE_NORMAL,
139 FALSE,
140 GX_OAM_EFFECT_NONE, GX_OAM_SHAPE_8x8, GX_OAM_COLOR_16, charNo, paletteNo, 0);
141 }
142
143
144 //--------------------------------------------------------------------------------
145 // V-Blank interrupt process
146 //
VBlankIntr(void)147 void VBlankIntr(void)
148 {
149 //---- OAM updating
150 DC_FlushRange(oamBak, sizeof(oamBak));
151 /* I/O register is accessed using DMA operation, so cache wait is not needed */
152 // DC_WaitWriteBufferEmpty();
153 MI_DmaCopy32(3, oamBak, (void *)HW_OAM, sizeof(oamBak));
154
155 //---- Reset interrupt request flag
156 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
157
158 //---- Start thread 1
159 OS_WakeupThreadDirect(&thread1);
160 OS_WakeupThreadDirect(&thread2);
161 }
162
163 //--------------------------------------------------------------------------------
164 // Thread 1
165 //
proc1(void * p1)166 void proc1(void *p1)
167 {
168 #pragma unused(p1)
169 while (1)
170 {
171 common(1);
172 OS_SleepThread(NULL);
173 }
174 }
175
176 //--------------------------------------------------------------------------------
177 // Thread 2
178 //
proc2(void * p1)179 void proc2(void *p1)
180 {
181 #pragma unused(p1)
182 while (1)
183 {
184 common(2);
185 }
186 }
187
188 //--------------------------------------------------------------------------------
189 // Shared
190 //
common(u32 val)191 void common(u32 val)
192 {
193 #ifdef SDK_FINALROM
194 #pragma unused( val )
195 #endif
196
197 OS_Printf("common IN thread=%d\n", val);
198 OS_LockMutex(&mutex);
199
200 OS_Printf("<Critical routine> thread=%d\n", val);
201
202 //---- Wait for A button trigger
203 while (!(PAD_Read() & PAD_BUTTON_A))
204 {
205 OS_SleepThread(NULL);
206 }
207 while (PAD_Read() & PAD_BUTTON_A)
208 {
209 OS_SleepThread(NULL);
210 }
211
212 OS_Printf("common OUT thread=%d\n", val);
213 OS_UnlockMutex(&mutex);
214 }
215
216 /*====== End of main.c ======*/
217