福野泰介の一日一創 - create every day

Armマシン語第三弾、超高速計算を画面表示に活かしてみましょう!
※今回以降はIchigoJamのバージョン1.1を使用します(開発版はグループのファイルからダウンロード可能

コンピューターの記憶には2種類あります。
データを保存しておく本棚と、作業用の机をイメージしてください。
本棚から必要なデータを机に出して、机の上であれこれ計算してつくったデータをまた本棚に戻したりします。

前回紹介したレジスタが机に相当します。
レジスタは一度に使える量は限られます。(ひとまず、R0〜R3の4つのみを使ってください)

もうひとつの記憶、本棚に相当するのがメモリ(RAM)です。
こどもパソコンIchigoJamは、4KB(4キロバイト=4096byte 約4千文字分)のメモリがあります。
※私のパソコンのメモリ、4GB(4ギガバイト=4,294,967,296byte 42億文字入る!)と比べて、100万倍の1!

今回、マシン語表に新たにメモリアクセスを追記しました。
これがデータが詰まった本棚からとってきたり、書き換えたりするためのマシン語です。

値 = [メモリの場所] ... メモリから値を読み出します
[メモリの場所] = 値 ... メモリを書き換えます

IchigoJamは、メモリの一部を画面に表示用に使っているので、そこを書き換えると画面を書き換えることができます。

HELP MEM MAP #000 CHAR #700 PCG #800 VAR #900 VRAM #C00 LIST #1002 KEY

HELPコマンドでメモリの位置を確認することができます。
画面用のメモリは、VRAM(ブイラム、ビデオ用のラムということ)が#900からなので、こんなBASICのプログラムを書くと、キャラクター一覧が画面上部に順番に表示されます。

FOR I=#900 TO #9FF:POKE I,I:NEXT

つらつらと書いていく様子が目に見えますね。
では、これをマシン語にしてみましょう。

IchigoJam ver 1.1 から、R0に渡されたパラメータ、R1にBASICで使うメモリの位置の実メモリ位置、R2にキャラクターマップの実メモリ位置がセットされるようになりました。 今回はR1のみを使います。

R3=9
R3=R3<<8
[R1+R3]=R3
R3=R3+1
R2=R3>>8
R2-10
IF !0 GOTO -4
RET

これをハンドアセンブル(マシン語表からひとつずつ2進数列に変換すること)します。

00100 011 00001001 ← R3=9
00000 01000 011 011 ← R3=R3<<8
0101010 011 001 011 ← [R1+R3]=R3
00110 011 00000001 ← R3+=1
00001 01000 011 010 ← R2=R3>>8
00101 010 00001010 ← R2-10
11010001 11111010 ← IF !0 GOTO -4
0100011101110000 ← RET

マシン語表を見ながら順番に書いていくだけなので簡単ですね!
* R3+=1 とは R3=R3+1 という意味です。後述の表記では3bit(0〜7)までですが、+=を使うと8bit(0〜255)まで表記できます。

GOTO命令だけがちょっと特殊なので、注意が必要です。
4つ分命令を戻りたいときは、更に-2した-6を、2進数8bit補数表現にします。

?BIN$(-4-2,8) 11111010

このように、IchigoJamで計算すると便利です。

では、マシン語をメモリに書き込んで実行してみましょう。前回はPOKE文で上のメモリマップでいう#700、キャラクターパターンの領域に書き込んでいましたが、今回は配列の領域#800を使って楽します。 上位8bitと下位8bitに分けずに、16bitそのまま書き込めるので楽です。

10 [0]=`00100 011 00001001 20 [1]=`00000 01000 011 011 30 [2]=`0101010 011 001 011 40 [3]=`00110 011 00000001 50 [4]=`00001 01000 011 010 60 [5]=`00101 010 00001010 70 [6]=`11010001 11111010 80 [7]=`0100011101110000 90 U=USR(#800,0)

実行すると一瞬にして、画面に全キャラクターコードが表示されます!

配列領域を使っているので、配列を使ったプログラムと混ぜる時には要注意です!

?BIN$(PEEK(#800),8),BIN$(PEEK(#801),8)

このように、ちゃんと入れ替わって#800からのメモリに入っていることを確認してみましょう。
(下位から順にいれる方式をリトルエンディアン、上位から入れる方式をビッグエンディアンといいます、現在リトルエンディアンが主流!)

ミッション
- 1. 画面全部をキャラクターコードで埋めてみよう
- 2. USRコマンドで渡したキャラクターコード(R0)で画面全体を埋めてみよう
- 3. 画面を市松模様で埋めるマシン語プログラムを背景に、BASICのゲームをつくってみよう

IchigoJamで使えるマシン語表(基本+1byteメモリアクセス編)

※GOTOに指定する値は、飛ばしたい命令数の差分から更に-2した数を指定する

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作
13. コンパイラはじめのいっぽ、EVAL実現法とマシン語生成
14. サイズを取るかスピードを取るか、割り算のアルゴリズムとマシン語実装
15. マシン語化で1万倍速!? セットで学ぶアルゴリズムとコンピューター

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / アイコン画像 / プロフィール画像