;******************************************************************** ; IRISモニタプログラム スタートアップルーチン ;******************************************************************** AREA Init, CODE, READONLY INCLUDE IrisDefineArm.s INCLUDE IrisMemoryMapArm.s INCLUDE IrisCardDefineArm.s INCLUDE IrisMonDefineArm.s INCLUDE IrisMonMempryMapArm.s ENTRY ;==================================================================== ; 割り込み領域 ;==================================================================== CODE32 start_v b start_handler undef_v b fiq_v swi_v b swi_handler code_abort_v b fiq_v data_abort_v b fiq_v reserve_v b fiq_v irq_v b irq_handler fiq_v b fiq_handler ;==================================================================== ; NINTENDOロゴデータ ;==================================================================== ALIGN GLOBAL Nin_Char_Diff_Huff Nin_Char_Diff_Huff DCB 0x24,0xff,0xae,0x51,0x69,0x9a,0xa2,0x21,0x3d,0x84,0x82,0x0a,0x84,0xe4,0x09,0xad DCB 0x11,0x24,0x8b,0x98,0xc0,0x81,0x7f,0x21,0xa3,0x52,0xbe,0x19,0x93,0x09,0xce,0x20 DCB 0x10,0x46,0x4a,0x4a,0xf8,0x27,0x31,0xec,0x58,0xc7,0xe8,0x33,0x82,0xe3,0xce,0xbf DCB 0x85,0xf4,0xdf,0x94,0xce,0x4b,0x09,0xc1,0x94,0x56,0x8a,0xc0,0x13,0x72,0xa7,0xfc DCB 0x9f,0x84,0x4d,0x73,0xa3,0xca,0x9a,0x61,0x58,0x97,0xa3,0x27,0xfc,0x03,0x98,0x76 DCB 0x23,0x1d,0xc7,0x61,0x03,0x04,0xae,0x56,0xbf,0x38,0x84,0x00,0x40,0xa7,0x0e,0xfd DCB 0xff,0x52,0xfe,0x03,0x6f,0x95,0x30,0xf1,0x97,0xfb,0xc0,0x85,0x60,0xd6,0x80,0x25 DCB 0xa9,0x63,0xbe,0x03,0x01,0x4e,0x38,0xe2,0xf9,0xa2,0x34,0xff,0xbb,0x3e,0x03,0x44 DCB 0x78,0x00,0x90,0xcb,0x88,0x11,0x3a,0x94,0x65,0xc0,0x7c,0x63,0x87,0xf0,0x3c,0xaf DCB 0xd6,0x25,0xe4,0x8b,0x38,0x0a,0xac,0x72,0x21,0xd4,0xf8,0x07,0x56,0xcf,0x00,0x00 ALIGN ;==================================================================== ; サブルーチン群 ;==================================================================== ;-------------------------------------------------------------------- ; デバッガモニタへジャンプ ;-------------------------------------------------------------------- CODE32 fiq_handler mrs sp, cpsr ; IRQ/FIQ不許可 orr sp, sp, #PSR_IRQ_DISABLE | PSR_FIQ_DISABLE msr cpsr_cxsf, sp ldr sp, fiq_sp ; SP のセット add sp, sp, #1 fiq_m stmfd sp!, {r12, lr} ; レジスタ の退避(合計4ワード) mrs lr, spsr mrc p15, 0, r12, c1, c0, 0 ; コプロセッサ・マスタ 退避 stmfd sp!, {r12, lr} bic r12, r12, #C1_PROTECT_UNIT_ENABLE ; プロテクションユニット ディセーブル mcr p15, 0, r12, c1, c0, 0 bic r12, sp, #1 ; デバッガ処理へジャンプ ldr r12, [r12, #16] cmp r12, #0 blxne r12 ;-------------------------------------------------------------------- ; デバッガモニタからの復帰 ;-------------------------------------------------------------------- CODE32 fiq_return ldmfd sp!, {r12, lr} ; レジスタ の復帰 mcr p15, 0, r12, c1, c0, 0 ; コプロセッサ・マスタ 復帰 msr spsr_sxcf, lr ldmfd sp!, {r12, lr} subs pc, lr, #4 ;-------------------------------------------------------------------- ; 初期化 ;-------------------------------------------------------------------- EXTERN init_cp15 EXTERN reset_cp15 EXTERN IrisMonMain EXTERN intr_main CODE32 start_handler cmp lr, #0 ; fiq_return => pc = -4 対策 moveq lr, #4 mov r12, #REG_BASE ; モニタ/ユーザ チェック ldrb r12, [r12, #OFFSET_REG_PAUSE] teq r12, #1 mrseq r12, cpsr ; IRQ/FIQ不許可 orreq r12, r12, #PSR_IRQ_DISABLE | PSR_FIQ_DISABLE msreq cpsr_cxsf,r12 ldreq sp, fiq_sp ; SP のセット beq fiq_m ; デバッガモニタへジャンプ mov r4, #REG_BASE ; カードリセットLow信号 1us以上出力 mov r0, #CARD_RESET_LO mov r1, #CARDMST_SEL_ROM | CARDMST_ENABLE str r0, [r4, #REG_CARDCNT - REG_BASE] str r1, [r4, #REG_CARD_MASTER_CNT - REG_BASE] ; データレジスタも同時にクリア ; (実際はリードオンリーフラグへ書き込んでしまっている ; <シャープさんからの指摘>) restart_v mov r0, #0xc0 | PSR_SYS_MODE ; システムモードへ切り換え & IRQ/FIQ不許可 msr cpsr_cxsf, r0 mov r0, #0x8000/4 ; メインメモリLow期間 0.97ms bl WaitByLoop mainmem_change_burst ; メインメモリ バーストモード遷移 ldr r4, =0x04000204 ; REG_EXMEMCNT mov r1, #MMEM_CE2_OUT strh r1, [r4] mov r0, #0x8000/4 ; メインメモリHigh期間 0.97ms bl WaitByLoop ldr r3, =MAIN_MEM_EX_END - 2 ldr r1, =MMEMD4_BURST_MODE | MMEMD4_BURST_CONTINUOUS \ | MMEMD4_PARTIAL_REFRESH_NONE | MMEMD4_SB1 ldr r2, =MMEMD5_1ST_R4_W3 | MMEMD5_BURST_WRITE | MMEMD5_BURST_LINER \ | MMEMD5_CLOCK_TRIGGER_UP | MMEMD5_SB1 ldr r12, =MAIN_MEM | MMEMP_CLOCK_TRIGGER_UP \ | MMEMP_BURST_MODE | MMEMP_BURST_CONTINUOUS \ | MMEMP_1ST_R4_W3 | MMEMP_BURST_WRITE | MMEMP_BURST_LINER \ | MMEMP_PARTIAL_REFRESH_NONE | MMEMP_SB1 ldrh r0, [r3] strh r0, [r3] strh r0, [r3] strh r1, [r3] strh r2, [r3] ldrh r0, [r12] ldr r4, =0x04000204 ; REG_EXMEMCNT mov r1, #MMEM_INTF_SYNC | MMEM_CE2_OUT strh r1, [r4] bl init_cp15 ; システム制御コプロセッサ 初期化 mov r4, #REG_BASE ; IME リセット strb r4, [r4, #OFFSET_REG_IME] bl bankreg_init_stack_clear ; バンクレジスタ リセット & スタック領域 クリア ; adr r0, intr_main ; 割り込みアドレスのセット ; str r0, [sp, #0x100-4] ldr r0, =IrisMonMain ; Cルーチン処理 blx r0 main_return bl terminate_mon ; モニタ終了処理 ldr r12, =MAIN_MEM_EX_END ; ユーザ・エントリポイント 獲得 IF :DEF: DISABLE_ENTRY_OF_ROM_HEADER ldr lr, [r12, #-(0x200 - 0x28)] ; rmhp->arm9->ramAddr ELSE ldr lr, [r12, #-(0x200 - 0x24)] ; rmhp->arm9->entryAddr ENDIF IF :DEF: DISABLE_BOOT_IPL2 ldrh r0, [r12, #-4] ; ROMヘッダ チェック cmp r0, #1 0 beq %b0 ; ROMヘッダ不整合時 sub r12, r12, #0x800 ldrh r0, [r12, #0x14] ; デバッガチェック add r12, r12, #0x800 cmp r0, #1 ; if (!shwp->isOnDebugger) mov r0, #0 ldreq r12, [r12, #-(0x200 - 0x168)]; デバッガエントリポイント 獲得 ; cmpeq r12, #0 ; rmhp->dbgArm9RamAddr ; cmpeq r12, #-1 bxeq r12 IF :DEF: BB_MON 0 b %b0 ; ブレッドボード開発用 ENDIF mov r0, #0 bx lr ELSE sub r12, r12, #0x800 ldrh r0, [r12, #0x2c] ; IPL2・CRCチェック cmp r0, #0 ; if (!shwp->flashCrcError) 0 bne %b0 ldr r12, [r12, #0x20] ; IPL2・エントリポイント 獲得 cmp r12, #0 ; shwp->flashArm9RamAddr 0 beq %b0 bx r12 ENDIF ;-------------------------------------------------------------------- ; ソフトリセット ;-------------------------------------------------------------------- CODE32 soft_reset bl terminate_mon ; 終了処理 ldr r12, =MAIN_MEM_EX_END ; ユーザ・エントリポイント 獲得 ldr lr, [r12, #-(0x200 - 0x24)] mov r12, #0 bx lr ;-------------------------------------------------------------------- ; モニタプログラム終了処理 ;-------------------------------------------------------------------- CODE32 terminate_mon mov r12, lr mov r0, #PSR_SYS_MODE ; IRQ/FIQ許可 msr cpsr_cxsf, r0 ldr r0, =C1_DTCM_ENABLE | C1_EXCEPT_VEC_UPPER \ | C1_SB1_BITSET bl reset_cp15 ; プロテクションユニットディセーブル bl bankreg_init_stack_clear ; バンクレジスタ リセット & スタック領域 クリア ldmea r4, {r0-r11} ; 汎用レジスタ クリア bx r12 ;-------------------------------------------------------------------- ; バンクレジスタ リセット & スタック領域 クリア ;-------------------------------------------------------------------- CODE32 bankreg_init_stack_clear mov r0, #0xc0 | PSR_SVC_MODE ; SVCモードへ切り換え & IRQ/FIQ不許可 msr cpsr_cxsf, r0 ldr sp, svc_sp ; SP のセット mov lr, #0 msr spsr_csxf, lr mov r0, #0xc0 | PSR_IRQ_MODE ; IRQモードへ切り換え & IRQ/FIQ不許可 msr cpsr_cxsf, r0 ldr sp, irq_sp ; SP のセット mov lr, #0 msr spsr_cxsf, lr mov r0, #0x40 | PSR_SYS_MODE ; システムモードへ切り換え & IRQ許可/FIQ不許可 msr cpsr_cxsf, r0 ldr sp, usr_sp ; SP のセット stack_clear IF :DEF: BB_MON ldr r4, =CPU_WRAM_END ELSE mrc p15, 0, r4, c9, c1, 0 ; DTCMアドレス獲得 ; bic r4, r4, lsr #0xff mov r4, r4, lsr #C9_TCMR_BASE_SHIFT mov r4, r4, lsl #C9_TCMR_BASE_SHIFT add r4, r4, #DTCM_SIZE ENDIF ; BB_MON adr r0, stack_clear_10 + 1 bx r0 CODE16 stack_clear_10 mov r0, #0 ldr r1, =-4*128 1 str r0, [r4, r1] add r1, #4 blt %b1 bx lr ;-------------------------------------------------------------------- ; IRQ処理へジャンプ ;-------------------------------------------------------------------- ALIGN CODE32 irq_handler stmfd sp!, {r0-r3,r12,lr} ; レジスタ の退避(6ワード) mrc p15, 0, r0, c9, c1, 0 ; DTCMアドレス獲得 ; bic r0, r0, lsr #0xff mov r0, r0, lsr #C9_TCMR_BASE_SHIFT mov r0, r0, lsl #C9_TCMR_BASE_SHIFT add r0, r0, #DTCM_SIZE adr lr, irq_return ldr pc, [r0, #-4] ; 32bitコードでジャンプ ;-------------------------------------------------------------------- ; IRQからの復帰 ;-------------------------------------------------------------------- CODE32 irq_return ldmfd sp!, {r0-r3,r12,lr} ; レジスタ の復帰 subs pc, lr, #4 ;-------------------------------------------------------------------- ; システムコールへジャンプ ;-------------------------------------------------------------------- CODE32 swi_handler stmfd sp!, {r11, r12, lr} ; SVCモード レジスタ退避 ldrh r12, [lr, #-2] ; システムコールNo 取得(ハーフワードアクセス対応) and r12, r12, #0xff adr r11, sys_table ; システムコール・アドレス 取得 ldr r12, [r11, r12, lsl #2] mrs r11, spsr ; SVCモード SPSR退避(合計4ワード) stmfd sp!, {r11} and r11, r11, #PSR_IRQ_DISABLE ; IRQ許可状態 コピー orr r11, r11, #PSR_SYS_MODE ; システムモードへ切り換え & FIQ許可 msr cpsr_cxsf,r11 stmfd sp!, {r2, lr} ; システムモード レジスタ退避(2ワード) blx r12 ; コードの切換とジャンプ ;-------------------------------------------------------------------- ; システムコールからの復帰 ;-------------------------------------------------------------------- GLOBAL swi_return CODE32 swi_return ldmfd sp!, {r2, lr} ; システムモード レジスタ復帰 mov r12, #0xc0 | PSR_SVC_MODE ; SVCモードへ切り換え msr cpsr_cxsf, r12 ; & IRQ/FIQ不許可 ldmfd sp!, {r11} ; SVCモード レジスタ復帰 msr spsr_cxsf, r11 ldmfd sp!, {r11, r12, lr} movs pc, lr ;-------------------------------------------------------------------- ; PAUSEレジスタ セット ;-------------------------------------------------------------------- GLOBAL SetPauseReg CODE16 SetPauseReg ldr r2, =REG_PAUSE str r0, [r2, #0] bx lr ;==================================================================== ; アドレステーブル ;==================================================================== ALIGN usr_sp DCD MON_DTCM_END - 0x140 irq_sp DCD MON_DTCM_END - 0x60 svc_sp DCD MON_DTCM_END - 0x40 fiq_sp DCD ROM_HEADER_BUF - 0x64 ;fiq_sp DCD MON_DTCM_END - 0x24 EXTERN AccessCard EXTERN WaitByLoop EXTERN WaitIntr EXTERN WaitVBlankIntr EXTERN Halt EXTERN IsMmem8MB EXTERN GetCRC16 EXTERN DivS32 EXTERN SqrtU32 EXTERN CpuSet16_32 EXTERN CpuSetFast32 EXTERN UnPackBits32 EXTERN UnCompLZ77Byte EXTERN UnCompLZ77Short EXTERN UnCompHuffman32 EXTERN UnCompRLByte EXTERN UnCompRLShort EXTERN UnDiffByte2Byte EXTERN UnDiffShort2Short sys_table DCD soft_reset ; 0 DCD 0 ; 1 DCD 0 ; 2 DCD WaitByLoop ; 3 DCD WaitIntr ; 4 DCD WaitVBlankIntr ; 5 DCD Halt ; 6 DCD 0 ; 7 DCD 0 ; 8 DCD DivS32 ; 9 DCD 0 ; 10 DCD CpuSet16_32 ; 11 DCD CpuSetFast32 ; 12 DCD SqrtU32 ; 13 DCD GetCRC16 ; 14 DCD IsMmem8MB ; 15 DCD UnPackBits32 ; 16 DCD UnCompLZ77Byte ; 17 DCD UnCompLZ77Short ; 18 DCD UnCompHuffman32 ; 19 DCD UnCompRLByte ; 20 DCD UnCompRLShort ; 21 DCD UnDiffByte2Byte ; 22 DCD 0 ; 23 DCD UnDiffShort2Short ; 24 DCD 0 ; 25 DCD 0 ; 26 DCD 0 ; 27 DCD 0 ; 28 DCD 0 ; 29 DCD 0 ; 30 DCD SetPauseReg ; 31 END