8.2.6 Initialization of RAM area section

Copy initial values to "data attribute" areas which are areas with initial values and clear "bss attribute" areas which are areas without initial values to 0. This processing is not required when there is no area that needs to be initialized before program execution.

 

First, instruct generation of initial value data with the -rom option of the optimizing linker, and define the RAM area section to where data is to be copied. For details, see "8.4 ROMization".

The defined RAM area section is written to the startup routine as follows.

.SECTION        .dataR, DATA
.SECTION        .sdataR, DATA

 

Next, in the startup routine, write a code to initialize the bss attribute areas.

When initializing sections .bss and .sbss to 0, the code will be as follows.

        ; clear external variables which doesn't have initial value (near)
        MOVW    HL,#LOWW(STARTOF(.bss))
        CMPW    AX,#LOWW(STARTOF(.bss) + SIZEOF(.bss))
        BR      $.L2_BSS
.L1_BSS:
        MOV     [HL+0],#0
        INCW    HL
.L2_BSS:
        CMPW    AX,HL
        BNZ     $.L1_BSS
 
        ; clear saddr variables which doesn't have initial value
        MOVW    HL,#LOWW(STARTOF(.sbss))
        CMPW    AX,#LOWW(STARTOF(.sbss) + SIZEOF(.sbss))
        BR      $.L2_SBSS
.L1_SBSS:
        MOV     [HL+0],#0
        INCW    HL
.L2_SBSS:
        CMPW    AX,HL
        BNZ     $.L1_SBSS

 

Then, in the startup routine, write a code to copy data attribute areas to the RAM area section.

When copying sections .data and .sdata to .dataR and .sdataR, respectively, the code will be as follows. Note that the copy routine does not support a section that exceeds the 64-Kbyte boundary.

        ; copy external variables having initial value (near)
        MOV     ES,#HIGHW(STARTOF(.data))
        MOVW    BC,#LOWW(SIZEOF(.data))
        BR      $.L2_DATA
.L1_DATA:
        DECW    BC
        MOV     A,ES:LOWW(STARTOF(.data))[BC]
        MOV     LOWW(STARTOF(.dataR))[BC],A
.L2_DATA:
        CLRW    AX
        CMPW    AX,BC
        BNZ     $.L1_DATA
 
        ; copy saddr variables having initial value
        MOV     ES,#HIGHW(STARTOF(.sdata))
        MOVW    BC,#LOWW(SIZEOF(.sdata))
        BR      $.L2_SDATA
.L1_SDATA:
        DECW    BC
        MOV     A,ES:LOWW(STARTOF(.sdata))[BC]
        MOV     LOWW(STARTOF(.sdataR))[BC],A
.L2_SDATA:
        CLRW    AX
        CMPW    AX,BC
        BNZ     $.L1_SDATA

 

Write a program for zero-initializing the RAM area section and copying sections in the C language, and this program can be called from the startup routine.

        ; initializing RAM section
        CALL    !!_INITSCT_RL

 

A C language example of a function for initializing the RAM area section is given below.

#define BSEC_MAX        2           /*Number of BSS sections to be initialized to 0*/
#define DSEC_MAX        2           /*Number of DATA sections to be copied*/
 
const struct bsec_t {
        char __near *ram_sectop;        /*Start address of section*/
        char __near *ram_secend;        /*End address + 1 of section*/
} bsec_table[BSEC_MAX] = {
        {(char __near *)__sectop(".bss"),
         (char __near *)__secend(".bss")},
        {(char __near *)__sectop(".sbss"),
         (char __near *)__secend(".sbss")}};
 
const struct dsec_t {
        char __far *rom_sectop;         /*Start address of copy source section*/
        char __far *rom_secend;         /*End address + 1 of copy source section*/
        char __near *ram_sectop;        /*Start address of copy destination section*/
} dsec_table[DSEC_MAX] = {
        {__sectop(".data"),
         __secend(".data"),
         (char __near *)__sectop(".dataR")},
        {__sectop(".sdata"),
         __secend(".sdata"),
         (char __near *)__sectop(".sdataR")}};
 
void INITSCT_RL(void)
{
        unsigned int i;
        char __far *rom_p;
        char __near *ram_p;
 
        for (i = 0; i < BSEC_MAX; i++) {
                ram_p = bsec_table[i].ram_sectop;
                for ( ; ram_p != bsec_table[i].ram_secend; ram_p++) {
                        *ram_p = 0;
                }
        }
        for (i = 0; i < DSEC_MAX; i++) {
                rom_p = dsec_table[i].rom_sectop;
                ram_p = dsec_table[i].ram_sectop;
                for ( ; rom_p != dsec_table[i].rom_secend; rom_p++, ram_p++) {
                        *ram_p = *rom_p;
                }
        }
}