2013.3.24
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第355回]


●MIDIデータの解読とデータ送信

前回からの続きです。
前回説明をしましたように、必要な設定処理を済ませたあとは、ひたすらトラック用ワークエリアを巡回チェックします。
各トラック用ワークエリアの(IX+02)〜(IX+04)には時間データが書かれていて、その値はZ8S180内蔵カウンタの割込みプログラムによって、時間経過とともにカウントダウンされていきます。
最後に0になると、(IX+01)に00が書き込まれます。
各トラック用ワークエリアを巡回して、その(IX+01)が00であることを確認したら、そのときの時間データの次に書かれているMIDIイベントデータの解読をします。

80CE DD6E05     LD L,(IX+05)
80D1 DD6606     LD H,(IX+06)
80D4 7E         LD A,(HL)
80D5 FEFF       CP FF
80D7 CA0781     JP Z,CODEFF
80DA FEF0       CP F0
80DC CA5381     JP Z,CODEF0
80DF E6F0       AND F0
80E1 F2FE80     JP P,RUNSTS;running status
80E4 FEC0       CP C0
80E6 CAF580     JP Z,CXOUT
80E9 FED0       CP D0
80EB CAF580     JP Z,CXOUT
80EE 7E         LD A,(HL)
80EF DD7707     LD (IX+07),A;code save
80F2 CD4B82     CALL MIDIOUT
80F5 CD4B82   CXOUT:CALL MIDIOUT
80F8 CD4B82     CALL MIDIOUT
80FB C31881     JP NEXTDT

(IX+05)および(IX+06)にはそのトラックのMIDIイベントデータがあるメモリアドレスが入っています。
それをHLレジスタに読み込んで(HL)の値(つまりMIDIイベントデータの第1バイトの値)を解読します。
いきなりMIDIデータとしてシリアル送出しないのは、イベントデータによって、シリアル送出せずに特別な処理をしたり、またデータバイト数が通常の3バイトとは異なっているものがあるためです。
ここでそれらを認識してそれぞれの処理に分岐します。
第1バイトがFFHはメタイベントコードです。
メタイベントの処理(CODEFF)にジャンプします。

MIDIのルールではイベントデータの第1バイトは8X〜FXということになっています。
しかしランニングステータスのときはここに7F以下のコードが置かれます。
ランニングステータスとは同じイベントステータスが連続する場合に第1バイトを省略するというルールです([第344回])。
第1バイトが省略されると、その次のデータは必ず7F以下のデータになります。
第1バイトの値が正の数(ビット7=0)ならランニングステータスですから、ランニングステータスの処理(RUNSTS)にジャンプします。

第1バイトがCX、DXのMIDIイベントデータはそのままシリアル送出しますが、2バイトしかありません。
そこでそのようにするためにCXOUTにジャンプします。

上記以外のMIDIイベントは、8X、9X、AX、BX、EXです。
8Xはノートオフ(音を止める)
9Xはノートオン(音を出す)
AXはポリフォニックキープレッシャー(アフタータッチ。鍵盤をさらに強く押したことを伝える)
BXはコントロールチェンジ(次に続く2バイトによってさまざまなコントロールを行なう)
EXはピッチベンド(音程をわずかずつ変化させる)
これらのコードはそのままシリアル送出します。
送出する前にアドレス80EEH〜80F1Hで(IX+07)に第1バイトの値を書き込んでいるのは、ランニングステータスに備えてイベントコードを保存しておくためです。
とりあえずCX、DXではランニングステータスは使われないと仮定しています。
またAX、EXでランニングステータスが使われるのかどうか疑問ですが、プログラム簡略化のためにこのようにしてあります。

MIDIOUTは(HL)の値をシリアル送出するサブルーチンです。
連続する3バイトの値(CX、DXの場合は2バイト)をシリアル送出したら、次のデータをトラック用ワークエリアに読み込むための処理(NEXTDT)にジャンプします。

●MIDI送出サブルーチン

[第351回]で少し書きましたようにMIDIデータをシリアルOUTするにはPIC16F886を使います。
PIC16F886にデータを送るためにハンドシェーク方式で8ビットのデータをパラレル出力します。
MIDI送出サブルーチンは(HL)の値をPIC16F886にパラレルOUTし、その後にHLレジスタの値を+1してリターンします。

824B DBFE     MIDIOUT:IN A,(FE)
824D E620       AND 20
824F CA4B82     JP Z,MIDIOUT
8252 7E         LD A,(HL)
8253 D3FD       OUT (FD),A
8255 3E02       LD A,02;bit1=L,bit0=H;bit0-4 are INVERT
8257 D3FE       OUT (FE),A
8259 DBFE     MIDIOUT2:IN A,(FE)
825B E620       AND 20
825D C25982     JP NZ,MIDIOUT2
8260 AF         XOR A
8261 D3FE       OUT (FE),A
8263 23         INC HL
8264 C9         RET

次回に続きます。

[2013.3.25追記]
第1バイトがF0のときの分岐についての説明が落ちていました。
第1バイトがF0はシステムエクスクルーシブメッセージです。
MIDI機器に対して特殊な操作を指示するために使われます。
CODEF0にジャンプします。

ワンボードマイコンでCP/Mを![第355回]
2013.3.24upload
2013.3.25追記

前へ
次へ
ホームページトップへ戻る