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