マスタエディタ:MRC機能(NTR互換)追加。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2291 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
nishikawa_takeshi 2008-08-27 12:21:36 +00:00
parent 0150141fec
commit df134bf147
5 changed files with 253 additions and 9 deletions

View File

@ -370,14 +370,11 @@ ECSrlResult RCSrl::setRomHeader(void)
//
// ヘッダのCRCを算出
//
#define HEADER_CRC16_INIT_VALUE (0xffff)
#define HEADER_CALC_CRC16_SIZE (0x15e)
ECSrlResult RCSrl::calcRomHeaderCRC(void)
static u16 calcCRC( const u16 start, const u8 *data, const int allsize )
{
u16 r1;
u16 total = HEADER_CRC16_INIT_VALUE;
int size = HEADER_CALC_CRC16_SIZE;
const u8 *data = (u8*)this->pRomHeader;
u16 total = start;
int size = allsize;
// CRCテーブルは固定
const u16 CRC16Table[16] =
@ -403,9 +400,13 @@ ECSrlResult RCSrl::calcRomHeaderCRC(void)
data++;
}
return total;
} // calcRomHeaderCRCCore()
ECSrlResult RCSrl::calcRomHeaderCRC(void)
{
// ROMヘッダのCRC領域を上書き
this->pRomHeader->s.header_crc16 = total;
this->pRomHeader->s.header_crc16 = calcCRC( CRC16_INIT_VALUE, (u8*)this->pRomHeader, CALC_CRC16_SIZE );
return (ECSrlResult::NOERROR);
} // ECSrlResult RCSrl::calcRomHeaderCRC(void)
@ -617,8 +618,246 @@ ECSrlResult RCSrl::mrc( FILE *fp )
this->hErrorList->Clear();
this->hWarnList->Clear();
ECSrlResult result;
result = this->mrcNTR( fp );
if( result != ECSrlResult::NOERROR )
{
return result;
}
result = this->mrcTWL( fp );
if( result != ECSrlResult::NOERROR )
{
return result;
}
//this->hErrorList->Add( gcnew RCMRCError( "テスト", 0x01, 0xfe, "テスト要因", "test", "reason", false ) );
//this->hWarnList->Add( gcnew RCMRCError( "テスト2", 0x01, 0xfe, "テスト要因2", "test2", "reason2", false ) );
return ECSrlResult::NOERROR;
}
// NTR互換MRC
ECSrlResult RCSrl::mrcNTR( FILE *fp )
{
System::Int32 i;
// ROMヘッダのチェック
// 文字コードチェック
for( i=0; i < TITLE_NAME_MAX; i++ )
{
char c = this->pRomHeader->s.title_name[i];
if( ((c < 0x20) || (0x5f < c)) && (c != 0x00) )
{
this->hErrorList->Add( gcnew RCMRCError(
"ソフトタイトル", 0x0, 0xb, "使用不可のASCIIコードが使用されています。",
"Game Title", "Unusable ASCII code is used.", false ) );
}
}
for( i=0; i < GAME_CODE_MAX; i++ )
{
char c = this->pRomHeader->s.game_code[i];
if( (c < 0x20) || (0x5f < c) )
{
this->hErrorList->Add( gcnew RCMRCError(
"イニシャルコード", 0xc, 0xf, "使用不可のASCIIコードが使用されています。",
"Game Code", "Unusable ASCII code is used.", false ) );
}
}
if( memcmp( this->pRomHeader->s.game_code, "NTRJ", GAME_CODE_MAX ) == 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"イニシャルコード", 0xc, 0xf, "SDKデフォルトのコード(NTRJ)が使用されています。",
"Game Code", "SDK default code(NTRJ) is used.", false ) );
}
for( i=0; i < MAKER_CODE_MAX; i++ )
{
char c = this->pRomHeader->s.maker_code[i];
if( (c < 0x20) || (0x5f < c) )
{
this->hErrorList->Add( gcnew RCMRCError(
"メーカーコード", 0x10, 0x11, "使用不可のASCIIコードが使用されています。",
"Maker Code", "Unusable ASCII code is used.", false ) );
}
}
// 値チェック
if( this->pRomHeader->s.rom_type != 0x00 )
{
this->hErrorList->Add( gcnew RCMRCError(
"デバイスタイプ", 0x13, 0x13, "不正な値です。00hを設定してください。",
"Device Type", "Invalid data. Please set 00h.", false ) );
}
fseek( fp, 0, SEEK_END );
u32 filesize = ftell(fp); // 実ファイルサイズ(単位Mbit)
u32 romsize = 1 << (this->pRomHeader->s.rom_size); // ROM容量
if( (romsize*1024*1024/8) < filesize )
{
this->hErrorList->Add( gcnew RCMRCError(
"デバイス容量", 0x14, 0x14, "実ファイルサイズよりも小さい値が指定されています。",
"Device Capacity", "Setting data is less than the actual file size.", false ) );
}
else if( filesize < (romsize*1024*1024/8) )
{
this->hWarnList->Add( gcnew RCMRCError( // 警告
"デバイス容量", 0x14, 0x14, "実ファイルサイズに比べて無駄のある値が設定されています。",
"Device Capacity", "Setting data is larger than the actual file size.", false ) );
}
if( (filesize % 2) != 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"実ファイルサイズ", METWL_ERRLIST_NORANGE, METWL_ERRLIST_NORANGE, "中途半端な値です。通常では2のべき乗の値です。",
"Actual File Size", "Invalid size. This size is usually power of 2.", false ) );
}
u8 romver = this->pRomHeader->s.rom_version;
if( ((romver < 0x00) || (0x09 < romver)) && (romver != 0xE0) )
{
this->hErrorList->Add( gcnew RCMRCError(
"リマスターバージョン", 0x1e, 0x1e, "不正な値です。正式版では01h-09hのいずれかの値、事前版ではE0hです。",
"Release Ver.", "Invalid data. Please set either one of 01h-09h(Regular ver.), or E0h(Preliminary ver.)", false ) );
}
if( this->pRomHeader->s.warning_no_spec_rom_speed != 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"諸フラグ", 0x1f, 0x1f, "rsfファイルでROMSpeedTypeが設定されていません。",
"Setting Flags", "In a RSF file, the item \"ROMSpeedType\" is not set.", false ) );
}
if( this->pRomHeader->s.banner_offset == 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"バナーオフセット", 0x68, 0x6b, "バナーデータが設定されていません。",
"Banner Offset.", "Banner data is not set.", false ) );
}
if( this->pRomHeader->s.rom_valid_size == 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"ROM実効サイズ", 0x80, 0x83, "値が設定されていません。",
"ROM Valid Size.", "Data is not set.", false ) );
}
// CRC
u16 crc;
// セキュア領域
{
// セキュア領域はROMヘッダ外
u8 *secures;
s32 secure_size = SECURE_AREA_END - this->pRomHeader->s.main_rom_offset;
if (secure_size > SECURE_AREA_SIZE)
{
secure_size = SECURE_AREA_SIZE;
}
if (secure_size <= 0)
{
this->hErrorList->Add( gcnew RCMRCError(
"セキュア領域CRC", 0x15e, 0x15f, "セキュア領域のアドレス指定が不正です。",
"Secure Area CRC.", "Illegal address of secure area.", false ) );
}
secures = new u8[secure_size]; // never return if not allocated
fseek( fp, (u32)this->pRomHeader->s.main_rom_offset, SEEK_SET );
if( secure_size != fread( secures, 1, secure_size, fp ) )
{
delete []secures;
return ECSrlResult::ERROR_FILE_READ;
}
crc = calcCRC(CRC16_INIT_VALUE, (u8 *)secures, secure_size);
delete []secures;
if( crc != this->pRomHeader->s.secure_area_crc16 )
{
this->hErrorList->Add( gcnew RCMRCError(
"セキュア領域CRC", 0x07c, 0x07d, "計算結果と一致しません。セキュア領域が改ざんされた可能性があります。",
"Secure Area CRC.", "Calclated CRC is different from Registered one.", false ) );
}
}
// ロゴ領域
crc = 0xcf56;
if( crc != this->pRomHeader->s.nintendo_logo_crc16 )
{
this->hErrorList->Add( gcnew RCMRCError(
"キャラクターデータCRC", 0x15c, 0x15d, "計算結果と一致しません。キャラクターデータが改ざんされた可能性があります。",
"Charactor Data CRC.", "Calclated CRC is different from Registered one.", false ) );
}
// ヘッダCRC
crc = calcCRC( CRC16_INIT_VALUE, (u8*)this->pRomHeader, CALC_CRC16_SIZE );
if( crc != this->pRomHeader->s.header_crc16 )
{
this->hErrorList->Add( gcnew RCMRCError(
"ROMヘッダCRC", 0x15e, 0x15f, "計算結果と一致しません。ROMヘッダが改ざんされた可能性があります。",
"ROM Header CRC.", "Calclated CRC is different from Registered one.", false ) );
}
// 予約領域
for( i=0; i < 8; i++ )
{
if( this->pRomHeader->s.ctrl_reserved_B[i] != 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"ROM情報予約領域", 0x078, 0x07f, "不正な値が含まれています。この領域をすべて0で埋めてください。",
"Reserved Area for ROM Info.", "Invalid data is included. Please set 0 into this area.", false ) );
}
}
for( i=0; i < 32; i++ )
{
if( this->pRomHeader->s.reserved_C[i] != 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"予約領域C", 0x078, 0x07f, "不正な値が含まれています。この領域をすべて0で埋めてください。",
"Reserved Area C", "Invalid data is included. Please set 0 into this area.", false ) );
}
}
// ROMヘッダ以外の領域のチェック (ファイルから適宜リードする)
// システムコールライブラリ
u8 syscall[32];
u32 offset = this->pRomHeader->s.main_rom_offset;
fseek( fp, offset, SEEK_SET );
if( 32 != fread( syscall, 1, 32, fp ) )
{
return ECSrlResult::ERROR_FILE_READ;
}
for( i=0; i < 32; i++ )
{
if( syscall[i] != 0x00 )
break;
}
if( i == 32 ) // 全部0
{
this->hErrorList->Add( gcnew RCMRCError(
"システムコールライブラリ", METWL_ERRLIST_NORANGE, METWL_ERRLIST_NORANGE, "SDKデフォルトです。",
"System-Call Library", "This Library is SDK default one.", false ) );
}
return ECSrlResult::NOERROR;
} // mrcNTR()
ECSrlResult RCSrl::mrcTWL( FILE *fp )
{
System::Int32 i;
// ROMヘッダのチェック
// 値チェック
u32 romsize = 1 << (this->pRomHeader->s.rom_size); // ROM容量
if( (romsize < METWL_ROMSIZE_MIN) || (METWL_ROMSIZE_MAX < romsize) )
{
this->hErrorList->Add( gcnew RCMRCError(
"デバイス容量", 0x14, 0x14, "指定可能な容量ではありません。",
"Device Capacity", "Invalid capacity.", false ) );
}
// 予約領域
for( i=0; i < 7; i++ )
{
if( this->pRomHeader->s.reserved_A[i] != 0 )
{
this->hErrorList->Add( gcnew RCMRCError(
"予約領域A", 0x015, 0x01b, "不正な値が含まれています。この領域をすべて0で埋めてください。",
"Reserved Area A", "Invalid data is included. Please set 0 into this area.", false ) );
}
}
// ROMヘッダ以外の領域のチェック
return ECSrlResult::NOERROR;
}

View File

@ -6,6 +6,11 @@
#include <twl/os/common/format_rom.h>
#include <twl/os/common/ownerInfoEx.h>
// 宣言
#define METWL_ERRLIST_NORANGE 0 // エラーのアドレス範囲を指定しないことを表す特別な値
#define METWL_ROMSIZE_MIN 256 // 最小のデバイス容量 256Mbit
#define METWL_ROMSIZE_MAX 4096 // 最大の.. 4Gbit
namespace MasterEditorTWL
{
// -------------------------------------------------------------------
@ -305,8 +310,8 @@ namespace MasterEditorTWL
// MRC(Master ROM Checker)@\
ECSrlResult mrc( FILE *fp );
//ECSrlResult mrcNTR( FILE *fp );
//ECSrlResult mrcTWL( FILE *fp );
ECSrlResult mrcNTR( FILE *fp );
ECSrlResult mrcTWL( FILE *fp );
}; // end of ref class RCSrl