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