;******************************************************************** ; IRIS-SUBPモニタ例外ハンドラ ;******************************************************************** AREA Init, CODE, READONLY INCLUDE IrisSubpDefineArm.s INCLUDE IrisSubpMemoryMapArm.s INCLUDE IrisSubpMonDefineArm.s INCLUDE IrisSubpMonMemoryMapArm.s ;==================================================================== ; 例外ハンドラ群 ;==================================================================== ;-------------------------------------------------------------------- ; デバッガモニタへジャンプ ;-------------------------------------------------------------------- GLOBAL fiq_handler 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} ; レジスタ の退避(合計3ワード) mrs lr, spsr stmfd sp!, {lr} bic r12, sp, #1 ; デバッガ処理へジャンプ ldr r12, [r12, #12] adr lr, fiq_return cmp r12, #0 bxne r12 ;-------------------------------------------------------------------- ; デバッガモニタからの復帰 ;-------------------------------------------------------------------- CODE32 fiq_return ldmfd sp!, {lr} ; レジスタ の復帰 msr spsr_sxcf, lr ldmfd sp!, {r12, lr} subs pc, lr, #4 ;-------------------------------------------------------------------- ; 初期化 ;-------------------------------------------------------------------- EXTERN IrisSubpMonMain EXTERN intr_main GLOBAL start_handler 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 ; デバッガモニタへジャンプ restart_v mov r0, #0xc0 | PSR_SYS_MODE ; システムモードへ切り換え & IRQ/FIQ不許可 msr cpsr_cxsf, r0 mov r4, #REG_BASE ; IME リセット strb r4, [r4, #OFFSET_REG_IME] bl bankreg_init_stack_clear ; バンクレジスタ リセット & スタック領域 クリア ldr r0, =intr_main ; 割り込みアドレスのセット str r0, [r4, #INTR_VECTOR_BUF - CPU_WRAM_END] ; str r0, [sp, #0x100-4] ldr r0, =IrisSubpMonMain ; Cルーチン処理 adr lr, main_return bx r0 main_return bl terminate_mon ; モニタ終了処理 ldr r12, =MAIN_MEM_EX_END ; ユーザ・エントリポイント 獲得 IF :DEF: DISABLE_ENTRY_OF_ROM_HEADER ldr lr, [r12, #-(0x200 - 0x38)] ; rmhp->arm7->ramAddr ELSE ldr lr, [r12, #-(0x200 - 0x34)] ; rmhp->arm7->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 - 0x16c)]; デバッガエントリポイント 獲得 ; cmpeq r12, #0 ; rmhp->dbgArm7RamAddr ; cmpeq r12, #-1 bxeq r12 IF :DEF: IRIS_BB 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, #0x24] ; IPL2・エントリポイント 獲得 cmp r12, #0 ; shwp->flashArm7RamAddr 0 beq %b0 bx r12 ENDIF ;-------------------------------------------------------------------- ; ソフトリセット ;-------------------------------------------------------------------- CODE32 soft_reset bl terminate_mon ; 終了処理 ldr r12, =MAIN_MEM_EX_END ; ユーザ・エントリポイント 獲得 ldr lr, [r12, #-(0x200 - 0x34)] mov r12, #0 bx lr ;-------------------------------------------------------------------- ; モニタプログラム終了処理 ;-------------------------------------------------------------------- CODE32 terminate_mon mov r12, lr mov r0, #PSR_SYS_MODE ; IRQ/FIQ許可 msr cpsr_cxsf, r0 bl bankreg_init_stack_clear ; バンクレジスタ リセット & スタック領域 クリア ldmea r4, {r0-r11} ; 汎用レジスタ クリア bx r12 ;-------------------------------------------------------------------- ; バンクレジスタ リセット & スタック領域 クリア ;-------------------------------------------------------------------- GLOBAL bankreg_init_stack_clear 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 mov r4, #REG_BASE ; r4: REG_BASE 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処理へジャンプ ;-------------------------------------------------------------------- GLOBAL irq_handler ALIGN CODE32 irq_handler stmfd sp!, {r0-r3,r12,lr} ; レジスタ の退避(6ワード) ; ldr r0, =CPU_WRAM_END mov r0, #REG_BASE adr lr, irq_return ldr pc, [r0, #-4] ; 32bitコードでジャンプ ; ldr r1, [r0, #-4] ; 32bitコードでジャンプ ; bx r1 ;-------------------------------------------------------------------- ; IRQからの復帰 ;-------------------------------------------------------------------- CODE32 irq_return ldmfd sp!, {r0-r3,r12,lr} ; レジスタ の復帰 subs pc, lr, #4 ;-------------------------------------------------------------------- ; システムコールへジャンプ ;-------------------------------------------------------------------- GLOBAL swi_handler CODE32 swi_handler stmfd sp!, {r11, r12, lr} ; SVCモード レジスタ退避 ldrh r12, [lr, #-2] ; システムコールNo 取得(ハーフワードアクセス対応/サウンドBB時) 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ワード) adr lr, swi_return bx r12 ; コードの切換とジャンプ ;-------------------------------------------------------------------- ;- システムコールからの復帰 18c - ;-------------------------------------------------------------------- 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 ;==================================================================== ; アドレステーブル ;==================================================================== ALIGN usr_sp DCD CPU_WRAM_END - 0x100 irq_sp DCD CPU_WRAM_END - 0x50 svc_sp fiq_sp DCD CPU_WRAM_END - 0x24 EXTERN AccessCard EXTERN WaitByLoop EXTERN WaitIntr EXTERN WaitVBlankIntr EXTERN Halt EXTERN Stop EXTERN SetPauseHi EXTERN ChangeSoundBias16 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 GetSoundSinTable EXTERN GetSoundPitchTable EXTERN GetSoundVolumeTable EXTERN GetFuncp4IPL2 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 Stop ; 7 DCD ChangeSoundBias16 ; 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 0 ; 22 DCD 0 ; 23 DCD 0 ; 24 DCD 0 ; 25 DCD GetSoundSinTable ; 26 DCD GetSoundPitchTable ; 27 DCD GetSoundVolumeTable ; 28 DCD GetFuncp4IPL2 ; 29 DCD 0 ; 30 DCD SetPauseHi ; 31 END