mirror of
https://github.com/rvtr/ntr_bootrom.git
synced 2025-10-31 07:11:11 -04:00
726 lines
20 KiB
ArmAsm
726 lines
20 KiB
ArmAsm
;********************************************************************
|
||
; 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
|
||
|
||
|
||
;--------------------------------------------------------------------
|
||
; CPU セット (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
|
||
|
||
|
||
;--------------------------------------------------------------------
|
||
; CPU 高速セット(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
|
||
|
||
|
||
;--------------------------------------------------------------------
|
||
; LZ77データ展開(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
|
||
|