From 16c266b1e721fdd7e691a84f15bd0ad50019a683 Mon Sep 17 00:00:00 2001 From: RichardBarry Date: Mon, 9 Feb 2009 20:05:59 +0000 Subject: [PATCH] Update startup file to workaround bug in IAR provided file. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@695 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Demo/NEC_78K0R_IAR/cstartup.s26 | 659 ++++++++++++++++++++++++++++++++ 1 file changed, 659 insertions(+) create mode 100644 Demo/NEC_78K0R_IAR/cstartup.s26 diff --git a/Demo/NEC_78K0R_IAR/cstartup.s26 b/Demo/NEC_78K0R_IAR/cstartup.s26 new file mode 100644 index 000000000..1bef12d24 --- /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 -- 2.39.5