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