1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - GX - demos - UnitTours/Window_HDMA
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-09-18#$
14   $Rev: 8573 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 //---------------------------------------------------------------------------
18 //  A sample that transforms a window with HDMA
19 //
20 //  Background image is displayed only in transformed window
21 //
22 //  HOWTO:
23 //  1.  Set HDMA copy function in V-Blank period
24 //
25 //---------------------------------------------------------------------------
26 #ifdef SDK_TWL
27 #include <twl.h>
28 #else
29 #include <nitro.h>
30 #endif
31 #include "DEMO.h"
32 #include "data.h"
33 
34 
35 //---------------------------------------------------------------------------
36 //  DMA No. for window transforming HDMA
37 //---------------------------------------------------------------------------
38 #define WINDOW_TRANSFORM_HDMA_NO    3
39 
40 //---------------------------------------------------------------------------
41 //  Array for window position per line
42 //---------------------------------------------------------------------------
43 u16     s_WindowSizePerLine[192];
44 BOOL    preparedGraphic;
45 
46 //---------------------------------------------------------------------------
47 // V-Blank interrupt function:
48 //
49 // Interrupt handlers are registered on the interrupt table by OS_SetIRQFunction.
50 // OS_EnableIrqMask selects IRQ interrupts to enable, and
51 // OS_EnableIrq enables IRQ interrupts.
52 // Notice that you have to call OS_SetIrqCheckFlag to check a V-Blank interrupt.
53 //---------------------------------------------------------------------------
VBlankIntr(void)54 void VBlankIntr(void)
55 {
56     // Don't use DMA #3 before "Load graphic data" function has finished
57     if (preparedGraphic)
58     {
59         // Stop HDMA
60         MI_StopDma(WINDOW_TRANSFORM_HDMA_NO);
61         // Set Window horizontal position (first line)
62         G2_SetWnd0Position(s_WindowSizePerLine[0] >> 8, 0, s_WindowSizePerLine[0] & 0x0ff, 192);
63         // Start HDMA which copies window position array to "Window size register"
64         MI_HBlankDmaCopy16(WINDOW_TRANSFORM_HDMA_NO,
65                            &(s_WindowSizePerLine[1]), (void *)REG_WIN0H_ADDR, 2);
66     }
67 
68     // Set flag that checks for V-Blank interrupt
69     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
70 }
71 
72 //---------------------------------------------------------------------------
73 //  Create window horizontal position table per line
74 //---------------------------------------------------------------------------
CreateWindowStyle(void)75 static void CreateWindowStyle(void)
76 {
77     int     i;
78     int     size;
79     u16     left_pos;
80     u16     right_pos;
81 
82     (void)OS_DisableIrq();
83     for (i = 0; i < 96; i++)
84     {
85         size = (256 * i) / 96;
86         left_pos = (u16)(128 - (size / 2));
87         right_pos = (u16)(128 + (size / 2));
88         s_WindowSizePerLine[i] = (u16)((left_pos << 8) | right_pos);
89     }
90     for (i = 96; i < 192; i++)
91     {
92         s_WindowSizePerLine[i] = s_WindowSizePerLine[191 - i];
93     }
94     (void)OS_EnableIrq();
95 
96     // Store the data in main memory and invalidate the cache
97     DC_FlushRange((void *)s_WindowSizePerLine, sizeof(s_WindowSizePerLine));
98     /* I/O register is accessed using DMA operation, so cache wait is not needed */
99     // DC_WaitWriteBufferEmpty();
100 }
101 
102 //---------------------------------------------------------------------------
103 //  Main
104 //---------------------------------------------------------------------------
105 #ifdef SDK_TWL
TwlMain(void)106 void TwlMain(void)
107 #else
108 void NitroMain(void)
109 #endif
110 {
111     // Initialize
112     preparedGraphic = FALSE;
113     DEMOInitCommon();
114     DEMOInitVRAM();
115     DEMOInitDisplayBG0Only();
116 
117     MI_SetMainMemoryPriority(MI_PROCESSOR_ARM9);
118 
119     // Load 2D graphic data
120     GX_LoadBG0Char(d_natsunoumi_schDT, 0, sizeof(d_natsunoumi_schDT));
121     GX_LoadBGPltt(d_natsunoumi_sclDT, 0, sizeof(d_natsunoumi_sclDT));
122     GX_LoadBG0Scr(d_natsunoumi_sscDT, 0, sizeof(d_natsunoumi_sscDT));
123 
124     // Window settings
125     GX_SetVisibleWnd(GX_WNDMASK_W0);   // Turn on WINDOW-0
126     // Set inside of window visible BG0
127     G2_SetWnd0InsidePlane(GX_WND_PLANEMASK_BG0, FALSE);
128     // Set outside of window non-visible
129     G2_SetWndOutsidePlane(GX_WND_PLANEMASK_NONE, FALSE);
130 
131     // Create window horizontal position table
132     CreateWindowStyle();
133 
134     // Turn on flag that specifies whether graphics data has been loaded
135     preparedGraphic = TRUE;
136 
137     DEMOStartDisplay();
138 
139     // Main loop
140     while (1)
141     {
142         // Wait for V-Blank
143         OS_WaitVBlankIntr();
144 
145 #ifdef SDK_AUTOTEST                    // Code for auto-test
146         GX_SetBankForLCDC(GX_VRAM_LCDC_C);
147         EXT_TestSetVRAMForScreenShot(GX_VRAM_LCDC_C);
148         EXT_TestScreenShot(100, 0x7490C85D);
149         EXT_TestTickCounter();
150 #endif //SDK_AUTOTEST
151     }
152 }
153