ntr_bootrom/trunk/IrisSubp/IrisSubpMon/crt0subArmCommon.s

726 lines
20 KiB
ArmAsm
Raw Permalink 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.

;********************************************************************
; IRIS-SUBPモニタプログラム サブルーチン群
;********************************************************************
AREA IrisSubpCrt0Sub, CODE, READONLY
INCLUDE IrisSubpDefineArm.s
INCLUDE IrisSubpMemoryMapArm.s
INCLUDE IrisSubpMonDefineArm.s
INCLUDE IrisSubpMonMemoryMapArm.s
MON_ONLY
NDEBUG2
;--------------------------------------------------------------------
; 割り込み分岐処理
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL intr_main
EXTERN intrTable
ALIGN
CODE32
intr_main
mov r12, #REG_BASE ; IE/IF
add r3, r12, #OFFSET_REG_IE ; r3: REG_IE
ldmia r3, {r1-r2}
and r1, r1, r2 ; r1: IE & IF
mov r2, #0
ands r0, r1, #CARD_DATA_INTR_FLAG ;
bne jump_intr
add r2, r2, #4
ands r0, r1, #TIMER3_INTR_FLAG ; カードタイマー 割り込み
bne jump_intr
add r2, r2, #4
ands r0, r1, #V_BLANK_INTR_FLAG ; V
jump_intr
str r0, [r3, #REG_IF - REG_IE] ; IF
ldr r1, =intrTable ; ユーザIRQ処理へジャンプ
add r1, r1, r2
ldr r0, [r1]
bx r0
;-----------------------------------------------------------------------
; ループ待ちr0=loopCount
;-----------------------------------------------------------------------
GLOBAL WaitByLoop
ALIGN
CODE16
WaitByLoop
sub r0, #1
bgt WaitByLoop
bx lr
;--------------------------------------------------------------------
;- Vブランク割り込みウェイト -
;--------------------------------------------------------------------
GLOBAL WaitVBlankIntr
ALIGN
CODE32
WaitVBlankIntr mov r0, #1
mov r1, #V_BLANK_INTR_FLAG
;--------------------------------------------------------------------
; 割り込みウェイトr0=initCheckClear, r1=intrFlag
;--------------------------------------------------------------------
GLOBAL WaitIntr
CODE32
WaitIntr stmfd sp!, {lr}
cmp r0, #0
blne WaitIntr_sub ; IfCheck クリア
0
mov lr, #0x80
strb lr, [r12,#REG_PAUSE+1 - REG_BASE] ; SVC_Halt() REG_PAUSE = 0x80
nop
nop
bl WaitIntr_sub
beq %b0 ; while (!(IfCheck & IfFlags))
ldmfd sp!, {lr}
bx lr
WaitIntr_sub
IF :DEF: BB_MON
ldr r12,=CPU_WRAM_END
ELSE
mov r12,#REG_BASE ; r12: #REG_BASE
ENDIF
str r12,[r12,#REG_IME - REG_BASE] ; IME = 0
ldr r2, [r12, #INTR_CHECK_BUF - CPU_WRAM_END]
ands r0, r1, r2 ; IfCheck 判定
eorne r2, r2, r0 ; IfCheck クリア
strne r2, [r12, #INTR_CHECK_BUF - CPU_WRAM_END]
mov r0, #1
str r0, [r12,#REG_IME - REG_BASE] ; IME = 1
bx lr
;--------------------------------------------------------------------
; サウンドBIAS 変更 (r0=up_down, r1=stepLoops)
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL ChangeSoundBias16
CODE16
ChangeSoundBias16
1 mov r2, #2 ; r12: 0x200
lsl r2, #8
mov r12, r2
ldr r3, =REG_SOUNDBIAS ; r3: soundBiasp = REG_SOUNDBIAS
ldrh r2, [r3, #0] ; r2: *soundBiasp
ldr r3, =REG_SOUNDBIAS
cmp r0, #0 ; if (up_down)
beq %f2
cmp r2, r12 ; if (*soundBiasp >= 0x200) break;
bge %f5
add r2, #1 ; *soundBiasp += 1
b %f3
2 cmp r2, #0 ; if (*soundBiasp <= 0) break;
ble %f5
sub r2, #1 ; *soundBiasp -= 1
3 strh r2, [r3, #0]
mov r2, r1 ; for (i=stepLoops; --i>=0; ) ;
4 sub r2,#1
bpl %b4
b %b1
5 bx lr
; ENDIF
;--------------------------------------------------------------------
; BIOS領域専用コピー (r0=srcp, r1=destp, r2=size)
;--------------------------------------------------------------------
EXTERN SecureAreaEndp
GLOBAL CopyBiosArea
CopyBiosArea
add r2, r1
1
ldr r3, =SecureAreaEndp
cmp r0, r3
bge %b2
ldmia r0!, {r3} ; *((vu32 *)(destp))++ = *((vu32 *)(srcp))++
stmia r1!, {r3}
cmp r1, r2
blt %b1
2 mov pc, lr
;--------------------------------------------------------------------
; セキュリティ・キー解除  Nintendoロゴ コピー
;--------------------------------------------------------------------
IF :DEF: TEST_AGB_MODE
KEY_START_BLOCK_NO * 3 ; キー・スタート ブロックNo
EXTERN NinLogoBak
; EXTERN NinLogoCopy
EXTERN DacsCheck
GLOBAL key_unlock__nin_logo_copy
CODE16
key_unlock__nin_logo_copy
push {r3, r4-r6, lr}
mov r6, #0x8 ; r6: ROM_BANK0
lsl r6, #24
mov r5, #MON_KEY_GROUP_NO - CARTRIDGE
add r5, r6 ; r5: MON_KEY_GROUP_NO
sub r0, r5, #1 ; r4: キー No オフセット 算出
mov r1, #27 ; Srcp=MON_KEY_GROUP_NO-1,Count=27
bl GetKeyNo
; mov r0, #2 ; ダミー キー No
mov r4, #2*6
mul r4, r0
ldrb r3, [r5] ; r3: キーグループ No(0-3) * 48
; lsl r3, #32-2 ;(r2: キーグループ オフセット固定 ダミー読み込み)
; lsr r3, #32-2
; mov r2, #2*6*4
; mul r2, r3
; add r4, r2 ; r4: キー No 算出 (キーグループ オフセット加算無し)
adr r5, key_addr ; r5: キー・アドレス
add r5, r4
mov r4, #0
nin_copy mov r0, r4
bl NinLogoCopy ; Nintendoロゴ コピー (20*10Byte)
cmp r4, #KEY_START_BLOCK_NO
blt key_unlock_end
cmp r4, #KEY_START_BLOCK_NO + 6
bge key_unlock_end
key_unlock ldrh r1, [r5] ; r1: キー・アドレス 読み込み
lsl r1, #1
orr r1, r6
ldrh r0, [r1]
add r5, #2
key_unlock_end add r4, #1
cmp r4, #11
bne nin_copy
pop {r3, r4-r6, pc}
INCLUDE crt0KeyAddr.s
ENDIF
;--------------------------------------------------------------------
; キーNo 算出 (r0=Srcp, r1=Count → r0=KeyNo:2)
;--------------------------------------------------------------------
IF :DEF: TEST_AGB_MODE
GLOBAL GetKeyNo
CODE16
GetKeyNo push {r4, r5, lr}
mov r4, #3 ; r4: Ror
mov r3, #0 ; r3: KeyNo
GetKeyNo_10 ldrb r2, [r0, #0] ; r2: *Srcp
ror r3, r4
mov r5, #4 ; r5: RorCount
GetKeyNo_20 eor r3, r2
lsl r2, #8
sub r5, #1 ; while (--RorCount > 0)
bgt GetKeyNo_20
add r0, #1
sub r1, #1 ; while (--Count > 0)
bgt GetKeyNo_10
mov r0, r3
lsl r0, #32-5
lsr r0, #32-2
pop {r4, r5, pc}
ENDIF
;--------------------------------------------------------------------
; NINTENDOロゴ コピー (r0=BlockNo)
;--------------------------------------------------------------------
IF :DEF: TEST_AGB_MODE
GLOBAL NinLogoCopy
CODE16
NinLogoCopy push {r4, lr}
mov r4, #20 ; r4: BlockOffset = BlockNo * 20
mul r4, r0
mov r3, #0x8 ; r3: ROM_BANK0
lsl r3, #24
add r0, r3, #4 ; r0: &((u8 *)ROM_BANK0)[BlockOffset + OFFSET_MON_NINLOGO]
add r0, r4
ldr r1, =NinLogoBak+36 ; r1: &NinLogoBak[BlockOffset + 36]
add r1, r4
mov r2, #10 ; r2: 0x0000000A (16bit転送10回)
bl CpuSet16_32 ; CpuCopy16_32()
pop {r4, pc}
ENDIF
LTORG
;--------------------------------------------------------------------
; 汎用符号付き割り算r0/r1→r0',r0%r1→r1',|r0'|→r3'
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL DivS32
ALIGN
CODE32
DivS32 ands r3, r1, #0x80000000 ; r1: 除数の絶対値
rsbmi r1, r1, #0
eors r12,r3, r0, asr #32 ; r12: d31=結果の符合,d30=被除数の符号
rsbcs r0, r0, #0 ; r0: 被除数の絶対値
movs r2, r1 ; r2: コントロール・ビット
; beq devide_by_zero
divide_just_l cmp r2, r0, lsr #1
movls r2, r2, lsl #1
blo divide_just_l
divide_div_l cmp r0, r2 ; 減算できるかチェック
adc r3, r3, r3 ; r3*2 + キャリー
subcs r0, r0, r2 ; 減算可能なら減算
teq r2, r1 ; 終了チェック
movne r2, r2, lsr #1 ; 終了でなければ2で割り再チェック
bne divide_div_l
mov r1, r0
mov r0, r3
movs r12,r12,lsl #1
rsbcs r0, r0, #0
rsbmi r1, r1, #0
bx lr
; ENDIF
;--------------------------------------------------------------------
; 平方根算出r0=param
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL SqrtU32
ALIGN
CODE32
SqrtU32 stmfd sp!, {r4}
mov r12,r0 ; r12: ParamBak
mov r1, #1
1 cmp r0, r1
movhi r0, r0, lsr #1
movhi r1, r1, lsl #1
bhi %b1
2 mov r0, r12 ; r0: 被除数
mov r4, r1 ; r1: 除数
mov r3, #0 ; r3: 商
mov r2, r1 ; r2: コントロール・ビット
3 cmp r2, r0, lsr #1
movls r2, r2, lsl #1
blo %b3
4 cmp r0, r2 ; 減算できるかチェック
adc r3, r3, r3 ; r3*2 + キャリー
subcs r0, r0, r2 ; 減算可能なら減算
teq r2, r1 ; 終了チェック
movne r2, r2, lsr #1 ; 終了でなければ2で割り再チェック
bne %b4
add r1, r1, r3
movs r1, r1, lsr #1
cmp r1, r4
bcc %b2
mov r0, r4
ldmfd sp!, {r4}
bx lr
; ENDIF
;--------------------------------------------------------------------
; セット (r0=srcp, r1=destp, r2=dmaCntData)
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL CpuSet16_32
CODE16
CpuSet16_32 push {r4, r5, lr}
lsl r4, r2, #11 ; r4: size = (dmaCntData & 0x1fffff)*4
lsr r4, #11-2
bl CheckSrcp16_32 ; ソースアドレス チェック
IF :DEF: CHECK_PROT_ADDR
ELSE
beq %f6
ENDIF
0 mov r5, #0 ; r5: i = 0
lsr r3, r2, #27 ; if ((dmaCntData) & DMA_32BIT_BUS)
bcc %f3
add r5, r1, r4 ; r5: destEndp = destp + size
lsr r3, r2, #25 ; if ((dmaCntData) & DMA_SRC_FIX)
bcc %f2
ldmia r0!, {r3}
1 cmp r1, r5 ; while (destp < destEndp)
bge %f6
stmia r1!, {r3} ; *((vu32 *)(destp))++ = *((vu32 *)(srcp))
b %b1
2 cmp r1, r5 ; while (destp < destEndp)
bge %f6
ldmia r0!, {r3} ; *((vu32 *)(destp))++ = *((vu32 *)(srcp))++
stmia r1!, {r3}
b %b2
3 lsr r4, #1
lsr r3, r2, #25 ; if ((dmaCntData) & DMA_SRC_FIX)
bcc %f5
ldrh r3, [r0, #0]
4 cmp r5, r4 ; for ( ; i<count; i++)
bge %f6
strh r3, [r1, r5] ; ((vu16 *)(destp))[i] = ((vu16 *)(srcp))[0]
add r5, #2
b %b4
5 cmp r5, r4 ; for ( ; i<count; i++)
bge %f6
ldrh r3, [r0, r5] ; ((vu16 *)(destp))[i] = ((vu16 *)(srcp))[i]
strh r3, [r1, r5]
add r5, #2
b %b5
6 pop {r4, r5}
pop {r3}
bx r3
; ENDIF
;--------------------------------------------------------------------
; ソースアドレス チェック 16bitインタフェース(r4=size → r12)
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL CheckSrcp16_32
CODE16
CheckSrcp16_32 adr r3, CheckSrcp
mov r12,r4
bx r3
;--------------------------------------------------------------------
; ソースアドレス チェック (r0=srcp,r12=size → Zフラグ)
;--------------------------------------------------------------------
GLOBAL CheckSrcp
ALIGN
CODE32
CheckSrcp cmp r12, #0 ; if (!size)
beq CheckSrcp_End
bic r12, r12,#0xfe000000
add r12, r0, r12 ; r12: srcEndp = srcp + size
tst r0, #0x0e000000 ; srcp チェック
tstne r12,#0x0e000000 ; srcEndp チェック
CheckSrcp_End bx lr
; ENDIF
;--------------------------------------------------------------------
; 高速セット(32Byte) (r0=srcp, r1=destp, r2=dmaCntData)
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL CpuSetFast32_T
GLOBAL CpuSetFast32
CODE16
CpuSetFast32_T mov r3, pc
bx r3
ALIGN
CODE32
CpuSetFast32 stmfd sp!, {r4-r10, lr}
mov r10, r2, lsl #11 ; r10: count = (dmaCntData & 0x1fffff)*4
movs r12, r10, lsr #11-2 ; r12: size = count * 4
bl CheckSrcp ; ソースアドレス チェック
IF :DEF: CHECK_PROT_ADDR
ELSE
beq %f5
ENDIF
add lr, r1, r10, lsr #11-2 ; lr: destEndp = destp + size
mov r10, r10, lsr #11+3 ; r10: blockEndp = srcp + size/32*32
add r10, r1, r10,lsl #3
0 movs r2, r2, lsr #25 ; if ((dmaCntData) & DMA_SRC_FIX)
bcc %f3
ldr r2, [r0, #0]
mov r3, r2
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov r8, r2
mov r9, r2
1 cmp r1, r10 ; while (destp < destEndp)
stmltia r1!, {r2-r9} ; *((vu32 *)(destp++)) = *((vu32 *)(srcp))
blt %b1
2 cmp r1, lr
stmltia r1!, {r2}
blt %b2
b %f5
3 cmp r1, r10 ; while (destp < destEndp)
ldmltia r0!, {r2-r9} ; *((vu32 *)(destp)++) = *((vu32 *)(srcp)++)
stmltia r1!, {r2-r9}
blt %b3
4 cmp r1, lr
ldmltia r0!, {r2}
stmltia r1!, {r2}
blt %b4
5 ldmfd sp!, {r4-r10, lr}
bx lr
; ENDIF
;--------------------------------------------------------------------
; Bit圧縮データ展開 (r0=srcp, r1=destp, r2=unPackBitsParamp)
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL UnPackBits32
ALIGN
CODE32
UnPackBits32
stmfd sp!, {r4-r11, lr}
sub sp, sp, #4
ldrh r7, [r2, #0] ; r7: srcNum = unPackBitsParamp->srcNum
movs r12, r7 ; r12: srcCount
bl CheckSrcp ; ソースアドレス チェック
beq %f6
0 ldrb r6, [r2, #2] ; r6: srcBitNum = unPackBitsParamp->srcBitNum
rsb r10, r6, #8 ; r10: srcBitNumInv = 8 - srcBitNum
mov r14, #0 ; r14: destBak = 0
ldr r11, [r2, #4] ; r8: destOffset0_On
mov r8, r11, lsr #31 ; = unPackBitsParamp->destOffset0_On
ldr r11,[r2, #4] ; destOffset = unPackBitsParamp->destOffset
mov r11,r11, lsl #1
mov r11,r11, lsr #1
str r11,[sp, #0]
ldrb r2, [r2, #3] ; r2: destBitNum = unPackBitsParamp->destBitNum
mov r3, #0 ; r3: destBitCount = 0
1 subs r7, r7, #1 ; while (--srcNum >= 0)
blt %f6
mov r11, #0xff ; r5: srcMask = 0xff >> srcBitNumInv
mov r5, r11, asr r10
ldrb r9, [r0], #1 ; r9: srcTmp = *srcp++
mov r4, #0 ; r4: srcBitCount = 0
2 cmp r4, #8 ; while (srcBitCount < 8)
bge %b1
and r11, r9, r5 ; r12: destTmp = ((srcTmp&srcMask) >>srcBitCount)
movs r12, r11, lsr r4
cmpeq r8, #0
beq %f4
3 ldr r11, [sp, #0] ; destTmp += destOffset
add r12, r12, r11
4 orr r14, r14, r12, lsl r3 ; destBak |= destTmp << destBitCount
add r3, r3, r2 ; destBitCount += destBitNum
cmp r3, #0x20 ; if (destBitCount >= 32)
blt %f5
str r14, [r1], #4 ; *destp++ = destBak
mov r14, #0 ; destBak = 0
mov r3, #0 ; destBitCount = 0
5 mov r5, r5, lsl r6 ; srcMask <<= srcBitNum
add r4, r4, r6 ; srcBitCount += srcBitNum
b %b2
6 add sp, sp, #4
ldmfd sp!, {r4-r11, lr}
bx lr
; ENDIF
;--------------------------------------------------------------------
; データ展開8Bit→8Bit(r0=srcp, r1=destp)
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL UnCompLZ77Byte
ALIGN
CODE32
UnCompLZ77Byte
stmfd sp!, {r4-r6, lr}
ldr r5, [r0], #4 ; r2: destCount = *(u32 *)srcp >> 8
mov r2, r5, lsr #8 ; r0: srcp += 4
movs r12, r2 ; r12: srcCount
bl CheckSrcp ; ソースアドレス チェック
beq %f6
1 cmp r2, #0 ; while (destCount > 0)
ble %f6
ldrb r14, [r0], #1 ; r14: flags = *srcp++
mov r4, #8 ; for (i=8; --i>=0; )
2 subs r4, r4, #1
blt %b1
tst r14, #0x80 ; if (!(flags & 0x80))
bne %f3
ldrb r6, [r0], #1 ; *srcp++
strb r6, [r1], #1 ; r1: *destp++
sub r2, r2, #1 ; destCount--
b %f5
3 ldrb r5, [r0, #0] ; r3: length = (*srcp >> 4) + 3
mov r6, #3
add r3, r6, r5, asr #4
ldrb r6, [r0], #1 ; r12: offset = (*srcp++ & 0x0f) << 8
and r5, r6, #0xf
mov r12,r5, lsl #8
ldrb r6, [r0], #1 ; offset = (offset | *srcp++) + 1
orr r5, r6, r12
add r12, r5, #1
sub r2, r2, r3 ; destCount -= length
4 ldrb r5, [r1, -r12] ; *destp++ = destp[-offset]
strb r5, [r1], #1
subs r3, r3, #1 ; while (--length > 0)
bgt %b4
5 cmp r2, #0 ; if (destCount <= 0) break;
movgt r14, r14, lsl #1 ; flags <<= 1
bgt %b2
b %b1
6 ldmfd sp!, {r4-r6, lr}
bx lr
; ENDIF
;--------------------------------------------------------------------
; ランレングスデータ展開8Bit→8Bit(r0=srcp, r1=destp)
;--------------------------------------------------------------------
; IF :DEF: SYSCALL_ASM
GLOBAL UnCompRLByte
CODE16
UnCompRLByte
push {r4-r7, lr}
ldmia r0!, {r3} ; r7: destCount = *(u32 *)srcp >> 8
lsr r7, r3, #8 ; r0: srcp += 4
mov r4, r7 ; r4: count
bl CheckSrcp16_32 ; ソースアドレス チェック
beq %f5
1 cmp r7, #0 ; while (destCount > 0)
ble %f5
ldrb r4, [r0, #0] ; r4: flags = *srcp++
add r0, #1
lsl r2, r4, #25 ; r2: length = flags & 0x7f
lsr r2, #25
lsr r3, r4, #8 ; if (!(flags & 0x80))
bcs %f3
add r2, #1 ; length++
sub r7, r2 ; destCount -= length
2 ldrb r3, [r0, #0] ; *destp++ = *srcp++
strb r3, [r1, #0]
add r0, #1
add r1, #1
sub r2, r2, #1 ; while (--length > 0)
bgt %b2
b %b1
3 add r2, #3 ; length += 3
sub r7, r2 ; destCount -= length
ldrb r5, [r0, #0] ; srcTmp = *srcp++
add r0, #1
4 strb r5, [r1, #0] ; *destp++ = srcTmp
add r1, #1
sub r2, r2, #1 ; while (--length > 0)
bgt %b4
b %b1
5 pop {r4-r7}
pop {r0}
; ENDIF
;--------------------------------------------------------------------
; r0レジスタによるルーチン呼び出し
;--------------------------------------------------------------------
GLOBAL __call_via_r0
CODE16
__call_via_r0 bx r0
;--------------------------------------------------------------------
; r1レジスタによるルーチン呼び出し
;--------------------------------------------------------------------
GLOBAL __call_via_r1
CODE16
__call_via_r1 bx r1
;--------------------------------------------------------------------
; r2レジスタによるルーチン呼び出し
;--------------------------------------------------------------------
GLOBAL __call_via_r2
CODE16
__call_via_r2 bx r2
;--------------------------------------------------------------------
; r3レジスタによるルーチン呼び出し
;--------------------------------------------------------------------
GLOBAL __call_via_r3
CODE16
__call_via_r3 bx r3
;--------------------------------------------------------------------
; r4レジスタによるルーチン呼び出し
;--------------------------------------------------------------------
GLOBAL __call_via_r4
CODE16
__call_via_r4 bx r4
;--------------------------------------------------------------------
; r5レジスタによるルーチン呼び出し
;--------------------------------------------------------------------
GLOBAL __call_via_r5
CODE16
__call_via_r5 bx r5
END