<< 目次に戻る

YM2203・YMZ294・SP0256を使ったハードウエアMIDI音源の製作
FIFOの実装

FIFO

左の図はMIDI用の8バイト FIFOの模式図です。 RCREGはPIC内蔵のUSARTが持っている受信バッファで、MIDIデータを完全に受信するとハードウエア割り込みが発生します。 割り込みが発生すると、PICは自動的に現在実行中のプログラムを中断して割り込みを禁止(GIE=0)状態に変更し、 現在のプログラムカウンタをスタックにプッシュして割り込みベクタ(0004H)へジャンプします。PICが行ってくれる動作はここで終了です。

割り込みルーチンでは、プログラムする人間の手で実行中だったプログラムのいくつかレジスタを保存しなければいけません。 具体的には W,STATUS,PCLATCH,FSR の4つです。その後、USARTの受信バッファからデータを取り出してFIFOに書き込むルーチンを呼びます。

書き込みが終われば、割り込み開始時に保存した W,STATUS,PCLATCH,FSR を逆の順番でリストアし、RETFIEで通常処理に戻ります。

割り込みルーチンは必ず320us以内で終わるようにしなければいけません。 320us以上時間がかかると次のデータが送られてきた時にRCREGがオーバーフローしてFIFOの役割を果たせません。


FIFOの書き込み手順

  1. BUFFERSIZE - 使用量カウンタ を行う。
  2. Z フラグが立ったらFIFOフルのフラグを立ててリターン。
  3. 書き込みポインタアドレスへデータを書き込む。
  4. 使用量カウンタをインクリメント。
  5. 書き込みポインタをインクリメント。
  6. 書き込みポインタ - BUFFERSIZE を行う。
  7. C フラグが立たなかったら(= FIFOの領域をオーバーした)、書き込みポインタを0に戻す。
  8. リターン

運悪くFIFOがいっぱいになった場合は、FIFOフルフラグが立った状態で割り込みルーチンに戻ってきますが、 そのタイミングでは何も処理しません。
次にデータを受信して割り込みが発生した時点で、前回失われたデータが何かわからないため、 MIDIイベント(80H~F7H)が来るまで一切FIFOに入れないようにします。 これはランニングステータスのイベント喪失による誤動作を回避するためのものです。 そして、80H~F7Hを受信した時に書き込みルーチンをコールします。依然FIFOフルの場合は、次の80H~F7Hが来るまでまた待機です。

一方、FIFOの読み出しルーチンはいわゆる通常スレッドで動いているので、読み出し中に割り込みが発生した場合は、 厳密に言うと使用量カウンタがデクリメントされた時点で次のデータを書き込むことが可能になります。

FIFOの読み出し手順

  1. 使用量カウンタをチェック。
  2. Z フラグが立ったらFIFOエンプティフラグを立ててリターン。
  3. 読み出しポインタアドレスからデータを読み込む。
  4. 使用量カウンタをデクリメント。
  5. 読み出しポインタをインクリメント。
  6. 読み出しポインタ - BUFFERSIZE を行う。
  7. C フラグが立たなかったら(= FIFOの領域をオーバーした)、読み出しポインタを0に戻す。
  8. リターン
通常スレッドでは読み出しルーチンをコールした直後にFIFOエンプティフラグを確認して、 有効なデータが入ってくるまでポーリングすれば良いだけです。

<< 目次に戻る