📄 cstart.asm
字号:
;***************************************************************************
;** *
;** FILE : cstart.asm *
;** *
;** DESCRIPTION : C startup code *
;** *
;** NOTE : When using EDE all macros are automatically set by the *
;** Project, Cpu and Bus configuration... dialog from the *
;** EDE menu. *
;** *
;** Copyright 1996-2006 Altium BV *
;** *
;**************************************************************************/
.global _START ; reset vector address
.global _start ; reset start address
.global _exit ; exit return address
.weak _Exit ; exit return address (weak definition)
.extern main ; start label user C program
.if !@DEF('_NO_EXIT')
.extern exit ; C library exit function
.endif
.if !@DEF('_NO_USP_INIT')
.extern _lc_ue_ustack ; user stack end
.endif
.if !@DEF('_NO_ISP_INIT')
.extern _lc_ue_istack ; interrupt stack end
.endif
.if !@DEF('_NO_BIV_INIT')
.extern (CODE) _lc_u_int_tab ; interrupt table
.endif
.if !@DEF('_NO_BTV_INIT')
.extern (CODE) _lc_u_trap_tab ; trap table
.endif
.if !@DEF('_NO_A0A1_ADDRESSING')
.extern (DATA) _SMALL_DATA_ ; centre of A0 addressable area
.extern (DATA) _LITERAL_DATA_ ; centre of A1 addressable area
.endif
.if !@DEF('_NO_A8A9_ADDRESSING')
.extern (DATA) _A8_DATA_ ; centre of A8 addressable area
.extern (DATA) _A9_DATA_ ; centre of A9 addressable area
.endif
.if !@DEF('_NO_C_INIT')
.extern _c_init ; C initialization function
.endif
.if @DEF('_SYNC_ON_HALT')
.extern _sync_on_halt ; CrossView utilty function
.endif
; Deviating naming conventions
;
.if @DEF('_REGTC1161_DEF') || @DEF('_REGTC1162_DEF') || @DEF('_REGTC1163_DEF') || @DEF('_REGTC1164_DEF') || @DEF('_REGTC1165_DEF') || @DEF('_REGTC1166_DEF') || @DEF('_REGTC1762_DEF') || @DEF('_REGTC1764_DEF') || @DEF('_REGTC1766B_DEF')
.define _REGTC1766_DEF '1'
.endif
.if @DEF('_REGTC11IB_DEF') || @DEF('_REGPXB4225_DEF')
WDT_CON0 .equ WDTCON0
WDT_CON1 .equ WDTCON1
.endif
.if @DEF('_REGPXB4260_DEF') || @DEF('_REGTC1775B_DEF') || @DEF('_REGTC1765_DEF')
EBU_ADDRSEL0 .equ EBU_ADDSEL0
EBU_ADDRSEL1 .equ EBU_ADDSEL1
EBU_ADDRSEL2 .equ EBU_ADDSEL2
EBU_ADDRSEL3 .equ EBU_ADDSEL3
.endif
.if @DEF('_REGPXB4260_DEF')
EBU_SDRMCON0 .equ EBU_DRMCON0
EBU_SDRMCON1 .equ EBU_DRMCON1
.endif
.if @DEF('_REGTC1100_DEF') || @DEF('_REGTC1115_DEF') || @DEF('_REGTC1130_DEF') || @DEF('_REGTC1766_DEF') || @DEF('_REGTC1792_DEF') || @DEF('_REGTC1796_DEF') || @DEF('_REGTC1796B_DEF')
DMU_CON .equ DMI_CON
.endif
.if @DEF('_REGTC1775B_DEF') || @DEF('_REGTC1765_DEF')
PMU_CON0 .equ PMU_CON
.endif
.if @DEF('_REGTC1766_DEF') || @DEF('_REGTC1792_DEF') || @DEF('_REGTC1796_DEF') || @DEF('_REGTC1796B_DEF')
PMU_CON0 .equ PMI_CON0
.endif
.if @DEF('_REGTC1100_DEF') || @DEF('_REGTC1115_DEF') || @DEF('_REGTC1130_DEF') || @DEF('_REGTC1766_DEF') || @DEF('_REGTC1792_DEF') || @DEF('_REGTC1796_DEF') || @DEF('_REGTC1796B_DEF')
S_BCU_CON .equ SBCU_CON
.endif
.if @DEF('_REGTC1910_DEF') || @DEF('_REGTC1912_DEF') || @DEF('_REGTC1920B_DEF')
S_BCU_CON .equ BCU_CON
.endif
.if @DEF('_REGTC11IB_DEF')
S_BCU_CON .equ BCU1_CON
F_BCU_CON .equ BCU0_CON
.endif
; macro for loading 32bit constants into address registers
CONST.A .MACRO ax,v
movh.a ax,#@his(v) ; high part with correction for signed addition
lea ax,[ax]@los(v)
.ENDM
; macro for loading 32bit constants into data registers
CONST.D .MACRO dx,v
movh dx,#@his(v)
addi dx,dx,#@los(v)
.ENDM
; macro for 32bit indirect call
CALL.I .MACRO ax,v
movh.a ax,#@his(v) ; high part with correction for signed addition
lea ax,[ax]@los(v) ; call function indirectly to have more
.if @DEF('__TC113_CPU16__') || @DEF('__CPU_TC048__')
nop
.endif
calli ax ; freedom with CODE section allocation
.ENDM
;
; Reset "vector"
; no .org: placed via the locator in appropriate boot section (see file tc.i)
;
.sdecl ".text.libc.reset",CODE
.sect ".text.libc.reset"
.align 4
; Turn CPU_TC065 CPU functional defect checking off in the reset vector
;
.if @DEF('__CPU_TC065__')
$CPU_TC065 OFF
.endif
_START:
;
; Turn TC113_CPU14 CPU functional defect checking off
;
.if @DEF('__TC113_CPU14__')
$TC113_CPU14 OFF
.endif
j _start
; Reset CPU_TC065 CPU functional defect checking after the reset vector
;
.if @DEF('__CPU_TC065__')
$CPU_TC065 ON
.endif
.align 4
;
; BOOTCFG
; External Boot Memory Configuration Word
; (Boot memory Offset Address + 0x4)
;
.if !(@DEF('_BOOTCFG_VALUE'))
_BOOTCFG_VALUE .equ 0x800C
.endif
.word ( _BOOTCFG_VALUE )
;
; argv[argc] of main() must yield 0
;
.if !@DEF('_NO_ARG_INIT')
.sdecl ".data.libc",DATA,ROM
.sect ".data.libc"
.align 4
argv_space:
.word 0
.endif
;
; Startup code at reset, residing in actual program space
;
.sdecl ".text.libc",CODE
.sect ".text.libc"
.align 4
_start:
.include "sibug_function_entry.inc"
;
; Re-enable and reset the call depth counter and make A0,A1,A8,A9
; write-able. It is required for CrossView that these RESET values are
; restored for each time the startup code is executed.
;
.if !@DEF('_NO_PSW_RESET')
mfcr d0,#PSW
andn d0,d0,#0x7f ; reset counter
insert d0,d0,#1,#7,#1 ; enable
insert d0,d0,#1,#8,#1 ; set GW bit
mtcr #PSW,d0
isync
.endif
;
; TC112_COR16 workaround (aka CPU_TC.033):
; The stack pointers are aligned to quad-word boundary
; to workaround the TC112_COR16 functional problem.
; Also the C compiler workaround for this CPU function problem
; need to be enabled with --silicon-bug=cpu-tc033, to align circular
; buffers on a quad-word boundary and to size all stack
; frames to an integral number of quad-words.
;
.if ( @DEF('__TC112_COR16__') || @DEF('__CPU_TC033__') )
STACK_ALIGN .equ 0xfffffff0
.else
STACK_ALIGN .equ 0xfffffff8
.endif
;
; Load user stack pointer
;
; Disable this if not started from RESET vector. (E.g.
; ROM monitors require to keep in control of vectors)
;
.if !@DEF('_NO_USP_INIT')
CONST.D d0,_lc_ue_ustack ; initialize user stack pointer
CONST.D d7,STACK_ALIGN ; align label ue_ustack, note that
and d0,d7 ; ub_ustack is aligned by the locator
mov.a sp,d0
.endif
;
; Clear Previous Context Pointer Segment Address and Offset Field.
; It is required for CrossView stack trace that these RESET values
; are restored for each time the startup code is executed.
;
.if !@DEF('_NO_PCX_RESET')
mfcr d0,#PCXI
movh d1,#0xfff0
and16 d0,d1
mtcr #PCXI,d0
isync
.endif
;
; Setup the context save area lists
;
; Tables with start/end addresses go in a separate 'csa_areas' section
;
.if !@DEF('_NO_CSA_INIT')
;
.sdecl ".text.libc.csa_areas", CODE
.sect ".text.libc.csa_areas"
.align 4
.if @DEF('__CPU_TC051__')
MAX_NR_OF_CSA_AREAS .equ 3
.else
MAX_NR_OF_CSA_AREAS .equ 1
.endif
csa_area_begin: ; csa_area_begin[MAX_NR_OF_CSA_AREAS]
.if @DEF('__CPU_TC051__')
.extern _lc_ub_csa.01 ; context save area 1 begin
.extern _lc_ub_csa.02 ; context save area 2 begin
.extern _lc_ub_csa.03 ; context save area 3 begin
;
.word _lc_ub_csa.01
.word _lc_ub_csa.02
.word _lc_ub_csa.03
.else
.extern _lc_ub_csa.01 ; context save area 1 begin
;
.word _lc_ub_csa.01
.endif
csa_area_end: ; csa_area_end[MAX_NR_OF_CSA_AREAS]
.if @DEF('__CPU_TC051__')
.extern _lc_ue_csa.01 ; context save area 1 end
.extern _lc_ue_csa.02 ; context save area 2 end
.extern _lc_ue_csa.03 ; context save area 3 end
;
.word _lc_ue_csa.01
.word _lc_ue_csa.02
.word _lc_ue_csa.03
.else
.extern _lc_ue_csa.01 ; context save area end
;
.word _lc_ue_csa.01
.endif
;
; Resume with the original '.text.libc' section
;
.sect ".text.libc"
;
mov d0,#-1 ; D0 = index of CSA area, refered to as 'i'
j test_max_csa_areas
;
start_linked_list:
CONST.A a2,csa_area_begin ; first calculate nr. of CSAs in this area:
addsc.a a2,a2,d0,#2 ; get csa_area_begin[i]
CONST.A a3,csa_area_end
addsc.a a3,a3,d0,#2 ; get csa_area_end[i]
ld16.w d15,[a3] ; load csa_area_end[i] address
ld16.w d2,[a2] ; load csa_area_begin[i] address
sub d15,d2 ;
sh d15,#-6 ; (csa_area_begin-csa_area_end)/64
jz d15,test_max_csa_areas ; if no CSA in this area, then get next area
;
ld16.a a2,[a2] ; A2 = csa_area_begin[i] address
mov16.d d1,a2 ;
extr.u d1,d1,#28,#4 ; extract segment number
sh d1,d1,#16 ; D1 = shifted segment number
jnz d0,next_areas
;
first_area: ; Initialize the first time only:
mov16.d d3,a2 ; D3 = first CSA from first area
mov16 d2,#0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -