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