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