]> git.sur5r.net Git - freertos/commitdiff
Update startup file to workaround bug in IAR provided file.
authorRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 9 Feb 2009 20:05:59 +0000 (20:05 +0000)
committerRichardBarry <RichardBarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 9 Feb 2009 20:05:59 +0000 (20:05 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@695 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/NEC_78K0R_IAR/cstartup.s26 [new file with mode: 0644]

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