Update startup file to workaround bug in IAR provided file.
diff --git a/Demo/NEC_78K0R_IAR/cstartup.s26 b/Demo/NEC_78K0R_IAR/cstartup.s26
new file mode 100644
index 0000000..1bef12d
--- /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