1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - MATH - demos
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-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17 /*---------------------------------------------------------------------------*
18 Demo for checking the operations of the MATH library API
19 *---------------------------------------------------------------------------*/
20
21 #include <nitro.h>
22
23
24
25 static void VBlankIntr(void);
26 static void DisplayInit(void);
27 static void FillScreen(u16 col);
28 static BOOL MathTest(void);
29
30 /*---------------------------------------------------------------------------*
31 Variable Definitions
32 *---------------------------------------------------------------------------*/
33
34 /*---------------------------------------------------------------------------*
35 Function Definitions
36 *---------------------------------------------------------------------------*/
37
38 /*---------------------------------------------------------------------------*
39 Name: NitroMain
40
41 Description: Initialization and main loop.
42
43 Arguments: None.
44
45 Returns: None.
46 *---------------------------------------------------------------------------*/
NitroMain(void)47 void NitroMain(void)
48 {
49 // Various types of initialization
50 OS_Init();
51
52 DisplayInit();
53
54 if (MathTest())
55 {
56 // Success
57 OS_TPrintf("------ Test Succeeded ------\n");
58 FillScreen(GX_RGB(0, 31, 0));
59 }
60 else
61 {
62 // Failed
63 OS_TPrintf("****** Test Failed ******\n");
64 FillScreen(GX_RGB(31, 0, 0));
65 }
66
67 // Main loop
68 while (TRUE)
69 {
70 // Waiting for the V-Blank
71 OS_WaitVBlankIntr();
72 }
73 }
74
75 /*---------------------------------------------------------------------------*
76 Name: VBlankIntr
77
78 Description: V-Blank interrupt vector.
79
80 Arguments: None.
81
82 Returns: None.
83 *---------------------------------------------------------------------------*/
VBlankIntr(void)84 static void VBlankIntr(void)
85 {
86 // sets the IRQ check flag
87 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
88 }
89
90 /*---------------------------------------------------------------------------*
91 Name: DisplayInit
92
93 Description: Graphics Initialization
94
95 Arguments: None.
96
97 Returns: None.
98 *---------------------------------------------------------------------------*/
DisplayInit(void)99 static void DisplayInit(void)
100 {
101
102 GX_Init();
103 FX_Init();
104
105 GX_DispOff();
106 GXS_DispOff();
107
108 GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
109
110 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
111 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
112 (void)GX_VBlankIntr(TRUE); // To generate V-Blank interrupt request
113 (void)OS_EnableIrq();
114
115
116 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
117 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
118
119 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); // Clear OAM
120 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); // Clear the standard palette
121
122 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE); // Clear OAM
123 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); // Clear the standard palette
124 MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
125
126
127 GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB); // Set VRAM-A,B for OBJ
128
129 GX_SetGraphicsMode(GX_DISPMODE_VRAM_C, // VRAM mode
130 (GXBGMode)0, // Dummy
131 (GXBG0As)0); // Dummy
132
133 GX_SetVisiblePlane(GX_PLANEMASK_OBJ); // Make OBJs visible
134 GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K); // 2D mapping OBJ
135
136 OS_WaitVBlankIntr(); // Waiting for the end of the V-Blank interrupt
137 GX_DispOn();
138
139 }
140
141
142 /*---------------------------------------------------------------------------*
143 Name: FillScreen
144
145 Description: Fills the screen
146
147 Arguments: col: FillColor
148
149 Returns: None.
150 *---------------------------------------------------------------------------*/
FillScreen(u16 col)151 static void FillScreen(u16 col)
152 {
153 MI_CpuFill16((void *)HW_LCDC_VRAM_C, col, 256 * 192 * 2);
154 }
155
156 /*---------------------------------------------------------------------------*
157 Name: MathTest
158
159 Description: Test routine for mathematical functions
160
161 Arguments: None.
162
163 Returns: TRUE if test succeeds.
164 *---------------------------------------------------------------------------*/
165 #define PrintResultEq( a, b, f ) \
166 { OS_TPrintf( ((a) == (b)) ? "[--OK--] " : "[**NG**] " ); (f) = (f) && ((a) == (b)); }
167
MathTest(void)168 static BOOL MathTest(void)
169 {
170 int i;
171 BOOL flag = TRUE;
172
173 {
174 int a[] = { 0, 1, 0x7fffffff, -1, -0x80000000 };
175 int result_abs[] = { 0, 1, 0x7fffffff, 1, -0x80000000 };
176 for (i = 0; i < sizeof(a) / sizeof(int); i++)
177 {
178 int result;
179 result = MATH_ABS(a[i]);
180 PrintResultEq(result, result_abs[i], flag);
181 OS_TPrintf("MATH_ABS(%d) = %d\n", a[i], result);
182 }
183 for (i = 0; i < sizeof(a) / sizeof(int); i++)
184 {
185 int result;
186 result = MATH_IAbs(a[i]);
187 PrintResultEq(result, result_abs[i], flag);
188 OS_TPrintf("MATH_IAbs(%d) = %d\n", a[i], result);
189 }
190 }
191
192 {
193 // TODO: NaN and subnormal numbers; also check -0.0
194 double a[] = { 0, 1, -1, 1.0e20, 1.123e-20, -1.0e20, -1.123e-20 };
195 double result_abs[] = { 0, 1, 1, 1.0e20, 1.123e-20, 1.0e20, 1.123e-20 };
196 for (i = 0; i < sizeof(a) / sizeof(double); i++)
197 {
198 double result;
199 result = MATH_ABS(a[i]);
200 PrintResultEq(result, result_abs[i], flag);
201 OS_Printf("MATH_ABS(%g) = %g\n", a[i], result);
202 }
203 }
204
205 {
206 int a[] = { 0, 1, 0, -1, 0, 32, 31, -32, -31 };
207 int b[] = { 0, 0, 1, 0, -1, 31, 32, -31, -32 };
208 int result_min[] = { 0, 0, 0, -1, -1, 31, 31, -32, -32 };
209 int result_max[] = { 0, 1, 1, 0, 0, 32, 32, -31, -31 };
210 for (i = 0; i < sizeof(a) / sizeof(int); i++)
211 {
212 int result;
213 result = MATH_MIN(a[i], b[i]);
214 PrintResultEq(result, result_min[i], flag);
215 OS_TPrintf("MATH_MIN(%d, %d) = %d\n", a[i], b[i], result);
216 }
217 for (i = 0; i < sizeof(a) / sizeof(int); i++)
218 {
219 int result;
220 result = MATH_IMin(a[i], b[i]);
221 PrintResultEq(result, result_min[i], flag);
222 OS_TPrintf("MATH_IMin(%d, %d) = %d\n", a[i], b[i], result);
223 }
224 for (i = 0; i < sizeof(a) / sizeof(int); i++)
225 {
226 int result;
227 result = MATH_MAX(a[i], b[i]);
228 PrintResultEq(result, result_max[i], flag);
229 OS_TPrintf("MATH_MAX(%d, %d) = %d\n", a[i], b[i], result);
230 }
231 for (i = 0; i < sizeof(a) / sizeof(int); i++)
232 {
233 int result;
234 result = MATH_IMax(a[i], b[i]);
235 PrintResultEq(result, result_max[i], flag);
236 OS_TPrintf("MATH_IMax(%d, %d) = %d\n", a[i], b[i], result);
237 }
238 }
239
240 {
241 // TODO: NaN and subnormal numbers; also check -0.0
242 double a[] = { 0, 1, 0, -1, 0, 1.0e15, 1.0e-15, 1.0e-15, 1.0e-16, -1.0e-15, -1.1e-15 };
243 double b[] = { 0, 0, 1, 0, -1, 1.0e-15, 1.0e15, 1.0e-16, 1.0e-15, -1.1e-15, -1.0e-15 };
244 double result_min[] =
245 { 0, 0, 0, -1, -1, 1.0e-15, 1.0e-15, 1.0e-16, 1.0e-16, -1.1e-15, -1.1e-15 };
246 double result_max[] =
247 { 0, 1, 1, 0, 0, 1.0e15, 1.0e15, 1.0e-15, 1.0e-15, -1.0e-15, -1.0e-15 };
248 for (i = 0; i < sizeof(a) / sizeof(double); i++)
249 {
250 double result;
251 result = MATH_MIN(a[i], b[i]);
252 PrintResultEq(result, result_min[i], flag);
253 OS_Printf("MATH_MIN(%g, %g) = %g\n", a[i], b[i], result);
254 }
255 for (i = 0; i < sizeof(a) / sizeof(double); i++)
256 {
257 double result;
258 result = MATH_MAX(a[i], b[i]);
259 PrintResultEq(result, result_max[i], flag);
260 OS_Printf("MATH_MAX(%g, %g) = %g\n", a[i], b[i], result);
261 }
262 }
263
264 {
265 int a[] = { -2, -1, 0, 1, 2, 0, 10, -2, -10, -0x80000000, 0x7fffffff };
266 int low[] = { -1, -1, -1, -1, -1, 1, 2, -8, -8, -0x80000000, -0x80000000 };
267 int high[] = { 1, 1, 1, 1, 1, 1, 8, -4, -4, 0x7fffffff, 0x7fffffff };
268 int result_clp[] = { -1, -1, 0, 1, 1, 1, 8, -4, -8, -0x80000000, 0x7fffffff };
269 for (i = 0; i < sizeof(a) / sizeof(int); i++)
270 {
271 int result;
272 result = MATH_CLAMP(a[i], low[i], high[i]);
273 PrintResultEq(result, result_clp[i], flag);
274 OS_TPrintf("MATH_CLAMP(%d, %d, %d) = %d\n", a[i], low[i], high[i], result);
275 }
276 }
277
278 {
279 int a[] = { 0, 1, 31, 32, 33, 128, -1, -31, -32, -33, 0x7fffffff, -0x80000000 };
280 int result_rup[] = { 0, 32, 32, 32, 64, 128, 0, 0, -32, -32, -0x80000000, -0x80000000 };
281 int result_rdn[] =
282 { 0, 0, 0, 32, 32, 128, -32, -32, -32, -64, 0x7fffffe0, -0x80000000 };
283 for (i = 0; i < sizeof(a) / sizeof(int); i++)
284 {
285 int result;
286 result = MATH_ROUNDUP(a[i], 32);
287 PrintResultEq(result, result_rup[i], flag);
288 OS_TPrintf("MATH_ROUNDUP(%d, 32) = %d\n", a[i], result);
289 }
290 for (i = 0; i < sizeof(a) / sizeof(int); i++)
291 {
292 int result;
293 result = MATH_ROUNDUP32(a[i]);
294 PrintResultEq(result, result_rup[i], flag);
295 OS_TPrintf("MATH_ROUNDUP32(%d) = %d\n", a[i], result);
296 }
297 for (i = 0; i < sizeof(a) / sizeof(int); i++)
298 {
299 int result;
300 result = MATH_ROUNDDOWN(a[i], 32);
301 PrintResultEq(result, result_rdn[i], flag);
302 OS_TPrintf("MATH_ROUNDDOWN(%d, 32) = %d\n", a[i], result);
303 }
304 for (i = 0; i < sizeof(a) / sizeof(int); i++)
305 {
306 int result;
307 result = MATH_ROUNDDOWN32(a[i]);
308 PrintResultEq(result, result_rdn[i], flag);
309 OS_TPrintf("MATH_ROUNDDOWN32(%d) = %d\n", a[i], result);
310 }
311 }
312
313 {
314 u32 a[] =
315 { 0, 1, 0xffffffff, 0xffff0000, 0x0000ffff, 0xaaaaaaaa, 0x55555555, 0x1234cdef };
316 int result_clz[] = { 32, 31, 0, 0, 16, 0, 1, 3 };
317 int result_ctz[] = { 32, 0, 0, 16, 0, 1, 0, 0 };
318 u32 result_lsb[] = { 0, 1, 1, 0x00010000, 1, 0x00000002, 0x00000001, 0x00000001 };
319 u32 result_msb[] =
320 { 0, 1, 0x80000000, 0x80000000, 0x00008000, 0x80000000, 0x40000000, 0x10000000 };
321 int result_pop[] = { 0, 1, 32, 16, 16, 16, 16, 17 };
322 int result_lg2[] = { -1, 0, 31, 31, 15, 31, 30, 28 };
323 for (i = 0; i < sizeof(a) / sizeof(int); i++)
324 {
325 u32 result;
326 result = MATH_CountLeadingZeros(a[i]);
327 PrintResultEq(result, result_clz[i], flag);
328 OS_TPrintf("MATH_CountLeadingZeros(0x%08x) = %d\n", a[i], result);
329 }
330 for (i = 0; i < sizeof(a) / sizeof(int); i++)
331 {
332 u32 result;
333 result = MATH_CLZ(a[i]);
334 PrintResultEq(result, result_clz[i], flag);
335 OS_TPrintf("MATH_CLZ(0x%08x) = %d\n", a[i], result);
336 }
337 for (i = 0; i < sizeof(a) / sizeof(int); i++)
338 {
339 u32 result;
340 result = MATH_CTZ(a[i]);
341 PrintResultEq(result, result_ctz[i], flag);
342 OS_TPrintf("MATH_CTZ(0x%08x) = %d\n", a[i], result);
343 }
344 for (i = 0; i < sizeof(a) / sizeof(int); i++)
345 {
346 u32 result;
347 result = MATH_LSB(a[i]);
348 PrintResultEq(result, result_lsb[i], flag);
349 OS_TPrintf("MATH_LSB(0x%08x) = %08x\n", a[i], result);
350 }
351 for (i = 0; i < sizeof(a) / sizeof(int); i++)
352 {
353 u32 result;
354 result = MATH_MSB(a[i]);
355 PrintResultEq(result, result_msb[i], flag);
356 OS_TPrintf("MATH_MSB(0x%08x) = %08x\n", a[i], result);
357 }
358 for (i = 0; i < sizeof(a) / sizeof(int); i++)
359 {
360 int result;
361 result = MATH_CountPopulation(a[i]);
362 PrintResultEq(result, result_pop[i], flag);
363 OS_TPrintf("MATH_CountPoulation(0x%08x) = %d\n", a[i], result);
364 }
365 for (i = 0; i < sizeof(a) / sizeof(int); i++)
366 {
367 int result;
368 result = MATH_ILog2(a[i]);
369 PrintResultEq(result, result_lg2[i], flag);
370 OS_TPrintf("MATH_ILog2(0x%08x) = %d\n", a[i], result);
371
372 }
373 }
374
375 return flag;
376 }
377
378 /*---------------------------------------------------------------------------*
379 End of file
380 *---------------------------------------------------------------------------*/
381