1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - demos - math - qsort
3 File: main.c
4
5 Copyright 2007-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 /*---------------------------------------------------------------------------*
21 Prototype definitions
22 *---------------------------------------------------------------------------*/
23 static void VBlankIntr(void);
24 static void KeyInit(void);
25 static void KeyRead(void);
26
27
28 // Key States
29 static struct
30 {
31 u16 con;
32 u16 trg;
33 }
34 keys;
35
36 #define DATA_NUM 1024
37
38 /*---------------------------------------------------------------------------*
39 Static variable definitions
40 *---------------------------------------------------------------------------*/
41 static u32 gDataArray[DATA_NUM];
42 static u8 *gSortBuf;
43
44
45 /*---------------------------------------------------------------------------*
46 Name: KeyInit
47
48 Description: Initialize Pad Keys.
49
50 Arguments: None.
51
52 Returns: None.
53 *---------------------------------------------------------------------------*/
KeyInit(void)54 static void KeyInit(void)
55 {
56
57 keys.trg = 0;
58 keys.con = 0;
59
60 }
61
62 /*---------------------------------------------------------------------------*
63 Name: KeyRead
64
65 Description: Read Pad Keys.
66
67 Arguments: None.
68
69 Returns: None.
70 *---------------------------------------------------------------------------*/
KeyRead(void)71 static void KeyRead(void)
72 {
73 u16 r = PAD_Read();
74
75 keys.trg = (u16)(~keys.con & r);
76 keys.con = r;
77 }
78
79
80 /*---------------------------------------------------------------------------*
81 Name: InitializeAllocateSystem
82
83 Description: Initializes the memory allocation system within the main memory arena.
84
85 Arguments: None.
86
87 Returns: None.
88 *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)89 static void InitializeAllocateSystem(void)
90 {
91 void *tempLo;
92 OSHeapHandle hh;
93
94 // Based on the premise that OS_Init has been already called
95 tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
96 OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
97 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
98 if (hh < 0)
99 {
100 OS_Panic("ARM9: Fail to create heap...\n");
101 }
102 hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
103 }
104
105
106
107 /*---------------------------------------------------------------------------*
108 Name: DisplayInit
109
110 Description: Graphics Initialization
111
112 Arguments: None.
113
114 Returns: None.
115 *---------------------------------------------------------------------------*/
DisplayInit()116 static void DisplayInit()
117 {
118
119 GX_Init();
120 FX_Init();
121
122 GX_DispOff();
123 GXS_DispOff();
124
125 GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
126
127 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
128 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
129 (void)GX_VBlankIntr(TRUE); // To generate V-Blank interrupt request
130 (void)OS_EnableIrq();
131
132
133 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
134 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
135
136 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); // Clear OAM
137 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); // Clear the standard palette
138
139 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE); // Clear OAM
140 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); // Clear the standard palette
141 MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
142
143
144 GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB); // Set VRAM-A,B for OBJ
145
146 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, // 2D / 3D Mode
147 GX_BGMODE_0, // BGMODE 0
148 GX_BG0_AS_2D); // Set BG0 as 2D
149
150 GX_SetVisiblePlane(GX_PLANEMASK_OBJ); // Make OBJs visible
151 GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K); // 2D mapping OBJ
152
153 OS_WaitVBlankIntr(); // Waiting for the end of the V-Blank interrupt
154 GX_DispOn();
155
156 }
157
158
159
160
161
162
163
164 /* User data comparison function */
compare(void * elem1,void * elem2)165 static s32 compare(void *elem1, void *elem2)
166 {
167 // To ensure there is no overflow into the sign bit, promote to s64 and then compare.
168 s64 diff = (s64)*(u32 *)elem1 - (s64)*(u32 *)elem2;
169 // Normalize only the large-small ordering to {+1,0,-1}, and return it.
170 return (diff > 0) ? +1 : ((diff < 0) ? -1 : 0);
171 }
172
173 /* Function for debug output of array data */
PrintArray(u32 * array,u32 size)174 static void PrintArray(u32 *array, u32 size)
175 {
176 #pragma unused( array )
177 u32 i;
178
179 for (i = 0; i < size; i++)
180 {
181 if ((i & 0x7) == 0)
182 {
183 OS_TPrintf("\n");
184 }
185 OS_TPrintf("%08lx,", array[i]);
186 }
187 OS_TPrintf("\n");
188 }
189
190
191 /*---------------------------------------------------------------------------*
192 Name: NitroMain
193
194 Description: Initialization and main loop
195
196 Arguments: None.
197
198 Returns: None.
199 *---------------------------------------------------------------------------*/
NitroMain(void)200 void NitroMain(void)
201 {
202 MATHRandContext32 context;
203
204 // Initialization
205 KeyInit();
206 OS_Init();
207 TP_Init();
208 OS_InitTick();
209
210 // Memory allocation
211 InitializeAllocateSystem();
212
213 DisplayInit();
214
215 // Empty call for getting key input data (strategy for pressing A Button in the IPL)
216 KeyRead();
217 // Bury data with random numbers
218 MATH_InitRand32(&context, 0);
219
220 OS_TPrintf("Press A Button to start MATH_QSort() test\n");
221
222 while (TRUE)
223 {
224 static u32 cnt = 0;
225 static OSTick sum = 0;
226
227 KeyRead();
228
229 if ((keys.trg & PAD_BUTTON_A) != 0)
230 {
231 u32 i;
232
233 {
234 for (i = 0; i < DATA_NUM; i++)
235 {
236 gDataArray[i] = MATH_Rand32(&context, 0);
237 }
238 }
239 {
240 OSTick before, after;
241
242 // Quick sort
243 gSortBuf = (u8 *)OS_Alloc(MATH_QSortStackSize(DATA_NUM));
244
245 before = OS_GetTick();
246 MATH_QSort(gDataArray, DATA_NUM, sizeof(u32), compare, NULL);
247 after = OS_GetTick();
248 OS_Free(gSortBuf);
249
250 // * Verify it is correctly sorted in ascending order
251 for (i = 0; i < DATA_NUM; i++)
252 {
253 u32 lower = gDataArray[MATH_MAX(i - 1, 0)];
254 u32 upper = gDataArray[i];
255 if (lower > upper)
256 {
257 OS_TPanic("result array is not sorted correctly!");
258 }
259 }
260
261 // Print and display sort results
262 PrintArray(gDataArray, DATA_NUM);
263 cnt++;
264 sum += OS_TicksToMicroSeconds(after - before);
265
266 OS_TPrintf("time = %lld us (avg %lld us)\n", OS_TicksToMicroSeconds(after - before),
267 sum / cnt);
268 OS_TPrintf("Press A Button to start MATH_QSort() test again\n");
269 }
270 }
271 // Wait for V-Blank interrupt
272 OS_WaitVBlankIntr();
273 }
274 }
275
276
277 /*---------------------------------------------------------------------------*
278 Name: VBlankIntr
279
280 Description: V-Blank function
281
282 Arguments: None.
283
284 Returns: None.
285 *---------------------------------------------------------------------------*/
VBlankIntr(void)286 static void VBlankIntr(void)
287 {
288
289 // Set IRQ check flag
290 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
291 }
292
293
294
295 /*---------------------------------------------------------------------------*
296 End of file
297 *---------------------------------------------------------------------------*/
298