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