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

もっと楽するコンパイラ、WebAssemblyマシン語入門その3

2017/12/05 23:55:00
#asm #wasm #js 

IchigoJam web(ブラウザで動くIchigoJam)で使っているお気に入り技術、WebAssembly。
マシン語をバイナリで直接書いてみる第一回、初歩的なアセンブラ体験する第二回に続く第三回のテーマは、コンパイラです。

おさらいとして、前回のアセンブラで、param+10 を計算するプログラムを作ってみましょう。

正解はこちら

get_local $0 i32.const 10 i32.add end

paramが1の時、ちゃんと答は11と出ます。では、param+100 を計算するプログラムに変えてみてください。

おや、おかしいですね!?では、128にすると、今度はコンパイルエラーになってしまいます。

WebAssemblyのマシン語での数値は大きさによって1byteから5byteまで長さを変えて表します。最上位bitが1なら、次のbyteを読んで上位に追加していく仕組みになっています。 つまり、1byteで表せる数は、7bitで表せる-64〜63まで。100(2進数で1100100)はこの範囲を超えているので、上位bitを1にして、残りのbitを次のbyteで表すので、1 1100100 (e4) と 0 0000000 (00) となります。

WebAssemblyのコードを書き換えて試してみましょう。

20 0 41 e4 0 6a b

i32.const を表す 41 の後の 64 (=10進数の100) を、e4 に変えてその後ろに 0 を加えて「RUN」
ちゃんと答がでました!

このような計算をいちいち手でやらなくて済む方法は?・・・そうです、プログラムですね。
命令表から手打ちするのも面倒なので、短く楽にプログラムを書けるようにするソフトをつくりましょう。

コンパイラはじめのいっぽ
「P 3 +」と空白区切りで書いたら対応するアセンブリ言語を出力するものです。
※ P は、パラーメータ0を意味することにします

compilebtn.onclick = function() { var src = srcprg.value.split(" "); var asm = []; for (var i = 0; i < src.length; i++) { var s = src[i]; if (s == "P") { asm.push("get_local 0"); } else if (s == "+") { asm.push("i32.add"); } else if (parseInt(s) == s) { asm.push("i32.const " + s); } } asm.push("end"); srcasm.value = asm.join("\n"); }

簡単ですね。このようなソフトをコンパイラといいます。
掛け算とかいろいろ足したものがこちら「WebAssembly poor compiler」です。

WebAssembly poor compiler

「P 3 +」と入力し「COMPILE」「ASSEMBLE」「RUN」と順に押して、答が出してみましょう。

課題:パラメータを自乗して1を足すプログラムをつくってみよう!

アセンブラも上記、大きな数値にも対応するよう改良してあるので、プログラムを確認してみてください。

次はこのコンパイラをもう一歩進めて、もっと自然な数式で書けるように改良してみます。
待ちきれない人は、どんどん進めちゃってください!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

- 連載、IchigoJamではじめる、ARMマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法

links
- WebAssembly Advent Calendar 2017 - Qiita 参加!

マシン語で作る!75円のかわいいARMマイコン、LPC810用エルチカプログラム

2017/11/28 23:55:00
#lpc810 #maker #asm 

小さくても立派な32bit ARM Cortex-M0+のCPU、NXP社製、LPC810、75円 @marutsu
最大動作周波数30MHz、秒間3000万回計算してくれます!

本ブログでも、暗闇で自転車を探すフラッシュライトにしてみたり、おもちゃに音を組み込んだりクリスマス手作りプレゼントや、PCGサウンドライブラリSoundCortexをつかってIchigoJamから三和音鳴らしたりと、活躍。

このかわいいマイコンLPC810をIchigoJamでクロスプロットフォーム開発できる環境を目指し、BASIC風表記なアセンブリ言語 asm15 で、まずは基本にして、コンピューター制御の本質、LEDをチカチカさせる「エルチカ」プログラムをつくってみます。

エルチカは、2ステップあります。まずは、LEDを光らせること。そして、思い通りの時間待たせること。

LPC810のピンをこのように並びで使います。

RESETLPC810RXD
TXDGND
PIO0_33.3V
PIO0_2ISP

LPC1114と同様、電源を入れた時や、RESETがGNDから復帰した際、ISPがGNDになっていると書き込みモードになり、RXD/TXDをつかって、USBシリアルとソフト(FlashMagicやlpc21ispなど)で書き込みます。


ちょっと横着して、PIO0_2にLEDの長い方、PIO0_3に短い方を差し込んでテストします。

DATA L #10000400 ' stack top DATA L #21 ' entry point DATA L 0,0,0,0,0 DATA L #EFFFFBDF ' VALID_CODE = 0x100000000-0x10000400-0x21 @ENTRY R0=[@SYSAHBCLKCTRL]L R1=#DF 'SWT, GPIO, I2C:off, FLASH, FLASHREG, RAM, ROM, SYS [R0]L=R1 R0=[@PINENABLE0]L R1=[@PINENABLE0_DATA]L [R0]L=R1 R0=[@GPIO_DIR0]L R1=`1100 ' PIO0_2 and PIO0_3 [R0]L=R1 R0=[@GPIO_B0]L R1=1 [R0+2]=R1 GOTO 0 @SYSAHBCLKCTRL DATA L #40048080 @PINENABLE0 DATA L #4000C1C0 @PINENABLE0_DATA DATA L #FFFFFFBF @GPIO_DIR0 DATA L #A0002000 @GPIO_B0 DATA L #A0000000

LPC1114はCortex-M0、LPC810はCortex-M0+とマシン語はほぼ一緒ですが、IOの扱い方が違います。
1. LPC810のRAMは#10000000からの1KBなので、スタック初期値を#10000400に設定
2. 書き込みチェック用コードの次、#21にプログラム本体をおく
3. SYSAHBCLKCTRLで、GPIO、SWT(スイッチマトリクス、IOを切り替えるモノ)を設定
4. PINENABLE0で、PIO0_2/PIO0_3をGPIOとして使うよう設定
5. GPIO_DIR0で、PIO0_2/PIO0_3を出力に切り替え
6. GPIO_B0で、PIO0_2に1を書き込むと光る!
7. そのまま実行を続けてしまわなないように GOTO 0 で停止させておく

asm15で、Start Addressを0に設定、「hex file」出力を選択し、USBシリアルで書き込みます。
*3はスキップしても大丈夫でしたが、念のため。(参考、LPC1114の場合

次に、IchigoJam BASICでいう、WAITコマンドを実現して、0.5秒ごとについたり消えたりさせます。

DATA L #10000400 ' stack DATA L #21 ' entry point DATA L 0,0,0,0,0 DATA L #EFFFFBDF ' VALID_CODE = 0x100000000-0x10000400-0x21 @ENTRY R0=[@SYSAHBCLKCTRL]L R1=#DF 'SWT, GPIO, I2C:off, FLASH, FLASHREG, RAM, ROM, SYS [R0]L=R1 R0=[@FLASHCFG]L R1=[R0]L R2=3 ' set 0b00 == no wait R2=~R2 R1&=R2 [R0]L=R1 R0=[@PINENABLE0]L R1=[@PINENABLE0_DATA]L [R0]L=R1 R0=[@GPIO_DIR0]L R1=`1100 ' PIO0_2 and PIO0_3 [R0]L=R1 R0=[@GPIO_NOT0]L R1=`100 ' PIO0_2 R2=[@WAIT_N]L @LOOP [R0]=R1 ' 1cycle single cycle I/O R3=R2 ' 1cycle R3-=1 ' 1cycle IF !0 GOTO -1 'wait R3*3+2 cycles GOTO @LOOP ' 2cycles @SYSAHBCLKCTRL DATA L #40048080 @FLASHCFG DATA L #40040010 @PINENABLE0 DATA L #4000C1C0 @PINENABLE0_DATA DATA L #FFFFFFBF @GPIO_DIR0 DATA L #A0002000 @GPIO_NOT0 DATA L #A0002300 @WAIT_N DATA L 2000000

Cortex-M0+は、Cortex-M0と比較しGPIOアクセスや、GOTOのサイクルが短くなっています。(2→1、3→2、詳細はマニュアル参照

起動時の動作クロックは、内蔵オシレーターの12MHz。ウェイト用の1ループにかかる時間は3cycles。よって、12M/3で400万回ループで1秒。0.5秒のウェイトのために、WAIT_Nに200万を設定すればOK!

GPIO_NOT0という指定したビットに対応するIOを反転させるという便利な機能をつかって、エルチカループ(LOOP)をつくります。

注意点は、FLASHCFGの設定でウェイトを外しておくこと。 初期状態ではFlash ROMへのアクセスにウェイトがついているため、思ったより遅い点滅に悩みました。


2.54mmピッチではんだづけ工作にも優しい、8ピンDIPパッケージ(Dual inline package)のLPC810は、マシン語でさくっと遊べちゃうところもかわいい!

ARMマシン語に興味もった方、「はじめてのマシン語 - IchigoJamではじめるARMマシン語」をどうぞ!

links
- [PDF]UM10601 LPC81x User manual - NXP Semiconductors
- LPCマイコン情報:LPC800 Cortex-M0+搭載-スイッチ・マトリックス,LPC824,LPC822,LPC810,LPC811,LPC812,LPC810M021FN8,LPC824M201,LPC822M101,LPC811M001,LPC812M101

プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2

2017/11/09 23:55:00
#asm #wasm #js 

前回「ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1」では、マシン語の命令表からひとつずつ選んで数を書いてみました。 プログラムをこのようにマシン語にする作業のことをアセンブル(英語で組み立てを意味する)と言います。

数が多くなってくると、こうして手で変換するのは大変なので、プログラムを作って自動化しましょう。 今使っている環境の範囲だけで動く簡易的なアセンブラ「WebAssembly poor assembler」をJavaScriptで作りました。


WebAssembly poor assembler

こちら、前回はマシン語だった param+1 を計算するプログラムのアセンブリ言語プログラムです。

get_local $0 i32.const 1 i32.add end

「ASSEMBLE」ボタンを押すと、下に数字の並びに変換され、RUNで動かせます。

20 0 41 1 6a b

試しに、i32.add を i32.mul に書き換えて、ASSEMBLE、RUNしてみましょう。
i32.const 1 を i32.const 5 に書き換えて、ASSEMBLE、RUNしてみましょう。
param に、10と入力しなおして、RUNしてみましょう。

ちょっとだけ複雑な計算をさせてみます。

get_local $0 i32.const 5 i32.mul i32.const 1 i32.add end

i32.const 1 と i32.add を書き加えて、n*5+1 を計算するプログラムにしました。
ASSEMBLE、RUNしたり、paramを書き換えてみましょう。

このようにアセンブルを自動化するプログラムのことを、アセンブラといいます。
(手でアセンブルすることをハンドアセンブルといい、アセンブラがない時代の必須テクニックでした)

次はコンパイラを作ってみます。お楽しみに!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1

2017/11/07 23:55:00
#asm #wasm 

コンピューターの気持ちに近づけるマシン語。
IchigoJamだけで始めるARMマシン語入門に続き、
ブラウザだけで始めるWebAssemblyマシン語入門その1です。

コンピューターは高速に計算する機械(=マシン)です。

メモリ(=記憶装置)に2つの数があったら足し算する電子回路があるとします。
1と1をメモリに書いたら瞬時に2が得られます。
(参考「なぜコンピューターは計算が速いのか? 電気回路で計算ができる謎を解く」)

足し算だけだと使いみちが限られるので、引き算・掛け算や、計算順序を変える機能などを追加します。
機能を区別する方法は何でもいいのですが、計算が得意なコンピューターのために、それぞれの機能に数を割り当ててあげると効率的です。
やってほしい計算を表す数をずらずらと並べたもの、これがマシン語プログラムとなります。

IchigoJamで使っているのはARMという会社が考えたコンピューターなので、ARMマシン語。
今回使うWebAssemblyマシン語は、ブラウザで動くことにした仮想的なコンピューターです。
仮想的とは、マシン(ハードウェア)をソフト(=プログラム)で表現したものを言います。

とりあえず、動かしてみましょう。
WebAssembly testenv」を開き、「RUN」を押すと、2とでます。


WebAssembly testenv」で、1+1=2 をマシン語プログラムでつくり、動かした様子

「param」に1と書いてあるものを、10に変えて、もう一度「RUN」を押してみましょう。
きっと、今度は11と出ます。
(もし動かないならば、きっとお使いのブラウザがWebAssemblyに対応していません!Chrome/FireFox/Safariの最新版をダウンロードしましょう)

20 0 41 1 6a 0b

実はこれがWebAssemblyのマシン語です。(0〜9とa〜fの15種類の文字を使った16進法表記)

右の表を照らし合わせてみると・・・
20 0 ・・・ get_local $0 (渡された数をメモリに書くよ)
41 1 ・・・ i32.const 1 (1をメモリに書くよ)
6a ・・・ i32.add (メモリに書かれた2つの数を足してメモリに書くよ)
0b ・・・ end (プログラムを終わって、メモリに書かれたものを返すよ)

と解読できます。

10-1を計算させるには、i32.add (6a) の代わりに i32.sub (6b) を使います。

20 0 41 1 6b 0b

計算できました!

コードの上に書いてある、WebAssmeblyマシン語であることを表すIDなどと組み合わせて、.wasmファイルを作成すれば、ブラウザ上で高速に動くプログラムができるわけです!

右の表にあるものはもちろん一部です。
興味があればWebAssemblyの仕様書を覗いてみましょう。

ひとつひとつ表から照らし合わせてプログラムを書くのは大変なので、普通はこの作業をプログラムで自動化します。
アセンブラとか、コンパイラなどと呼ばれるソフトで、その数だけプログラミング言語があるわけですね!

マシン語が分かれば自分だけのプログラミング言語を作ることもできちゃいます!
日本生まれで世界に広がるプログラミング言語 Ruby に続こう!

WebAssemblyマシン語入門
- ブラウザだけでOK! 1+1からはじめる、WebAssemblyマシン語入門その1
- プログラミングはプログラミングで楽をする、WebAssemblyマシン語入門その2
- もっと楽するコンパイラ、WebAssemblyマシン語入門その3

LPC1114マシン語ベアメタル開発の魅力、プログラミングも世界共通語!

2017/10/21 23:55:00
#IchigoJam #asm 

たった28byteから始めるマシン語アプリ開発」でエルチカがうまくいかない謎が解けました。
4byteの数値が続くヘッダの8番目「Criterion for valid user code」の不備でした。(Thanks Amaganagi-san

ということで、LED1に相当するマシン語の最小コード改はこのコードを含めた32byteとなります。

DATA L #10001000 DATA L #00000009 R1=[@GPIO1DIR]L R0=`100000 [R1]=R0 R1=[@LED]L [R1]L=R0 GOTO 0 @GPIO1DIR DATA L #50018000 @LED ' PIO1_5 DATA L #50010080 @VALID_USER_CODE DATA L #FEDC5665

命令byteが20byteを超える場合は、次のように記述します。

DATA L #10001000 DATA L #00000021 DATA L 0,0,0,0,0 DATA L #EFFFEFDF R1=[@GPIO1DIR]L R0=`100000 [R1]L=R0 R2=0 R7=[@WAITCNT]L R1=[@LED]L @LOOP [R1]L=R0 R6=R7 R6-=1 IF !0 GOTO -1 [R1]L=R2 R6=R7 R6-=1 IF !0 GOTO -1 GOTO @LOOP @GPIO1DIR DATA L #50018000 @LED ' PIO1_5 DATA L #50010080 @WAITCNT DATA L 3000000

VALID_CODEは、hex(0x100000000-0x10001000-0x21) = 0xEFFFEFDF と計算します。
これで心置きなくマシン語でプログラミングできそうです!

夜中の帰国となり、大阪泊、オーストラリアから来ていたプログラマーの人に会いました。
LPC1114の開発に興味津々、C言語/マシン語でのベアメタル開発、楽しさを紹介!

世界に広がるPCN、音楽と同じようにプログラミングも世界共通語になりそうです!

大阪、道頓堀近く、HOLTEL HYAKU にて!

- 連載、IchigoJamではじめる、ARMマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法

画面をイチゴで埋め尽くす12の方法 / IchigoJamではじめるARMマシン語その11

2017/09/24 23:55:00
#IchigoJam #asm 

IchigoJamのキャラクターコード255は、イチゴ。
これで画面を埋め尽くす12の方法、まずはBASICから!


1. 延々イチゴを表示して埋め尽くす(GOTO編)

10 ?CHR$(255);:GOTO10 RUN

2. 延々イチゴを表示して埋め尽くす(CONT編)

1 ?CHR$(255);:CONT

再開するCONTコマンドは、プログラム内に書くとその行を再度実行として機能します

3. FOR/NEXTコマンドで埋め尽くす(768=32*24)

FORI=1TO768:?CHR$(255);:NEXT

4. VIDEO0で一旦画面出力を止めて高速化(画面表示OFFで約3倍速)

VIDEO0:FORI=1TO768:?CHR$(255);:NEXT:VIDEO1

5. LOCATE(短縮計LC)を使って縦に埋める

FORI=0TO31:FORJ=0TO23:LCI,J:?CHR$(255);:NEXT:NEXT

6. VRAMに直接書き込む(HELPコマンドでVRAMのアドレスが確認できます)

FORI=#900TO#BFF:POKEI,255:NEXT

7. COPYコマンドを使って一瞬で埋める

POKE#900,255:COPY#901,#900,768-1

実用的にはこれで十分ですが、マシン語を使って究極を目指してみます

8. マシン語を使って埋める (22byte 5383cycle)

R2=9 R2=R2<<8 R1=R1+R2 R2=32 R3=24 R2*=R3 @LOOP [R1]=R0 R1+=1 R2-=1 IF !0 GOTO @LOOP RET

32*48で768、数値が1byteの上限255を超えるので、掛け算命令で設定。

POKE#700,9,34,18,2,137,24,32,34,24,35,90,67,8,112,1,49,1,58,251,209,112,71 U=USR(#700,255)

ハンドアセンブルか、asm15アセンブラを使ってマシン語を作成しUSRコマンドで実行!
1cycle = 21nsec、割込が無いとすれば、113usec、つまり0.1ミリ秒で処理完了です。

9. マシン語、4byteまとめて埋めて高速化 (32byte 1356cycle)

R2=9 R2=R2<<8 R1=R1+R2 R2=R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R0=192 @LOOP [R1]L=R2 R1+=4 R0-=1 IF !0 GOTO @LOOP RET

メモリへの書き込みは1byte、2byte、4byteと3種類。まとめて4byte書くように変更することで、プログラムは10byte増えてしまいましたが、約4倍速に!

10. マシン語、まとめて転送命令STMを使って高速化 (42byte 381cycle)

PUSH {LR,R4,R5,R6,R7} R2=9 R2=R2<<8 R1=R1+R2 R2=R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R3=R2 R4=R2 R5=R2 R6=R2 R7=R2 R0=32 @LOOP STM R1,{R2,R3,R4,R5,R6,R7} R0-=1 IF !0 GOTO @LOOP POP {PC,R4,R5,R6,R7}

ARM Cortex-M0にあるまとめて転送命令STMは、アドレスR1へ複数指定したレジスタの値をアドレスの値を変更しながら高速に転送してくれます(転送時間=転送数+1クロック)。 R2からR7まで6レジスタ、24byteまとめて転送できるので32回ループすれば画面全部を埋められます。

11. マシン語、ループ展開 (92byte 251cycle、転送部分220cycle)

PUSH {LR,R4,R5,R6,R7} R2=9 R2=R2<<8 R1=R1+R2 R2=R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R3=R2 R4=R2 R5=R2 R6=R2 R7=R2 R0=R2 STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3,R4,R5,R6,R7} STM R1,{R0,R2,R3} POP {PC,R4,R5,R6,R7}

ループのために分岐すると3cycle時間を消費してしまうので、ループの数がそれほど多くなければ展開して高速化できます。 ループ用の変数が不要になるので、7レジスタ使ってSTMの回数も減らせて一石二鳥。 ただ、プログラム量は必然的に多くなりがちなので、容量に余裕がある時に使いましょう。

12. キーボードで ALT+V 押しっぱなし(手動)
プログラムを作ることはあくまで手段。手でやったほうが速いこともあります。

目的を達成するための方法は様々です。

同じマシン語でも8番のシンプルなマシン語に比べ、11番のプログラムでは、24倍も速くできました。
ターゲットのCPUに合わせた最適化を行うことで、ぐっと効率が上げられたりします。

BASICであってもコマンドの使い方次第でぐっと速くできます。
リファレンスを見直して、いろいろな使い方を探ってみるのもいいですね。

速度重視?容量重視?作りやすさ重視?
目的に合わせて選択できる手段を増やしておくと、叶う夢の幅が広がります!

(追記)
13. マシン語、ループ展開 PUSH編 (90byte 250cycle、転送部分214cycle)
IchigoJam-FANにて、PUSHを使った更に速い方法が発見されました!(Thanks Amanagi-san)
転送部分のみで214cycle、方法11と仕様を合わせても90byte/250cycleと、2byte減って1cycle/21nsec高速!

PUSH {LR,R4-R7} R2=#C R2=R2<<8 R1=R1+R2 R2=R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R2=R2<<8 R2=R2+R0 R12=R13 R13=R1 R1=R2 R3=R2 R4=R2 R5=R2 R6=R2 R7=R2 R0=R2 R14=R2 PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {LR,R0-R7} PUSH {R0-R2} R13=R12 POP {PC,R4-R7}

* スタックポインタ(R13)を破壊可能なR12に退避し、VRAMの末尾アドレスに変更、LR(R14)も使って36byte(9レジスタ*4byte)転送するという技!埋めるキャラクターがイチゴ(#FF)なのを利用して、更に縮めることも!?

- 連載、IchigoJamではじめる、ARMマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法

MSXのZ80マシン語解析と、IchigoJamの太字化マシン語プログラム

2017/09/17 23:55:00
#IchigoJam #asm #MSX 

IchigoJamの太字化、MSXの例に習ってマシン語化してみました。

POKE#800,7,34,18,2,137,24,10,120,19,70,82,8,26,67,10,112,1,49,1,56,247,209,112,71

PCGの#700に使いたい文字のパターンをコピー(この例は0〜9の数字をALT+0〜9へコピー)

COPY#700,ASC("0")*8,10*8

あとは太字化処理したいバイト数を指定してマシン語呼び出し!(2度実行すると更に太字に!)

U=USR(#800,10*8)

ALT+0〜9で書いてみましょう!プログラムでももちろん使えます

FOR I=0 TO 9:?CHR$(224+I):NEXT

ベースのアイデアはこちらMSX版

MSX BASICのプログラム、70行で書き込んでいる23byteのマシン語部分を解析(逆ハンドアセンブル)してみました。(表示用につくった MSXLIST

Z80のニーモニックを、asm15表記風に書いてみるとこんな感じです。

BC=#700 HL=#100 @LOOP CALL @RDVRM E=A A>>=1 A|=E CALL @WRVRM HL+=1 BC-=1 A=B A|=C IF !0 GOTO @LOOP RET

Z80のレジスタは基本8bitなので、16bitとして使うBCレジスタの0判定がおもしろいですね! MSXのVRAMはRAMに割り当てられていないので、BIOSというMSX組み込みのコードを呼び出していました(RDVRM/WRVRM)。 どうもこの呼出が結構遅い様子。VDPという一種のGPUを使って高速化するのが常套手段だったようです。(VDPはGPUの元祖かも?)

IchigoJam用に書き換えたマシン語がこちら(asm15 assemblerでアセンブルできます)

R2=7 R2=R2<<8 R1=R1+R2 @LOOP R2=[R1] R3=R2 R2=R2>>1 R2|=R3 [R1]=R2 R1+=1 R0-=1 IF !0 GOTO @LOOP RET

ほぼ一緒ですね!

このようにCPUが違うとそのCPUで使えるレジスタや、コマンドが違いますが、やっていることは基本的に同じ。 C言語やJavaなどは、このようなCPU毎の差を埋めるプログラム(コンパイラ)が助けてくれているわけです。

何でも作れちゃう感がアップする「マシン語」おすすめです!
連載、IchigoJamではじめる、ARMマシン語入門 1. はじめてのマシン語

amiiboも読める! マシン語で実用的になったRFID-RC522リーダー on IchigoJam

2017/08/22 23:55:00
#IchigoJam #maker #asm 

電車社会では手放せないFeliCa。
ピッと読み取るひみつは NFC(Near Field Communication / 近距離無線通信)という技術にあります。
カード側には電池が不要なので、安く、手軽に使えるのがポイントです。

先日実験した300円のNFCリーダー、RFID-RC522のIchigoJamプログラムを一部マシン語化して、実用的な速度になりました!(Amazonでタグ1枚100円未満!、リーダーRC522はなんと250円〜

FeliCaとは違う規格、RC522はMIFAREのRFIDリーダーですが、なんと任天堂の人形、amiiboが読めました!

amiibo認識するIchigoJamのデモ、子供に人気でした!

高校生三崎くんは、どこまで浮かせて読めるか早速実験!楽しいおもちゃを作って上げられそうっ

RC522-RFIDリーダープログラム、マシン語化手順(参考、SPI高速送信SPI高速受信
OUT2がSCK、OUT3がMOSI、IN1がMISOとして使う1byte(=8bit)のSPI通信は、BASICで書くとこうなります。

10 @SPI:N=0 'send:M recv:N 20 FOR I=7 TO 0 STEP-1 30 OUT2,0 40 OUT3,M>>I&1 50 N=IN(1)<<I|N 60 OUT2,1 70 NEXT

これをアセンブリ言語で書いて

@SPI PUSH {LR,R4,R5} R3=#50 ' R3=#50010000 GPIO1 R3=R3<<8 R4=R3 ' R4=#50000000 + (1<<(10+2)) IN(1) GPIO0_10 R3=R3+1 R3=R3<<16 R4=R4<<16 R2=1 R2=R2<<12 R4=R4+R2 R5=0 R1=#80 @LOOP R2=0 R0&R1 'F=N>>(7-I)&1 IF 0 goto @SKIP1 R2+=4 @SKIP1 [R3+`110]L=R2 ' OUT2,0:OUT3,F R2=2 [R3+`0010]L=R2 ' OUT2,1 R2=[R4]L ' IN(1) R2-0 IF 0 goto @SKIP2 R5=R5+R1 @SKIP2 R1=R1>>1 IF !0 goto @LOOP @END R0=R5 POP {PC,R4,R5}

レジスタの役割:R0 送信データ、R1 カウンタ、R2 書き込み用、R3 GPIO1 for OUT、R4 GPIO0 for IN、R5 受信データ

asm15アセンブラでマシン語化

10 POKE#700,48,181,80,35,27,2,28,70,91,28,27,4,36,4,1,34,18,3,164,24,0,37,128,33,0,34,8,66,0,208,4,50,154,97,2,34,154,96,34,104 20 POKE#728,0,42,0,208,109,24,73,8,242,209,40,70,48,189

前回はBASICだったSPI通信部分をマシン語呼び出しに置き換えて、できあがり!

1 'RFID-RC522 1/2 2 A=#700:POKEA,48,181,80,35,27,2,28,70,91,28,27,4,36,4,1,34,18,3,164,24,0,37,128,33,0,34,8,66,0,208,4,50,154,97,2,34,154,96,34,104 3 POKE#728,0,42,0,208,109,24,73,8,242,209,40,70,48,189 10 OUT4,0:WAIT4:OUT1,1:OUT4,1 20 LET[0],#2400,#2600,#4826,#5480,#56A9,#5803,#5AE8,#2A40,#223D 30 FORJ=0TO8:N=[J]:GSB@SPIW:NEXT 40 N=#28:GSB@SPIR:IF N&3!=3 N=#2800|N|3:GSB@SPIW 50 @LOOP:?"."; 55 LET[0],#2400,#2600,#4826 60 FORJ=0TO2:N=[J]:GSB@SPIW:NEXT 70 N=#1C:GSB@SPIR:N=#1C00|N&#7F:GSB@SPIW 90 LET[0],#200,#87F,#1480,#1226,#1A07,#20C 100 FORJ=0TO5:N=[J]:GSB@SPIW:NEXT 110 N=#1A:GSB@SPIR:N=#1A00|N|#80:GSB@SPIW 120 N=#8:GSB@SPIR:IF N&1 GOTO@LOOP 130 IF N&#30=0 GOTO120 140 N=#C:GSB@SPIR:IFN&#13?"ERR";N:GOTO@LOOP 150 N=#14:GSB@SPIR:IFN!=2GOTO@LOOP 160 N=#12:GSB@SPI2R 170 N=#18:GSB@SPIR 190 ?"!":LRUN FILE()+1 500 @SPIW:OUT1,0:U=USR(A,N>>8):U=USR(A,N):OUT1,1:RTN 510 @SPIR:OUT1,0:U=USR(A,N|#80):N=USR(A,0):OUT1,1:RTN 520 @SPI2R:OUT1,0:N=N|#80:U=USR(A,N):N=USR(A,N)<<8|USR(A,0):OUT1,1:RTN SAVE0 NEW 1 'RFID-RC522 2/2 10 N=#1C:GSB@SPIR:N=#1C00|N&~#80:GSB@SPIW:N=#1A00:GSB@SPIW 30 LET[0],#200,#87F,#1480:FORJ=0TO2:N=[J]:GSB@SPIW:NEXT 50 N=#1293:M=2<<4:GSB@SPI2W:N=#1A00:GSB@SPIW:N=#20C:GSB@SPIW 110 N=#1A:GSB@SPIR:N=#1A00|N|#80:GSB@SPIW 120 N=#8:GSB@SPIR:IFN&1GOTO@END 130 IFN&#30=0GOTO120 140 N=#C:GSB@SPIR:E=N:IFE&#13GOTO@END 150 N=#14:GSB@SPIR:IF N!=5 GOTO@END 160 M=N:N=#12:GSB@SPIAR:FORI=0TOM-1:?HEX$([I],2);:NEXT:? 170 N=#18:GSB@SPIR 190 @END:LRUNFILE()-1 'ASM 500 @SPIW:OUT1,0:U=USR(A,N>>8):U=USR(A,N):OUT1,1:RTN 505 @SPI2W:OUT1,0:U=USR(A,N>>8):U=USR(A,N):U=USR(A,M):OUT1,1:RTN 510 @SPIR:OUT1,0:U=USR(A,N|#80):N=USR(A,0):OUT1,1:RTN 530 @SPIAR:OUT1,0:N=N|#80:U=USR(A,N) 540 FORJ=0TOM-1:[J]=USR(A,N):NEXT 550 J=J+1:[J]=USR(A,0):OUT1,1:RTN SAVE1 LRUN0

* RC522の初期化とカード認識と、ID読み込みで2ファイル使います(上記はFILE0とFILE1使用)

高専インターン2日目は企画づくりとチーム決定、4名ずつ4チームが決定です!
チームとタイトルの二日目 - jigintern2017の日記

全国から集まった高専生、お土産も多彩!お返しに IchigoJamハーフキット!

鯖江市市民主役事業、中学校の先生向けプログラミング研修では、はんだづけからのパソコンづくりと、プログラミングづくり体験を実施。 興味持った子供が通える「Hana道場」が鯖江のいいところ!

未来の高専生!? 夏休み中の小学生で賑わうHana道場
Ichigoチョコ越前がにロボコンテストコース、片道攻略!

どんなロボットでも歓迎、小学生向け越前がにロボコン、エントリー締切は8月末!

54byteのスーファミコントローラドライバ、IchigoJam BASICとマシン語でつなぐ極上のコントローラ

2017/08/16 23:55:00
#IchigoJam #asm #game 

IchigoJamにスーファミコントローラがつながりました!
個人的コントローラランキング、ナンバーワンのスーファミコントローラ、konashiでiPhoneにつないだこともありました。

接続に便利だった、Raspberry Piのスーパーファミコン化プロジェクトのコントローラ変換器!(official site)

こちら先日のコミケC92で入手! (スーファミコスプレな @ichigonosaatan さぁたん)

配線は本の記述とはちょっと違っていて、CLKの上にある3.3V、P/Sの下にあるGNDを使っていました。
スーファミのコントローラ3.3Vでも動くようです!

ファミコンもスーファミも、コントローラとの通信はYMF825と同じ、おなじみSPI。
ファミコンは8bit、スーファミはボタンが増えた分、上位8bitが追加されて16bitでの通信となります。

ひとまず、下記のようにつないで、IchigoJam BASICで動作確認。
OUT1 P/S(LATCH)
OUT2 CLK
IN1 1PAD

10 OUT1,1:OUT2,1 20 GSB@SPIR:?BIN$(N,16):CONT 100 @SPIR:OUT1,0:N=0:FORI=0TO15:OUT2,0:N=IN(1)<<I|N:OUT2,1:NEXT:OUT1,1:RTN

これだけで動きました!感動!

ただ、ゲームなどに使うには動作が遅すぎるので、マシン語でSPIテクニックを使って、高速化します。

@SPIR PUSH {LR,R4} R3=#50 ' R3=#50010000 GPIO1 R3=R3<<8 R4=R3 ' R4=#50000000 + (1<<(10+2)) IN(1) R4=R4<<16 R3=R3+1 R3=R3<<16 R2=1 R2=R2<<12 R4=R4+R2 R2=0 [R3+`0001]L=R2 ' OUT1,0 R1=0 @LOOP R2=0 [R3+`0010]L=R2 ' OUT2,0 R2=[R4]L ' IN(1) R2=R2>>10 R2<<=R1 R0=R0+R2 R2=2 [R3+`0010]L=R2 ' OUT2,1 R1+=1 R1-16 IF !0 goto @LOOP @END R2=1 [R3+`0001]L=R2 ' OUT1,1 POP {LR,R4}

マシン語入門その4を参考にIN1を調べるとピンの名前はPIO0_10、GPIO0のベースアドレスが#50000000と分かります。

できあがった、マシン語のスーファミコントローラドライバ(ファミコンにも使えます)を組み合わせたテストプログラムがこちら

1 POKE#700,16,181,80,35,27,2,28,70,36,4,91,28,27,4,1,34,18,3,164,24,0,34,90,96,0,33,0,34,154,96,34,104,146,10,138,64,128,24,2,34 2 POKE#728,154,96,1,49,16,41,244,209,1,34,90,96,16,189 10 OUT1,1:OUT2,1 20 N=USR(#700,0):?BIN$(N,16):CONT

マシン語は一度メモリに書き込んでおけばOKなので、メインプログラムを広々使っていろいろつくれますね!

BASICとマシン語の動作速度の違いが分かる動画がこちら!

IchigoJamでスーファミコントローラを読む(BASICとマシン語でSPI)

スーファミコントローラ接続、真の狙いは、FM音源モジュールYMF825Boardと合わせた楽器づくり!

YMF825で楽器づくり「FM音源キーボード」マシン語で高速SPI、IchigoJamでまなぶ ARMマシン語入門その9

2017/08/15 23:55:00
#IchigoJam #music #asm 

FM音源チップ、YMF825、IchigoJam BASICで鳴ったので、次は楽器づくり!
問題は、BASICでは遅いこと。音を鳴らすための2byteのSPI送信5回に、0.73秒もかかっているので、ゆっくりチャイムを鳴らすくらいしか使えません。
* SPIとは、クロックに合わせて信号を送受信するシンプルな通信方式 (SPI on Wikipedia)


FM音源キーボード on IchigoJam デモ動画

おや!?小気味よく鳴ってますね!これがマシン語パワーです!
復習を兼ねて、OUTポートをマシン語で使う実験をしてみます。(参考、マシン語でLEDを光らせよう

LEDが接続されている端子は、PIO1_5、アドレスとしてはPIO1のベースアドレス#50010000に、2進数の`10000000(= 1&<&<(5+2))を加えた場所に書き込めばOK!

@LED1 R3=#50 ' R3=#50010000 R3=R3<<8 R3=R3+1 R3=R3<<16 R2=`10000000 R3=R3+R2 R2=R2>>2 [R3]L=R2 ' GPIO1_5 <- 1 RET

asm15アセンブラを使うか、ハンドアセンブルして、できたマシン語コードを動かしてマシン語でLED1!

POKE#700,80,35,27,2,91,28,27,4,128,34,155,24,146,8,26,96,112,71 ?USR(#700,0)

次はBASICでつくったSPI送信をマシン語化します。

@SPIW:OUT4,0:FORI=0TO15:OUT2,0:OUT3,N>>(15-I)&1:OUT2,1:NEXT:OUT4,1:RTN

まずは分解!

OUT4,0 FORI=0TO15 F=N>>(15-I)&1 OUT2,0:OUT3,F OUT2,1 NEXT OUT4,1 RTN

ひとつずつマシン語化すれば、できあがり!

@SPIW R3=#50 ' R3=#50010000 R3=R3<<8 R3=R3+1 R3=R3<<16 R2=0 [R3+`1000]L=R2 ' OUT4,0 R1=1 R1=R1<<15 @LOOP R2=0 R0&R1 'F=N>>(15-I)&1 IF 0 goto @SKIP R2+=4 @SKIP [R3+`110]L=R2 ' OUT2,0:OUT3,F R2+=2 [R3+`110]L=R2 ' OUT2,1 R1=R1>>1 IF !0 goto @LOOP @END R2=8 [R3+`1000]L=R2 ' OUT4,1 RET

アセンブラasm15を使って2byte送信SPIマシン語バイナリができました!
送信したい16bitの数値を、USRコマンドの第二パラメータにいれるだけ!(マシン語にはレジスタR0として渡される)

POKE#700,80,35,27,2,91,28,27,4,0,34,26,98,1,33,201,3,0,34,8,66,0,208,4,50,154,97,2,50,154,97,73,8,246,209,8,34,26,98,112,71

準備ができたので、早速楽器づくり、まずはIchigoJamのボタンを使った単音楽器で実験!
前回のYMF825の初期化プログラムを動かし、音がなる状態にしてからNEW、次のプログラムを入力。
*マシン語化した初期化プログラム、後述します

1 'FM BTN 10 A=#700:POKEA,80,35,27,2,91,28,27,4,0,34,26,98,1,33,201,3,0,34,8,66,0,208,4,50,154,97,2,50,154,97,73,8,246,209,8,34,26,98,112,71 20 T=#1465 30 IF !BTN() CONT 40 U=USR(A,#0B00):U=USR(A,#0C54):U=USR(A,#0D00+T>>8):U=USR(A,#0E00+T&#FF):U=USR(A,#0F40) 50 IF BTN() CONT 60 U=USR(A,#0F00) 70 GOTO 30

ボタンを押したら鳴り始め、離したたらキーオフ!
反応速度もいい感じ!いろんなボタンをつなげて遊べそうですね!
*時間を測ってみると、1回の送信でTICKで1、約1/60秒、100倍速い!

次は、キーボードで楽器キーボードをつくってみます。
キーボードのZXCがドレミ、SDなどで半音にも対応します。

1 'FM KEYBOARD 10 A=#700:POKEA,80,35,27,2,91,28,27,4,0,34,26,98,1,33,201,3,0,34,8,66,0,208,4,50,154,97,2,50,154,97,73,8,246,209,8,34,26,98,112,71 100 FORI=0TO15:U=USR(A,#0B00+I):U=USR(A,#0F30):U=USR(A,#1071):U=USR(A,#1101):U=USR(A,#1208):U=USR(A,#1300):U=USR(A,#0C54):NEXT 200 LET[0],357,378,401,425,450,477,505,535,567,601,637,674 210 M="ZSXDCVGBHNJM,L." 220 K=INKEY():IF!KCONT 230 N=0 240 IF PEEK(M+N)=K GOTO300 250 N=N+1:IF N=15 GOTO 220 260 GOTO240 300 ?N:T=[N%12]:B=4+N/12:T=T&#7F+T>>7<<11+B<<8 310 U=USR(A,#0B00+N):U=USR(A,#0F00): 320 U=USR(A,#0D00+T>>8):U=USR(A,#0E00+T&#FF):U=USR(A,#0F40) 330 GOTO 220

キーは離されたタイミングが取得できないので、キーが押された時に、キーオフ(310行)してから、キーオン(320行)するようにしています。

ついでに、初期化コードもマシン語で高速化!

1 'FM INIT 10 OUT1,0:WAIT1:OUT4,1:OUT1,1 13 A=#700:POKEA,80,35,27,2,91,28,27,4,0,34,26,98,1,33,201,3,0,34,8,66,0,208,4,50,154,97,2,50,154,97,73,8,246,209,8,34,26,98,112,71 14 S=#728:POKES,80,35,27,2,91,28,27,4,128,33,0,34,8,66,0,208,4,50,154,97,2,50,154,97,73,8,246,209,112,71 15 'INIT 20 LET[0],#1D01,#020E,-1,#0001,#0100,#1AA3,-1,#1A00,-30,#0204,-1,#0204,-1,#0200,#197C,#1B3F,#1400,#0301,#08F6,-21,#0800,#09FB,#0A00,#01740,#1800,0 22 FORJ=0TO99:N=[J]:IF!N J=99:GOTO26 24 IF N<0 WAIT -N ELSE U=USR(A,N) 26 NEXT 30 'SETCH 31 LET[0],#0F30,#1071,#1101,#1208,#1300 32 FORJ=0TO4:U=USR(A,[J]):NEXT 40 'SETTONE 41 U=USR(A,#08F6):WAIT1:U=USR(A,#0800) 42 LET[0],7,#81,1,#43,0,#E7,#FF,#9D,0,#10,#40,#20,#33,#E2,#73,0,#50,#40,#10,#41,#D3,#5B,0,#10,#41,#20,#63,#D4,2,1,#10,#40,#80,3,#81,#80 43 M=36 50 @SPIAW:OUT4,0:FORK=0TOM-1:U=USR(S,[K]):NEXT:OUT4,1

配列をSPIで送信する @SPIAW の内部、8bitのSPI送信もマシン語化しました(アドレス#728=S)

@SPI1W R3=#50 ' R3=#50010000 R3=R3<<8 R3=R3+1 R3=R3<16 R1=#80 @LOOP R2=0 R0&R1 'F=N>>(7-I)&1 IF 0 goto @SKIP R2+=4 @SKIP [R3+`110]L=R2 ' OUT2,0:OUT3,F R2+=2 [R3+`110]L=R2 ' OUT2,1 R1=R1>>1 IF !0 goto @LOOP @END RET

FM音源音色エディタもマシン語化!

1 'FM EDITOR 5 CLS 10 ?" 1 BO 3:";[40] 20 ?" 2 LFO 3:";[41] 30 ?" 3 ALG 7:";[42] 40 LET[80],"SR 15","XOF 1","KSR 1","RR 15","DR 15","AR 15","SL 15","TL 63","KSL 3","EAM 1","DAM 3","EVB 1","DVB 3","MUL15","DT 7","WS 31","FB 7" 50 FORJ=0TO1:FORI=0TO16:LCJ*15,3+I:?DEC$(4+I+J*17,2);" ";STR$([80+I]);":";[43+I+J*17]:NEXT:NEXT 60 INPUT"ID :",I 70 INPUT"VAL:",V:[39+I]=V 75 GSB@TESTTONE 80 GOTO 5 100 @TESTTONE 110 LET[0],7,#81,[40],[41]<<6+[42] 120 FORJ=0TO1:P=43+J*17 130 LET[4+J*7],[P]<<4+[P+1]<<3+[P+2],[P+3]<<4+[P+4],[P+5]<<4+[P+6],[P+7]<<2+[P+8],[P+9]<<4+[P+10]<<5+[P+11]+[P+12]<<1,[P+13]<<4+[P+14],[P+15]<<3+[P+16] 132 NEXT 141 U=USR(A,#08F6):WAIT1:U=USR(A,#0800) 143 M=36:GSB@SPIAW 150 T=#1465 160 U=USR(A,#0F00):U=USR(A,#0B00):U=USR(A,#0C54):U=USR(A,#0D00+T>>8):U=USR(A,#0E00+T&#FF):U=USR(A,#0F40) 180 RTN 1010 @SPIAW:OUT4,0:FORK=0TOM-1:U=USR(S,[K]):NEXT:OUT4,1:RTN

YMF825初期化コード実行後に動かし、いい音色ができたら、ボタン楽器や、キーボード楽器で演奏しよう!

Enjoy to create original musical instruments with FM!
オリジナル楽器作りを楽しもう!

links
- YMF825 x IchigoJamで鳴らすFM音源チャイム、BASICでつくるYMF825Board用FM音源エディタ (ハードウェア準備、接続方法)
- YMF825Board GitHubPage へようこそ!
- ヤマハ製YMF825使用FM音源LSIモジュール: 組立キット 秋月電子通商 電子部品 ネット通販
- ヤマハFM音源LSI YMF825搭載モジュール YMF825Board - SWITCH-SCIENCE

- 連載、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