176 lines
5.8 KiB
ArmAsm
176 lines
5.8 KiB
ArmAsm
|
@---------------------------------------------------------------------------------
|
||
|
.section ".init"
|
||
|
@---------------------------------------------------------------------------------
|
||
|
.global _start
|
||
|
.type _start STT_FUNC
|
||
|
.align 4
|
||
|
.arm
|
||
|
|
||
|
@---------------------------------------------------------------------------------
|
||
|
_start:
|
||
|
@---------------------------------------------------------------------------------
|
||
|
b reset_vector @ 0x00 Reset
|
||
|
b reserved_vector @ 0x04 Undefined
|
||
|
b swi_vector @ 0x08 SWI
|
||
|
b reserved_vector @ 0x0C Abort Prefetch
|
||
|
b reserved_vector @ 0x10 Abort Data
|
||
|
b reserved_vector @ 0x14 Reserved
|
||
|
b irq_vector @ 0x18 IRQ
|
||
|
b irq_vector @ 0x1C FIQ
|
||
|
|
||
|
@---------------------------------------------------------------------------------
|
||
|
irq_vector:
|
||
|
@---------------------------------------------------------------------------------
|
||
|
@ Save these registers, IRQ functions will be allowed to modify them w/o
|
||
|
@ saving.
|
||
|
stmdb sp!, { r0 - r3, r12, lr }
|
||
|
|
||
|
@ Pointer to IRQ handler is at 0x03FFFFFC (mirrored WRAM)
|
||
|
mov r0, #0x04000000
|
||
|
|
||
|
@ Store return address and branch to handler
|
||
|
mov lr, pc
|
||
|
ldr pc, [ r0, #-4 ]
|
||
|
|
||
|
@ Return from IRQ
|
||
|
ldmia sp!, { r0 - r3, r12, lr }
|
||
|
subs pc, lr, #4
|
||
|
|
||
|
@---------------------------------------------------------------------------------
|
||
|
reset_vector: @This isn't required if not booting from bios
|
||
|
@---------------------------------------------------------------------------------
|
||
|
mov r0, #0xDF
|
||
|
msr cpsr_cf, r0
|
||
|
|
||
|
@Disable Interrupts IME=0
|
||
|
mov r3, #0x04000000
|
||
|
strb r3, [r3,#0x208]
|
||
|
|
||
|
@Setup stacks
|
||
|
bl init
|
||
|
|
||
|
mov r2, #1
|
||
|
strb r2, [r3,#0x208]
|
||
|
|
||
|
ldr r0, =DrawLogo
|
||
|
ldr lr, =swi_SoftReset
|
||
|
bx r0
|
||
|
|
||
|
@---------------------------------------------------------------------------------
|
||
|
reserved_vector: @Lets just infinite loop for now
|
||
|
@---------------------------------------------------------------------------------
|
||
|
b reserved_vector
|
||
|
|
||
|
@ SWI calling convention:
|
||
|
@ Parameters are passed in via r0 - r3
|
||
|
@ Called SWI can modify r0 - r3 (and return things here), r12, and r14.
|
||
|
@ They can't modify anything else.
|
||
|
@---------------------------------------------------------------------------------
|
||
|
swi_vector:
|
||
|
@---------------------------------------------------------------------------------
|
||
|
@ Save these as temporaries
|
||
|
stmdb sp!, { r11, r12, lr }
|
||
|
|
||
|
@ Load comment from SWI instruction, which indicates which SWI
|
||
|
@ to use.
|
||
|
ldrb r12, [lr,#-2]
|
||
|
adr r11, swi_branch_table
|
||
|
ldr r12, [r11,r12,lsl#2]
|
||
|
|
||
|
@ get SPSR and enter system mode, interrupts on
|
||
|
MRS R11, SPSR
|
||
|
@ This must be stacked and not just saved, because otherwise SWI won't
|
||
|
@ be reentrant, which can happen if you're waiting for interrupts and the
|
||
|
@ interrupt handler triggers the SWI.
|
||
|
stmfd sp!, {r11}
|
||
|
|
||
|
@ Set up new CPSR value
|
||
|
and r11, r11, #0x80
|
||
|
orr r11, r11, #0x1f
|
||
|
msr cpsr_cf, r11
|
||
|
|
||
|
@ We have to now save system-mode lr register as well
|
||
|
stmfd sp!, {r2, r3, lr}
|
||
|
|
||
|
@ Set return address
|
||
|
adr lr, swi_complete
|
||
|
@ Branch to SWI handler
|
||
|
bx r12
|
||
|
|
||
|
swi_complete:
|
||
|
@ Restore system mode lr
|
||
|
ldmfd sp!, {r2, r3, lr}
|
||
|
|
||
|
@ Go back to supervisor mode to get back to that stack
|
||
|
mov r12, #0xD3
|
||
|
msr cpsr_cf, r12
|
||
|
|
||
|
@ SPSR has to be restored because the transition to system mode broke it
|
||
|
ldmfd sp!, {r11}
|
||
|
msr spsr_cf, r11
|
||
|
|
||
|
@ Restore stuff we saved
|
||
|
ldmfd sp!, {r11,r12,lr}
|
||
|
|
||
|
@ Return from exception handler
|
||
|
movs pc, lr
|
||
|
|
||
|
@---------------------------------------------------------------------------------
|
||
|
swi_branch_table:
|
||
|
@---------------------------------------------------------------------------------
|
||
|
.word swi_SoftReset @ 0x00_SoftReset
|
||
|
.word swi_RegisterRamReset @ 0x01_RegisterRAMReset
|
||
|
.word swi_Halt @ 0x02_Halt
|
||
|
.word swi_Stop @ 0x03_Stop
|
||
|
.word swi_IntrWait @ 0x04_IntrWait
|
||
|
.word swi_VBlankIntrWait @ 0x05_VBlankIntrWait
|
||
|
.word swi_Div @ 0x06_Div
|
||
|
.word swi_DivARM @ 0x07_DivARM
|
||
|
.word swi_Sqrt @ 0x08_Sqrt
|
||
|
.word swi_ArcTan @ 0x09_ArcTan
|
||
|
.word swi_ArcTan2 @ 0x0A_ArcTan2
|
||
|
.word swi_CpuSet @ 0x0B_CPUSet
|
||
|
.word swi_CpuFastSet @ 0x0C_CPUFastSet
|
||
|
.word swi_GetBiosChecksum @ 0x0D_GetBiosChecksum
|
||
|
.word swi_BgAffineSet @ 0x0E_BgAffineSet
|
||
|
.word swi_ObjAffineSet @ 0x0F_ObjAffineSet
|
||
|
.word swi_BitUnPack @ 0x10_BitUnPack
|
||
|
.word swi_LZ77UnCompWram @ 0x11_LZ77UnCompWram
|
||
|
.word swi_LZ77UnCompVram @ 0x12_LZ77UnCompVram
|
||
|
.word swi_HuffUnComp @ 0x13_HuffUnComp
|
||
|
.word swi_RLUnCompWram @ 0x14_RLUnCompWram
|
||
|
.word swi_RLUnCompVram @ 0x15_RLUnCompVram
|
||
|
.word swi_Diff8bitUnFilterWram @ 0x16_Diff8bitUnFilterWram
|
||
|
.word swi_Diff8bitUnFilterVram @ 0x17_Diff8bitUnFilterVram
|
||
|
.word swi_Diff16bitUnFilter @ 0x18_Diff16bitUnFilter
|
||
|
.word swi_Invalid @ 0x19_SoundBiasChange
|
||
|
.word swi_Invalid @ 0x1A_SoundDriverInit
|
||
|
.word swi_Invalid @ 0x1B_SoundDriverMode
|
||
|
.word swi_Invalid @ 0x1C_SoundDriverMain
|
||
|
@ .word swi_SoundDriverMain @ 0x1C_SoundDriverMain
|
||
|
.word swi_Invalid @ 0x1D_SoundDriverVSync
|
||
|
.word swi_Invalid @ 0x1E_SoundChannelClear
|
||
|
.word swi_MidiKey2Freq @ 0x1F_MidiKey2Freq
|
||
|
.word swi_Invalid @ 0x20_MusicPlayerOpen
|
||
|
.word swi_Invalid @ 0x21_MusicPlayerStart
|
||
|
.word swi_Invalid @ 0x22_MusicPlayerStop
|
||
|
.word swi_MusicPlayerContinue @ 0x23_MusicPlayerContinue
|
||
|
.word swi_MusicPlayerFadeOut @ 0x24_MusicPlayerFadeOut
|
||
|
.word swi_Invalid @ 0x25_MultiBoot
|
||
|
.word swi_Invalid @ 0x26_HardReset
|
||
|
.word swi_CustomHalt @ 0x27_CustomHalt
|
||
|
.word swi_Invalid @ 0x28_SoundDriverVSyncOff
|
||
|
.word swi_Invalid @ 0x29_SoundDriverVSyncOn
|
||
|
.word swi_SoundGetJumpList @ 0x2A_SoundGetJumpList
|
||
|
|
||
|
@---------------------------------------------------------------------------------
|
||
|
.global swi_Invalid
|
||
|
.type swi_Invalid STT_FUNC
|
||
|
swi_Invalid:
|
||
|
@---------------------------------------------------------------------------------
|
||
|
@ Infinite loop for now
|
||
|
@b swi_Invalid
|
||
|
|
||
|
@ Do nothing for release builds
|
||
|
bx lr
|
||
|
@---------------------------------------------------------------------------------
|