1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX -
3   File:     g3x.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-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #include <nitro/gx/g3x.h>
18 #include <nitro/gx/g3imm.h>
19 #include <nitro/gx/gx.h>
20 #include <nitro/gx/gx_bgcnt.h>
21 #ifdef SDK_NITRO
22 #include <nitro/hw/ARM9/ioreg_GX.h>
23 #include <nitro/hw/ARM9/ioreg_G3.h>
24 #include <nitro/hw/ARM9/ioreg_G2.h>
25 #else
26 #include <twl/hw/ARM9/ioreg_GX.h>
27 #include <twl/hw/ARM9/ioreg_G3.h>
28 #include <twl/hw/ARM9/ioreg_G2.h>
29 #endif
30 #include <nitro/fx/fx_const.h>
31 #include <nitro/mi/dma.h>
32 
33 #ifdef SDK_TWL
34 #include <twl/mi/common/dma.h>
35 #endif
36 
37 #include <nitro/mi/memory.h>
38 #include "gxasm.h"
39 
40 
41 /*---------------------------------------------------------------------------*
42   Static function prototype definition.
43  *---------------------------------------------------------------------------*/
44 static asm void GXi_NopClearFifo128_( register void* pDest );
45 
46 
47 /*---------------------------------------------------------------------------*
48   Name:         G3X_Init
49 
50   Description:  Initializes the registers for 3D graphics.
51 
52   Arguments:    none
53 
54   Returns:      none
55  *---------------------------------------------------------------------------*/
G3X_Init()56 void G3X_Init()
57 {
58 #ifdef SDK_DEBUG
59     {
60         GXPower power = GX_GetPower();
61         SDK_WARNING(power & GX_POWER_RE, "GX_POWER_RE is off now, registers for it not initialized.");
62         SDK_WARNING(power & GX_POWER_GE, "GX_POWER_GE is off now, registers for it not initialized.");
63     }
64 #endif
65 
66     G3X_ClearFifo();
67     G3_End();
68 
69     while ( G3X_IsGeometryBusy() ) { }
70 
71     // clear registers before settings
72     reg_G3X_DISP3DCNT = 0;
73     reg_G3X_GXSTAT = 0;
74 
75     // Horizontal Offset
76     reg_G2_BG0OFS = 0;
77 
78     // DISP3DCNT
79     G3X_ResetListRamOverflow();
80     G3X_ResetLineBufferUnderflow();
81     G3X_SetShading(GX_SHADING_TOON);
82     G3X_AntiAlias(TRUE);
83     G3X_AlphaTest(FALSE, 0);
84 
85     // GXSTAT
86     G3X_ResetMtxStackOverflow();
87 
88     G3X_SetFifoIntrCond(GX_FIFOINTR_COND_EMPTY);
89 
90     // matrix stack and GXSTAT
91     G3X_InitMtxStack();
92 
93     // G3X_SetClearColor(GX_RGB(0, 0, 0), 0, 0x7fff, 0, FALSE);
94     reg_G3X_CLEAR_COLOR = 0;
95     reg_G3X_CLEAR_DEPTH = 0x7fff;
96 
97     // G3X_SetClearImageOffset(0, 0);
98     reg_G3X_CLRIMAGE_OFFSET = 0;
99 
100     // G3X_SetFogColor(GX_RGB(0, 0, 0), 0);
101     reg_G3X_FOG_COLOR = 0;
102 
103     // FOG_OFFSET
104     reg_G3X_FOG_OFFSET = 0;
105 
106     // BG0CNT
107     G2_SetBG0Priority(0);
108 
109     G3X_InitTable();
110 
111     // POLYGON_ATTR
112     G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_BACK, 0, 31, GX_POLYGON_ATTR_MISC_NONE);
113 
114     // TEXIMAGE_PARAM
115     G3_TexImageParam(GX_TEXFMT_NONE,
116 
117                      GX_TEXGEN_NONE,
118                      GX_TEXSIZE_S8, GX_TEXSIZE_T8, GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE, GX_TEXPLTTCOLOR0_USE, 0);
119 
120     // TEXPLTT_BASE
121     G3_Direct1(G3OP_TEXPLTT_BASE, 0);
122 }
123 
124 
125 /*---------------------------------------------------------------------------*
126   Name:         G3X_Reset
127 
128   Description:  Resets FIFO, matrix stacks, overflow flags,
129                 and attributes of polygons.
130 
131   Arguments:    none
132 
133   Returns:      none
134  *---------------------------------------------------------------------------*/
G3X_Reset()135 void G3X_Reset()
136 {
137 #ifdef SDK_DEBUG
138     {
139         GXPower power = GX_GetPower();
140         SDK_WARNING(power & GX_POWER_RE,
141                     "GX_POWER_RE is off now, registers for it not initialized.");
142         SDK_WARNING(power & GX_POWER_GE,
143                     "GX_POWER_GE is off now, registers for it not initialized.");
144     }
145 #endif
146     // DO NOT REMOVE THIS
147     // Swapbuffers may be canceled if you remove.
148     while (G3X_IsGeometryBusy())
149     {
150     }
151 
152     G3X_ResetMtxStackOverflow();
153     G3X_ResetListRamOverflow();
154     G3X_ResetLineBufferUnderflow();
155 
156     G3X_ResetMtxStack();
157     // POLYGON_ATTR
158     G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_BACK, 0, 31,
159                    GX_POLYGON_ATTR_MISC_NONE);
160 
161     // TEXIMAGE_PARAM
162     G3_TexImageParam(GX_TEXFMT_NONE,
163                      GX_TEXGEN_NONE,
164                      GX_TEXSIZE_S8, GX_TEXSIZE_T8, GX_TEXREPEAT_NONE, GX_TEXFLIP_NONE,
165                      GX_TEXPLTTCOLOR0_USE, 0);
166 
167     // TEXPLTT_BASE
168     G3_Direct1(G3OP_TEXPLTT_BASE, 0);
169 }
170 
171 
172 
173 /*---------------------------------------------------------------------------*
174   Name:         G3X_ClearFifo
175 
176   Description:  Clear FIFO
177 
178   Arguments:    none
179 
180   Returns:      none
181  *---------------------------------------------------------------------------*/
G3X_ClearFifo(void)182 void G3X_ClearFifo(void)
183 {
184 
185     GXi_NopClearFifo128_((void *)&reg_G3X_GXFIFO);
186 //  G3_End();
187 
188     while (G3X_IsGeometryBusy())
189     {
190     }
191 }
192 
193 
194 /*---------------------------------------------------------------------------*
195   Name:         G3X_InitMtxStack
196 
197   Description:  Initializes the level of matrix stacks and the current matrices.
198 
199   Arguments:    none
200 
201   Returns:      none
202  *---------------------------------------------------------------------------*/
G3X_InitMtxStack()203 void G3X_InitMtxStack()
204 {
205     s32     levelPV;
206     s32     levelPJ;
207 #ifdef SDK_DEBUG
208     {
209         GXPower power = GX_GetPower();
210         SDK_WARNING(power & GX_POWER_GE,
211                     "GX_POWER_GE is off now, registers for it not initialized.");
212     }
213 #endif
214     G3X_ResetMtxStackOverflow();
215 
216     while (G3X_GetMtxStackLevelPV(&levelPV))
217         ;
218     while (G3X_GetMtxStackLevelPJ(&levelPJ))
219         ;
220 
221     G3_MtxMode(GX_MTXMODE_TEXTURE);
222     G3_Identity();
223 
224     G3_MtxMode(GX_MTXMODE_PROJECTION);
225     if (levelPJ != 0)
226     {
227         G3_PopMtx(levelPJ);
228     }
229     G3_Identity();
230 
231     G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
232     G3_PopMtx(levelPV);
233     G3_Identity();
234 
235 }
236 
237 
238 /*---------------------------------------------------------------------------*
239   Name:         G3X_ResetMtxStack
240 
241   Description:  Initializes the level of matrix stacks,
242                 and the current matrices except the current projection matrix.
243 
244   Arguments:    none
245 
246   Returns:      none
247  *---------------------------------------------------------------------------*/
G3X_ResetMtxStack()248 void G3X_ResetMtxStack()
249 {
250     s32     levelPV;
251     s32     levelPJ;
252 #ifdef SDK_DEBUG
253     {
254         GXPower power = GX_GetPower();
255         SDK_WARNING(power & GX_POWER_GE, "GX_POWER_GE is off now, registers for it not changes.");
256     }
257 #endif
258     G3X_ResetMtxStackOverflow();
259 
260     while (G3X_GetMtxStackLevelPV(&levelPV))
261         ;
262     while (G3X_GetMtxStackLevelPJ(&levelPJ))
263         ;
264 
265     G3_MtxMode(GX_MTXMODE_TEXTURE);
266     G3_Identity();
267 
268     G3_MtxMode(GX_MTXMODE_PROJECTION);
269     if (levelPJ != 0)
270     {
271         G3_PopMtx(levelPJ);
272     }
273 //    G3_Identity(); // Projection Matrix may not be set in a main loop
274 
275     G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
276     G3_PopMtx(levelPV);
277     G3_Identity();
278 
279 }
280 
281 
282 /*---------------------------------------------------------------------------*
283   Name:         G3X_SetFog
284 
285   Description:  Sets attributes for fog.
286 
287   Arguments:    enable       enables fog if not FALSE
288                 fogMode      fog blending manner(alpha only/color and alpha)
289                 fogSlope     slope of fog blending
290                 fogOffset    depth where fog blending starts
291 
292   Returns:      none
293  *---------------------------------------------------------------------------*/
G3X_SetFog(BOOL enable,GXFogBlend fogMode,GXFogSlope fogSlope,int fogOffset)294 void G3X_SetFog(BOOL enable, GXFogBlend fogMode, GXFogSlope fogSlope, int fogOffset)
295 {
296     if (enable)
297     {
298         SDK_MINMAX_ASSERT(fogOffset, 0, 0x7fff);
299         SDK_MINMAX_ASSERT(fogSlope, GX_FOGSLOPE_0x8000, GX_FOGSLOPE_0x0020);
300         SDK_ASSERT(GX_FOGBLEND_COLOR_ALPHA == fogMode || GX_FOGBLEND_ALPHA == fogMode);
301 
302         reg_G3X_FOG_OFFSET = (u16)fogOffset;
303 
304         reg_G3X_DISP3DCNT = (u16)((reg_G3X_DISP3DCNT &
305                                    ~(REG_G3X_DISP3DCNT_FOG_SHIFT_MASK
306                                      | REG_G3X_DISP3DCNT_FMOD_MASK
307                                      | REG_G3X_DISP3DCNT_RO_MASK
308                                      | REG_G3X_DISP3DCNT_GO_MASK))
309                                   | ((fogSlope << REG_G3X_DISP3DCNT_FOG_SHIFT_SHIFT)
310                                      | (fogMode << REG_G3X_DISP3DCNT_FMOD_SHIFT)
311                                      | (REG_G3X_DISP3DCNT_FME_MASK)));
312     }
313     else
314     {
315         reg_G3X_DISP3DCNT &= (u16)~(REG_G3X_DISP3DCNT_FME_MASK
316                                     | REG_G3X_DISP3DCNT_RO_MASK | REG_G3X_DISP3DCNT_GO_MASK);
317     }
318 }
319 
320 
321 /*---------------------------------------------------------------------------*
322   Name:         G3X_GetClipMtx
323 
324   Description:  Gets a clip matrix.
325 
326   Arguments:    m            a pointer to a 4x4 matrix.
327 
328   Returns:      0 if the result is in *m,
329                 otherwise, the geometry engine is busy.
330  *---------------------------------------------------------------------------*/
G3X_GetClipMtx(MtxFx44 * m)331 int G3X_GetClipMtx(MtxFx44 *m)
332 {
333     SDK_NULL_ASSERT(m);
334 
335     if (G3X_IsGeometryBusy())
336     {
337         return -1;
338     }
339     else
340     {
341 #if 1
342         MI_Copy64B((void *)REG_CLIPMTX_RESULT_0_ADDR, &m->_00);
343 #else
344         m->_00 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 0);
345         m->_01 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 1);
346         m->_02 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 2);
347         m->_03 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 3);
348 
349         m->_10 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 4);
350         m->_11 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 5);
351         m->_12 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 6);
352         m->_13 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 7);
353 
354         m->_20 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 8);
355         m->_21 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 9);
356         m->_22 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 10);
357         m->_23 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 11);
358 
359         m->_30 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 12);
360         m->_31 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 13);
361         m->_32 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 14);
362         m->_33 = *((fx32 *)REG_CLIPMTX_RESULT_0_ADDR + 15);
363 #endif
364         return 0;
365     }
366 }
367 
368 
369 /*---------------------------------------------------------------------------*
370   Name:         G3X_GetVectorMtx
371 
372   Description:  Gets a vector matrix.
373 
374   Arguments:    m            a pointer to a 3x3 matrix.
375 
376   Returns:      0 if the result is in *m,
377                 otherwise, the geometry engine is busy.
378  *---------------------------------------------------------------------------*/
G3X_GetVectorMtx(MtxFx33 * m)379 int G3X_GetVectorMtx(MtxFx33 *m)
380 {
381     SDK_NULL_ASSERT(m);
382 
383     if (G3X_IsGeometryBusy())
384     {
385         return -1;
386     }
387     else
388     {
389 #if 1
390         MI_Copy36B((void *)(REG_VECMTX_RESULT_0_ADDR), &m->_00);
391 #else
392         m->_00 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 0);
393         m->_01 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 1);
394         m->_02 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 2);
395 
396         m->_10 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 3);
397         m->_11 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 4);
398         m->_12 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 5);
399 
400         m->_20 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 6);
401         m->_21 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 7);
402         m->_22 = *((fx32 *)REG_VECMTX_RESULT_0_ADDR + 8);
403 #endif
404 
405         return 0;
406     }
407 }
408 
409 
410 /*---------------------------------------------------------------------------*
411   Name:         G3X_SetEdgeColorTable
412 
413   Description:  Sets a edge color table.
414 
415   Arguments:    m            a pointer to a the data to set(16 bytes length).
416 
417   Returns:      None.
418  *---------------------------------------------------------------------------*/
G3X_SetEdgeColorTable(const GXRgb * rgb_8)419 void G3X_SetEdgeColorTable(const GXRgb *rgb_8)
420 {
421     SDK_NULL_ASSERT(rgb_8);
422 #if 1
423     MI_CpuCopy16(rgb_8, (void *)REG_EDGE_COLOR_0_L_ADDR, 16);
424 #else
425     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 0) = (u16)(*(rgb_8 + 0));
426     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 1) = (u16)(*(rgb_8 + 1));
427     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 2) = (u16)(*(rgb_8 + 2));
428     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 3) = (u16)(*(rgb_8 + 3));
429     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 4) = (u16)(*(rgb_8 + 4));
430     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 5) = (u16)(*(rgb_8 + 5));
431     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 6) = (u16)(*(rgb_8 + 6));
432     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 7) = (u16)(*(rgb_8 + 7));
433 #endif
434 }
435 
436 
437 /*---------------------------------------------------------------------------*
438   Name:         G3X_SetFogTable
439 
440   Description:  Sets a fog table.
441 
442   Arguments:    fogTable     a pointer to the data to set(32 bytes length)
443 
444   Returns:      none
445  *---------------------------------------------------------------------------*/
G3X_SetFogTable(const u32 * fogTable)446 void G3X_SetFogTable(const u32 *fogTable)
447 {
448     SDK_NULL_ASSERT(fogTable);
449 #if 1
450     MI_Copy32B(&fogTable[0], (void *)REG_FOG_TABLE_0_ADDR);
451 #else
452     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 0) = *(fogTable + 0);
453     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 1) = *(fogTable + 1);
454     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 2) = *(fogTable + 2);
455     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 3) = *(fogTable + 3);
456     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 4) = *(fogTable + 4);
457     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 5) = *(fogTable + 5);
458     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 6) = *(fogTable + 6);
459     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 7) = *(fogTable + 7);
460 #endif
461 }
462 
463 
464 /*---------------------------------------------------------------------------*
465   Name:         G3X_SetToonTable
466 
467   Description:  Sets a toon table.
468 
469   Arguments:    rgb_32       a pointer to the data to set(64 bytes length)
470 
471   Returns:      none
472  *---------------------------------------------------------------------------*/
G3X_SetToonTable(const GXRgb * rgb_32)473 void G3X_SetToonTable(const GXRgb *rgb_32)
474 {
475 #if 1
476     SDK_NULL_ASSERT(rgb_32);
477     MI_CpuCopy16(rgb_32, (void *)REG_TOON_TABLE_0_L_ADDR, 64);
478 #else
479     int     i;
480     SDK_NULL_ASSERT(rgb_32);
481     for (i = 0; i < 32; ++i)
482     {
483         *((REGType16 *)REG_TOON_TABLE_0_L_ADDR + i) = (u16)(*(rgb_32 + i));
484     }
485 #endif
486 }
487 
488 
489 /*---------------------------------------------------------------------------*
490   Name:         G3X_SetClearColor
491 
492   Description:  Sets a clear color, alpha, depth, polygonID
493 
494   Arguments:    rgb          clear color on the color buffer
495                 alpha        clear alpha on the color buffer
496                 depth        clear depth(15 bits) on the depth buffer
497                 polygonID    clear polygon ID(opaque) on the attribute buffer
498                 fog          fog enable flag on the attribute buffer
499 
500   Returns:      none
501  *---------------------------------------------------------------------------*/
G3X_SetClearColor(GXRgb rgb,int alpha,int depth,int polygonID,BOOL fog)502 void G3X_SetClearColor(GXRgb rgb, int alpha, int depth, int polygonID, BOOL fog)
503 {
504     u32     val;
505     GX_POLYGONID_ASSERT(polygonID);
506     GX_ALPHA_ASSERT(alpha);
507     GXRGB_ASSERT(rgb);
508     GX_DEPTH_ASSERT(depth);
509 
510     val =
511         (u32)(rgb | (alpha << REG_G3X_CLEAR_COLOR_ALPHA_SHIFT) |
512               (polygonID << REG_G3X_CLEAR_COLOR_POLYGONID_SHIFT));
513     if (fog)
514         val |= REG_G3X_CLEAR_COLOR_F_MASK;
515 
516     reg_G3X_CLEAR_COLOR = val;
517     reg_G3X_CLEAR_DEPTH = (u16)depth;
518 }
519 
520 
521 /*---------------------------------------------------------------------------*
522   Name:         G3X_InitTable
523 
524   Description:  Initializes the edge color table, the fog table,
525                 the toon table, and the shininess table.
526 
527   Arguments:    none
528 
529   Returns:      none
530  *---------------------------------------------------------------------------*/
G3X_InitTable()531 void G3X_InitTable()
532 {
533     int     i;
534 #if 1
535     if (GXi_DmaId != GX_DMA_NOT_USE)
536     {
537 #ifdef SDK_TWL
538         if (GXi_DmaId > 3)
539         {
540             MI_NDmaFillAsync(GXi_DmaId-4, (void *)REG_EDGE_COLOR_0_L_ADDR, 0, 16, NULL, NULL);
541             MI_NDmaFill(GXi_DmaId-4, (void *)REG_FOG_TABLE_0_ADDR, 0, 96);
542         }
543         else
544 #endif
545         {
546             MI_DmaFill32Async(GXi_DmaId, (void *)REG_EDGE_COLOR_0_L_ADDR, 0, 16, NULL, NULL);
547             MI_DmaFill32(GXi_DmaId, (void *)REG_FOG_TABLE_0_ADDR, 0, 96);
548         }
549     }
550     else
551     {
552         MI_CpuFill32((void *)REG_EDGE_COLOR_0_L_ADDR, 0, 16);
553         MI_CpuFill32((void *)REG_FOG_TABLE_0_ADDR, 0, 96);
554     }
555 #else
556     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 0) = 0;
557     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 1) = 0;
558     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 2) = 0;
559     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 3) = 0;
560     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 4) = 0;
561     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 5) = 0;
562     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 6) = 0;
563     *((REGType16 *)REG_EDGE_COLOR_0_L_ADDR + 7) = 0;
564 
565     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 0) = 0;
566     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 1) = 0;
567     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 2) = 0;
568     *((REGType32 *)REG_FOG_TABLE_0_ADDR + 3) = 0;
569 
570     for (i = 0; i < 32; ++i)
571     {
572         *((REGType16 *)REG_TOON_TABLE_0_L_ADDR + i) = 0;
573     }
574 #endif
575     for (i = 0; i < 32; ++i)
576     {
577         reg_G3_SHININESS = 0;
578     }
579 }
580 
581 
582 /*---------------------------------------------------------------------------*
583   Name:         G3X_GetMtxStackLevelPV
584 
585   Description:  Get the current level of the Position/Vector matrix stack.
586 
587   Arguments:    level      a pointer to the current Position/Vector matrix
588                            stack level
589 
590   Returns:      if 0, *level has the result(0 to 31),
591                 otherwise, the matrix stack is busy.
592  *---------------------------------------------------------------------------*/
G3X_GetMtxStackLevelPV(s32 * level)593 int G3X_GetMtxStackLevelPV(s32 *level)
594 {
595     SDK_NULL_ASSERT(level);
596     if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_SB_MASK)
597     {
598         return -1;
599     }
600     else
601     {
602         *level = (s32)((reg_G3X_GXSTAT & REG_G3X_GXSTAT_PV_MASK) >> REG_G3X_GXSTAT_PV_SHIFT);
603         return 0;
604     }
605 }
606 
607 
608 /*---------------------------------------------------------------------------*
609   Name:         G3X_GetMtxStackLevelPJ
610 
611   Description:  Get the current level of the Projection matrix stack.
612 
613   Arguments:    level      a pointer to the current Projection matrix
614                            stack level
615 
616   Returns:      if 0, *level has the result(0 or 1),
617                 otherwise, the matrix stack is busy.
618  *---------------------------------------------------------------------------*/
G3X_GetMtxStackLevelPJ(s32 * level)619 int G3X_GetMtxStackLevelPJ(s32 *level)
620 {
621     SDK_NULL_ASSERT(level);
622     if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_SB_MASK)
623     {
624         return -1;
625     }
626     else
627     {
628         *level = (s32)((reg_G3X_GXSTAT & REG_G3X_GXSTAT_PJ_MASK) >> REG_G3X_GXSTAT_PJ_SHIFT);
629         return 0;
630     }
631 }
632 
633 
634 /*---------------------------------------------------------------------------*
635   Name:         G3X_SetDisp1DotDepth
636 
637   Description:  If GX_POLYGON_ATTR_MISC_DISP_1DOT is set in G3*_PolygonAttr,
638                 the depth(w) value set by this function is the boundary
639                 to display or not to display the polygons which are mapped
640                 to less than one dot square.
641 
642   Arguments:    w          w-value(even if z-buffering mode) in fx32 format
643 
644   Returns:      None
645  *---------------------------------------------------------------------------*/
G3X_SetDisp1DotDepth(fx32 w)646 void G3X_SetDisp1DotDepth(fx32 w)
647 {
648     SDK_MINMAX_ASSERT(w, 0, FX32_ONE * 0x1000 - 1);
649     reg_G3X_DISP_1DOT_DEPTH = (u16)((w >> 9) & 0x7fff);
650 }
651 
652 
653 /*---------------------------------------------------------------------------*
654   Name:         G3X_GetBoxTestResult
655 
656   Description:  Obtain the result of boxtest.
657                 If *in is 0, the box is out the frustum.
658                 otherwise, the box is in/across the frustum.
659 
660   Arguments:    in         a pointer to the result
661 
662   Returns:      if 0, *in has the result.
663                 otherwise, the test is on the way.
664  *---------------------------------------------------------------------------*/
G3X_GetBoxTestResult(s32 * in)665 int G3X_GetBoxTestResult(s32 *in)
666 {
667     SDK_NULL_ASSERT(in);
668     if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_TB_MASK)
669         return -1;
670     else
671     {
672         *in = (s32)(reg_G3X_GXSTAT & REG_G3X_GXSTAT_TR_MASK);
673         return 0;
674     }
675 }
676 
677 
678 /*---------------------------------------------------------------------------*
679   Name:         G3X_GetPositionTestResult
680 
681   Description:  Obtain the result of positiontest.
682 
683   Arguments:    vec, w     a pointer to the result
684 
685   Returns:      if 0, *vec, *w have the result.
686                 otherwise, the test is on the way.
687  *---------------------------------------------------------------------------*/
G3X_GetPositionTestResult(VecFx32 * vec,fx32 * w)688 int G3X_GetPositionTestResult(VecFx32 *vec, fx32 *w)
689 {
690     SDK_NULL_ASSERT(vec);
691     SDK_NULL_ASSERT(w);
692 
693     if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_TB_MASK)
694     {
695         return -1;
696     }
697     else
698     {
699         vec->x = (fx32)reg_G3X_POS_RESULT_X;
700         vec->y = (fx32)reg_G3X_POS_RESULT_Y;
701         vec->z = (fx32)reg_G3X_POS_RESULT_Z;
702         *w = (fx32)reg_G3X_POS_RESULT_W;
703         return 0;
704     }
705 }
706 
707 
708 /*---------------------------------------------------------------------------*
709   Name:         G3X_GetVectorTestResult
710 
711   Description:  Obtain the result of vectortest.
712 
713   Arguments:    vec       a pointer to the result
714 
715   Returns:      if 0, *vec has the result.
716                 otherwise, the test is on the way.
717  *---------------------------------------------------------------------------*/
G3X_GetVectorTestResult(fx16 * vec)718 int G3X_GetVectorTestResult(fx16 *vec)
719 {
720     SDK_NULL_ASSERT(vec);
721     if (reg_G3X_GXSTAT & REG_G3X_GXSTAT_TB_MASK)
722     {
723         return -1;
724     }
725     else
726     {
727         *(vec + 0) = (fx16)reg_G3X_VEC_RESULT_X;
728         *(vec + 1) = (fx16)reg_G3X_VEC_RESULT_Y;
729         *(vec + 2) = (fx16)reg_G3X_VEC_RESULT_Z;
730         return 0;
731     }
732 }
733 
734 
735 /*---------------------------------------------------------------------------*
736   Name:         G3X_SetHOffset
737 
738   Description:  Sets a horizontal offset of 3D plane.
739 
740   Arguments:    hOffset      horizontal offset of 3D plane
741 
742   Returns:      none
743  *---------------------------------------------------------------------------*/
G3X_SetHOffset(int hOffset)744 void G3X_SetHOffset(int hOffset)
745 {
746     SDK_WARNING((reg_GX_DISPCNT & REG_GX_DISPCNT_BG02D3D_MASK) != 0,
747                 "BG0 is in 2D mode now. call \'G2_SetBG0Offset\'\n");
748     SDK_ASSERT(hOffset >= -256 && hOffset <= 255);
749 
750     reg_G2_BG0OFS = (u32)hOffset;
751 }
752 
753 
754 #include <nitro/code32.h>
755 
756 /*---------------------------------------------------------------------------*
757   Name:         G3Xi_NopClearFifo_
758 
759   Description:  Set Nop for clear FIFO
760 
761   Arguments:    pDest  - pointer to Fifo command register.
762 
763   Returns:      none
764  *---------------------------------------------------------------------------*/
GXi_NopClearFifo128_(register void * pDest)765 static asm void GXi_NopClearFifo128_( register void* pDest )
766 {
767     mov     r1,  #0         // r0-r3, r12 need not be saved.
768     mov     r2,  #0
769     mov     r3,  #0
770     mov     r12, #0
771 
772     // set 128 NOP command for 4 PACKED Shineness command. (32 * 4 NOP)
773 
774     stmia   r0, {r1-r3, r12}    // 0 - 15
775     stmia   r0, {r1-r3, r12}
776     stmia   r0, {r1-r3, r12}
777     stmia   r0, {r1-r3, r12}
778 
779     stmia   r0, {r1-r3, r12}    // 16 - 31
780     stmia   r0, {r1-r3, r12}
781     stmia   r0, {r1-r3, r12}
782     stmia   r0, {r1-r3, r12}
783 
784     stmia   r0, {r1-r3, r12}    // 32 - 47
785     stmia   r0, {r1-r3, r12}
786     stmia   r0, {r1-r3, r12}
787     stmia   r0, {r1-r3, r12}
788 
789     stmia   r0, {r1-r3, r12}    // 48 - 63
790     stmia   r0, {r1-r3, r12}
791     stmia   r0, {r1-r3, r12}
792     stmia   r0, {r1-r3, r12}
793 
794     stmia   r0, {r1-r3, r12}    // 64 - 79
795     stmia   r0, {r1-r3, r12}
796     stmia   r0, {r1-r3, r12}
797     stmia   r0, {r1-r3, r12}
798 
799     stmia   r0, {r1-r3, r12}    // 80 - 95
800     stmia   r0, {r1-r3, r12}
801     stmia   r0, {r1-r3, r12}
802     stmia   r0, {r1-r3, r12}
803 
804     stmia   r0, {r1-r3, r12}    // 96 - 111
805     stmia   r0, {r1-r3, r12}
806     stmia   r0, {r1-r3, r12}
807     stmia   r0, {r1-r3, r12}
808 
809     stmia   r0, {r1-r3, r12}    // 112 - 127
810     stmia   r0, {r1-r3, r12}
811     stmia   r0, {r1-r3, r12}
812     stmia   r0, {r1-r3, r12}
813 
814     bx      lr
815 }
816 
817 #include <nitro/codereset.h>
818