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

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

[第354回]


●トラック用ワークエリアの巡回

いよいよトラック用ワークエリアの巡回チェックです。
必要な設定処理を済ませたあとは、ひたすらトラック用ワークエリアを巡回チェックします。
何をチェックするかといいますと、各トラック用ワークエリアの(IX+01)が00であるかどうかをぐるぐる回りながらチェックするのです。
各トラック用ワークエリアの(IX+02)〜(IX+04)には時間データが書かれていて、その値は前回説明しました割込みプログラムによって、カウントダウンされていきます。
最後に0になると、(IX+01)に00が書き込まれます。
メインルーチンはそれを待っているのです。
時間データが最初から0のときもあります。
その場合には最初から(IX+01)には00が書き込まれますから、それはいきなり検出されることになります。

なにをやっているのか、いまひとつうまく説明ができません。
やっていることをひとわたり説明しますと、何をやっているのかご理解いただけると思います。

8093 DD21DE82 START1:LD IX,TPRMTOP
8097 3A0B84     LD A,(TRKNO)
809A 32DC82     LD (CNTR),A
809D AF         XOR A
809E 32DD82     LD (ENDCK),A
              ;loop
80A1 3A0B84   ST1LP:LD A,(TRKNO)
80A4 47         LD B,A
80A5 3D         DEC A
80A6 CAB680     JP Z,ST1LP1;mode0?
80A9 3ADC82     LD A,(CNTR)
80AC B8         CP B
80AD C2B680     JP NZ,ST1LP1
80B0 DD7E00     LD A,(IX+00);if mode1,pass trk1 timedata
80B3 C3C380     JP ST1LP2
80B6 3ADD82   ST1LP1:LD A,(ENDCK)
80B9 47         LD B,A
80BA DD7E00     LD A,(IX+00)
80BD F5         PUSH AF
80BE B0         OR B
80BF 32DD82     LD (ENDCK),A
80C2 F1         POP AF
80C3 B7       ST1LP2:OR A
80C4 CA3781     JP Z,NEXT
80C7 DD7E01     LD A,(IX+01)
80CA B7         OR A
80CB C23781     JP NZ,NEXT

まずは巡回チェックの前半の部分です。
トラック用ワークエリアの先頭アドレスをIXレジスタに入れて巡回をスタートします。
最初にトラック数を(CNTR)に入れます。
そして(ENDCK)に00を入れておきます。
(ENDCK)は全トラックデータの処理が完了したときに00のまま残ります。
プログラムの処理終了の判断に使います。

トラック数=1はフォーマット0のときです。
もともとはフォーマット0もフォーマット1も処理に違いはなかったのですが、フォーマット1形式のMIDIファイルでトラック1の終わりに異常に長い時間が設定してあるために演奏が終了してもプログラムが終らない場合が出てきました([第345回])。
そこでフォーマット1のトラック1のみトラックの処理が完了したかどうかの判断から外す部分を追加しました。
アドレス80A9H〜80B5Hの部分です。
その前のアドレス80A1H〜80A8Hでフォーマット0のときは、その部分をスキップしているのは、フォーマット0はトラック1しか存在しないからです。
トラック数が1であるのはフォーマット0のみです。フォーマット1のときはトラック数は2以上になります。

80A9H〜80B5Hでトラック1かどうかのチェックをしています。
レジスタBにはその上の80A1H〜80A4Hのところでトラック数が入ります。
(CNTR)の値は最初はトラック数が入りますが、トラック毎のワークエリアをチェックするたびにカウントダウンされていきます。
つまりレジスタBと(CNTR)の値が一致するのは最初のトラック(トラック1)だけです。
トラック1のときには、その後ろの80B6H〜80B2Hはスキップします。

80B6H〜80B2Hでは、そのトラックの処理が完了したことを示す(IX+00)の値を、全トラック処理が完了したかどうかを判断するための(ENDCK)とORして(ENDCK)に入れます。
(IX+00)はそのトラックの処理が完了したときに00が入れられますから(それまではFFH)、全トラックを一巡してそれでも(ENDCK)が00だったらもう処理が完了していないトラックは残っていないことがわかります。
その判断からトラック1のみを外すようにしているのが、80A9H〜80B5Hです。

80C3H〜80C6Hでは、あらためて(IX+00)が00であるかどうかを確認して、もし00ならばこのトラックの処理は完了していますから、次のトラックの処理(NEXT)に移ります。
次に(IX+01)をチェックして、その値が00ではないときにも次のトラックの処理(NEXT)に移ります。
(IX+01)は時間データが0の時には00が入れられますが、それ以外のときには非00が入っています。
時間データは時間の経過とともに割り込みプログラムによってカウントダウンしていきます。
その時間データがまだ0になっていないということは、その時間データの次にあるMIDIイベントを処理する時ではないことを意味しています。
ですから(IX+01)が00ではないときには、このトラックの処理は行なわずに、次のトラックの処理に進むのです。

この次のところからがいよいよMIDIイベントデータの解読処理になりますが、そこはまた少し説明が長くなりそうですので、今回はここまでといたします。

ワンボードマイコンでCP/Mを![第354回]
2013.3.23upload

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