未知の論理演算調査
2023年12月24日


 ロビ2のプログラムコマンドについて以前調査しました。
 その時演算コマンドの0xd0〜0xd6と判定コマンドの0xd9〜0xdfについてはロビ1のプログラムを参考に解読する事ができました。
 この間の0xd7と0xd8については実際にロビのプログラムでは使われていないと思っていました。
 今まで不明だったふたつの演算子について解明できたので記事にしました。

コマンド0xd7

 コマンド0xd7はロビ2のアイドリングループの中で使われています。
 アイドリングループというのはロビが音声認識をしたり電圧の監視をしたりしている待機状態で動きとしては手を小刻みに振動させたり目のLEDを点滅させたりします。
 このアイドリングループは0.7秒周期で実行されています。
 この時のポーズは2種類あって手の角度やLEDの明るさを微妙に変えて手の振動や目の点滅を表しています。
 この時どちらのポーズを実行するかはマイコンボードのメモリの1ビットを使って管理しています。
 具体的にはアドレス0xf24の9ビット目(0x0080)の1ビットをこの制御に割り当てています。

 標準状態(目が橙)の場合は以下の命令で判定しています。
  0x00004697
   <calc><mem_r size="2" adr="0x0f24"/><const data="128"/><and/><ne/><jump adr="0x00004dce"/></calc>
 管理フラグをチェック(and)してフラグが立っている場合(≠0)は分岐してLEDが暗いポーズ(0x00004dce)を実行します。
 フラグが立っていない場合(=0)は分岐せずLEDが明るいポーズ(0x00004e7a)を実行します。

 この他顔認識した場合目の色がピンクになったりBluetooth信号を受信した場合目の色が黄色になったりしますがこれらは別のポーズを実行して目の色を変えていますが点滅させる方法は標準の場合と同じです。
 ちなみにピンクの判定アドレスは0x00005249で黄色の判定アドレスは0x000050daです。

 それぞれのポーズが実行したら次のループの時に違うポーズを実行するためにこの管理フラグを反転させる必要があります。
 6個所でポーズを実行した後は同じアドレス(0x00004d1d)に飛んできてこのフラグを反転させています。
 実際のプログラムをバイナリで記述すると以下の様になります。
 0xc0 0xc9 0x24 0x0f 0x00 0x00 0xc4 0x80 0x00 0x00 0x00 0xd7 0xcd 0x24 0x0f 0x00 0x00
 最初の0xc0はnoop(何もしない)で次の0xc9はメモリからの読込みで次の4バイトはメモリのアドレス(0x0f24)次の0xc4が定数のロードで次の4バイトは定数(0x0080)の次の0xd7が演算子となります。
 次の0xcはメモリに書き込みで次の4バイトはメモリのアドレス(0x0f24)となりメモリ0x0f24と定数0x0080を演算してメモリ0x0f24に戻しています。
 これをRM4表記で記述すると以下のようになります。   0x00004d1d
   <calc><mem_r size="2" adr="0x0f24"/><const data="128"/><???/><mem_w size="2" adr"=0x0f24"/></calc>
 前にも記載したようにこの演算は管理フラグを反転するためのものでビットを反転させるには論理演算の排他的論理和(XOR)を用います。
 すなわち???はxorとなります。

テストプログラム

 次のプログラムをロビプログラムコンパイラでSTARTUP.BINに組み込んで論理演算のテストをしてみました。
 andtest.txt
 音声認識語「テストなんだ」に割付けます。
 ロビプログラムコンパイラでバイナリコマンドに変換するためにとりあえずサポートしている論理演算andで演算しています。
 これをロビプログラムアナライザーでandの演算子0xd5を0xd7)に変換します。


 このプログラムを実行するとTEST.LOGの内容は以下の様になりました。


 16ビット変数をそのまま書いたので前半バイトと後半バイトが逆に書かれているので値としては0x0af5となります。
 ビットで表記すると以下の様になります。
 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 (0x00ff)
 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 (0x0a0a)
       XOR↓
 0 0 0 0 1 0 1 0 1 1 1 1 0 1 0 1 (0x0af5)
   排他的論理和はビットが両方同じ時は0になりそれ以外は1になります。

コマンド0xd8
 残念ながら演算子0xd8はSTARTUP.BINでは使われていないようです。
 上記と同様にandtestをロビプログラムアナライザーで演算子を0xa8に変更して実行してみます。
 このプログラムを実行するとTEST.LOGの内容は以下の様になりました。


 値は0xf5f5となりビットで表記すると以下の様になります。
 1 1 1 1 0 1 0 1 1 1 1 1 0 1 0 1 (0xf5f5)
         NOT↑
 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 (0x0a0a)
 この値は定数でロードした0x0a0aのビット反転した値は0xf5f5となっています。
 という事はNOT(論理否定)のという事になります。
 通常NOT(論理否定)は対象となる値はひとつなので前に書いた値は演算の対象となりません。
 ちなみに0x0efcに違う値を入れても結果は同じでした。

 notの場合は演算対象の値はひとつなのでRM4表記は以下の様になります。
   <calc><mem_r size="2" adr="0x0efc"/><not/><mem_w size="2" adr"=0x0f24"/></calc>
 今回分かった論理演算のRM4形式のプロクラムは以下のファイルとなります。
 XORテスト
 NOTテスト
 ダウンロードしたファイルは拡張子を.RM4に変更してください。
 今回ロビプログラムコンパイラーとロビプログラムアナライザーの最新版でxorとnotに対応しました。

 なお結果を書き出すTEST.LOGは予め2バイト以上のファイルを作ってください。
 ロビ2のVOLUME.BINが2バイトなのでそのままRENAMEして使えます。
 またロビ1でもこのプログラムがそのまま実行できます。


目次に戻る