1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - demos - CTRDG - pullout-1
3   File:     main.c
4 
5   Copyright 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:: $
14   $Rev: $
15   $Author: $
16  *---------------------------------------------------------------------------*/
17 #include  <nitro.h>
18 #include  "font.h"
19 #include  "screen.h"
20 
21 static void myForceTerminate(void);
22 
23 static void myInit(void);
24 static void myVBlankIntr(void);
25 
26 static BOOL myPulledOutCallback_CARTRIDGE(void);
27 static BOOL myPulledOutCallback_CARD(void);
28 static BOOL myPulledOutCallback_dummy(void);
29 
30 typedef enum
31 {
32     MY_TERMINATE_NONE = 0,
33     MY_TERMINATE_CARTRIDGE = 1,
34     MY_TERMINATE_CARD = 2
35 }
36 MyTerminateFlag;
37 
38 MyTerminateFlag terminateFlag = MY_TERMINATE_NONE;
39 
40 /*---------------------------------------------------------------------------*
41   Name:         NitroMain
42 
43   Description:  Main
44 
45   Arguments:    None.
46 
47   Returns:      None.
48  *---------------------------------------------------------------------------*/
NitroMain(void)49 void NitroMain(void)
50 {
51     BOOL    isCartridgeExist;
52 
53     u16     preButton;
54     u16     button;
55     u16     trigger;
56 
57     //---------------- Initialize
58     myInit();
59 
60     preButton = PAD_Read();            // Dummy read for pressing 'A' on IPL
61 
62     //---- Set pullout callback
63     CTRDG_SetPulledOutCallback(myPulledOutCallback_CARTRIDGE);
64     CARD_SetPulledOutCallback(myPulledOutCallback_CARD);
65 
66     //---- Check if Game Pak exists
67     isCartridgeExist = CTRDG_IsExisting();
68 
69     //---------------- Main loop
70     while (TRUE)
71     {
72         button = PAD_Read();
73         trigger = (u16)((button ^ preButton) & button);
74         preButton = button;
75 
76         //---- Clear screen buffer
77         ClearScreen();
78 
79         //---- Display key description
80         PrintString(3, 2, 15, "push START to sleep");
81         PrintString(3, 3, 15, "till push SELECT");
82         if (isCartridgeExist)
83         {
84             PrintString(3, 4, 15, "or pull out cartridge");
85             PrintString(3, 5, 15, "or pull out card.");
86         }
87         else
88         {
89             PrintString(3, 4, 15, "or pull out card.");
90         }
91 
92         //---- Display time
93         {
94             static RTCTime myCurrentTime;
95             static int myResult;
96             myResult = RTC_GetTime(&myCurrentTime);
97             if (myResult == 0 /*No error */ )
98             {
99                 PrintString(5, 20, 6, "%02d:%02d:%02d",
100                             myCurrentTime.hour, myCurrentTime.minute, myCurrentTime.second);
101             }
102         }
103 
104         //---- Display counter
105         PrintString(18, 20, 4, "%08X", OS_GetVBlankCount());
106 
107         //---- Push START to sleep
108         if (trigger & PAD_BUTTON_START)
109         {
110             PM_GoSleepMode(PM_TRIGGER_CARD | PM_TRIGGER_CARTRIDGE | PM_TRIGGER_KEY,
111                            PM_PAD_LOGIC_AND, PAD_BUTTON_SELECT);
112         }
113 
114         //---- Close cover to sleep
115         if (PAD_DetectFold() == TRUE)
116         {
117             PM_GoSleepMode(PM_TRIGGER_COVER_OPEN | PM_TRIGGER_CARD | PM_TRIGGER_CARTRIDGE, 0, 0);
118         }
119 
120         //---- Terminate program if need
121         if (terminateFlag != MY_TERMINATE_NONE)
122         {
123             myForceTerminate();
124         }
125 
126         OS_WaitVBlankIntr();
127     }
128 }
129 
130 
131 //----------------------------------------------------------------
132 //  myForceTerminate
133 //
myForceTerminate(void)134 void myForceTerminate(void)
135 {
136     int     n;
137 
138     //---- Set callback to do nothing because termination occurs soon anyway
139     CTRDG_SetPulledOutCallback(myPulledOutCallback_dummy);
140     CARD_SetPulledOutCallback(myPulledOutCallback_dummy);
141 
142     for (n = 0; n < 10; n++)
143     {
144         ClearScreen();
145         if (terminateFlag == MY_TERMINATE_CARTRIDGE)
146         {
147             PrintString(4, 10, 1, "DON'T PULL OUT CARTRIDGE!");
148         }
149         else
150         {
151             PrintString(6, 10, 1, "DON'T PULL OUT CARD!");
152         }
153 
154         OS_WaitVBlankIntr();
155     }
156 
157     //---- Terminate
158     if (terminateFlag == MY_TERMINATE_CARTRIDGE)
159     {
160         CTRDG_TerminateForPulledOut();
161     }
162     else
163     {
164         CARD_TerminateForPulledOut();
165     }
166 
167     // ** Never reach this line **
168 }
169 
170 //----------------------------------------------------------------
171 //  myInit
172 //
myInit(void)173 void myInit(void)
174 {
175     //---- Init
176     OS_Init();
177     OS_InitTick();
178     OS_InitAlarm();
179     RTC_Init();
180     FX_Init();
181     GX_Init();
182     GX_DispOff();
183     GXS_DispOff();
184 
185     //---- Display init
186     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
187     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
188     (void)GX_DisableBankForLCDC();
189 
190     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
191     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
192     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
193     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
194 
195     //---- Setting 2D for top screen
196     GX_SetBankForBG(GX_VRAM_BG_128_A);
197 
198     G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
199                      GX_BG_COLORMODE_16,
200                      GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
201     G2_SetBG0Priority(0);
202     G2_BG0Mosaic(FALSE);
203     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
204     GX_SetVisiblePlane(GX_PLANEMASK_BG0);
205 
206     GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
207     GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
208 
209 
210 
211     //---- Setting 2D for bottom screen
212     GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C);
213 
214     G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
215                       GX_BG_COLORMODE_16,
216                       GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
217     G2S_SetBG0Priority(0);
218     G2S_BG0Mosaic(FALSE);
219     GXS_SetGraphicsMode(GX_BGMODE_0);
220     GXS_SetVisiblePlane(GX_PLANEMASK_BG0);
221 
222     GXS_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
223     GXS_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
224 
225 
226     //---- Screen
227     MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
228     DC_FlushRange(gScreen, sizeof(gScreen));
229     /* I/O register is accessed using DMA operation, so cache wait is not needed */
230     // DC_WaitWriteBufferEmpty();
231     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
232     GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
233 
234     //---- Init interrupt
235     OS_SetIrqFunction(OS_IE_V_BLANK, myVBlankIntr);
236     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
237 
238     (void)GX_VBlankIntr(TRUE);
239     (void)OS_EnableIrq();
240     (void)OS_EnableInterrupts();
241 
242     //---- Start displaying
243     GX_DispOn();
244     GXS_DispOn();
245 }
246 
247 //----------------------------------------------------------------
248 //  myVBlankIntr
249 //             V-Blank interrupt handler.
250 //
myVBlankIntr(void)251 static void myVBlankIntr(void)
252 {
253     //---- Upload pseudo screen to VRAM
254     DC_FlushRange(gScreen, sizeof(gScreen));
255     /* I/O register is accessed using DMA operation, so cache wait is not needed */
256     // DC_WaitWriteBufferEmpty();
257     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
258     GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
259 
260     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
261 }
262 
263 //----------------------------------------------------------------
264 //  myPulledOutCallback_CARTRIDGE
265 //
myPulledOutCallback_CARTRIDGE(void)266 static BOOL myPulledOutCallback_CARTRIDGE(void)
267 {
268     terminateFlag = MY_TERMINATE_CARTRIDGE;
269     return FALSE;                      //---- Means not to terminate immediately by system
270 }
271 
272 //----------------------------------------------------------------
273 //  myPulledOutCallback_CARD
274 //
myPulledOutCallback_CARD(void)275 static BOOL myPulledOutCallback_CARD(void)
276 {
277     terminateFlag = MY_TERMINATE_CARD;
278     return FALSE;                      //---- Means not to terminate immediately by system
279 }
280 
281 //----------------------------------------------------------------
282 //  myPulledOutCallback_dummy
283 //
myPulledOutCallback_dummy(void)284 static BOOL myPulledOutCallback_dummy(void)
285 {
286     //---- Do nothing
287     return FALSE;
288 }
289