Everything
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言語で初期化関数を作成して,スタートアップ・ルーチン内から呼び出すことも可能です。
ただし,スタック領域を初期化しないよう注意してください。

スタートアップ・ルーチン内:

CALL !!_ram_init

 

初期化関数:

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++;
   }
  }
 }
}