MOV R0, #0x12
MSR CPSR_cf, R0 ; IRQMode
LDR SP, =IRQStack ; set IRQStack
MOV R0, #0x13 ; R0 = Supervisor Mode
MSR CPSR_cf, R0 ; Supervisor Mode
LDR SP, =SVCStack ; SVCStack
MOV R0, #0x1F ; R0 = SysMode
MSR CPSR_cf, R0 ; SysMode
LDR SP, =SysModeStack ; SysModeStack
LDR R0, =UserHandle ; user handle
LDR R1, =UserHandle_Code ; user handle code
STR R1, [R0] ; store a pointer to userhandle
LDR R0, =WAITCNT ; game pak access
LDR R1, =0x45B4 ; value to setup game pak
STR R1, [R0] ; store value
MOV R0, #0x3000000 ; Clear Fast WRAM
MOV R1, #0x7E00
BL memset_zero ; void memset_zero(0x3000000, 0x7E00)
MOV R0, #0x2000000 ; clear Slow WRAM
MOV R1, #0x40000
BL memset_zero ; void memset_zero(0x2000000, 0x40000)
MOV R0, #0x6000000 ; clear VRAM
MOV R1, #0x18000
BL memset_zero ; void memset_zero(0x6000000, 0x18000)
MOV R0, #0x7000000 ; clear OAM
MOV R1, #0x400
BL memset_zero ; void memset_zero(0x7000000, 0x400)
MOV R0, #0x5000000 ; clear Palette
MOV R1, #0x400
BL memset_zero ; void memset_zero(0x5000000, 0x400)
LDR R0, =UserHandle_Dispatcher
LDR R1, =UserHandle_Code
LDR R2, =0x1ED4
BL SetupUserHandle ; void SetupUserHandle(void *src, void *dst, size_t size)
LDR R0, =(_CallCpuSet_Copy+1) ; R0 = addr
MOV LR, PC ; Save Return Addr
BX R0 ; _CallCpuSet_Copy ; u32 _CallCpuSet_Copy()
LDR R0, =(psRandom_And_Copy_Data+1) ; r0 = addr
MOV LR, PC ; save return addr/r10 = 0x20093B0
BX R0 ; psRandom_And_Copy_Data ; void psRandom_And_Copy_Data(void *dst)
LDR R0, =(BiosInterrupt_funcPtr+1)
MOV LR, PC
BX R0 ; BiosInterrupt_funcPtr
LDR R0, =wram_var_3 ; r0 = wram_var_3
MOV R1, #0 ; r1 = 0
STRB R1, [R0] ; wram_var_3 = 0
LDR R0, =hblank_r_2 ; r0 = wram_var_4
MOV R1, #1 ; r1 = 1
STR R1, [R0] ; wram_var_4 = 1
LDR R0, =hblank_r_1 ; r0 = wram_var_5
MOV R1, #0 ; r1 = 0
STR R1, [R0] ; wram_var_5 = 0
LDR R0, =DISPSTAT ; DisplayStatus
MOV R1, #8 ; VBLANK Enable
STRH R1, [R0] ; Store VBLANK Enable
LDR R0, =KEYCNT ; Key Interrupt
LDR R1, =0x83FF ; Select all buttons and Logical AND
STRH R1, [R0] ; store key value
LDR R0, =(init_main_game_loop+1)
BX R0 ; init_main_game_loop
#define userHandle_unk 0x03001D60
userHandleDispatcher:
mov r3, #0x4000200 @ IE
ldr r2, [r3] @ read interrupt enable register
ldrh r1, [r3, #8] @ read interrupt master enable register
mrs r0, spsr @ r0 saved program status register
stmfd sp!, {r0-r3, lr} @ store in stack r0,r1,r2,r3 and lr
mov r0, #0x0 @ r0 = 0
strh r0, [r3, #8] @ disable all interrupts in IM
and r1, r2, r2, lsr #16 @ ((r1 & r2) >> 16)
ldr r0, =userHandle_unk @ r0 ??
ldr r0, [r0] @ value of ??
tst r0, r0 @ r0 & r0
bne _verifyInterrupt_2 @ r0 & r0 != 0, goto _handleInterrupt_2
mov r12, #0x8 @ interruptValue = 8
ands r0, r1, #4 @ verify LCD VCounter Match
bne _handleInterrupt
mov r0, #1 @ r0 = 1
strh r0, [r3, #8] @ enable all interrupt
mov r12, #0x1C @ interruptValue = 0x1C
ands r0, r1, #0x80 @ Serial Communication
bne _handleInterrupt
mov r12, #0x18 @ interruptValue = 0x18
ands r0, r1, #0x40 @ Timer 3
bne _handleInterrupt
mov r12, #0x0 @ interruptValue = 0
ands r0, r1, #1 @ LCD VBLANK
bne _handleInterrupt
mov r12, #0x4 @ interruptValue = 4
ands r0, r1, #2 @ LCD HBLANK
bne _handleInterrupt
b _continueInterruptCheck_
_verifyInterrupt_2:
mov r0, #1 @ r0 = 1
strh r0, [r3, #8] @ enable all interrupt
mov r12, #0x1C @ interruptValue = 0x1C
ands r0, r1, #0x80 @ Serial Communication
bne _handleInterrupt
mov r12, #0x18 @ interruptValue = 0x18
ands r0, r1, #0x40 @ Timer 3
bne _handleInterrupt
mov r12, #0x0 @ interruptValue = 0
ands r0, r1, #1 @ LCD VBLANK
bne _handleInterrupt
mov r12, #0x4 @ interruptValue = 4
ands r0, r1, #2 @ LCD HBLANK
mov r12, #0x8 @ interruptValue = 8
ands r0, r1, #4 @ verify LCD VCounter Match
bne _handleInterrupt
_continueInterruptCheck_:
mov r12, #0xC @ interruptValue = 0xC
ands r0, r1, #8 @ Timer 0
bne _handleInterrupt
mov r12, #0x10 @ interruptValue = 0x10
ands r0, r1, #0x10 @ Timer 1
bne _handleInterrupt
mov r12, #0x14 @ interruptValue = 0x14
ands r0, r1, #0x20 @ Timer 2
bne _handleInterrupt
mov r12, #0x20 @ interruptValue = 0x20
ands r0, r1, #0x100 @ DMA 0
bne _handleInterrupt
mov r12, #0x24 @ interruptValue = 0x24
ands r0, r1, #0x200 @ DMA 1
bne _handleInterrupt
mov r12, #0x28 @ interruptValue = 0x28
ands r0, r1, #0x400 @ DMA 2
bne _handleInterrupt
mov r12, #0x2C @ interruptValue = 0x2C
ands r0, r1, #0x800 @ DMA 3
bne _handleInterrupt
mov r12, #0x30 @ interruptValue = 0x30
ands r0, r1, #0x1000 @ KeyPad
bne _handleInterrupt
mov r12, #0x34 @ interruptValue = 0x34
ands r0, r1, #0x2000 @ Game Pak
bne _handleInterrupt
ands r0, r1, #0x2000 @ game pak
strneb r0, [r3, #-0x17C] @ External IRQ ?
waitExternalIRQ_Or_Panic:
bne waitExternalIRQ_Or_Panic
_handleInterrupt:
strh r0, [r3, #2] @ set interrupt request flag
ldr r1, =0x20C8 @ r1 0x20C8
bic r2, r2, r0 @ r2 IE &~ InterruptValue (bitclear)
and r1, r1, r2 @ r1 IE & 0x20C8
strh r1, [r3] @ store IE
mrs r3, cpsr @ r3 current processor status register
bic r3, r3, #0xDF
orr r3, r3, #0x1F @ Enable IRQ and FIQ, Set SysMode
msr cpsr_cf, r3 @ Store CPSR
ldr r1, =userInterrupt_ @ userInterrupt_
add r1, r1, r12 @
ldr r0, [r1]
stmfd sp!, {lr}
adr lr, _end
bx r0
_end:
ldmfd sp!, {lr} @ load lr of stack
mrs r3, cpsr @
bic r3, r3, #0xDF @
orr r3, r3, #0x92 @ disable IRQ, enable FIQ and enable IRQ Mode in CPU
msr cpsr_cf, r3 @ store cpsr
ldmfd sp!, {r0-r3, lr} @ restore registers
strh r2, [r3] @ restore IE
strh r1, [r3, #8] @ restore IME
msr spsr_cf, r0 @ restore spsr
bx lr @ back