198 lines
4.6 KiB
ArmAsm
198 lines
4.6 KiB
ArmAsm
.global _start
|
|
_start:
|
|
# START Interrupt Vector Table [[
|
|
jmp __PMSIZE-4 # RESET Vector
|
|
jmp interrupt_33 # Watchdog reset vector
|
|
jmp interrupt_0
|
|
jmp interrupt_1
|
|
jmp interrupt_2
|
|
jmp interrupt_3
|
|
jmp interrupt_4
|
|
jmp interrupt_5
|
|
jmp interrupt_6
|
|
jmp interrupt_7
|
|
jmp interrupt_8
|
|
jmp interrupt_9
|
|
jmp interrupt_10
|
|
jmp interrupt_11
|
|
jmp interrupt_12
|
|
jmp interrupt_13
|
|
jmp interrupt_14
|
|
jmp interrupt_15
|
|
jmp interrupt_16
|
|
jmp interrupt_17
|
|
jmp interrupt_18
|
|
jmp interrupt_19
|
|
jmp interrupt_20
|
|
jmp interrupt_21
|
|
jmp interrupt_22
|
|
jmp interrupt_23
|
|
jmp interrupt_24
|
|
jmp interrupt_25
|
|
jmp interrupt_26
|
|
jmp interrupt_27
|
|
jmp interrupt_28
|
|
jmp interrupt_29
|
|
jmp interrupt_30
|
|
jmp interrupt_31
|
|
jmp __PMSIZE-8 # Interrupt vector 32 (NMI)
|
|
# ]] END Interrupt Vector Table
|
|
|
|
codestart:
|
|
jmp init
|
|
|
|
.global _exithook
|
|
_exithook: # Debugger uses '_exithook' at 0x90 to catch program exit
|
|
return
|
|
|
|
init:
|
|
ldk $sp,__RAMSIZE
|
|
# Disable all interrupts
|
|
lda $r1,0x10000
|
|
lshr $r1,$r1,20
|
|
cmp $r1,0x90
|
|
ldk $r1,0x100e3 # FT900 IRQ Control Register
|
|
jmpc z,1f
|
|
ldk $r1,0x10123 # FT930 IRQ Control Register
|
|
1:
|
|
ldk $r4,0x80
|
|
sti.b $r1,0,$r4
|
|
|
|
# Initialize DATA by copying from program memory
|
|
ldk.l $r4,__data_load_start
|
|
ldk.l $r1,__data_load_end
|
|
ldk.l $r2,0 # Will use __data after binutils patch
|
|
|
|
jmp .dscopy
|
|
.dsloop:
|
|
# Copy PM[$r4] to RAM $r2
|
|
lpmi.l $r3,$r4,0
|
|
sti.l $r2,0,$r3
|
|
add.l $r4,$r4,4
|
|
add.l $r2,$r2,4
|
|
.dscopy:
|
|
cmp.l $r4,$r1
|
|
jmpc lt,.dsloop
|
|
|
|
# Zero BSS
|
|
ldk.l $r4,_bss_start
|
|
ldk.l $r2,_end
|
|
sub.l $r2,$r2,$r4
|
|
ldk.l $r1,0
|
|
ldk $r3,32764
|
|
1:
|
|
cmp $r2,$r3
|
|
jmpc lt,2f
|
|
memset $r4,$r1,$r3
|
|
add $r4,$r4,$r3
|
|
sub $r2,$r2,$r3
|
|
jmp 1b
|
|
2:
|
|
memset $r4,$r1,$r2
|
|
|
|
sub.l $sp,$sp,24 # Space for the caller argument frame
|
|
call main
|
|
|
|
.equ EXITEXIT,0x1fffc
|
|
|
|
.global _exit
|
|
_exit:
|
|
sta.l EXITEXIT,$r0 # simulator end of test
|
|
jmp _exithook
|
|
|
|
# Macro to construct the interrupt stub code.
|
|
# it just saves r0, loads r0 with the int vector
|
|
# and branches to interrupt_common.
|
|
|
|
.macro inth i=0
|
|
interrupt_\i:
|
|
push $r0 # {
|
|
lda $r0,(vector_table + 4 * \i)
|
|
jmp interrupt_common
|
|
.endm
|
|
|
|
inth 0
|
|
inth 1
|
|
inth 2
|
|
inth 3
|
|
inth 4
|
|
inth 5
|
|
inth 6
|
|
inth 7
|
|
inth 8
|
|
inth 9
|
|
inth 10
|
|
inth 11
|
|
inth 12
|
|
inth 13
|
|
inth 14
|
|
inth 15
|
|
inth 16
|
|
inth 17
|
|
inth 18
|
|
inth 19
|
|
inth 20
|
|
inth 21
|
|
inth 22
|
|
inth 23
|
|
inth 24
|
|
inth 25
|
|
inth 26
|
|
inth 27
|
|
inth 28
|
|
inth 29
|
|
inth 30
|
|
inth 31
|
|
inth 32
|
|
inth 33
|
|
|
|
# On entry: r0, already saved, holds the handler function
|
|
interrupt_common:
|
|
push $r1 # {
|
|
push $r2 # {
|
|
push $r3 # {
|
|
push $r4 # {
|
|
push $r5 # {
|
|
push $r6 # {
|
|
push $r7 # {
|
|
push $r8 # {
|
|
push $r9 # {
|
|
push $r10 # {
|
|
push $r11 # {
|
|
push $r12 # {
|
|
push $cc # {
|
|
|
|
calli $r0
|
|
|
|
pop $cc # }
|
|
pop $r12 # }
|
|
pop $r11 # }
|
|
pop $r10 # }
|
|
pop $r9 # }
|
|
pop $r8 # }
|
|
pop $r7 # }
|
|
pop $r6 # }
|
|
pop $r5 # }
|
|
pop $r4 # }
|
|
pop $r3 # }
|
|
pop $r2 # }
|
|
pop $r1 # }
|
|
pop $r0 # } matching push in interrupt_0-31 above
|
|
reti
|
|
|
|
# Null function for unassigned interrupt to point at
|
|
.global nullvector
|
|
nullvector:
|
|
return
|
|
|
|
.section .data
|
|
.global vector_table
|
|
vector_table:
|
|
.rept 34
|
|
.long nullvector
|
|
.endr
|
|
|
|
|
|
.section .text
|
|
.global __gxx_personality_sj0
|
|
__gxx_personality_sj0:
|