68000からのZ80制御
68000とZ80の通信手段
68000とZ80の通信手段は、Z80のRAMを読み書きする事で行います。
また同様の手順でZ80のRAMにプログラムを書き込みます。
例えばZ80にBGM演奏ルーチンを仕組むなら、
起動時にZ80のRAMにBGM演奏ルーチンを書き込んでおき、
動作中は必要に応じてBGMの演奏開始/停止フラグやBGMデータのアドレス等をZ80に知らせる為に、
68000からZ80の特定のRAMアドレスにそれらを書き込みます。
68000からのZ80制御とZ80のRAMへのアクセス
下記がZ80に関するアドレスです。
(アドレスについては明記しない限り68000側から見たアドレスになります)
0xA00000 Z80のRAM 〜 0xA02000 0xA11100 Z80のHALT ...起動時は非HALT 0xA11200 Z80のRESET ...起動時はRESET中
Z80のRAMへはバイト単位でアクセスします。
ワード単位やロングワード単位でアクセスした場合、偶数バイトが無視されます。
Z80のRAMにアクセスするには、まずアクセスする前にZ80をHALT(停止)させます。
尚、起動時は非HALT状態且つRESET状態になっているので、
HALT(停止)させてZ80にプログラムを転送し終えたら、RESETをクリアする事でプログラムを実行します。
0xA11100 0x01 = HALT開始, 0x00 = HALT解除
HALTしても直ぐにはZ80のアドレス空間にアクセス出来る状態にならないので、
アクセス可能になるまで待機します。
アクセス可能になったかどうかは、0xA11100の値を読む事で判ります。
0xA11100 0x01 = Z80は動作中, 0x00 = Z80はHALT中
Z80とデータのやり取り等をする場合はHALTのみで、リセットする必要は
ありません。リセットは初期化時等でZ80にコードを転送した際に行います。
またリセットした場合、同時にFM音源もリセットされます。
0xA11200 0x01 = リセット解除, 0x00 = リセット中
以下はZ80をHALTさせ、Z80のRAMへデータを転送し、実行させる関数の例です。
void initZ80(source, length) uchar *source; /* source = 転送元のアドレス */ uint length; /* length = 転送サイズ */ { register uchar *haltZ80; register uchar *resetZ80; register uchar *ramZ80; register uint cnt; haltZ80 = (uchar *)0xA11100; resetZ80 = (uchar *)0xA11200; /* 停止 */ *resetZ80 = 0x01; *haltZ80 = 0x01; /* 転送 */ ramZ80 = (uchar *)0xA00000; for(cnt = length; cnt != 0; cnt--) *ramZ80++ = *source++; /* 実行 */ *resetZ80 = 0x00; *haltZ80 = 0x00; *resetZ80 = 0x01; }