# XSTORMY16 startup code

# Interrupt vectors at 0x8000.
	.section .int_vec,"ax"
	.global	_start
	.align 1
_start:
	;; Reset, watchdog timer interrupt
	jmpf _int_reset
	;; base timer interrupt
	jmpf _int_basetimer
	;; timer 0
	jmpf _int_timer0
	;; timer 1
	jmpf _int_timer1
	;; SIO0 interrupt
	jmpf _int_sio0
	;; SIO1 interrupt
	jmpf _int_sio1
	;; port0 interrupt
	jmpf _int_port0
	;; port1 interrupt
	jmpf _int_port1

# Reset code, set up memory and call main.
        .section        .rodata
2:	.word	__rdata
	.text
_int_reset:
	;; Set up the stack pointer.
	mov r0,#__stack
        bz  r0,#0,0f
	mov sp,r0
0:
	;; Zero the data space
	mov r0,#_edata
	mov r1,#_end
	mov r2,#0
0:	mov.w (r0++),r2
	blt r0,r1,0b

	;; Copy data from ROM into RAM.  ROM area may be above 64k,
	;; but RAM may not.
	mov r1,#__data
	mov r3,#_edata
	mov r4,#2b
	mov.w r0,(r4++)
	mov.w r2,(r4) 
	mov r8,r2
	;; If _data == _rdata there's no need to copy anything.
	bnz r0,r1,0f
	bz r2,#0,1f
0:	movf.w r2,(r0++)
	bnz r0,#0,2f
	add r8,#1
2:	mov.w (r1++),r2
	blt r1,r3,0b
1:	
	;; Call hardware init routine
	callf _hwinit
	;; Call initialization routines
	callf _init
	;; Set up fini routines to be called from exit
	mov r2,#@fptr(_fini)
	callf atexit
	;; Call main() with empty argc/argv/envp
	mov r2,#0
	mov r3,#0
	mov r4,#0
	callf main
	;; Exit.
	callf exit
	;; Should never reach this code.
	halt
1:	.size _int_reset,1b-_int_reset
		
# Stub interrupt routines.
	.globl _int_timer0
	.weak _int_timer0
	.globl _int_timer1
	.weak _int_timer1
	.globl _int_sio0
	.weak _int_sio0
	.globl _int_sio1
	.weak _int_sio1
	.globl _int_port0
	.weak _int_port0
	.globl _int_port1
	.weak _int_port1
	.globl _int_basetimer
	.weak _int_basetimer
_int_timer0:
_int_timer1:
_int_sio0:
_int_sio1:
_int_port0:
_int_port1:
_int_basetimer:
	iret
1:	.size _int_timer0,1b-_int_timer0

# Stub hardware init
	.globl _hwinit
	.weak _hwinit
_hwinit:
	ret
1:	.size _hwinit,1b-_hwinit

# The first word in .data has address 0, so it's not a good
# idea to use it as its address conflicts with NULL.
# Place a HALT instruction there to try to catch NULL pointer
# dereferences.
	.data
	halt
