//******************************************************************* // IRIS-SUBPモニタプログラム //******************************************************************* #include "IrisSubpMon.h" //---------------------------------------------------------------------- // メインルーチン //---------------------------------------------------------------------- extern u8 SecureAreaEndp[]; CardIntrWork *cardIntrWorkp; RomHeader *romHeaderp; void Iris2Agb(void); s32 CalledFormIPL2(void); s32 CheckCardHeader(void); s32 CheckCartridgeHeader(void); void LoadCardHeader(void); void LoadSecure4Card(void); #define CARD_DMA_NO 3 void IrisSubpMonMain() { SharedWork *shwp = GetSharedWorkAddr(); NotifyMainpIntf(0); // ブート・ハンドシェイク #ifdef NDEBUG WaitMainpIntf(1); NotifyMainpIntf(1); #endif // NDEBUG InitReg(); // レジスタ初期化 PreInitRam(); // メモリ初期化 WaitMainpIntf(2); // ARM9 初期化完了待ち(この後で上記レジスタ設定が有効になる) *(vu32 *)REG_CARDCNT = CARD_RESET_HI; // カード スタート(リセットはMAINPで行っている、事前設定) *(vu8 *)REG_CARD_MASTER_CNT = CARDMST_SEL_ROM | CARDMST_ENABLE; // カードマスターイネーブル PostInitRam(); // メモリ初期化(共用ワークRAMクリア、 // カードリセットHI期間に含まれる) InitRtc(); // RTC初期化 & リード(共用ワークRAM使用、 // カードリセットHI期間に含まれる) *(u32 *)REG_TM0CNT = TMR_PRESCALER_256CK | TMR_ENABLE; // タイマー スタート *(u32 *)REG_TM1CNT = TMR_CONNECT | TMR_ENABLE; sharedWorkp = GetSharedWorkAddr(); // 共有ワーク領域デバッグ用 secureWorkp = GetSecureWorkAddr(); // セキュアワーク領域デバッグ用 cardIntrWorkp = GetCardIntrWorkAddr(); // カード割り込みワーク領域 romHeaderp = GetRomHeaderAddr(); // ROMヘッダ領域 shwp->sysromCrc16 = GetInvCRC16(NULL, BIOS_SIZE); // システムROMのCRC算出(メインメモリクリア完了後、 // カードリセットHI期間に含まれる) NotifyMainpIntf(2); // 初期化完了の通知 intrTable[0] = CardIntr; // カード割り込み関数 セット LoadCardHeader(); // カードヘッダ領域のロード LoadFlashHeader(); // フラッシュメモリヘッダのロード #ifndef NDEBUG WaitMainpIntf(15); // デバッグ通信 #endif // NDEBUG LoadSecure4Card(); // カードセキュア領域(+FLASHデモ)のロード *(vu16 *)REG_TM0CNT_H = 0; // タイマー停止 *(vu16 *)REG_TM1CNT_H = 0; #ifdef DISP_READY_CARD_4_IPL2 NotifyMainpIntf(9); // IPL2カード読み込み準備完了通知 while(1) ; #endif // DISP_READY_CARD_4_IPL2 #ifdef DISABLE_BOOT_IPL2 intrTable[0] = CardIntr; // カード割り込み関数 再セット while (CalledFormIPL2() != -1) { // IPL2メモリ呼び出し部分 WaitVBlank(1); } #endif // DISABLE_BOOT_IPL2 *(vu32 *)REG_IME = 0; // IME クリア *(vu32 *)REG_IE = 0; // IE クリア *(vu32 *)REG_IF = -1; // IF クリア NotifyMainpIntf(3); // ダウンロード完了の通知 WaitMainpIntf(3); } //---------------------------------------------------------------------- // ROMヘッダ領域のロード //---------------------------------------------------------------------- void LoadCardHeader(void) { SharedWork *shwp = GetSharedWorkAddr(); RomHeader *rmhp = GetRomHeaderAddr(); *(vu8 *)REG_CARD_MASTER_CNT = CARDMST_SEL_ROM // カードマスターイネーブル | CARDMST_ENABLE | CARDMST_IF_ENABLE; LoadCardTable(); // フラッシュメモリ・テーブル設定 ReadCardHeader(); // ROMヘッダ読み込み shwp->cardHeaderCrc16 = GetInvCRC16((u16 *)rmhp, 0x15e); // ROMヘッダのCRC算出 // クロックタイプとレイテンシ設定以外 クリア SetCardCnt4Normal(GetCardCnt4Normal() & (CARD_CLOCK_TYPE | CARD_LATENCY_MASK)); shwp->nCardID = ReadCardID4Normal(); // カードID格納 } #ifdef BOOT_FROM_CARTRIDGE void LoadHeader4Cartridge(void) { *(vu32 *)REG_EXMEMCNT = CTRDG_AD16_1ST_10CYC | CTRDG_AD16_2ND_6CYC; // 10-6アクセス(メインメモリ/カード関係はリードオンリー) CpuCopy16_32(CTRDG_AD16_BANK0, ROM_HEADER_BUF, 0x170, 32); // ROMヘッダ読み込み } #endif // BOOT_FROM_CARTRIDGE //---------------------------------------------------------------------- // カードヘッダのチェック //---------------------------------------------------------------------- #define IS_EXIST_CARD_WORD 0xcf56 // 0x2e03 s32 CheckCardHeader(void) { SharedWork *shwp = GetSharedWorkAddr(); RomHeader *rmhp = GetRomHeaderAddr(); u32 retval; *(vu16 *)(MAIN_MEM_EX_END - 0x4) = 1; // ヘッダ読み込み失敗フラグ 初期化 shwp->cardHeaderError = 1; if (shwp->cardHeaderCrc16 != rmhp->headerCRC16) return 1; // ROMヘッダのCRCチェック if (rmhp->ninLogoCRC16 != IS_EXIST_CARD_WORD) return 1; *(vu16 *)(MAIN_MEM_EX_END - 0x4) = 0; // ヘッダ読み込み成功フラグ セット shwp->cardHeaderError = 0; return 0; } //---------------------------------------------------------------------- // カートリッジヘッダのチェック //---------------------------------------------------------------------- #ifdef BOOT_FROM_CARTRIDGE s32 CheckCartridgeHeader(void) { if ((*(u32 *)(ROM_HEADER_BUF + 0) != *(vu32 *)"NINT") || (*(u32 *)(ROM_HEADER_BUF + 4) != *(vu32 *)"ENDO")) { return 1; } *(vu16 *)(MAIN_MEM_EX_END - 0x4) = 0; // ヘッダ読み込み成功フラグ セット return 0; } #endif // BOOT_FROM_CARTRIDGE //---------------------------------------------------------------------- // ROMセキュア領域のロード //---------------------------------------------------------------------- extern u32 png_off_key[]; void LoadSecure4Card(void) { SharedWork *shwp = GetSharedWorkAddr(); SecureWork *scwp = GetSecureWorkAddr(); RomHeader *rmhp = GetRomHeaderAddr(); FlashHeader *fhp = GetFlashHeaderAddr(); u8 *loadStartp = (void *)((u32 )rmhp->arm9.romAddr & ~(MROM_SEGMENT_SIZE - 1)); u8 *loadDestp = rmhp->arm9.ramAddr; s32 loadSize = rmhp->arm9.romSize; s32 secureSize = MROM_GAME_AREA - (s32 )loadStartp; if (secureSize < 0) secureSize = 0; // SECURE領域サイズ補正 scwp->secureSize = secureSize; ClearMmemSecureArea(); // セキュリティのためメインメモリ先頭64KB事前クリア InitSecureParamFook(); // SECUREモードパラメータ 初期化 if (!CheckCardHeader() // カード・ヘッダのチェック && !shwp->enableCardNormalOnly // NORMALカード・チェック && !shwp->rtcError // RTCエラーチェック && (secureSize > 0) // アドレス情報のチェック && ((loadStartp >= (u8 *)MROM_SECURE_AREA) && (loadStartp < (u8 *)MROM_GAME_AREA)) && ((loadDestp >= (u8 *)MAIN_MEM) && (loadDestp < (u8 *)MON_MMEM_LOAD_LIMIT))) scwp->enableReadSecure = 1; // SECURE領域リード・イネーブル CheckDebugger(); // デバッガ起動チェック // ARM9先頭16KBエリア転送 #ifndef DISABLE_SECURE_CODE if (shwp->enableCardNormalOnly) { // NORMALカード使用時(SECURE領域は読まない) LoadFlashDemo(); // FLASHデモプログラム読み込み } else #endif // DISABLE_SECURE_CODE if ((shwp->isOnDebugger == 1) && IsMmem8MB()) { // デバッガ起動時 if (scwp->enableReadSecure) SetCardIntr4Normal(loadStartp, loadDestp, secureSize); // NORMALモード読み込み LoadFlashDemo(); // FLASHデモプログラム読み込み if (scwp->enableReadSecure) WaitCardIntr(); // NORMALモード読み込み終了待ち ChangeCardMode4Normal(); // GAMEモード遷移 #ifndef DISABLE_SECURE_CODE } else { // SECUREカード使用時 ChangeCardMode4Normal(); // SECUREモード遷移 intrTable[0] = CardIntr4Secure; // カード割り込み関数 セット intrTable[1] = CardTimerIntr4Secure; // カードタイマー割り込み関数 セット InitCardParam4Secure(); // SECUREコマンドパラメータ初期化 SetCardIntr4Secure(loadStartp, loadDestp, secureSize); // SECUREモード読み込み LoadFlashDemo(); // FLASHデモプログラム読み込み WaitCardIntr(); // SECUREモード読み込み終了待ち TerminateCardParam4Secure(); // SECUREコマンドパラメータ復元 if ((scwp->unScrambleKey[0] != png_off_key[0]) // スクランブル解除キー無効時 || (scwp->unScrambleKey[1] != png_off_key[1])) { SetCardCnt4Game(GetCardCnt4Game() | CARD_SCRAMBLE_SET_MASK);// スクランブル強制設定 } #endif // DISABLE_SECURE_CODE } if (scwp->enableReadSecure) // SECURE領域のCRC算出 shwp->cardSecureCrc16 = GetInvCRC16((u16 *)loadDestp, secureSize); DecryptObjectFileFook(); // 暗号化オブジェクトの復号 #ifndef DISABLE_SECURE_CODE *(vu32 *)REG_BIOS_PROTECT_ADDR = (u32 )&SecureAreaEndp; // BIOSセキュリティアドレス セット #endif // DISABLE_SECURE_CODE #ifndef TRACE_SECURE_OP CpuClearFast32(0, GetSecureWorkAddr(), sizeof(SecureWork)); // セキュアワーク クリア #endif // TRACE_SECURE_OP if (shwp->flashCrcError) // IPL2のCRC不一致時、SECURE領域 クリア ClearMmemSecureArea(); } #ifdef BOOT_FROM_CARTRIDGE void LoadSecure4Cartridge(void) { LoadFlashDemo(); // FLASHデモプログラム読み込み { u32 loadStartp = *(u32 *)(ROM_HEADER_BUF + 0x20) | CTRDG_AD16_BANK0; u32 loadSize = *(u32 *)(ROM_HEADER_BUF + 0x2c) & (MAIN_MEM_SIZE - 1); u32 loadDestp = *(u32 *)(ROM_HEADER_BUF + 0x28); while (!loadStartp || !loadDestp) ; CpuCopy16_32(loadStartp, loadDestp, loadSize, 32); // ARM9実行イメージ読み込み } } #endif // BOOT_FROM_CARTRIDGE //---------------------------------------------------------------------- // IPL2メモリ呼び出し部分 //---------------------------------------------------------------------- void LoadGame4Card(void); void LoadHeader4Cartridge(void); void LoadSecure4Cartridge(void); void LoadGame4Cartridge(void); void LoadDebugger(void); #ifndef DISABLE_READ_CARD_4_IPL2 s32 CalledFormIPL2(void) { SharedWork *shwp = GetSharedWorkAddr(); RomHeader *rmhp = GetRomHeaderAddr(); s16 *sequenceNop = &shwp->cardSequenceNo; if (*(vu8 *)REG_PAUSE & 1) return -2; switch (*sequenceNop) { case 0: if (!shwp->cardHeaderError) { // カード・ヘッダのチェック u8 *arm9LoadStartp = rmhp->arm9.romAddr; u8 *arm9LoadDestp = rmhp->arm9.ramAddr; u8 *arm9LoadDestEndp; s32 arm9LoadSize = rmhp->arm9.romSize; s32 arm9SecureSize = (u8 *)MROM_GAME_AREA - arm9LoadStartp; // セキュリティ上 再計算 if (arm9SecureSize < 0) arm9SecureSize = 0; arm9LoadStartp += arm9SecureSize; arm9LoadDestp += arm9SecureSize; arm9LoadSize -= arm9SecureSize; if ((arm9LoadDestp >= (u8 *)MAIN_MEM) && (arm9LoadDestp < (u8 *)MON_MMEM_LOAD_LIMIT)) { arm9LoadDestEndp = arm9LoadDestp + arm9LoadSize; if (arm9LoadDestEndp > (u8 *)MON_MMEM_LOAD_LIMIT) arm9LoadSize -= (arm9LoadDestEndp - (u8 *)MON_MMEM_LOAD_LIMIT); if (arm9LoadSize > 0) { // GAMEモード読み込み SetCardIntr4Game(arm9LoadStartp, arm9LoadDestp, arm9LoadSize); *sequenceNop = 1; } else { *sequenceNop = 2; } } else { *sequenceNop = 2; } } else { *sequenceNop = 6; } break; case 1: if (*(vu32 *)INTR_CHECK_BUF & CARD_DATA_INTR_FLAG) { TerminateCardIntr(); *sequenceNop = 2; } break; case 2: #ifdef TEST_CARD_BY_MAINP NotifyMainpIntf(5); // カードバス切り換え検証の通知 WaitMainpIntf(5); #endif // TEST_CARD_BY_MAINP { u8 *arm7LoadStartp = rmhp->arm7.romAddr; u8 *arm7LoadDestp = rmhp->arm7.ramAddr; u8 *arm7LoadDestEndp = NULL; s32 arm7LoadSize = rmhp->arm7.romSize; // 内部ワークRAM ロードサイズ調整 if ((arm7LoadDestp >= (u8 *)CPU_WRAM) && (arm7LoadDestp < (u8 *)MON_WRAM_LOAD_LIMIT)) { arm7LoadDestEndp = arm7LoadDestp + arm7LoadSize; if (arm7LoadDestEndp > (u8 *)MON_WRAM_LOAD_LIMIT) arm7LoadSize -= (arm7LoadDestEndp - (u8 *)MON_WRAM_LOAD_LIMIT); } // メインメモリ ロードサイズ調整 if ((arm7LoadDestp >= (u8 *)MAIN_MEM) && (arm7LoadDestp < (u8 *)MON_MMEM_LOAD_LIMIT)) { arm7LoadDestEndp = arm7LoadDestp + arm7LoadSize; if (arm7LoadDestEndp > (u8 *)MON_MMEM_LOAD_LIMIT) arm7LoadSize -= (arm7LoadDestEndp - (u8 *)MON_MMEM_LOAD_LIMIT); } if (arm7LoadDestEndp) { if (arm7LoadSize > 0) { // ARM7実行イメージ読み込み SetCardIntr4Game(arm7LoadStartp, arm7LoadDestp, arm7LoadSize); *sequenceNop = 3; } else { *sequenceNop = 4; } } else { *sequenceNop = 4; } } break; case 3: if (*(vu32 *)INTR_CHECK_BUF & CARD_DATA_INTR_FLAG) { TerminateCardIntr(); *sequenceNop = 4; } break; case 4: #ifdef TEST_CARD_BY_MAINP NotifyMainpIntf(6); // カードバス切り換え検証の通知 WaitMainpIntf(6); #endif // TEST_CARD_BY_MAINP if ((shwp->isOnDebugger == 1) && IsMmem8MB()) { u8 *dbgLoadStartp = rmhp->dbgRomAddr; u8 *dbgLoadDestp = rmhp->dbgArm9RamAddr; u8 *dbgLoadDestEndp; s32 dbgLoadSize = rmhp->dbgRomSize; if ((dbgLoadDestp >= (u8 *)MAIN_MEM_END) && (dbgLoadDestp < (u8 *)MON_DBG_LOAD_LIMIT)) { dbgLoadDestEndp = dbgLoadDestp + dbgLoadSize; if (dbgLoadDestEndp > (u8 *)MON_DBG_LOAD_LIMIT) dbgLoadSize -= (dbgLoadDestEndp - (u8 *)MON_DBG_LOAD_LIMIT); if (dbgLoadSize > 0) { // デバッガモニタ読み込み (u32 )dbgLoadStartp &= 0x7fffffff; // アドレス修正 SetCardIntr4Game(dbgLoadStartp, dbgLoadDestp, dbgLoadSize); *sequenceNop = 5; } else { *sequenceNop = 6; } } else { *sequenceNop = 6; } } else { *sequenceNop = 6; } break; case 5: if (*(vu32 *)INTR_CHECK_BUF & CARD_DATA_INTR_FLAG) { TerminateCardIntr(); *sequenceNop = 6; } break; case 6: SetPauseCheckFlag(); // チェックフラグ セット *sequenceNop = -1; break; } return *sequenceNop; } #else // DISABLE_READ_CARD_4_IPL2 s32 CalledFormIPL2(void) { SharedWork *shwp = GetSharedWorkAddr(); s16 *sequenceNop = &shwp->cardSequenceNo; if (!shwp->cardHeaderError) { // カード・ヘッダのチェック LoadGame4Card(); // カードゲーム領域 } else { #ifdef BOOT_FROM_CARTRIDGE WaitVBlank(20); // UICアクセス遅延 LoadHeader4Cartridge(); // カートリッジ・ヘッダ領域のロード if (!CheckCartridgeHeader()) { // カートリッジ・ヘッダのチェック LoadSecure4Cartridge(); // カートリッジ・セキュア領域のロード LoadGame4Cartridge(); // カートリッジ・ゲーム領域 } else { #endif // BOOT_FROM_CARTRIDGE #ifdef TEST_AGB_MODE ReadNintendoLogo4AGB(); // AGBカートリッジのロゴ読み込み if (!CheckNintendoLogo(&NinLogoBak[36/2])) { //(u16 *)(CARTRIDGE + 4))) Iris2Agb(); // AGBモード遷移 #ifdef DISP_AGB_HEADER_ERROR } else { NotifyMainpIntf(8); // AGBヘッダエラー通知 WaitMainpIntf(8); // AGBヘッダエラー表示待ち Iris2Agb(); // AGBモード遷移 #endif // DISP_AGB_HEADER_ERROR } #else while(1) ; // AGBモード非対応時 無限ループ #endif // TEST_AGB_MODE #ifdef BOOT_FROM_CARTRIDGE } #endif // BOOT_FROM_CARTRIDGE } // ReadNintendoLogo4AGB(); // AGBカートリッジのロゴ読み込み //(IRISモードでAGBカートリッジをアクセスできるようにするため) // LoadDebugger(); // デバッガ領域 TerminateIntr(CARD_DATA_INTR_FLAG); *sequenceNop = -1; return *sequenceNop; } #endif // DISABLE_READ_CARD_4_IPL2 //---------------------------------------------------------------------- // ROMイメージ後半のロード //---------------------------------------------------------------------- #ifdef DISABLE_READ_CARD_4_IPL2 void LoadGame4Card(void) { { u8 *Arm9LoadStartp = *(u8 **)(ROM_HEADER_BUF + 0x20); u8 *Arm9LoadDestp = *(u8 **)(ROM_HEADER_BUF + 0x28); s32 Arm9LoadSize = *(s32 * )(ROM_HEADER_BUF + 0x2c) & (MAIN_MEM_SIZE - 1); s32 Arm9SecureSize = (u8 *)MROM_GAME_AREA - Arm9LoadStartp; if (Arm9SecureSize < 0) Arm9SecureSize = 0; SetCardIntr4Game(Arm9LoadStartp + Arm9SecureSize, // GAMEモード読み込み Arm9LoadDestp + Arm9SecureSize, Arm9LoadSize - Arm9SecureSize); WaitCardIntr(); } { u8 *Arm7LoadStartp = *(u8 **)(ROM_HEADER_BUF + 0x30); u8 *Arm7LoadDestp = *(u8 **)(ROM_HEADER_BUF + 0x38); s32 Arm7LoadSize = *(s32 * )(ROM_HEADER_BUF + 0x3c) & (CPU_WRAM_SIZE - 1); while (!Arm7LoadSize) ; SetCardIntr4Game(Arm7LoadStartp, Arm7LoadDestp, Arm7LoadSize);// ARM7実行イメージ読み込み WaitCardIntr(); } } #ifdef BOOT_FROM_CARTRIDGE void LoadGame4Cartridge(void) { { u32 Arm7LoadStartp = *(u32 *)(ROM_HEADER_BUF + 0x30) | CTRDG_AD16_BANK0; u32 Arm7LoadSize = *(u32 *)(ROM_HEADER_BUF + 0x3c) & (MAIN_MEM_SIZE - 1); u32 Arm7LoadDestp = *(u32 *)(ROM_HEADER_BUF + 0x38); while (!Arm7LoadStartp || !Arm7LoadDestp) ; CpuCopy16_32(Arm7LoadStartp, Arm7LoadDestp, Arm7LoadSize, 32); // ARM7実行イメージ読み込み } } #endif // BOOT_FROM_CARTRIDGE #endif // DISABLE_READ_CARD_4_IPL2 //---------------------------------------------------------------------- // デバッガモニタのロード //---------------------------------------------------------------------- #ifdef DISABLE_READ_CARD_4_IPL2 void LoadDebugger(void) { if (IsMmem8MB()) { u8 *DbgLoadStartp = *(u8 **)(ROM_HEADER_BUF + 0x160); u8 *DbgLoadDestp = *(u8 **)(ROM_HEADER_BUF + 0x168); s32 DbgLoadSize = *(u32 * )(ROM_HEADER_BUF + 0x164) & (MAIN_MEM_SIZE - 1); if (DbgLoadSize > 0 && DbgLoadSize < (MAIN_MEM_SIZE - 512)) { if ((s32 )DbgLoadStartp < 0) { // デバッガモニタ読み込み (u32 )DbgLoadStartp &= 0x7fffffff; // アドレス修正 SetCardIntr4Game(DbgLoadStartp, DbgLoadDestp, DbgLoadSize); WaitCardIntr(); } else { CpuCopy16_32(DbgLoadStartp, DbgLoadDestp, DbgLoadSize, 32); } } } } #endif // DISABLE_READ_CARD_4_IPL2 //---------------------------------------------------------------------- // メインプロセッサ・インタフェース通知 //---------------------------------------------------------------------- void NotifyMainpIntf(u32 param) { *(vu16 *)REG_MAINPINTF = param <