summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2009-02-09 20:05:59 +0000
committerRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2009-02-09 20:05:59 +0000
commitb6d774475fabab710bd8f43e0d6da532553c3fbf (patch)
treec5f5bfac721c48e57a85466063bb6ec122fccaee
parent5c2a7714b78d121630d33c25309adbe8e305ec0c (diff)
downloadfreertos-b6d774475fabab710bd8f43e0d6da532553c3fbf.tar.gz
freertos-b6d774475fabab710bd8f43e0d6da532553c3fbf.tar.bz2
freertos-b6d774475fabab710bd8f43e0d6da532553c3fbf.tar.xz
Update startup file to workaround bug in IAR provided file.
git-svn-id: https://freertos.svn.sourceforge.net/svnroot/freertos/trunk@695 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
-rw-r--r--Demo/NEC_78K0R_IAR/cstartup.s26659
1 files changed, 659 insertions, 0 deletions
diff --git a/Demo/NEC_78K0R_IAR/cstartup.s26 b/Demo/NEC_78K0R_IAR/cstartup.s26
new file mode 100644
index 00000000..1bef12d2
--- /dev/null
+++ b/Demo/NEC_78K0R_IAR/cstartup.s26
@@ -0,0 +1,659 @@
+;
+; This file should only be included in the 78K0R_Kx3L demo. The 78K0R_Kx3 demo
+; uses the standard startup file. This is work around a bug in the startup
+; file provided with the IAR tools.
+;
+
+
+;------------------------------------------------------------------------------
+; CSTARTUP source for 78K
+;
+; This module contains the code executed before the C/C++ "main"
+; function is called.
+;
+; The code usually must be tailored to suit a specific hardware
+; configuration.
+;
+; Assembler options:
+;
+; -D__STANDARD_MODEL__ To assemble for use with compiler standard
+; code model.
+;
+; -D__BANKED_MODEL__ To assemble for use with compiler banked
+; code model.
+;
+; -D__NEAR_MODEL__ To assemble for use with compiler near
+; code model.
+;
+; -D__FAR_MODEL__ To assemble for use with compiler far
+; code model.
+;
+; Linker options:
+;
+; -D_CODEBANK_REG=0 To link for use with "standard" code model,
+; no banked functions.
+;
+; -D_CODEBANK_REG='addr' To link for use with "banked" code model or
+; "standard" code model with banked functions.
+; 'addr' = bank switch register address.
+;
+;------------------------------------------------------------------------------
+; Copyright (c) 2003-2008 IAR Systems AB.
+; $Revision: 3577 $
+;------------------------------------------------------------------------------
+
+#if !defined(__STANDARD_MODEL__) && !defined(__BANKED_MODEL__) && !defined(__NEAR_MODEL__) && !defined(__FAR_MODEL__)
+ #error One of the macros __STANDARD_MODEL__, __BANKED_MODEL__, __NEAR_MODEL__ or __FAR_MODEL__ must be defined !
+#endif
+
+;------------------------------------------------------------------------------
+; The stack segment.
+; The stack size is defined in the linker command file
+;------------------------------------------------------------------------------
+
+ MODULE ?CSTARTUP
+
+ RSEG CSTACK:DATA:ROOT(1)
+
+
+;------------------------------------------------------------------------------
+; The interrupt vector segment.
+; Interrupt functions with defined vectors will reserve
+; space in this area as well as conformingly written assembly
+; language interrupt handlers
+;------------------------------------------------------------------------------
+
+ COMMON INTVEC:CODE:ROOT(1)
+
+ DC16 __program_start_fr ; Reset vector
+
+
+;------------------------------------------------------------------------------
+; The actual startup code
+;
+; Entry: __program_start
+;------------------------------------------------------------------------------
+
+ RSEG RCODE:CODE:ROOT(0)
+
+ PUBLIC ?C_STARTUP
+ PUBLIC `@cstart` ; NEC debugger specific
+ PUBLIC __program_start_fr
+
+ EXTERN __low_level_init
+ EXTERN __MAIN_CALL
+
+#if defined(__STANDARD_MODEL__) || defined(__BANKED_MODEL__)
+ EXTERN _CODEBANK_REG
+#else
+ EXTERN _NEAR_CONST_LOCATION
+PMC DEFINE 0xFFFFE
+#endif
+#if defined(__BANKED_MODEL__)
+ EXTERN ?FAR_CALL_L07
+
+ SFRTYPE BANK_REG BYTE, READ, WRITE = _CODEBANK_REG
+#endif
+
+ REQUIRE __MAIN_CALL
+
+
+;------------------------------------------------------------------------------
+; Perform the run-time initialization.
+;------------------------------------------------------------------------------
+
+?C_STARTUP:
+`@cstart`:
+__program_start_fr:
+ DI
+
+#if defined(__BANKED_MODEL__)
+ MOV BANK_REG, #0 ; Banked, clear bank register
+#elif defined(__STANDARD_MODEL__)
+ MOVW AX, #_CODEBANK_REG
+ OR A, X
+ BZ nobank ; Standard, no banked functions, no bank register (=0)
+ MOVW HL, #_CODEBANK_REG
+ XOR A, A
+ MOV [HL], A ; Standard with banked functions, clear bank register
+nobank:
+#else
+ MOV A, #(_NEAR_CONST_LOCATION & 1) ; Near/Far, set mirror area
+ MOV1 CY, A.0
+ MOV1 PMC.0, CY
+#endif
+
+#if __CORE__ != __78K0S__
+ MOVW SP, #sfe(CSTACK)
+#else
+ MOVW AX, #sfe(CSTACK)
+ MOVW SP, AX
+#endif
+
+
+ ; Init stack segment for 78K0R, as the generated code may sometimes
+ ; access the 4th byte of a return address before it is initialized
+#if __CORE__ == __78K0R__
+ MOVW HL, #sfb(CSTACK)
+ MOVW BC, #LWRD(sizeof(CSTACK))
+ CMP0 C
+ SKZ
+ INC B
+ MOV A, #0xCD
+loop_s:
+ MOV [HL], A
+ INCW HL
+ DEC C
+ BNZ loop_s
+ DEC B
+ BNZ loop_s
+#endif
+
+#if __CORE__ == __78K0R__
+ MOV CS, #0
+#endif
+
+;------------------------------------------------------------------------------
+; Here is the place to put user initializations.
+;------------------------------------------------------------------------------
+
+; User initialization code
+
+;------------------------------------------------------------------------------
+; Call __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: to do nothing but return 1.
+;------------------------------------------------------------------------------
+
+#if defined(__FAR_MODEL__)
+ CALL F:__low_level_init
+#elif defined(__BANKED_MODEL__)
+ MOV E, #byte3(__low_level_init)
+ MOVW HL, #lwrd(__low_level_init)
+ CALL ?FAR_CALL_L07
+#else
+ CALL __low_level_init
+#endif
+ OR A, X
+#if __CORE__ == __78K0R__
+ SKNZ
+ BR N:__MAIN_CALL
+#else
+ BZ __MAIN_CALL
+#endif
+ ENDMOD
+
+#if defined(__NEAR_MODEL__) || defined(__FAR_MODEL__)
+;------------------------------------------------------------------------------
+; Segment initialization
+;
+; FAR_Z "uninitialized far data" are filled with zero
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_FAR_Z
+
+ RSEG FAR_Z:DATA(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_FAR_Z
+
+__INIT_FAR_Z:
+ MOV ES, #BYTE3(sfb(FAR_Z))
+ MOVW HL, #LWRD(sfb(FAR_Z))
+ MOV D, #BYTE3(sizeof(FAR_Z))
+ MOVW BC, #LWRD(sizeof(FAR_Z))
+ CMP0 C
+ SKZ
+ INC B
+ CMP0 B
+ SKZ
+ INC D
+ CLRB A
+loop:
+ MOV ES:[HL], A
+ INCW HL
+ MOV A, H
+ OR A, L
+ CLRB A
+ SKNZ
+ INC ES
+ DEC C
+ BNZ loop
+ DEC B
+ BNZ loop
+ DEC D
+ BNZ loop
+
+ ENDMOD
+#endif
+
+
+;------------------------------------------------------------------------------
+; Segment initialization
+;
+; NEAR_Z "uninitialized near data" are filled with zero
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_NEAR_Z
+
+ RSEG NEAR_Z:DATA(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_NEAR_Z
+
+__INIT_NEAR_Z:
+#if __CORE__ == __78K0R__
+ LIMIT sfb(NEAR_Z)>=0xF0000,1,1,"NEAR_I not placed in near memory"
+#endif
+ MOVW HL, #sfb(NEAR_Z)
+ MOVW BC, #sizeof(NEAR_Z)
+#if __CORE__ == __78K0R__
+ CMP0 C
+ SKZ
+ INC B
+ CLRB A
+#else
+ MOV A, C
+ OR A, A
+ BZ cont
+ INC B
+ XOR A, A
+cont:
+#endif
+loop:
+ MOV [HL], A
+ INCW HL
+#if __CORE__ == __78K0R__
+ DEC C
+ BNZ loop
+ DEC B
+ BNZ loop
+#else
+ DBNZ C, loop
+ DBNZ B, loop
+#endif
+
+ ENDMOD
+
+
+;------------------------------------------------------------------------------
+; Segment initialization
+;
+; SADDR_Z "uninitialized saddr data" are filled with zero
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_SADDR_Z
+
+ RSEG SADDR_Z:DATA(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_SADDR_Z
+
+__INIT_SADDR_Z:
+#if __CORE__ == __78K0R__
+ LIMIT sfb(SADDR_Z),0xFFE20,0xFFF1F,"SADDR_Z not within saddr memory range"
+ LIMIT sfe(SADDR_Z),0xFFE20,0xFFF1F,"SADDR_Z not within saddr memory range"
+#else
+ LIMIT sfb(SADDR_Z),0xFE20,0xFF1F,"SADDR_Z not within saddr memory range"
+ LIMIT sfe(SADDR_Z),0xFE20,0xFF1F,"SADDR_Z not within saddr memory range"
+#endif
+ MOVW HL, #sfb(SADDR_Z)
+ MOV B, #sizeof(SADDR_Z)
+#if __CORE__ == __78K0R__
+ CLRB A
+#else
+ XOR A, A
+#endif
+loop:
+ MOV [HL], A
+ INCW HL
+#if __CORE__ == __78K0R__
+ DEC B
+ BNZ loop
+#else
+ DBNZ B, loop
+#endif
+
+ ENDMOD
+
+
+;------------------------------------------------------------------------------
+; Segment initialization
+;
+; WRKSEG short address work area is filled with zero
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_WRKSEG
+
+ RSEG WRKSEG:DATA(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_WRKSEG
+
+__INIT_WRKSEG:
+#if __CORE__ == __78K0R__
+ LIMIT sfb(WRKSEG),0xFFE20,0xFFF1F,"WRKSEG not within saddr memory range"
+ LIMIT sfe(WRKSEG),0xFFE20,0xFFF1F,"WRKSEG not within saddr memory range"
+#else
+ LIMIT sfb(WRKSEG),0xFE20,0xFF1F,"WRKSEG not within saddr memory range"
+ LIMIT sfe(WRKSEG),0xFE20,0xFF1F,"WRKSEG not within saddr memory range"
+#endif
+ MOVW HL, #sfb(WRKSEG)
+ MOV B, #sizeof(WRKSEG)
+#if __CORE__ == __78K0R__
+ CLRB A
+#else
+ XOR A, A
+#endif
+loop:
+ MOV [HL], A
+ INCW HL
+#if __CORE__ == __78K0R__
+ DEC B
+ BNZ loop
+#else
+ DBNZ B, loop
+#endif
+
+ ENDMOD
+
+
+#if defined(__NEAR_MODEL__) || defined(__FAR_MODEL__)
+;------------------------------------------------------------------------------
+; Segment initialization
+;
+; FAR_ID is copied to FAR_I "initialized far data"
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_FAR_I
+
+ RSEG FAR_I:DATA(0)
+ RSEG FAR_ID:DATA(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_FAR_I
+
+__INIT_FAR_I:
+ ; First make sure FAR_I and FAR_ID have the same size
+ LIMIT sizeof(FAR_I)-sizeof(FAR_ID),0,0,"FAR_I and FAR_ID not same size"
+
+ ; Sanity check
+ LIMIT (sfb(FAR_I)-sfb(FAR_ID))==0,0,0,"FAR_I and FAR_ID have same start address"
+
+ ; FAR_I and FAR_ID must start at the same offset in a 64k page, unless sizeof
+ ; FAR_I is less than 64k, then it's enugh if both segments reside within a 64k
+ ; boundary
+ LIMIT (((sfb(FAR_I)^sfb(FAR_ID)) & 0xFFFF) == 0) || ( (sizeof(FAR_I)< 0x10000) && (((sfb(FAR_I)^sfe(FAR_I)) & 0xF0000) == 0) && (((sfb(FAR_I)^sfe(FAR_I)) & 0xF0000) == 0) ),1,1,"FAR_I and FAR_ID have same start address"
+
+
+
+ ; LIMIT (sfb(FAR_I)^sfb(FAR_ID)) & 0xFFFF,0,0,"FAR_I and FAR_ID must start at the same offset into a 64k page"
+ MOV ES, #BYTE3(sfb(FAR_ID))
+ MOVW HL, #LWRD(sfb(FAR_ID))
+ MOV CS, #BYTE3(sizeof(FAR_ID)) ; CS is used as counter
+ MOVW AX, #LWRD(sizeof(FAR_ID))
+ MOVW BC, AX
+ CMP0 C
+ SKZ
+ INC B
+ CMP0 B
+ SKZ
+ INC CS ; counter
+ MOV A, #BYTE3(sfb(FAR_I))
+ MOVW DE, #LWRD(sfb(FAR_I))
+ MOV X, A
+loop:
+ MOV A, ES:[HL]
+ XCH A, X
+ XCH A, ES
+ XCH A, X
+ MOV ES:[DE], A
+ XCH A, X
+ XCH A, ES
+ XCH A, X
+ INCW HL
+ MOV A, H
+ OR A, L
+ SKNZ
+ INC ES
+ INCW DE
+ MOV A, D
+ OR A, E
+ SKNZ
+ INC X
+ DEC C
+ BNZ loop
+ DEC B
+ BNZ loop
+ DEC CS ; counter
+ BNZ loop
+
+ ENDMOD
+#endif
+
+
+;------------------------------------------------------------------------------
+; Segment initialization
+;
+; NEAR_ID is copied to NEAR_I "initialized near data"
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_NEAR_I
+
+ RSEG NEAR_I:DATA(0)
+ RSEG NEAR_ID:DATA(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_NEAR_I
+
+__INIT_NEAR_I:
+#if __CORE__ == __78K0R__
+ LIMIT sfb(NEAR_I)>=0xF0000,1,1,"NEAR_I not placed in near memory"
+#endif
+ LIMIT sizeof(NEAR_I)-sizeof(NEAR_ID),0,0,"NEAR_I and NEAR_ID not same size"
+#if __CORE__ == __78K0R__
+ MOV ES, #BYTE3(sfb(NEAR_ID))
+#endif
+ MOVW HL, #sfb(NEAR_ID)
+ MOVW BC, #sizeof(NEAR_ID)
+#if __CORE__ == __78K0R__
+ CMP0 C
+ SKZ
+ INC B
+#else
+ MOV A, C
+ OR A, A
+ BZ cont
+ INC B
+cont:
+#endif
+ MOVW DE, #sfb(NEAR_I)
+loop:
+#if __CORE__ != __78K0R__
+ MOV A, [HL]
+#else
+ MOV A, ES:[HL]
+#endif
+ MOV [DE], A
+ INCW HL
+ INCW DE
+#if __CORE__ == __78K0R__
+ DEC C
+ BNZ loop
+ DEC B
+ BNZ loop
+#else
+ DBNZ C, loop
+ DBNZ B, loop
+#endif
+
+ ENDMOD
+
+
+;------------------------------------------------------------------------------
+; Segment initialization
+;
+; SADDR_ID is copied to SADDR_I "initialized saddr data"
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_SADDR_I
+
+ RSEG SADDR_I:DATA(0)
+ RSEG SADDR_ID:DATA(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_SADDR_I
+
+__INIT_SADDR_I:
+#if __CORE__ == __78K0R__
+ LIMIT sfb(SADDR_I),0xFFE20,0xFFF1F,"SADDR_I not within saddr memory range"
+ LIMIT sfe(SADDR_I),0xFFE20,0xFFF1F,"SADDR_I not within saddr memory range"
+#else
+ LIMIT sfb(SADDR_I),0xFE20,0xFF1F,"SADDR_I not within saddr memory range"
+ LIMIT sfe(SADDR_I),0xFE20,0xFF1F,"SADDR_I not within saddr memory range"
+#endif
+ LIMIT sizeof(SADDR_I)-sizeof(SADDR_ID),0,0,"SADDR_I and SADDR_ID not same size"
+#if __CORE__ == __78K0R__
+ MOV ES, #BYTE3(sfb(SADDR_ID))
+#endif
+ MOVW HL, #sfb(SADDR_ID)
+ MOV B, #sizeof(SADDR_ID)
+ MOVW DE, #sfb(SADDR_I)
+loop:
+#if __CORE__ != __78K0R__
+ MOV A, [HL]
+#else
+ MOV A, ES:[HL]
+#endif
+ MOV [DE], A
+ INCW HL
+ INCW DE
+#if __CORE__ == __78K0R__
+ DEC B
+ BNZ loop
+#else
+ DBNZ B, loop
+#endif
+
+ ENDMOD
+
+
+;------------------------------------------------------------------------------
+; Initialize constructors
+;
+; This segment part is required by the compiler when it is
+; necessary to call constructors of global objects.
+;------------------------------------------------------------------------------
+
+ MODULE ?__INIT_CTORS
+
+ RSEG DIFUNCT(0)
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __INIT_CTORS
+
+ EXTERN __call_ctors
+#if defined(__BANKED_MODEL__)
+ EXTERN ?FAR_CALL_L07
+#endif
+
+__INIT_CTORS:
+#if __CORE__ == __78K0R__
+ MOV X, #byte3(sfe(DIFUNCT))
+ PUSH AX
+ MOVW AX, #lwrd(sfe(DIFUNCT))
+ PUSH AX
+ MOV X, #byte3(sfb(DIFUNCT))
+ PUSH AX
+ MOVW AX, #lwrd(sfb(DIFUNCT))
+ PUSH AX
+ CALL F:__call_ctors
+#elif defined(__BANKED_MODEL__)
+ MOVW AX, #sfb(DIFUNCT)
+ MOVW BC, #sfe(DIFUNCT)
+ MOV E, #byte3(__call_ctors)
+ MOVW HL, #lwrd(__call_ctors)
+ CALL ?FAR_CALL_L07
+#else
+ MOVW AX, #sfb(DIFUNCT)
+ MOVW BC, #sfe(DIFUNCT)
+ CALL __call_ctors
+#endif
+
+ ENDMOD
+
+
+;------------------------------------------------------------------------------
+; Enter main
+;
+; Call the actual "main" function
+;------------------------------------------------------------------------------
+
+ MODULE ?__MAIN_CALL
+
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __MAIN_CALL
+ PUBLIC `@cend` ; NEC debugger specific
+
+ EXTERN main
+ EXTERN exit
+#if defined(__BANKED_MODEL__)
+ EXTERN ?FAR_CALL_L07
+#endif
+
+__MAIN_CALL:
+#if defined(__FAR_MODEL__)
+ CALL F:main
+ CALL F:exit
+#elif defined(__BANKED_MODEL__)
+ MOV E, #byte3(main)
+ MOVW HL, #lwrd(main)
+ CALL ?FAR_CALL_L07
+
+ MOV E, #byte3(exit)
+ MOVW HL, #lwrd(exit)
+ CALL ?FAR_CALL_L07
+#else
+ CALL main
+ CALL exit
+#endif
+
+`@cend`:
+
+; STOP ; Should not return
+
+ ENDMOD
+
+
+;------------------------------------------------------------------------------
+; Low level initialization function
+;
+; Entry: __low_level_init
+;
+; The only action of this default version of '__low_level_init' is to
+; return 1. By doing so it signals that normal initialization of data
+; segments should be done.
+;
+; A customized version of '__low_level_init' may be created in order to
+; perform initialization before initializing segments and calling main
+; and/or to skip initialization of data segments under certain
+; circumstances.
+;------------------------------------------------------------------------------
+
+ MODULE ?__low_level_init_stub
+
+ RSEG RCODE:CODE:NOROOT(0)
+
+ PUBLIC __low_level_init
+
+__low_level_init: ; By returning 1 this function
+ MOVW AX, #1 ; indicates that the normal
+ RET ; initialization should take place
+
+ ENDMOD
+
+ END