この世のCPUを食べ尽くすのだ! 第0章 第1節
~あんたCPUなんか創ってどうするのよ?! Vol.3~
2018/10/8
技術書典5 け39
第0章 第1節 これまでの経緯
TD4には実用性が無いと書きましたが、理由を説明します。
まず分かりやすいのは、最大プログラムサイズが16バイト(16命令)しかない点です。TD4はプログラムカウンタが4ビットしかなく、ジャンプ命令でのジャンプ先アドレスの指定も4ビットしかありません。そのため最大プログラムサイズが16バイトに制限されています。
そこで筆者はTD4に可変長命令を導入し、ジャンプ命令(条件ジャンプ命令を含む)だけを2バイト命令に変更しました。これによりジャンプ命令中のジャンプ先のアドレス指定を12ビットに拡張し、それに合わせてプログラムカウンタを12ビットに拡大しました。
筆者はこれをTD4EX2と命名しました。詳細は「あんたCPUなんか創ってどうするのよ?!」をご覧ください。
TD4EX2は12ビットのプログラムカウンタにより4KBもの広大なプログラムエリアを持っています。これは世界初の商用ワンチップCPUであるIntel 4004と同じ広さです。
4004の開発者の一人である嶋正利氏は、完成した4004を利用した電卓を開発する際に、プログラムサイズを1KB以内に収めた そうですから、本プロジェクトでも4KBあれば余裕で電卓の作成できるでしょう。(どうせ2桁ですし。)
2個目の欠点はプログラミングの知識がないと理解できないかもしれません。
表1のTD4の命令一覧を見れば分かりますがTD4はイミディエイトデータとの加算しかできません。
命令 | オペコード | 説明 | ||
---|---|---|---|---|
ADD | A, | Im | 0000 | Aレジスタの内容に命令中で指定された定数(Im)を加算 |
MOV | A, | B | 0001 | AレジスタにBレジスタの内容を転送 |
IN | A | 0010 | 入力ポートからデータを取り込み、Aレジスタに格納 | |
MOV | A, | Im | 0011 | Aレジスタに命令中で指定された定数(Im)を格納 |
MOV | B, | A | 0100 | BレジスタにAレジスタの内容を転送 |
ADD | B, | Im | 0101 | Bレジスタの内容に命令中で指定された定数(Im)を加算 |
IN | B | 0110 | 入力ポートからデータを取り込み、Bレジスタに格納 | |
MOV | B, | Im | 0111 | Bレジスタに命令中で指定された定数(Im)を格納 |
OUT | B | 1001 | Bレジスタの内容を出力ポートに出力 | |
OUT | Im | 1011 | 命令中で指定された定数を出力ポートに出力 | |
JNC | Im | 1110 | キャリー(C)がゼロならば指定アドレス(Im)にジャンプ | |
JMP | Im | 1111 | 指定アドレス(Im)にジャンプ |
イミディエイトデータとはプログラム中に記述された数値、つまり即値のことです。これはプログラム中に記述されているために、プログラムを書き換えない限り値の変更ができません。例えばプログラム作成時に5と記述したら、プログラムの実行中はずっと5のままで、値を変更できません。
電卓を実現するためには数値を2つ入力して加減乗除を実行できる必要がありますが、TD4はイミディエイトデータとの加算しかできないため、入力した数値同士を加算することができません。2つあるアキュムレーター(レジスタAとレジスタB)に数値を入力しても、両者を加算できないのです。
これでは電卓用CPUとして使い物になりません。
そこで筆者は前作「ええっ?! CPU創ったの?! すっごーい!」でアキュムレータ間加算を実現しました。レジスタAとレジスタBの内容を加算し、結果をレジスタAまたはレジスタBに格納することができます。
筆者はこれをTD4EX1と命名しました。
とは言え、TD4EX1は前作限りで終了です。本書以降ではTD4EX2をベースとしてCPUを拡張していきます。なぜならRAMを追加してしまえばアキュムレータ間加算は不要だからです。
AレジスタとBレジスタとを加算するアキュムレータ間加算命令は、無いよりはあった方が便利なのですが、それを実現するためには余分なICが必要となります。TD4の「必要最小限のICでCPUを作る」という方針を守るためには「必須」な命令のみを採用し、「あった方が良い」程度の命令は削除する必要があります。