8.2.6.1 Initialization of RAM area sections by using an initialization table [V1.12 or later]
In V1.12 or later, a table with the information required for initializing RAM area sections can be embedded in an executable file by specifying -ram_init_table_section for the linker.
Each record (row) of the table corresponds to the sections to be initialized and has the following fields.
|
|
|
|
|
Field 1
|
4 bytes
|
Start address of initial value data
|
Section start address
|
0
|
Field 2
|
2 bytes
|
Section size
|
Section size
|
0
|
Field 3
|
2 bytes
|
Section start address
|
Section start address
|
0
|
For details, see the description of the link option -ram_init_table_section.
> rlink a.obj b.obj -form=absolute -output=a.abs -rom=.data=.dataR
-rom=.sdata=.sdataR -ram_init_table_section
|
To initialize the RAM by using the table generated by the liker, use the following code instead of the initialization codes for the bss attribute areas and data attribute areas described above.
MOVW DE, #LOWW(STARTOF(.ram_init_table))
MOV A, #LOW(HIGHW(STARTOF(.ram_init_table)))
PUSH AX
PUSH DE
.TABLE_LOOP:
MOV A, [SP+0x03]
MOV ES, A
MOVW AX, [SP+0x00]
MOVW DE, AX
CLRB B
# src_lo
CALL $!.GET_RAM_INIT_RECORD
PUSH AX
# src_hi
CALL $!.GET_RAM_INIT_RECORD
PUSH AX
# size
CALL $!.GET_RAM_INIT_RECORD
PUSH AX
# dest
CALL $!.GET_RAM_INIT_RECORD
PUSH AX
CMP0 B
BZ $.RETURN
MOVW AX, DE
MOVW [SP+0x08], AX
MOV A, ES
MOV [SP+0x0B], A
|
# dest
POP DE
# size
POP BC
# src_hi
POP AX
MOV A, X
MOV ES, A
# src_lo
POP HL
MOVW AX, DE
CMPW AX, HL
BNZ $.COPY
MOV A, ES
CMP A, #0xF
BNZ $.COPY
.CLEAR:
MOVW AX, BC
OR A, X
BZ $.TABLE_LOOP
DECW BC
CLRB A
MOV [DE], A
INCW DE
BR $.CLEAR
.COPY:
MOVW AX, BC
OR A, X
BZ $.TABLE_LOOP
DECW BC
MOV A, ES:[HL]
MOV [DE], A
INCW HL
INCW DE
BR $.COPY
.RETURN:
ADDW SP, #0x0C
RET
.GET_RAM_INIT_RECORD:
MOVW AX, ES:[DE]
MOVW HL, AX
OR A, X
OR B, A
MOVW AX, DE
ADDW AX, #0x0002
MOVW DE, AX
MOV A, ES
ADDC A, #0
MOV ES, A
MOVW AX, HL
RET
|
It is also possible to create an initialization function in C language, and call it in the startup routine. However, take care not to initialize the stack area.
Write as follows in the startup routine:
Initialization function:
typedef unsigned char __far * src_ptr;
typedef unsigned short src_len;
typedef unsigned char __near * dest_ptr;
struct table {
src_ptr src;
src_len len;
dest_ptr dest;
};
typedef struct table __far * table_ptr;
void ram_init(void)
{
table_ptr record;
for(record = __sectop(".ram_init_table"); ; record++)
{
src_ptr src = record->src;
src_len len = record->len;
dest_ptr dest = record->dest;
if(src == 0 && len == 0 && dest == 0) /* END OF RECORD */
break;
if(src == dest)
{
/* RAM CLEAR */
while(len--)
{
*dest = 0;
dest++;
}
}
else
{
/* ROM -> RAM COPY */
while(len--)
{
*dest = *src;
src++;
dest++;
}
}
}
}
|