« 2018年10月 | トップページ | 2020年1月 »

2019年8月の5件の記事

Ichigojam の WS.LED コマンド

 夏休みの自由研究的な電子工作

 以前にPCN秋葉原でLEDを虹色に光らせる研究がなされていたので、教えを乞うことにしました。

 9月といえばそろそろ十五夜お月様のじきかな、ということでウサギさんとお団子を光らせることにしてみました。え、月は光らないの?というツッコみはなしでお願いします。例によってアイロンビーズでウサギさんを作ってみると以下の写真のようになりました。



 光らせる場所はウサギさんの目とおなかのあたりとお団子の中心に1球ずつフルカラーLEDを裏から張り付ける作戦です。WS2812Bのミニ基板モジュールと PL9823 という砲弾型の5mmのLEDを連結させてみました。これらを連結して光るかどうかはまだ誰も確かめたことがなさそうだったのでやってみました。

 配線を隠しながら LED をアイロンビーズの裏側に接着するために、グルーガンを使いました。IYN はこの透明な樹脂を熱で溶かして LED を張り付けるというのがそんなに有効なのか知らなかったので、ちょっと感激してしまいました。ええっ、こんな簡単に、LED が思うように固定できてしまうなんて!



 適当に配列に数値を入れて WS.LED 3 とコマンドを実行するとうまいこと光ってくれました。ただし、配列の[0]~[5]はWS2812Bの2球に対応しているのでカラーデータの並びはGRBGRB、配列の[6]~[8]はPL9823(ウサギさんの眼球)なのでカラーデータの並びはRGBとなります。127くらいで光量としてはサチっているみたいなのでこのくらいの出力値にしておくのが良いでしょう。なぜなら、消費電力のわりに見た目の輝度が変わりませんし、Ichigojamからドライブさせる電力としても抑え気味にした方が賢いからです。





 さて、WS.LEDコマンドが思ったように動かせることが分かったら虹色出力です。虹色というと起点となる7色をRGBで表現したり、それを連続的に変化させるようなプログラムを書こうと思うとちょっとめんどくさいな、と感じました。それで PCN秋葉原 のお店の人に相談したところ以下のような数式1行で表現できると教えていただいたのです。

[ I % 3 ] = ABS( I % 2 * 100 - H )



   この式の説明をします。色相環では360度で一周する虹色を6つのステージに分割すると、I = 0 ~ 5 となります。I % 3 は配列の要素数で、I=0, 1, 2, ... とステージが進むたびに [0] [1] [2] [0] [1] [2] と配列の添え字が変化します。つまり、G R B G R B の順番に出力するカラー情報が変化するということです。ABS の方はもう少し複雑で、ステージが I=0, 1, 2, ... と進むとABS( ... ) の数式の評価結果は

I=0: H (=Gが0→100と変化)

I=1: 100-H (=Rが100→0)

I=2: H (=Bが0→100)

I=3: 100-H (Gが100→H)

I=4: H (Rが0→100)

I=5: 100-H (Bが100→0)


というようになり、各ステージの中でHを0~100とカウントアップさせることで色相環の六角形(輝度はまちまちだけど)の中をたどることができるという優れモノなのです。上記をきちんと理解したうえで Ichigojam BASIC でプログラムを書くと以下のようになりました。

 プログラムでやっていることは、ウサギさんのおなかのあたりを虹色に変化させていることに加えてウサギさんの目は赤固定でお団子はぼんやり点滅しています。



 お彼岸が近付くにつれ、寝苦しい夜も少なくなってきました。Ichigojam を使った電子工作もゲーム開発もこれからが身に入るころですね!

Ichigojam マシン語デバッグ術

 コードレビューが一番効果的なんだけど…。

 たった数十バイトのマシン語でも暴走した時は一瞬途方にくれますね…。特に Ichigojam のようなデバッグ環境がほとんど存在しないような場合にどうしたらいいのか、頭をひねります。自己流を持ってる人は確認の意味でも IYN のやり方と比較してみてください。

 デバッグで必要なのはとにかくレジスタの値を見ることです。暴走するのは、とにかくレジスタの初期設定がおかしい時が多いのです。ループさせるコードは IYN は経験上ほとんど間違えずにループしています。アセンブラを書いていてループさせること自体にミスを含む要素はかなり少ないと考えています。

 レジスタの値を見るためには、Ichigojam の場合は R0 に目的の値を代入して BASIC に制御を返す必要があります。つまりループが始まる前に各レジスタの初期値を R0 に入れて RET するコードを書いて、それぞれのレジスタが設計意図通りなのかすべて見回しておくことです。具体的にはマシン語のループのコードにアポストロフィ(')を入れてコメントアウトしてからアセンブラ asm15 にかけて ?HEX$(USR(#700,0)) などと一発実行するわけです。

 Ichigojam の USR 関数は R1 の値を最初にベースアドレスとして用いることが多いので、このレジスタを別用途に流用するときは十分注意が必要です。IYN は R2 に VRAM の先頭アドレス #900 を作っておいて、R2 = R2 + R1 として実VRAM先頭アドレスにしていたのに、R1 を VRAM の最後アドレスにしようとしたときに R1 = R2 + R1 などともう一度ベースアドレスを加算してしまうというミスをしていたのでした。

 自分も Ichigojam のプログラミングを習得してゲーム開発をしてみたいとお考えのあなた、ベーマガ投稿研究会のメンバーになってPCN秋葉原で私と一緒に活動しましょう!

Ichigojam 用逆アセンブラ 印刷機能付き

 逆アセンブラのツール開発が進みました

ダウンロード - disasm_for_ichigojam_1_0_2.zip

 変更点 … 印刷機能と印刷プレビュー機能を追加

 印刷プレビューはプリンタの設定はデフォルト以外変更できません。用紙サイズの変更などをした結果を印刷プレビューで見たい場合はプリンタについてるユーティリティを使ってください。

 ここからは VisualStudio の話題となります。非常に参考になったのは dobon.net というサイト。印刷プレビューについては、

  1. PrintPreviewDialog オブジェクトを生成して
  2. printDocument オブジェクトを生成して
  3. printPage イベントハンドラで印刷描画を実装する

という手順で実装できました。プレビューに使ったprintPageイベントハンドラはそのまま印刷ダイアログの中で再利用できます。印刷プレビューダイアログはとても簡単に表示できるように作られていました。

 肝心の PrintPage ハンドラの中身はというと、ウィンドウ画面を描画するのと同じことを紙の上でDrawStringとやるだけでした。marginBounds.Top/Bottom/Left/Right で囲まれた座標空間の中で DrawString して文字列を置いていく作業は、きちんと考えるとなかなか大変なことをしています。画面上の描画ははみ出ないように書くのに対して、印刷物の描画ははみ出たら次のページに続きを描画する、という管変え方が必要になります。

 ですから PringPage ハンドラは1ページごとに呼び出されて次のページで呼び出される必要があるかどうか自己判断しなきゃいけないようなのです。それで e.HasMorePages = True といった代入式を最後に書くことになります。

 IYN はこの dobon.net のサイト管理者が作ったアルゴリズムを1ページに3列繰り返すことによって、番地の列、マシン語の列、ニーモニックの列をそれぞれ印刷することに成功しました。

 アセンブラの解析でも開発でも、紙に印刷して好きにメモを書き込んで使うことは頻繁に発生するので、逆アセンブラに印刷機能がついてることは利便性がかなり高いと思います。

注意: 開発は VS2015 で行ったので、.NET Framework はバージョン4.6に依存していると思ったのですが、dumpbinで調べてみるとバージョン2.0依存になっていました。アプリを実行できないという方は、両方のバージョンの.NET Frameworkのインストールをお試しください。

Ichigojam マシン語で LED ピカピカ

 ichigojam マシン語熱が高まってきた夏休み

20190814_disasm01   ichigojam の OUT1ポートにWS2878用のデータを出力するマシン語プログラムを解読してみました。R0にはLEDの個数*3の値を代入して、R1にはデータアドレス、R2には出力ポートアドレスを代入して#EE番地に書いてあるWS.LEDコマンドのベクターにgotoするというコードです。

 R1には画面のアドレス#900番地を入れていますが、画面上に乱数生成した文字列をBASICで書いているので結局は256*3個の乱数をOUT1ポートに送信することになっています。

 もともと福野さんが書いたハンドアセンブラが R2=[@OUT1]L となっているところが実際のマシン語でどうなるのか見てみたかったため、逆アセンブラしてみたわけです。[PC+2]L ということで、4バイト単位のアドレッシングになっているのですが、NOPを挿入することでアラインを取って#714、#716番地からOUT1ポートの番地#50010004を読み取っていることが分かります。

 マシン語でないと速度で気に間に合わないケースがあると聞いてどうやって実装するんだろうと疑問に思っていましたが、これで IYN にもマシン語で I/O 出力のやりかたが分かってきました。I2CコマンドもAPI呼び出しすればよいのでしょう。

 

逆アセンブラ for Ichigojam

 久しぶりにwinアプリ作りました!

ダウンロード - disasm_for_ichigojam.zip

 zip ファイルを展開すると小さな exe ファイルが一つ出てきます。実行すると、発行元不明とか言われて止められますがわかる方はそのまま実行してみてください。このブログがハッカーに侵されない限り安全だと思います。念のためにセキュリティスキャンしてみてください。実行が確認できたのは、win10 Home edition のみです。開発ツールは VS2015 express です。

 実行すると以下のようなウィンドウが出てきます。各所の説明をします。

  • 開始番地…ここに16進数で先頭番地を入力しておくと、マシン語変換の際に「番地」にアドレスが表示されます
  • 番地…アドレスを自動生成した結果を表示します
  • マシン語…テキスト入力で、各種マシン語表記を入力します
  • ニーモニック…逆アセンブラの出力結果を表示します

「ファイル」メニュー

  • 終了 … プログラムを終了します
  • 印刷、印刷プレビュー … 開発中

「解析」メニュー

  • カンマ区切り10進数 … マシン語の枠に記入された「254,181, ... 」といった8ビットずつカンマ区切りされた10進数を16ビット16進数に変換します
  • カンマ区切り2進数 … マシン語の枠に記入された「`00000001,`00110000, ... 」といった、8ビットずつカンマ区切りされた2進数を16ビット16進数に変換します
  • 16ビット2進数 … マシン語の枠に記入された「`0000000100110000 …」といった改行で区切られた16ビット2進数を16ビット16進数に変換します
  • 逆アセンブル … マシン語の枠に記入された改行区切りの16ビット16進数を逆アセンブルし、結果をニーモニックの枠に出力します

「ヘルプ」メニュー

  • バージョン情報 … 現在使用しているツールのバージョンを示します。印刷、印刷プレビューが実装できた段階で ver 1.0.0 とするつもりです。

 という説明から使用方法がわかると思いますが、順を追って説明します。

1. マシン語コードの準備 … カンマ区切り2進数のマシン語を例にとって用意します。エディタなどで、「POKE #700」の文字列を取り除いてマシン語データ部分のみ残します(元のコードは Ichigojam 開発者の福野さんのページからお借りしました)。

20190810_02_bin_array

2. マシン語の枠へのマシン語データの貼り付け … 作ったカンマ区切りデータを「マシン語」の枠に貼り付けます。ここで、開始番地にデフォルト値#700を変更することもできます。

20190810_03_paste_bin

3. マシン語変換 … 「解析」→「カンマ区切り2進数」をクリックして4ケタの16進数に変換するコマンドをメニューから選びます。

20190810_04_convert_bin

4. マシン語変換結果 … 上記3. のコマンドを実行すると以下のような画面になります。4ケタの16進数に変換できなかったものは空行になります。

20190810_05_convert_result 

5. 逆アセンブル実行 … 「解析」→「逆アセンブル実行」をクリックします

20190810_06_disassemble_cmd

6. 逆アセンブル実行結果 … 上記5. のコマンドを実行すると以下のように、ニーモニックの枠に逆アセンブル結果が出力されます。

20190810_07_disassemble_result

 ここからは注意書きになりますが、基本的に自分のために作ったツールですのでいろいろと不備があります。くれぐれも objdump とかと比較したりしないでください。

  • 逆アセンブルできる命令は Cortex-M0 Arm マシン語表(asm15, 抜粋) に書いてあるものから有用なものだけ取り出して対応しています。
  • つまり、asm15 が吸えるニーモニックを部分的に解釈できるようにしたものです。
  • goto 文の分岐先はマシン語コードに対して2を足しています。したがって飛び先は命令個数分だけ数えれば済みます。
  • 改行文字はCRLFのみ対応しています。そのほかは動作確認しておりません。
  • 印刷機能は最終的に削除するかもしれません。自分の勉強用の課題ということにしておきます。

« 2018年10月 | トップページ | 2020年1月 »

2022年3月
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
無料ブログはココログ