#RETROF-16 機械語命令一覧
全ての命令を13クロックで実行します。(停止命令のみ10クロックで実行)
クロックは16MHzですので、本機は本記事の命令を1秒間に123万命令実行できます。
###表中の略語
- mnim : ニモニック
- opr : オペランドを要する命令か否か(〇 要、― 不要)
- flg : フラグが変化する命令か否か(〇 変化する、― 変化しない)
- Acc : アキュムレータ
- Memory[op] : オペランドをアドレスとする主メモリの値
- VRAM[op] : オペランドをアドレスとするビデオメモリの値
- xx :オペランド。以下の4通りの書き方がある。
|書式|意味|補足|
|---|---|---|---|
| 数値 |数値をそのまま参照する|数値は0~255(または#00~#FF)|
| $数値 |n番レジスタの値を参照する|nが数値。0~255(または#00~#FF)|
| %数値 |n番レジスタが示すメモリの値
を参照する|nが数値。0~255(または#00~#FF)|
|数値|数値をそのままop参照する
この書式は2ワード命令となる|数値は256~65535
(または#0100~#FFFF)|
###命令一覧
機械語 | mnim | opr | flg | 機能 | 注 |
---|---|---|---|---|---|
0000_00xx | jmp xx | 〇 | ― | 絶対アドレス分岐する | |
0001_00xx | jb xx | 〇 | ― | LCD表示回路が水平帰還時なら(以下同上) | *1 |
0010_00xx | jnf xx | 〇 | ― | 演算結果が0xFFFF以外なら(以下同上) | |
0011_00xx | jf xx | 〇 | ― | 演算結果が0xFFFFなら(以下同上) | |
0100_00xx | jnc xx | 〇 | ― | 加算にキャリーが無ければ(以下同上) | *2 |
0101_00xx | jc xx | 〇 | ― | 加算にキャリーがあれば(以下同上) | *2 |
0110_00xx | jm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
0111_00xx | jnm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
0000_01xx | fj xx | 〇 | ― | opの値分、前方へ相対アドレス分岐する | *3 |
0001_01xx | fb xx | 〇 | ― | LCD表示回路が水平帰還時なら(以下同上) | *1 |
0010_01xx | fnf xx | 〇 | ― | 演算結果が0xFFFF以外なら(以下同上) | |
0011_01xx | ff xx | 〇 | ― | 演算結果が0xFFFFなら(以下同上) | |
0100_01xx | fnc xx | 〇 | ― | 加算にキャリーが無ければ(以下同上) | *2 |
0101_01xx | fc xx | 〇 | ― | 加算にキャリーがあれば(以下同上) | *2 |
0110_01xx | fm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
0111_01xx | fnm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
0000_10xx | bj xx | 〇 | ― | opの値分、後方へ相対アドレス分岐する | *3 |
0001_10xx | bb xx | 〇 | ― | LCD表示回路が水平帰還時なら(以下同上) | *1 |
0010_10xx | bnf xx | 〇 | ― | 演算結果が0xFFFF以外なら(以下同上) | |
0011_10xx | bf xx | 〇 | ― | 演算結果が0xFFFFなら(以下同上) | |
0100_10xx | bnc xx | 〇 | ― | 加算にキャリーが無ければ(以下同上) | *2 |
0101_10xx | bc xx | 〇 | ― | 加算にキャリーがあれば(以下同上) | *2 |
0110_10xx | bm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
0111_10xx | bnm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
0000_11xx | hlt xx | 〇 | ― | opの値を基板のLEDに表示し停止する | |
0001_11xx | hb xx | 〇 | ― | LCD表示回路が水平帰還時なら(以下同上) | *1 |
0010_11xx | hnf xx | 〇 | ― | 演算結果が0xFFFF以外なら(以下同上) | |
0011_11xx | hf xx | 〇 | ― | 演算結果が0xFFFFなら(以下同上) | |
0100_11xx | hnc xx | 〇 | ― | 加算にキャリーが無ければ(以下同上) | *2 |
0101_11xx | hc xx | 〇 | ― | 加算にキャリーがあれば(以下同上) | *2 |
0110_11xx | hm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
0111_11xx | hnm xx | 〇 | ― | 演算結果のMSBが1なら(以下同上) | |
1000_00xx | ldi xx | 〇 | 〇 | opの値をAccに格納する | |
1000_01xx | add xx | 〇 | 〇 | Acc+opをAccに格納する | |
1000_10xx | sub xx | 〇 | 〇 | Acc-opをAccに格納する | |
1000_11xx | ldn xx | 〇 | 〇 | opの反転値をAccに格納する | |
1001_00xx | and xx | 〇 | 〇 | Acc&opをAccに格納する | |
1001_01xx | or xx | 〇 | 〇 | Acc|opをAccに格納する | |
1001_10xx | xor xx | 〇 | 〇 | Acc^opをAccに格納する | |
1001_11xx | add xx | 〇 | 〇 | Acc^opの反転値をAccに格納する | |
1100_00xx | stm xx | 〇 | ― | Memory[op]にAcc値をストアする | |
1100_01xx | ldm xx | 〇 | 〇 | Memory[op]の値をAcc値をロードする | |
1100_10xx | stv xx | 〇 | ― | VRAM[op]にAcc値をストアする | |
1100_11xx | ldv xx | 〇 | 〇 | VRAM[op]の値をAcc値をロードする | |
1101_00xx | out xx | 〇 | ― | Accの値を下段、op値を上段LEDに表示する | |
1101_01xx | lpc xx | ― | 〇 | プログラムカウンタの値をAccに格納する | *4 |
1101_10xx | sft xx | ― | 〇 | Accを右シフトする。MSBには0が入る | |
1101_11xx | ina xx | ― | ― | 入力ポートAの値をAccに格納する | |
1111_11xx | inb xx | ― | ― | 入力ポートBの値をAccに格納する |
(*1) 「水平帰還時」に関しては、ここでは詳細説明は割愛。「水平帰還信号」「水平ポーチ信号」「水平ブランキング機関」等で検索のこと。
(*2) 減算時はjncが「ボローがあれば分岐」、jcが「ボローが無ければ分岐」となる。
(*3) 相対分岐はlpc命令の次の命令が起点。自分自身への分岐は「bj 1」もしくは「ff 65535」。
(*4) Accに格納される値はlpc命令の次の命令のアドレスとなる。
ldv命令とstv命令に関する補足
- ldv(load from video-RAM)=> オペランドで決まる位置のドットの色をAccに読み込む
- stv(store to video-RAN)=> オペランドで決まる位置にAcc値で決まる色のドットを描画する
「オペランドで決まる位置」とは、画面上の左上が0x0000、右下が0xFFFFとなります。
本機は16bitマシンですが、画像データバスは6bitです。従ってldv命令の実行直後はAccの上位10bitは「不定」となります。また、stv命令実行時はAccの上位10bitは意味を持ちません。
RGBの3色は各々2bit(4階調)です。青色を例にとると、この2bitと明度の関係は以下となります(赤や緑も同様です)。
- XXXX_XXXX_XX00_0011 ⇒ 青
- XXXX_XXXX_XX00_0010 ⇒ やや暗い青
- XXXX_XXXX_XX00_0001 ⇒ とても暗い青
- XXXX_XXXX_XX00_0011 ⇒ 黒
ldi命令とldm命令の差異に関する補足
本機は主メモリの0~255番地を汎用レジスタ領域としているため、例えば「主メモリの100番地の値」と「100番レジスタの値」は同義となる。
このためldiとldm命令はアドレッシングモードによっては全く同じ動作をする命令となることがある。
- ldi(load immediate) => 値(オペランド)を直接ACCに格納する
- ldm(load from memory)=> 値をアドレスとし、メモリ値をACCに格納する
以下は、4つのアドレッシングモードを加味したldiとldm命令の比較である。
記述例 | 対応する機械語命令 | 機能 | |
---|---|---|---|
A | ldi 5 | 1000_0000_0000_0101 | 数値5がAccに格納される |
B | ldi $5 | 1000_0001_0000_0101 | 5番レジスタの内容がAccに格納される |
C | ldi %5 | 1000_0010_0000_0101 | 5番レジスタの内容をアドレスとした 主メモリの内容がAccに格納される |
D | ldi 255 | 1000_0000_0000_0000 0000_0001_0000_0000 |
数値256がAccに格納される (数値が256以上は2ワード命令となる) |
E | ldm 5 | 1000_0000_0000_0101 | 5番レジスタの内容がAccに格納される |
F | ldm $5 | 1000_0001_0000_0101 | 5番レジスタの内容をアドレスとした 主メモリの内容がAccに格納される |
G | ldm %5 | 1000_0010_0000_0101 | 5番レジスタの内容をアドレスとした 主メモリの値を、更にアドレスとして その主メモリの値がAccに格納される |
H | ldm 255 | 1000_0000_0000_0000 0000_0001_0000_0000 |
256番地の内容がAccに格納される (数値が256以上は2ワード命令となる) |
この表で判るように「BとE」及び「CとF」は全く同じ命令となる。
どちらを使用しても問題は無いが、immediate(即値)と言う言葉を意識するのであれば、、即値代入以外はldi命令と称するのは好ましくない。このため運用上の制限ではあるが「BとC」は使わない事とする。