スパイス  組み込み制御装置の受注製作

モニタプログラムを移植する
平成26年4月 9日

モニタプログラムの雛形
 割り込み処理への対応方針が固まったことで、ほぼモニタプログラムの必要な機能は出揃いました。残りはモニタプログラムからユーザープログラムへ制御を移すGoコマンドの実装だけになります。
 最初に割り込み処理を終わらせます。モニタプログラムでは0番地からを除くROMアドレスからの割り込み実行を0x8000番地に配置したジャンプテーブルにジャンプさせます。0x8000番地にジャンプ命令を置くのはユーザープログラムで行います(理由はこのアドレス領域はユーザー領域だからです)。スタートアップルーチンstart.xasを下記のように変更します。重要な変更箇所は太字で示してあります。
変更後のstart.xasリスト
   EXTNAL  _DATA_SIZE  ; 初期値のあるデータのサイズ
   EXTNAL  _DATA_TOP   ; 初期値のあるデータのアドレス(RAM)上
   EXTNAL  _BSS_SIZE   ; 初期値のないデータのサイズ
   EXTNAL  _BSS_TOP    ; 初期値のないデータのアドレス(RAM)上
   EXTNAL  _main
;
;-------------------------------+
;   Stack   (RAM)       +
;-------------------------------+
_STACK  sect    stak
   ds  100h
_STACK_END:
;-------------------------------+
;   init section    (ROM)   +
;-------------------------------+
_INIT_DATA  SECT    COMM    ; 初期値のあるデータの配置されたセクション(ROM)上
;-------------------------------+
;   Control data    (RAM)   +
;-------------------------------+
D_DATA  sect    comm
   global  _errno
   _errno  dw  0   ;for math lib
;
;----------------------------------------------------------------
;   Interrupt table
;----------------------------------------------------------------
INIT        SECT    CODE,ORG=0  ; nmi
       JP  START
JMP_TBL EQU 8000H          ;ジャンプテーブル
       AORG 08H
       JP JMP_TBL+3
       AORG 10H
       JP JMP_TBL+6
       AORG 18H
       JP JMP_TBL+9
       AORG 20H
       JP JMP_TBL+0CH
       AORG 28H
       JP JMP_TBL+10H
       AORG 30H
       JP JMP_TBL+13H
       AORG 38H
       JP JMP_TBL+16H
       AORG 66H
       JP JMP_TBL+19H
C_START     SECT    CODE,ORG=80H
START:
       ld  HL,_STACK_END       ;Set Stack Pointer
       ld  SP,HL
;
; 初期値のあるデータをROMからRAMへ転送する
;
       LD  HL, _INIT_DATA
       LD  DE, _DATA_TOP
       LD  BC, _DATA_SIZE
       LDIR
;
; 初期値のないRAMエリアを0クリアする
;
       LD  IX, _BSS_TOP
       LD  HL, _BSS_SIZE
       LD  DE,1
CP_BSS1:        
       SBC HL,DE
       JP  C,CP_BSS2
       LD  (IX),0  
       INC IX
       JP  CP_BSS1
CP_BSS2:
;
; main 関数を呼び出す
;
       CALL    _main
       JR  START
   
       HALT
;
       END START
アセンブラでの記述になるので少しわかり難いですが、ジャンプテーブルの先頭アドレスをJMP_TBLと命名し、このアドレスとのオフセットを加算することでジャンプ先アドレスを指定しています。AORGというアセンブラ擬似命令が使用されていますが、これは基本的にはORG命令と同じで命令コードを記憶させる開始アドレスを変更します。したがって各ジャンプ命令はINT割り込みで実行される8の倍数のアドレスに正しく配置されます。

 次はリンクパラメータファイルの変更です。RAMの開始アドレスを0xfe00に変更します。
変更後のリンクパラメータファイルのリスト
;-------------------------------+
;RAM Area|
;-------------------------------+
/ADDR=fe00
/SECT=D_*|COMM(data=_DATA)
/SECT=B_*|COMM(bss=_BSS)
/SECT=_STACK
;-------------------------------+
;ROM Area|
;-------------------------------+
/ADDR=0
/SECT=C_*|CODE
/SECT=I_*
;-------------------------------+
;init data section+
;-------------------------------+
/init_section = _INIT_DATA(_DATA)
;-------------------------------+
;linkage module|
;-------------------------------+
/Name=z80mon
/Module=START.xao
/Module=z80mon.xao
/slib=C:\PROGRA~1\AKIZ80\lib\z80\cs\csze1

最後はモニタプログラムからユーザープログラムへ制御を移すGoコマンドの実装です。ユーザープログラムはロードコマンドによってRAM上に配置されます。プログラムの開始アドレスは0x8000番地です。このアドレスにはユーザープログラムの開始アドレスへのジャンプ命令が配置されています。これは仕様として決めたものです。
 Goコマンドでは通信を介してPCから"g <開始アドレス>"と入力されると、指定された開始アドレスにジャンプします。しかし、ほとんどはプログラムの開始アドレスから実行しますので開始アドレスを省略した場合は0x8000番地にジャンプするようにしておきます。

 ユーザープログラムへの移動は下記になります。
uint startAddr=0x8000; //開始アドレスを記憶。PCからアドレスの指定があれば書き換えられている
void commandGo(void)
{
#asm
LD BC,(_startAddr)
PUSH BC
RET
#endasm
}
 逆にユーザープログラムからモニタプログラムに戻るときは下記のようにします。つまりリセットと同じ処理を行います。
#asm
DI
JP 0
#endasm
 これで「取り合えず」ですが、ユーザープログラムをRAM上にロードし、それを実行できる環境が出来ます。

 ページ先頭へ 前へ 次へ ページ末尾へ