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

マシン語メモリアクセスで画面超速表示! - IchigoJamではじめるARMマシン語その3

2015/10/25 23:55:00
#IchigoJam #KidsIT #event #ARM 

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 CLS:A=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の方法

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