8.2.6.1 初期化テーブルを利用したRAM領域セクションの初期化処理【V1.12以降】
V1.12以降では,リンカに-ram_init_table_sectionを指定することにより,RAM領域セクションを初期化するための情報を持つテーブルを実行形式に埋め込むことができます。
テーブルの各レコード(行)は初期化対象のセクションに対応し,次のフィールドを持ちます。
|
|
|
|
|
フィールド1
|
4byte
|
初期値データの先頭アドレス
|
セクション先頭アドレス
|
0
|
フィールド2
|
2byte
|
セクション・サイズ
|
セクション・サイズ
|
0
|
フィールド3
|
2byte
|
セクション先頭アドレス
|
セクション先頭アドレス
|
0
|
詳細は,リンク・オプションの-ram_init_table_sectionを参照してください。
> rlink a.obj b.obj -form=absolute -output=a.abs -rom=.data=.dataR
-rom=.sdata=.sdataR -ram_init_table_section
|
リンカが生成したテーブルを用いてRAMを初期化するには,前述のbss属性領域の初期化コード,data属性領域の初期化コードのかわりに,次のようなコードを使用します。
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
|
C言語で初期化関数を作成して,スタートアップ・ルーチン内から呼び出すことも可能です。
ただし,スタック領域を初期化しないよう注意してください。
スタートアップ・ルーチン内:
初期化関数:
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++;
}
}
}
}
|