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