*このパートはH8/300/TinyにMidiを導入するためのノウハウを蓄積するための場所です*
関連項目:

  
H8/3664
  
AKI-H8
  
PallarellPort増設
  
VHDL coding

  次の頁
さて、どこから順を追って説明するか、真面目に考えると頭が痛くなってしまうが、ここはプログラムを部分的に分析することで、理解をしていこうと思う。また、煩雑になることを避けるため、MIDIに直接関係のないポイントは重要だけれども理解不能な呪文として取り扱うことにする。

まず、基本的な事柄から。 コードをタイプするスタイルは各人色々な作法を持っているが、まず一見して解る違いとして、大文字、小文字の使い分けがある。例えば、次のような式を書く場合、、


control_number_set:

 push.w r2

 mov.b @pdatA,r3l       ;loading port data
 and.b #b'01111111,r3l    ;msb reset to zero
 sub.w r2,r2 ;clear
 mov.b r3l,r2l
 and.b #h'0F,r3l        ;clear msb 4bit, r3l contains BCD lower 4bits
 and.b #h'F0,r2l        ;clear lsb 4bit, r2l contains BCD upper 4bits

 shlr.b r2l            ;shift data from msb 4bit to the lsb 4 bit
 shlr.b r2l
 shlr.b r2l
 shlr.b r2l

 MOV.B #10,R1L        ;LOADING VALUE #10
 MULXU.B R2L,R1       ;MULTIPLEX BY 10
 ADD.B R1L,R3L

 CMP.B #0, R3L        ;DETECTING ZERO
 BNE CCSTATUS_OUT

 MOV.B #69,R3L       ;PRESET #69
 BRA CCSTATUS_OUT


後半は大文字でタイプしてみたが、小文字で書くか大文字で書くかだけの違いで、えらく印象が変わってしまう。これは、個人の感性なのでどちらが正しいと言うことにはならないが、僕は大文字を読みにくく感じることが多いので、コードを書く場合は主に小文字を使うことにしている。ただし、このスタイルには弱点があって、例えば、

 r3l と間違えて r31

とキーを打ってしまう可能性があるのだ。しかも、見てくれが似ているのでコレが原因で不具合が起こっても、見つけ出すことが意外と難しかったりする。ちなみに、これを大文字で書くと、、、、

   R3L と R31 

このように、間違いは一目瞭然となる。僕のような過去に「タイプライター」を使っていたロートルは小文字のエルを「壱」の代わりに打つことを身体で覚えているので、この手の間違いを起こし易い。心配な人は最初から大文字を使った方がよいかも知れない。

さて、次に紹介するルールは、コメント文についてである。プログラムは暗号に近いものがあって、しかも、一連の作業ルーティンは単純な作業の集積となる。従って、自分で書いたモノであっても、時間が経ってしまうと何を意図して書いたモノなのか、解らなくなってしまうことが多い。その手のトラブルを未然に防ぐための工夫が「コメント」だ。プログラム上のセミコロンは、「コレより右は改行するまでプログラムとして認識しない」という決まりなのだ。
したがって上の例では、1行目後半の ;loading port data という部分をコメントとして扱うことになる。

僕のようなシロートがコンピューターのプログラミングを行う上で最初に感じる違和感は、日頃何の気ナシにやっている事をプログラムに書くとやたらと細かいステップで記述する必要があることだ。例として、上のコードを解説してみよう。

control_number_set:
処理の項目: プログラムのメインルーティンからこの項目を目指してジャンプしてくる。ここに、解りやすい題名を付けると、後々プログラムを俯瞰で見るときに役に立つので、ネーミングは慎重に行おう。 このプログラムは、ポートAに入力されたデジタルスイッチによる数値データを、バイナリー(二進法)に翻訳し、それをMIDI/cc(コントロールチェンジ信号)のアドレスとして使用するためのものだ。
 push.w r2
レジスタ2の内容を待避。汎用レジスタは合計8本あるがそのウチのER7はスタックポインタという待避アドレス格納用レジスタとして使うので、実質は7本ということになる。レジスタの構造は別途掲載するが、ERがロングワードで32ビット、EとRがワードで16ビット、RLとRHがそれぞれ8ビットのデータ幅を持つ。ココで使われているレジスタは push.w だから、ワード幅となる。
 mov.b @pdatA,r3l
ポートAに入力されているデータをレジスタ3のLSB8ビットに転送 MOVは転送命令。Bは8ビットのデータ幅を示す。@pdatAはアドレス先に格納されているデータを直接参照することを意味していて、予め設定してあるpdatAという入力ポートの状態を参照している。ポートAには4ビット出力のデジタルスイッチ(注1)が2個接続されることを想定している。
 and.b #b'01111111,r3l
レジスタ3のMSBをクリア。ANDは論理演算で、入力が全てH(ハイ)の時に出力がHになるという論理和を意味する。従ってこの場合は、最上位のビットがマスクされることになる。これは、MIDIのデータ幅7ビットに合わせて入力を制限するために使うことが多い手法だ。MSB4ビットの上限は”7”となる。通常は必要なし。
 sub.w r2,r2
レジスタ2からレジスタ2を減算=データ消去 SUBは算出演算の減算
 mov.b r3l,r2l
レジスタ2L(下位8ビット)にレジスタ3Lの内容を転送
 and.b #h'0F,r3l レジスタ3にHex0FをAND(論理和)する=上位4ビットを消去
 and.b #h'F0,r2l 同様にレジスタ2の下位4ビットを消去、ポートAに入力された4ビットのデータを2つに分離したことになる。
 shlr.b r2l
 shlr.b r2l
 shlr.b r2l
 shlr.b r2l
レジスタ2のデータ上位4ビットを下位4ビットにスライド。これで、データは正常値となる。
 MOV.B #10,R1L
レジスタ1に数値10を入力。
 MULXU.B R2L,R1
レジスタ2の内容に10を掛けて10の位を作る。答えはレジスタ1に返る.ディスティネーションのデータ幅がワードサイズになることに注意
 ADD.B R1L,R3L
レジスタ3(1の位)にレジスタ1(10の位)を加算する。これで、ポートAに入力された10進法2桁を二進法7桁に変換している。
 CMP.B #0, R3L
比較演算。ゼロとレジスタ3の内容を比較している
 BNE CCSTATUS_OUT
一致しない場合は別項目へ分岐
 MOV.B #69,R3L
通常MIDIのアドレスでは0は使用しないので、ゼロを検知したときは、69に数字を自動的に置き換える。69はフットコントローラーにアサインされたcc#101〜#108とのコンフリクトを避けるために設定している。
 BRA CCSTATUS_OUT
別項目へジャンプ
 
注1) デジタルスイッチ: 0〜9の数字を入力するためのロータリースイッチの一種。スイッチはモジュール化されていて、桁数に合わせて増設することが出来る。このモデルは10進法に対応したデバイスなので、4ビットあたり0〜9の表現を行う。8ビット入力ではデータを受ける側で、2進法にエンコードする必要がある。上記のプログラムはそのプロセスを表している。また、このデータ幅では表現出来る数が0〜99となってしまう事に注意。256を表現するためには、12ビット幅が必要となる。



つづく→