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

  
H8/3664
  
AKI-H8
  
PallarellPort増設
  
VHDL coding

  前の頁  次の頁
これからが、今回のコラムのハイライトである!ということで、気張ってコードを貼ってはみたが、余りの量に混乱は必至だ。そこで今回は、段毎にコメントを書く方式で解説を行い、スパゲッティーな構造を少しでも理解出来るように、ルーティンのジャンプ先を色分けしてみた。内容が重複するが、前項で解説した「窓口」の部分も再掲しておく。
data_Read:
  
mov.b @(rx_fifo,er1),r0h  ; rx data -> [r0h]
  
inc.w #1,r1
  
bclr #1,r1h          ; rx buffer 512
  
mov.w r1,e5         ; reWrite rx data address

  
cmp.b #h'F0,r0h       ; sysex data thru
  
bls ditector

  
rts

まず、rx_fifoからデータをr0hにロードし、読み出し用のアドレス、er1の番地を1つ繰り上げる。読み出したデータの内容がSySexだった場合は、処理をスキップする。
ditector:

  
btst #3,r4h        ; detecting 4th data flag =>r4h
  
bne data_store2

  
btst #2,r4h        ; detecting 3rd data flag
  
bne detector_2

  
btst #1,r4h        ; detecting 2nd data flag
  
bne data_store

  
btst #0,r4h        ; detecting 1st data flag
  
bne next_flag

  
cmp.b #h'B0,r0h  ; data header reading from MotorMix
  
beq data_set1

  
btst #6,r4h        ; detecting second ping flag
  
bne trigger_out

  
btst #5,r4h        ; detecting first ping flag
  
bne next_flag2

  
cmp.b #h'90,r0h     ; ping header flag
  
beq receive_flag1

  
rts

受信データを判定するディテクター。r4h に設置したフラッグを 0bit から順番に立てていく。最初に B0 を検知した後、引き続き 0C を検知したタイミングで、その直後に来る数値をレジスタ r6l に記録する。次に来る 2C の確認をキッカケとして、data_store2 にジャンプ、LED点滅情報のディストネーションと状態が確定する。

一方、ディテクターが ping signal を検知した場合は、オンオフの状態を次に来るデータで判断し、結果をポート1のMSBに送る。
receive_flag1:
  
bset #5,r4h
  
bra data_Read
  
next_flag2:
  
cmp.b #h'00,r0h        ; ping second flag
  beq
receive_flag2
  
sub.b r4h,r4h          ;flag clear
  
rts
  
receive_flag2:
  
bset #6,r4h
  
bra data_Read

trigger_out:
  
cmp.b #h'7F,r0h
  
beq rx_trig_on
  
bra next_trig

rx_trig_on:
  
bset #7,r4l
  
mov.b r4l,@pdr1
  
and.b #b'10011111,r4h    ; erase the flags
  
rts

next_trig:
  
cmp.b #h'00,r0h
  
beq rx_trig_off
  
rts

rx_trig_off:
  
bclr #7,r4l
  
mov.b r4l,@pdr1
  
and.b #b'10011111,r4h    ; erase the flags
  
rts

data_set1:
  
bset #0,r4h
  
bra data_Read

next_flag:
  
cmp.b #h'0C,r0h        ; second data detector
  
beq data_set2
  
sub.b r4h,r4h
  
rts

data_set2:
  
bset #1,r4h
  
bra data_Read

data_store:
  
cmp.b #h'08,r0h        ; detecting sw data
  
blt data_set3
  
sub.b r4h,r4h
  
rts

data_set3:
  
mov.b r0h,r6l          ; loading the sw line data
  
bset #2,r4h           ; setting the 3rd flag
  
bra data_Read

detector_2:
  
cmp.b #h'2C,r0h        ; detecting the 4th flag
  
beq data_set4
  
sub.b r4h,r4h
  
rts

data_set4:
  
bset #3,r4h
  
bra data_Read

この部分で信号の選別を行っている。 r0h に入力される受信データの状態を判断し、その結果を r4h に設けたデータ判別フラッグに反映している。前述したように、0C 判定後に入力されたデータは r6l に格納され、次のルーティンまで保持される。
data_store2:
  
and.b #b'01100000,r4h     ; erase the flags

  
cmp.b #h'45,r0h
  
beq line_01_on
  
cmp.b #h'05,r0h
  
beq line_01_off

  
cmp.b #h'44,r0h
  
beq line_02_on
  
cmp.b #h'04,r0h
  
beq line_02_off

  
cmp.b #h'43,r0h
  
beq line_03_on
  
cmp.b #h'03,r0h
  
beq line_03_off

  
cmp.b #h'42,r0h
  
beq line_04_on
  
cmp.b #h'02,r0h
  
beq line_04_off

  
rts


line_01_on:
  
mov.b @outputs_1,r2l
  
bset r6l,r2l
  
mov.b r2l,@outputs_1
  
rts

line_02_on:
  
mov.b @outputs_2,r2h
  
bset r6l,r2h
  
mov.b r2h,@outputs_2
  
rts

line_03_on:
  
mov.b @outputs_3,r3l
  
bset r6l,r3l
  
mov.b r3l,@outputs_3
  
rts

line_04_on:
  
mov.b @outputs_4,r3h
  
bset r6l,r3h
  
mov.b r3h,@outputs_4
  
rts

line_01_off:
  
mov.b @outputs_1,r2l
  
bclr r6l,r2l
  
mov.b r2l,@outputs_1
  
rts

line_02_off:
  
mov.b @outputs_2,r2h
  
bclr r6l,r2h
  
mov.b r2h,@outputs_2
  
rts

line_03_off:
  
mov.b @outputs_3,r3l
  
bclr r6l,r3l
  
mov.b r3l,@outputs_3
  
rts

line_04_off:
  
mov.b @outputs_4,r3h
  
bclr r6l,r3h
  
mov.b r3h,@outputs_4
  
rts
最終バイトのデータをこのパートで判定し、データのラインを確定、r6l に格納されたLEDの状態を出力レジスタ r2l に蓄積し@outputs_n に結果を反映する。
ということで、かなり怪しげな構造ではあるが、とりあえず回路は問題なく稼働している。唯一、MotorMixに向けて出力されるPINGの出力タイミングがよく理解出来ていないので、そこが少し気に掛かる点ではある。そろそろ、MIDI専用のデータロガーが必要だと思う今日この頃であった。
つづく→