TwlIPL/build/systemMenu_RED/NandInitializer/ARM9.TWL/src/process_norfirm.c
kamikawa 196826e6af NANDの擬似フォーマット処理に対応。シーン切り替えにフェード効果を追加。
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@626 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-02-08 08:56:10 +00:00

428 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: TwlSDK - NandInitializer
File: process_norfirm.c
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <nitro/snd.h>
#include <twl/fatfs.h>
#include <nitro/card.h>
#include <twl/nam.h>
#include <stddef.h>
#include "kami_font.h"
#include "kami_pxi.h"
#include "process_topmenu.h"
#include "process_import.h"
#include "process_norfirm.h"
#include "process_fade.h"
#include "cursor.h"
#include "keypad.h"
#include "TWLHWInfo_api.h"
#include <firm/format/firm_common.h>
#include <firm/format/norfirm.h>
#include <../build/libraries/spi/ARM9/include/spi.h>
/*---------------------------------------------------------------------------*
Œ^’è‹`
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
è<E28099>è`
*---------------------------------------------------------------------------*/
#define DOT_OF_MENU_SPACE 8
#define CHAR_OF_MENU_SPACE 1
#define CURSOR_ORIGIN_X 32
#define CURSOR_ORIGIN_Y 40
#define FILE_NUM_MAX 16
#define ROUND_UP(value, alignment) \
(((u32)(value) + (alignment-1)) & ~(alignment-1))
/*---------------------------------------------------------------------------*
“à•”•Ï<E280A2>è`
*---------------------------------------------------------------------------*/
static s32 sMenuSelectNo;
static char sFilePath[FILE_NUM_MAX][FS_ENTRY_LONGNAME_MAX];
static u8 sFileNum;
/*---------------------------------------------------------------------------*
“à•”ŠÖ<C5A0><EFBFBD>錾
*---------------------------------------------------------------------------*/
static void MakeFullPathForSD(char* file_name, char* full_path);
static BOOL WriteNorfirm(char* file_name);
/*---------------------------------------------------------------------------*
ƒvƒ<76>ƒZƒXŠÖ<C5A0>è`
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
Name: Import ƒvƒ<76>ƒZƒXO
Description:
Arguments: None.
Returns: next sequence
*---------------------------------------------------------------------------*/
void* NorfirmProcess0(void)
{
FSFile dir;
int i;
// •¶Žš—ñSƒNƒŠƒA
kamiFontClear();
// ƒo<C692>[ƒWƒ‡ƒ“•\ަ
kamiFontPrintf(2, 1, FONT_COLOR_BLACK, "Import Norfirm from SD");
kamiFontPrintf(0, 2, FONT_COLOR_BLACK, "--------------------------------");
// ”z—ñƒNƒŠƒA
MI_CpuClear8( sFilePath, sizeof(sFilePath) );
// ƒtƒ@ƒCƒ<C692><EFBFBD>‰Šú‰»
sFileNum = 0;
// ”wŒiSƒNƒŠƒA
for (i=0;i<24;i++)
{
kamiFontFillChar( i, BG_COLOR_TRANS, BG_COLOR_TRANS );
}
// ”wŒi<C592>ã•”
kamiFontFillChar( 0, BG_COLOR_VIOLET, BG_COLOR_VIOLET );
kamiFontFillChar( 1, BG_COLOR_VIOLET, BG_COLOR_VIOLET );
kamiFontFillChar( 2, BG_COLOR_VIOLET, BG_COLOR_TRANS );
// SDƒJ<C692>[ƒh̃<C692>[ƒgƒfƒBƒŒƒNƒgƒŠðŒŸ<C592>õ
if ( !FS_OpenDirectory(&dir, "sdmc:/", FS_FILEMODE_R | FS_FILEMODE_W) )
{
OS_Printf("Error FS_OpenDirectory(sdmc:/)\n");
kamiFontPrintf(3, 13, FONT_COLOR_BLACK, "Error FS_OpenDirectory(sdmc:/)");
}
else
{
FSDirectoryEntryInfo info[1];
OS_Printf("[%s]:\n", "sdmc:/");
kamiFontPrintfConsole(0, "------ nor file list -----\n");
// .nor ðTµÄƒtƒ@ƒCƒ¼ð•۵Ĩ­
while (FS_ReadDirectory(&dir, info))
{
OS_Printf(" %s", info->longname);
if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) != 0)
{
OS_Printf("/\n");
}
else
{
char* pExtension;
OS_Printf(" (%d BYTEs)\n", info->filesize);
// Šg£Žq̃`ƒFƒbƒN
pExtension = STD_SearchCharReverse( info->longname, '.');
if (pExtension)
{
if (!STD_CompareString( pExtension, ".nor") || !STD_CompareString( pExtension, ".NOR"))
{
STD_CopyString( sFilePath[sFileNum], info->longname );
kamiFontPrintfConsole(0, "%d:%s\n", sFileNum, info->longname);
// <20>Åå16ŒÂÅ<E2809A>I—¹
if (++sFileNum >= FILE_NUM_MAX)
{
break;
}
}
}
}
}
(void)FS_CloseDirectory(&dir);
kamiFontPrintfConsole(0, "--------------------------\n");
}
// ƒ<>ƒjƒ…<C692>[ˆê——
kamiFontPrintf((s16)3, (s16)4, FONT_COLOR_BLACK, "+--------------------+----+");
kamiFontPrintf((s16)3, (s16)(5+sFileNum+1), FONT_COLOR_BLACK, "+--------------------+----+");
// tad ƒtƒ@ƒCƒƒŠƒXƒgð•\ަ
for (i=0;i<sFileNum; i++)
{
// ƒtƒ@ƒCƒ¼Ç‰Á
kamiFontPrintf((s16)3, (s16)(5+CHAR_OF_MENU_SPACE*i), FONT_COLOR_BLACK, "l %-16.16s l l", sFilePath[i]);
}
// <20>ÅŒãÉƒŠƒ^<5E>[ƒ“‚ð’ljÁ
kamiFontPrintf((s16)3, (s16)(5+CHAR_OF_MENU_SPACE*sFileNum), FONT_COLOR_BLACK, "l RETURN l l");
// ƒJ<C692>[ƒ\ƒ<C692>ÁŽ
SetCursorPos((u16)200, (u16)200);
FADE_IN_RETURN( NorfirmProcess1 );
}
/*---------------------------------------------------------------------------*
Name: ƒvƒ<76>ƒZƒXP
Description:
Arguments: None.
Returns: next sequence
*---------------------------------------------------------------------------*/
void* NorfirmProcess1(void)
{
// Iðƒ<C3B0>ƒjƒ…<C692>[Ì•Ï<E280A2>X
if ( kamiPadIsRepeatTrigger(PAD_KEY_UP) )
{
if (--sMenuSelectNo < 0) sMenuSelectNo = sFileNum;
}
else if ( kamiPadIsRepeatTrigger(PAD_KEY_DOWN) )
{
if (++sMenuSelectNo > sFileNum) sMenuSelectNo = 0;
}
// ƒJ<C692>[ƒ\ƒ”zu
SetCursorPos((u16)CURSOR_ORIGIN_X, (u16)(CURSOR_ORIGIN_Y + sMenuSelectNo * DOT_OF_MENU_SPACE));
// Œˆ’è
if (kamiPadIsTrigger(PAD_BUTTON_A))
{
return NorfirmProcess2;
}
// ƒgƒbƒvƒ<76>ƒjƒ…<C692>[‚Ö–ß‚é
else if (kamiPadIsTrigger(PAD_BUTTON_B))
{
FADE_OUT_RETURN( TopmenuProcess0 );
}
return NorfirmProcess1;
}
/*---------------------------------------------------------------------------*
Name: ƒvƒ<76>ƒZƒX2
Description:
Arguments: None.
Returns: next sequence
*---------------------------------------------------------------------------*/
void* NorfirmProcess2(void)
{
BOOL ret;
if (STD_GetStringLength(sFilePath[sMenuSelectNo]))
{
ret = WriteNorfirm(sFilePath[sMenuSelectNo]);
}
else
{
// ƒŠƒ^<5E>[ƒ“
FADE_OUT_RETURN( TopmenuProcess0 );
}
// <20>¡‰ñÌŒ‰Êð•\ަ
if ( ret == TRUE )
{
kamiFontPrintf((s16)26, (s16)(5+sMenuSelectNo*CHAR_OF_MENU_SPACE), FONT_COLOR_GREEN, "OK");
}
else
{
kamiFontPrintf((s16)26, (s16)(5+sMenuSelectNo*CHAR_OF_MENU_SPACE), FONT_COLOR_RED, "NG");
}
return NorfirmProcess1;
}
/*---------------------------------------------------------------------------*
<20>ˆ<CB86>ŠÖ<C5A0>è`
*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*
Name: MakeFullPathForSD
Description:
Arguments: no
Returns: None.
*---------------------------------------------------------------------------*/
static void MakeFullPathForSD(char* file_name, char* full_path)
{
// ƒtƒƒpƒXð<E2809A>ì<EFBFBD>¬
STD_CopyString( full_path, "sdmc:/" );
STD_ConcatenateString( full_path, file_name );
}
/*---------------------------------------------------------------------------*
Name: MakeFullPathForSD
Description:
Arguments: no
Returns: None.
*---------------------------------------------------------------------------*/
#define NVRAM_PAGE_SIZE 256
static BOOL WriteNorfirm(char* file_name)
{
FSFile file;
char full_path[FS_ENTRY_LONGNAME_MAX+6];
BOOL open_is_ok;
BOOL read_is_ok;
u8* pTempBuf;
u32 file_size;
u32 alloc_size;
BOOL result = TRUE;
int nor_addr;
u16 crc_w1, crc_w2;
u16 crc_r1, crc_r2;
// .nor̃tƒƒpƒXð<E2809A>ì<EFBFBD>¬
MakeFullPathForSD(file_name, full_path);
// .norƒtƒ@ƒCƒƒI<C692>[ƒvƒ“
FS_InitFile(&file);
open_is_ok = FS_OpenFile(&file, full_path);
OS_Printf("FS_OpenFile(\"%s\") ... %s!\n", full_path, open_is_ok ? "OK" : "ERROR");
// ƒTƒCƒYƒ`ƒFƒbƒN
file_size = FS_GetFileLength(&file) ;
if (file_size > 256*1024)
{
kamiFontPrintfConsoleEx(1, "too big file size!\n");
FS_CloseFile(&file);
return FALSE;
}
// ƒoƒbƒtƒ@Šm•Û
alloc_size = ROUND_UP(file_size, 32) ;
pTempBuf = OS_Alloc( alloc_size );
if (pTempBuf == NULL)
{
kamiFontPrintfConsoleEx(1, "Fail Alloc()\n");
FS_CloseFile(&file);
return FALSE;
}
// .norƒtƒ@ƒCƒƒŠ<C692>[ƒh
read_is_ok = FS_ReadFile( &file, pTempBuf, (s32)file_size );
DC_FlushRange(pTempBuf, file_size);
if (!read_is_ok)
{
kamiFontPrintfConsoleEx(1, "FS_ReadFile(\"%s\") ... ERROR!\n", full_path);
FS_CloseFile(&file);
OS_Free(pTempBuf);
return FALSE;
}
// ƒtƒ@ƒCƒƒNƒ<4E><C692>[ƒY
FS_CloseFile(&file);
// <20>«<E2809A>žÝOÌCRCðŒvŽZ
crc_w1 = SVC_GetCRC16( 0xffff, pTempBuf, sizeof(NORHeaderDS) );
crc_w2 = SVC_GetCRC16( 0xffff, pTempBuf+512, file_size-512 );
// ܸNORHeaderDS—̈æð<E2809A>«<E2809A>žÞ<E2809A>i40byte?<3F>j
if (kamiNvramWrite(0, (void*)pTempBuf, sizeof(NORHeaderDS)) == KAMI_RESULT_SEND_ERROR)
{
kamiFontPrintfConsoleEx(1, "Fail SPI_NvramPageWrite()\n");
result = FALSE;
}
// CRCƒ`ƒFƒbƒN̽ßNvram©çƒŠ<C692>[ƒh
if (kamiNvramRead(0, pTempBuf, sizeof(NORHeaderDS) ) == KAMI_RESULT_SEND_ERROR)
{
OS_Printf("kamiNvramRead ... ERROR!\n");
}
// “ÇÝ<E2809A>žÝÍARM7ª¼<E28099>Úƒ<C39A>ƒƒŠÉ<E2809A>«<E2809A>o·
DC_InvalidateRange(pTempBuf, sizeof(NORHeaderDS));
// <20>«<E2809A>žÝŒãÌCRCðŒvŽZ
crc_r1 = SVC_GetCRC16( 0xffff, pTempBuf, sizeof(NORHeaderDS) );
// NVRAMO”¼•”ÌCRCðƒ`ƒFƒbƒN
if ( crc_w1 != crc_r1 )
{
OS_Free(pTempBuf);
kamiFontPrintfConsoleEx(1, "Fail! CRC check %x!=%x\n", crc_w1, crc_r1);
return FALSE;
}
nor_addr = offsetof(NORHeader, l); // 512byte
// <20>i»ƒ<C2BB><C692>[ƒ^<5E>[<5B>‰Šú‰»
ProgressInit();
kamiFontPrintfConsole(0, "NOR Firm Import Start!\n");
while ( nor_addr < file_size)
{
// <20>«±Ý
if (kamiNvramWrite((u32)nor_addr, (void*)(pTempBuf + nor_addr), NVRAM_PAGE_SIZE) == KAMI_RESULT_SEND_ERROR)
{
OS_TPrintf("======= Fail SPI_NvramPageWrite() ======== \n");
result = FALSE;
break;
}
nor_addr += NVRAM_PAGE_SIZE;
// <20>i»ƒ<C2BB><C692>[ƒ^<5E>[•\ަ
ProgressDraw((f32)nor_addr/file_size);
}
kamiFontPrintfConsoleEx(0, "Start CRC check\n");
kamiFontLoadScreenData();
// CRCƒ`ƒFƒbƒN̽ßNvram©çƒŠ<C692>[ƒh
if (kamiNvramRead(0, pTempBuf, file_size ) == KAMI_RESULT_SEND_ERROR)
{
OS_Printf("kamiNvramRead ... ERROR!\n");
}
// “ÇÝ<E2809A>žÝÍARM7ª¼<E28099>Úƒ<C39A>ƒƒŠÉ<E2809A>«<E2809A>o·
DC_InvalidateRange(pTempBuf, file_size);
// <20>«<E2809A>žÝŒãÌCRCðŒvŽZ
crc_r2 = SVC_GetCRC16( 0xffff, pTempBuf+512, file_size-512 );
// CRC”äŠr
if (crc_w2 != crc_r2)
{
result = FALSE;
kamiFontPrintfConsoleEx(1, "Fail! CRC check %x!=%x\n", crc_w2, crc_r2);
}
// ƒ<>ƒƒŠ‰ð•ú
OS_Free(pTempBuf);
return result;
}