rt-thread/bsp/m16c62p/cstartup.s34

328 lines
9.6 KiB
Plaintext

;-----------------------------------------------------------------------
;
; This file contains the M16C C startup routine and must usually
; be tailored to suit customer's hardware.
;
; Copyright 2002 IAR Systems. All rights reserved.
;
; $Revision: 1.16 $
;
;-----------------------------------------------------------------------
MODULE ?cstart
PUBLIC __program_start
PUBLIC __data16_init
PUBLIC __data16_zero
PUBLIC ?cstart_call_ctors
EXTERN main
EXTERN exit
EXTERN __call_ctors
EXTERN __low_level_init
EXTERN ?GENERIC_MOVE_LONG_L08
EXTERN RelocatableVectTbl
;------------------------------------------------------
; Useful macros
;------------------------------------------------------
; Load 24-bit constant value to (high,low)
LD24 MACRO value,high,low
MOV.B #BYTE3(value),high
MOV.W #LWRD(value),low
ENDM
; Load 32-bit constant value to (high,low)
LD32 MACRO value,high,low
MOV.W #HWRD(value),high
MOV.W #LWRD(value),low
ENDM
; Load a stack-pointer with last even address of segment
LDSTACK MACRO segment,reg
LDC #sfe(segment), reg
ENDM
;------------------------------------------------------
; __program_start - Reset vector should point to here.
;
; Calls __low_level_init to perform initialization
; before initializing segments and calling main.
; If the function returns 0 no segment initialization
; should take place.
;
; Link with your own version of __low_level_init to
; override the default action: do nothing but return 1.
;------------------------------------------------------
RSEG CSTACK
RSEG ISTACK
RSEG CSTART:CODE:NOROOT
REQUIRE call_main
__program_start:
LDC #sfe(ISTACK), ISP ; Set up interrupt stack
FCLR U ; Select interrupt stack
LDC #sfe(CSTACK), SP ; Set up C stack
LDINTB #RelocatableVectTbl ; Set up INTB register
JSR.A __low_level_init ; Call __low_level_init
;-----------------------------------------------------------
; Run-time test whether we should do segment initialization
;-----------------------------------------------------------
TST.B R0L, R0L
JNE do_segment_init
JMP skip_segment_init
do_segment_init:
;------------------------------------------------------
; Perform segment initialization of DATA16 memory.
;------------------------------------------------------
RSEG DATA16_Z
RSEG CSTART:CODE:NOROOT
__data16_zero:
MOV.W #sizeof(DATA16_Z), R3
MOV.W #sfb(DATA16_Z), A1
MOV.B #0, R0L
SSTR.B
RSEG DATA16_I
RSEG DATA16_ID
RSEG CSTART:CODE:NOROOT
__data16_init:
MOV.W #sizeof(DATA16_ID), R3
MOV.W #sfb(DATA16_I), A1
LD24 sfb(DATA16_ID), R1H, A0
SMOVF.B
RSEG CSTART:CODE:NOROOT
skip_segment_init:
; Fall through to next required CSTART segment part
;------------------------------------------------------
; Call constructors
;------------------------------------------------------
RSEG DIFUNCT
RSEG CSTART:CODE:NOROOT
PUBLIC ?cstart_call_ctors
EXTERN __call_ctors
?cstart_call_ctors:
PUSH.W #HWRD(sfe(DIFUNCT))
PUSH.W #LWRD(sfe(DIFUNCT))
LD32 sfb(DIFUNCT),R2,R0
JSR.A __call_ctors
; Fall through to next required CSTART segment part
;------------------------------------------------------
; Call main and exit
;------------------------------------------------------
; This segment part is marked as ROOT, since it must
; be preserved by the linker.
;
RSEG CSTART:CODE:NOROOT
call_main:
MOV.W #0, R0 ; Call main with argc = 0
JSR.A main
JMP.A exit ; Argument to exit is return value of main
;------------------------------------------------------
; Fixed interrupt table.
;
; We install all fixed interrupts in a segment called
; INTVEC1. All fixed interrupts have a hard coded name.
; Write an interrupt handler in C using this name, with
; no vector specification, and it will replace the
; default handler.
;------------------------------------------------------
EXTERN __undefined_instruction_handler
EXTERN __overflow_handler
EXTERN __break_instruction_handler
EXTERN __address_match_handler
EXTERN __single_step_handler
EXTERN __watchdog_timer_handler
EXTERN __DBC_handler
EXTERN __NMI_handler
; Labels for the ID Code Check Function.
; (To be initialized in the linker file)
EXTERN _ID_CODE_1
EXTERN _ID_CODE_2
EXTERN _ID_CODE_3
EXTERN _ID_CODE_4
EXTERN _ID_CODE_5
EXTERN _ID_CODE_6
EXTERN _ID_CODE_7
EXTERN _OFS_VALUE
PUBLIC ??intvec_start
COMMON INTVEC1:NOROOT
??intvec_start:
DC24 __undefined_instruction_handler
DC8 _ID_CODE_1
DC24 __overflow_handler
DC8 _ID_CODE_2
DC24 __break_instruction_handler
DC8 0
DC24 __address_match_handler
DC8 _ID_CODE_3
DC24 __single_step_handler
DC8 _ID_CODE_4
DC24 __watchdog_timer_handler
DC8 _ID_CODE_5
DC24 __DBC_handler
DC8 _ID_CODE_6
DC24 __NMI_handler
DC8 _ID_CODE_7
DC24 __program_start ; Reset vector
DC8 _OFS_VALUE
ENDMOD
;------------------------------------------------------
; Default handlers for fixed interrupts
;------------------------------------------------------
MODULE __undefined_instruction
EXTERN ??reit
REQUIRE ??reit
PUBLIC __undefined_instruction_handler
RSEG CSTART:CODE:NOROOT(1)
__undefined_instruction_handler:
; Fall through to ??reit
ENDMOD
MODULE __overflow
EXTERN ??reit
REQUIRE ??reit
PUBLIC __overflow_handler
RSEG CSTART:CODE:NOROOT(1)
__overflow_handler:
; Fall through to ??reit
ENDMOD
MODULE __break_instruction
EXTERN ??reit
REQUIRE ??reit
PUBLIC __break_instruction_handler
RSEG CSTART:CODE:NOROOT(1)
__break_instruction_handler:
; Fall through to ??reit
ENDMOD
MODULE __address_match
EXTERN ??reit
REQUIRE ??reit
PUBLIC __address_match_handler
RSEG CSTART:CODE:NOROOT(1)
__address_match_handler:
; Fall through to ??reit
ENDMOD
MODULE __single_step
EXTERN ??reit
REQUIRE ??reit
PUBLIC __single_step_handler
RSEG CSTART:CODE:NOROOT(1)
__single_step_handler:
; Fall through to ??reit
ENDMOD
MODULE __watchdog_timer
EXTERN ??reit
REQUIRE ??reit
PUBLIC __watchdog_timer_handler
RSEG CSTART:CODE:NOROOT(1)
__watchdog_timer_handler:
; Fall through to ??reit
ENDMOD
MODULE __DBC
EXTERN ??reit
REQUIRE ??reit
PUBLIC __DBC_handler
RSEG CSTART:CODE:NOROOT(1)
__DBC_handler:
; Fall through to ??reit
ENDMOD
MODULE __NMI
EXTERN ??reit
REQUIRE ??reit
PUBLIC __NMI_handler
RSEG CSTART:CODE:NOROOT(1)
__NMI_handler:
; Fall through to ??reit
ENDMOD
;------------------------------------------------------
; Return from interrupt
;------------------------------------------------------
MODULE __reit
PUBLIC ??reit
RSEG CSTART:CODE:NOROOT(1)
EXTERN ??intvec_start
REQUIRE ??intvec_start
??reit:
REIT
ENDMOD
;------------------------------------------------------
; FUNCTION: __low_level_init
;
; You can replace this routine by linking with your
; own version.
;
; The default action is to do nothing and return 1.
;------------------------------------------------------
MODULE __low_level_init
PUBLIC __low_level_init
RSEG CSTART:CODE:NOROOT
__low_level_init:
MOV.B #1,R0L
RTS
ENDMOD
;------------------------------------------------------
; __overflow - This variable is used by the intrinsic
; functions __RMPA_W_overflow and
; __RMPA_B_overflow.
;------------------------------------------------------
MODULE __overflow
PUBLIC __overflow
EXTERN __data13_zero
RSEG DATA13_Z:NEAR:NOROOT
__overflow:
DC8 0
REQUIRE __data13_zero
END