1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - demos.TWL - SPI - pm-2
3 File: main.c
4
5 Copyright 2008-2009 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-11-13#$
14 $Rev: 0 $
15 $Author: yada $
16 *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 #include "font.h"
19 #include "screen.h"
20
21 #define EXIT_COUNT 0xA0
22
23 //---- For RTC
24 static RTCTime myCurrentTime;
25
26 //---- VCount
27 static u32 myVCount;
28
29 //---- Auto exit flag
30 static BOOL isAutoExit = FALSE;
31
32 //---- Exit callback info
33 static PMExitCallbackInfo exitCallbackInfo;
34
35 //---- Whether exit callback was called
36 static BOOL isExit = FALSE;
37
38 //---- Exit delay counter
39 static int exitCounter;
40
41 static void myInit(void);
42 static void myVBlankIntr(void);
43 static void myExitCallback(void *arg);
44
45 /*---------------------------------------------------------------------------*
46 Name: NitroMain
47
48 Description: Main.
49
50 Arguments: None.
51
52 Returns: None.
53 *---------------------------------------------------------------------------*/
NitroMain(void)54 void NitroMain(void)
55 {
56 u16 preButton;
57 u16 button;
58 u16 trigger;
59
60 //---------------- Initialize
61 myInit();
62 RTC_Init();
63
64 if ( OS_IsRunOnTwl() )
65 {
66 PM_SetAutoExit( isAutoExit );
67 }
68 else
69 {
70 OS_Printf("\nThis demo is only for TWL mode.");
71 OS_Exit(0);
72 }
73
74 OS_Printf("[ARM9] set exit callback\n");
75 PM_SetExitCallbackInfo( &exitCallbackInfo, myExitCallback, (void*)100 );
76 PM_AppendPreExitCallback( &exitCallbackInfo );
77
78 preButton = PAD_Read(); // Dummy read for pressing 'A' on IPL
79
80 //---------------- Main loop
81 while (TRUE)
82 {
83 button = PAD_Read();
84 trigger = (u16)((button ^ preButton) & button);
85 preButton = button;
86
87 //---- V-Blank count
88 myVCount = OS_GetVBlankCount();
89
90 //---- Counter
91 if ( isExit )
92 {
93 if ( -- exitCounter < 0 )
94 {
95 PM_ReadyToExit();
96 }
97 }
98
99 //---- Clear screen buffer
100 ClearScreen();
101
102 //---- Display key description
103 PrintString(3, 4, 15, "A : toggle Auto Exit mode");
104 PrintString(3, 6, 15, "X : do hardware reset");
105
106 //---- Display time
107 if (RTC_GetTime(&myCurrentTime) == 0 /*no error */ )
108 {
109 PrintString(5, 20, 8, "%02d:%02d:%02d", myCurrentTime.hour, myCurrentTime.minute, myCurrentTime.second);
110 }
111
112 //---- Display AutoExit mode
113 {
114 BOOL a = PM_GetAutoExit();
115 PrintString(8, 16, 15, "AUTO EXIT : %s", a? "TRUE": "FALSE" );
116 }
117
118 //---- Display v-counter
119 PrintString(18, 20, 4, "%08X", myVCount);
120
121 //---- Display count
122 if ( isExit )
123 {
124 static int blinkCount = 0;
125 if ( (++ blinkCount) & 0x4 )
126 {
127 PrintString(12, 12, 1, "NOW EXIT...");
128 }
129 PrintString(15, 10, 4, "%X", exitCounter / 0x10);
130 }
131
132 //---- Push A to switch top backlight on/off
133 if (trigger & PAD_BUTTON_A)
134 {
135 isAutoExit = (isAutoExit == FALSE);
136 PM_SetAutoExit( isAutoExit );
137 }
138
139 //---- Push X to do hardware reset
140 if (trigger & PAD_BUTTON_X)
141 {
142 (void)OS_RebootSystem();
143 // Do not call the PM_ForceToResetHardware function directly
144 }
145
146 OS_WaitVBlankIntr();
147 }
148 }
149
150 //----------------------------------------------------------------
151 // myInit
152 //
myInit(void)153 void myInit(void)
154 {
155 //---- Init
156 OS_Init();
157 OS_InitTick();
158 OS_InitAlarm();
159 FX_Init();
160 GX_Init();
161 GX_DispOff();
162 GXS_DispOff();
163
164 //---- Display init
165 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
166 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
167 (void)GX_DisableBankForLCDC();
168
169 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
170 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
171 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
172 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
173
174 //---- Setting 2D for top screen
175 GX_SetBankForBG(GX_VRAM_BG_128_A);
176
177 G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
178 GX_BG_COLORMODE_16,
179 GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
180 G2_SetBG0Priority(0);
181 G2_BG0Mosaic(FALSE);
182 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
183 GX_SetVisiblePlane(GX_PLANEMASK_BG0);
184
185 GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
186 GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
187
188
189
190 //---- Setting 2D for bottom screen
191 GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C);
192
193 G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
194 GX_BG_COLORMODE_16,
195 GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
196 G2S_SetBG0Priority(0);
197 G2S_BG0Mosaic(FALSE);
198 GXS_SetGraphicsMode(GX_BGMODE_0);
199 GXS_SetVisiblePlane(GX_PLANEMASK_BG0);
200
201 GXS_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
202 GXS_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
203
204
205 //---- Screen
206 MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
207 DC_FlushRange(gScreen, sizeof(gScreen));
208 /* I/O register is accessed using DMA operation, so cache wait is not needed */
209 // DC_WaitWriteBufferEmpty();
210 GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
211 GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
212
213 //---- Init interrupt
214 OS_SetIrqFunction(OS_IE_V_BLANK, myVBlankIntr);
215 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
216 (void)GX_VBlankIntr(TRUE);
217 (void)OS_EnableIrq();
218 (void)OS_EnableInterrupts();
219
220 //---- FileSytem init
221 FS_Init(FS_DMA_NOT_USE);
222
223 //---- Start displaying
224 GX_DispOn();
225 GXS_DispOn();
226 }
227
228 //----------------------------------------------------------------
229 // myVBlankIntr
230 // V-Blank interrupt handler
231 //
myVBlankIntr(void)232 static void myVBlankIntr(void)
233 {
234 //---- Upload pseudo screen to VRAM
235 DC_FlushRange(gScreen, sizeof(gScreen));
236 /* I/O register is accessed using DMA operation, so cache wait is not needed */
237 // DC_WaitWriteBufferEmpty();
238 GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
239 GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
240
241 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
242 }
243
244 //================================================================
245 //----------------------------------------------------------------
246 // myExitCallback
247 //
myExitCallback(void * arg)248 void myExitCallback(void *arg)
249 {
250 #ifdef SDK_FINALROM
251 #pragma unused( arg )
252 #endif
253 OS_Printf("exit callback. arg=%d factor=%d\n", arg, PM_GetExitFactor() );
254
255 exitCounter = EXIT_COUNT;
256 isExit = TRUE;
257 }
258