1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS
3 File: os_attention.c
4
5 Copyright 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:: 2009-10-19#$
14 $Rev: 11099 $
15 $Author: mizutani_nakaba $
16 *---------------------------------------------------------------------------*/
17
18 #include <os_attention.h>
19 #include <nitro/os/common/interrupt.h>
20
21 #ifdef SDK_TWLLTD
22
23
24 /*---------------------------------------------------------------------------*
25 * Constant definitions
26 *---------------------------------------------------------------------------*/
27 typedef enum
28 {
29 SPEC_DEST_NONE,
30 SPEC_DEST_KOREA,
31 SPEC_DEST_CHINA,
32
33 SPEC_DEST_NUM
34 }SPEC_DEST;
35
36 typedef enum
37 {
38 IMAGE_OBJ_01_CHR, // Character data for the upper screen
39 IMAGE_OBJ_01_SCR, // Screen data for the upper screen
40 IMAGE_OBJ_02_CHR, // Character data for the lower screen
41 IMAGE_OBJ_02_SCR, // Screen data for the lower screen
42 IMAGE_OBJ_PAL, // Palette data
43
44 IMAGE_OBJ_NUM
45 }IMAGE_OBJ_INDEX;
46
47
48 /*---------------------------------------------------------------------------*
49 * Function Declarations
50 *---------------------------------------------------------------------------*/
51 static u8* OSi_LoadImage(SPEC_DEST dest, IMAGE_OBJ_INDEX index, u32 *p_size);
52 void OSi_WaitVBlank(void);
53 void OSi_VBlankIntr(void);
54 void OSi_PrepareAttention(void);
55 void OSi_ShowAttention(void);
56
57
58
59 /*---------------------------------------------------------------------------*
60 Name: OSi_LoadImage
61
62 Description: Loads an image file (provisional). Note: This function actually just returns a pointer.
63
64 Arguments: dest: A particular market
65 index: Index to the file to load
66 p_size: u32 pointer to the file size
67 If not needed, specify NULL, and it will be ignored.
68
69 Returns: Returns the starting address of the image data.
70 *---------------------------------------------------------------------------*/
OSi_LoadImage(SPEC_DEST dest,IMAGE_OBJ_INDEX index,u32 * p_size)71 static u8 *OSi_LoadImage(SPEC_DEST dest, IMAGE_OBJ_INDEX index, u32 *p_size)
72 {
73 extern u8 _binary_attention_limited_01nbfc_bin[];
74 extern u8 _binary_attention_limited_01nbfc_bin_end[];
75 extern u8 _binary_attention_limited_01nbfs_bin[];
76 extern u8 _binary_attention_limited_01nbfs_bin_end[];
77 extern u8 _binary_attention_limited_02nbfc_bin[];
78 extern u8 _binary_attention_limited_02nbfc_bin_end[];
79 extern u8 _binary_attention_limited_02nbfs_bin[];
80 extern u8 _binary_attention_limited_02nbfs_bin_end[];
81 extern u8 _binary_attention_limited_nbfp_bin[];
82 extern u8 _binary_attention_limited_nbfp_bin_end[];
83
84 extern u8 _binary_attention_limited_korea_01nbfc_bin[];
85 extern u8 _binary_attention_limited_korea_01nbfc_bin_end[];
86 extern u8 _binary_attention_limited_korea_01nbfs_bin[];
87 extern u8 _binary_attention_limited_korea_01nbfs_bin_end[];
88 extern u8 _binary_attention_limited_korea_02nbfc_bin[];
89 extern u8 _binary_attention_limited_korea_02nbfc_bin_end[];
90 extern u8 _binary_attention_limited_korea_02nbfs_bin[];
91 extern u8 _binary_attention_limited_korea_02nbfs_bin_end[];
92 extern u8 _binary_attention_limited_korea_nbfp_bin[];
93 extern u8 _binary_attention_limited_korea_nbfp_bin_end[];
94
95 extern u8 _binary_attention_limited_china_01nbfc_bin[];
96 extern u8 _binary_attention_limited_china_01nbfc_bin_end[];
97 extern u8 _binary_attention_limited_china_01nbfs_bin[];
98 extern u8 _binary_attention_limited_china_01nbfs_bin_end[];
99 extern u8 _binary_attention_limited_china_02nbfc_bin[];
100 extern u8 _binary_attention_limited_china_02nbfc_bin_end[];
101 extern u8 _binary_attention_limited_china_02nbfs_bin[];
102 extern u8 _binary_attention_limited_china_02nbfs_bin_end[];
103 extern u8 _binary_attention_limited_china_nbfp_bin[];
104 extern u8 _binary_attention_limited_china_nbfp_bin_end[];
105
106 static u8 *ptr_table[SPEC_DEST_NUM][IMAGE_OBJ_NUM] =
107 {
108 {
109 _binary_attention_limited_01nbfc_bin,
110 _binary_attention_limited_01nbfs_bin,
111 _binary_attention_limited_02nbfc_bin,
112 _binary_attention_limited_02nbfs_bin,
113 _binary_attention_limited_nbfp_bin
114 },
115 {
116 _binary_attention_limited_korea_01nbfc_bin,
117 _binary_attention_limited_korea_01nbfs_bin,
118 _binary_attention_limited_korea_02nbfc_bin,
119 _binary_attention_limited_korea_02nbfs_bin,
120 _binary_attention_limited_korea_nbfp_bin
121 },
122 {
123 _binary_attention_limited_china_01nbfc_bin,
124 _binary_attention_limited_china_01nbfs_bin,
125 _binary_attention_limited_china_02nbfc_bin,
126 _binary_attention_limited_china_02nbfs_bin,
127 _binary_attention_limited_china_nbfp_bin
128 }
129 };
130
131 static u8 *ptr_end_table[SPEC_DEST_NUM][IMAGE_OBJ_NUM] =
132 {
133 {
134 _binary_attention_limited_01nbfc_bin_end,
135 _binary_attention_limited_01nbfs_bin_end,
136 _binary_attention_limited_02nbfc_bin_end,
137 _binary_attention_limited_02nbfs_bin_end,
138 _binary_attention_limited_nbfp_bin_end
139 },
140 {
141 _binary_attention_limited_korea_01nbfc_bin_end,
142 _binary_attention_limited_korea_01nbfs_bin_end,
143 _binary_attention_limited_korea_02nbfc_bin_end,
144 _binary_attention_limited_korea_02nbfs_bin_end,
145 _binary_attention_limited_korea_nbfp_bin_end
146 },
147 {
148 _binary_attention_limited_china_01nbfc_bin_end,
149 _binary_attention_limited_china_01nbfs_bin_end,
150 _binary_attention_limited_china_02nbfc_bin_end,
151 _binary_attention_limited_china_02nbfs_bin_end,
152 _binary_attention_limited_china_nbfp_bin_end
153 }
154 };
155
156 if(p_size)
157 {
158 *p_size = (u32)(ptr_end_table[dest][index] - ptr_table[dest][index]);
159 }
160
161 return (u8 *)ptr_table[dest][index];
162 }
163
164 /*---------------------------------------------------------------------------*
165 Name: OSi_WaitVBlank
166
167 Description: Waits for a V-Blank interrupt.
168
169 Arguments: None.
170
171 Returns: None.
172 *---------------------------------------------------------------------------*/
OSi_WaitVBlank(void)173 void OSi_WaitVBlank(void)
174 {
175 #if 0
176 OS_WaitIrq(TRUE, OS_IE_V_BLANK);
177 #else
178 /* Loop and wait because threads have not been initialized */
179 while(1)
180 {
181 if(OS_GetIrqCheckFlag() & OS_IE_V_BLANK) break;
182 }
183 OS_ClearIrqCheckFlag(OS_IE_V_BLANK);
184 #endif
185 }
186
187 /*---------------------------------------------------------------------------*
188 Name: OSi_VBlankIntr
189
190 Description: V-Blank interrupt vector.
191
192 Arguments: None.
193
194 Returns: None.
195 *---------------------------------------------------------------------------*/
OSi_VBlankIntr(void)196 void OSi_VBlankIntr(void)
197 {
198 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
199 }
200
201 /*---------------------------------------------------------------------------*
202 Name: OS_ShowAttentionOfLimitedRom
203
204 Description: Displays notice for running in limited mode in NITRO.
205
206 Arguments: None.
207
208 Returns: None.
209 *---------------------------------------------------------------------------*/
OS_ShowAttentionOfLimitedRom(void)210 SDK_WEAK_SYMBOL void OS_ShowAttentionOfLimitedRom(void)
211 {
212 /* Preparation */
213 OSi_PrepareAttention();
214
215 /* Load image data */
216 {
217 /* Reference the market flag and in response, switch the image to load */
218 u8 flag = *(u8*)(HW_ROM_HEADER_BUF + 0x1d);
219 SPEC_DEST dest;
220 u32 plt_size;
221 void *data_plt;
222
223 if(flag & 0x40)
224 {
225 dest = SPEC_DEST_KOREA;
226 }
227 else if(flag & 0x80)
228 {
229 dest = SPEC_DEST_CHINA;
230 }
231 else
232 {
233 dest = SPEC_DEST_NONE;
234 }
235
236 /* Load data for the upper screen into VRAM-A */
237 MI_UncompressLZ16(OSi_LoadImage(dest, IMAGE_OBJ_01_CHR, NULL), (u32 *)HW_BG_VRAM);
238 MI_UncompressLZ16(OSi_LoadImage(dest, IMAGE_OBJ_01_SCR, NULL), (u32 *)(HW_BG_VRAM + 0xf000));
239
240 /* Load data for the lower screen into VRAM-C */
241 MI_UncompressLZ16(OSi_LoadImage(dest, IMAGE_OBJ_02_CHR, NULL), (u32 *)HW_DB_BG_VRAM);
242 MI_UncompressLZ16(OSi_LoadImage(dest, IMAGE_OBJ_02_SCR, NULL), (u32 *)(HW_DB_BG_VRAM + 0xf000));
243
244 /* Load palette data into standard palette ROM */
245 data_plt = OSi_LoadImage(dest, IMAGE_OBJ_PAL, &plt_size);
246
247 SVC_CpuCopyFast(data_plt, (u32 *)(HW_BG_PLTT), plt_size);
248 SVC_CpuCopyFast(data_plt, (u32 *)(HW_DB_BG_PLTT), plt_size);
249 }
250
251 /* Display (Note: This will loop) */
252 OSi_ShowAttention();
253 }
254
255 /*---------------------------------------------------------------------------*
256 Name: OSi_PrepareAttention
257
258 Description: Prepares to display the warning screen.
259
260 Arguments: None.
261
262 Returns: None.
263 *---------------------------------------------------------------------------*/
OSi_PrepareAttention(void)264 void OSi_PrepareAttention(void)
265 {
266 u16 gx_powcnt = reg_GX_POWCNT;
267
268 /* Stop display */
269 reg_GX_DISPCNT = 0;
270 reg_GXS_DB_DISPCNT = 0;
271
272 /* Initialize power control */
273 if(!(gx_powcnt & REG_GX_POWCNT_LCD_MASK))
274 {
275 /* When changing LCD enable from OFF to ON, wait 100 ms */
276 SVC_WaitByLoop(HW_CPU_CLOCK_ARM9 / 40);
277 }
278
279 reg_GX_POWCNT = (u16)(REG_GX_POWCNT_DSEL_MASK | REG_GX_POWCNT_E2DG_MASK |
280 REG_GX_POWCNT_E2DGB_MASK | REG_GX_POWCNT_LCD_MASK);
281
282 /* Initialization of master brightness */
283 reg_GX_MASTER_BRIGHT = (u16)(1 << REG_GX_MASTER_BRIGHT_E_MOD_SHIFT);
284 reg_GXS_DB_MASTER_BRIGHT = reg_GX_MASTER_BRIGHT;
285
286 /* Prepare to display the upper screen */
287 reg_GX_VRAMCNT_A = (u8)((1 << REG_GX_VRAMCNT_A_MST_SHIFT) | (1 << REG_GX_VRAMCNT_A_E_SHIFT));
288 reg_G2_BG0CNT = (u16)((GX_BG_SCRSIZE_TEXT_256x256 << REG_G2_BG0CNT_SCREENSIZE_SHIFT) |
289 (GX_BG_COLORMODE_16 << REG_G2_BG0CNT_COLORMODE_SHIFT) |
290 (GX_BG_SCRBASE_0xf000 << REG_G2_BG0CNT_SCREENBASE_SHIFT) |
291 (GX_BG_CHARBASE_0x00000 << REG_G2_BG0CNT_CHARBASE_SHIFT) |
292 (0 << REG_G2_BG0CNT_PRIORITY_SHIFT));
293 reg_G2_BG0OFS = 0;
294 reg_GX_DISPCNT |= ((GX_BGMODE_0 << REG_GX_DISPCNT_BGMODE_SHIFT) |
295 (GX_PLANEMASK_BG0 << REG_GX_DISPCNT_DISPLAY_SHIFT));
296
297 /* Prepare to display the lower screen */
298 reg_GX_VRAMCNT_C = (u8)((4 << REG_GX_VRAMCNT_C_MST_SHIFT) | (1 << REG_GX_VRAMCNT_C_E_SHIFT));
299 reg_G2S_DB_BG0CNT = (u16)((GX_BG_SCRSIZE_TEXT_256x256 << REG_G2S_DB_BG0CNT_SCREENSIZE_SHIFT) |
300 (GX_BG_COLORMODE_16 << REG_G2S_DB_BG0CNT_COLORMODE_SHIFT) |
301 (GX_BG_SCRBASE_0xf000 << REG_G2S_DB_BG0CNT_SCREENBASE_SHIFT) |
302 (GX_BG_CHARBASE_0x00000 << REG_G2S_DB_BG0CNT_CHARBASE_SHIFT) |
303 (0 << REG_G2S_DB_BG0CNT_PRIORITY_SHIFT));
304 reg_G2S_DB_BG0OFS = 0;
305 reg_GXS_DB_DISPCNT |= ((GX_BGMODE_0 << REG_GXS_DB_DISPCNT_BGMODE_SHIFT) |
306 ((GX_PLANEMASK_BG0 | GX_PLANEMASK_OBJ) << REG_GXS_DB_DISPCNT_DISPLAY_SHIFT));
307 }
308
309 /*---------------------------------------------------------------------------*
310 Name: OSi_ShowAttention
311
312 Description: Displays the warning screen.
313
314 Arguments: None.
315
316 Returns: None.
317 *---------------------------------------------------------------------------*/
OSi_ShowAttention(void)318 void OSi_ShowAttention(void)
319 {
320 /* Start display */
321 reg_GX_DISPCNT |= (u32)(GX_DISPMODE_GRAPHICS << REG_GX_DISPCNT_MODE_SHIFT);
322 reg_GXS_DB_DISPCNT |= (u32)(REG_GXS_DB_DISPCNT_MODE_MASK);
323
324 /* Interrupt settings */
325 reg_GX_DISPSTAT |= REG_GX_DISPSTAT_VBI_MASK;
326 OS_SetIrqFunction(OS_IE_V_BLANK, OSi_VBlankIntr);
327
328 /* Loop */
329 while(1)
330 {
331 OSi_WaitVBlank();
332 }
333 }
334
335
336 #endif // #ifdef SDK_TWLLTD
337 /*---------------------------------------------------------------------------*
338 End of file
339 *---------------------------------------------------------------------------*/
340