TX-0 世界初のホビーマシン
目次
TX-0 の命令セット
先に書いた通り、TX-0 は、大容量コアメモリの動作試験のために作られました。
そのため、メモリ空間は 16bit 、65536ワードあります。
1ワードは 18bit でした。
…現在の常識から見ると、中途半端なビット数に見えますが、これには2つの理由があります。
まず、当時は、1ワードで1命令を表現するのが普通でした。この中には、命令で使うメモリのアドレスも含みます。
16bit アドレス、というのは開発当初からの目標でした。1ワードにそのアドレスを含むのですから、ワード長は 16bit +αである必要があります。
もう一つの理由は、当時は「6bit が1バイト」であることが普通だったためです。
バイト、というのは、コンピューターが処理を行う上で、扱いやすいまとまりのことです。
BCD (2進化10進)で計算を行うのであれば 4bit 単位が扱いやすいのですが、もっと重要なのは、文字の扱いでした。
当時は ASCII コード(7bit コード)の制定前で、統一的な文字コードはありません。また、当時の文字コードはタイプライターの考えで作られていたため、大文字小文字の使い分けは「シフトモード」によって区別していました。
このため、アルファベット 26文字と数字10文字、これに記号をいくつか入れてもせいぜい 50文字程度。6bit あれば十分だったのです。
TX-0 は、16bit アドレスを含む命令を 1word で実現できること、6bit バイトを処理しやすい処理単位であること、の2つを考慮して、1ワード 18bit が選択されました。
つまり、アドレスに 16bit 、命令に 2bit というコード体系です。2bit なら、4つの命令を定義できます。
たった4つの命令
そうなのです。TX-0 は、たった4命令しか持ちません。
しかし、この4命令は非常によく考えられたもので、コンピューターとして完全に動作することが出来ました。
4命令のうち3つは、次のようなものでした。(先頭の数字は、命令を示す2進数)
00 sto ストア。アキュムレータの内容を、指定されたメモリアドレスに格納する。
01 add 加算。アキュムレータの内容に、指定されたメモリアドレスの内容を加算する。
減算を行いたいときは、2の補数表現で表現された「負の値」を足してやればよい。
アキュムレータの内容が「0」のときに加算を行えば、アキュムレータに値をロードできることになる。
10 trn 分岐。アキュムレータの最上位ビットが 1 のとき、指定されたメモリアドレスに制御をうつす。
加算だけで、減算とロードも兼ねている、というところが命令を少なくする工夫でしょうか。
しかし、これだけではまだ、プログラムなんてできそうにありません。
そこで、残りの1命令です。
11 opr 制御。
指定アドレス部分をビット単位で内部回路の制御信号とみなし、演算回路を直接駆動する。
…なんのこっちゃわからん、という反応が普通です。
制御命令では、メモリアクセスを行いません。つまり、アドレス分の 16bit が別の目的に使えます。
そこで、この 16bit を「命令フィールド」として使うことで、実質的な命令を増やしているのです。
命令フィールドが 2bit しかないから、4命令しか持っていない…と言うのは論理的な話で、事実上はもっと命令を持っている、と言うだけの話です (^^;
自由に命令を作り出せる命令
この制御命令は、非常に興味深いです。
この当時のコンピューターは、通常「命令」ごとに、その命令の動作を行う「演算回路」が作られていました。
しかし、実際には命令ごとに類似の動作も多く、命令ごとの回路を全て用意するのは無駄が多いのです。
WWI では、類似の回路はまとめてしまい、次々と回路を動かすことで1つの命令を処理する、と言う方法が取られました。
たとえば、基本的な命令である「加算」は、
・メモリからデータを取り出す
・あらかじめ持っていたデータと、メモリから取り出したデータを「半加算」する。
・半加算時に作られた「繰上りデータ」と、半加算結果を半加算し、「全加算」とする
という3つの動作を連続して行っています。
実は、「半加算」の結果得られるデータは「排他的論理和」(XOR)と呼ばれる演算結果と同じです。
つまり、上の動作のうち、最後の動作を行わなければ「XOR」命令として動作することになります。
同じ回路の組み合わせ方を変えるだけで、別の命令が作り出せる。
これが、WWI 方式の利点でした。
ただし、WWI ではこれは内部回路の問題であって、ユーザー(プログラマ)が「複数の回路の組み合わせ」を意識することはありませんでした。
TX-0 では、この部分を積極的にユーザーに見せてしまっています。
「制御」命令で使う回路を直接指定し、自由に組み合わせて命令を作り出せるようになっているのです。
基本命令では、アキュムレータ(以下 AC と略記)とメモリの間の加算しかできませんでした。
この限りにおいては、TX-0 で使用できるレジスタは AC だけである、と考えられます。
実際には、TX-0 には他にいくつかのレジスタを持っていました。
メモリバッファレジスタ(以下 MBR) は、メモリから読み込んだデータを記憶しておくレジスタです。
AC とメモリの間の演算の際は、実際には メモリから MBR にデータを読み込み、AC と MBR で演算を行っています。
また、レジスタではありませんが、18個のトグルスイッチをセットにした入力装置である、トグルバッファレジスタ(TBR) というものも存在しています。
さて、TBR(入力装置) は、TBR(命令)で、MBR にコピーすることができます。
PAD 命令を使うと、MBR と AC を半加算(繰上りの無い加算)することができ、さらにその後 CRY 命令で繰上りの処理ができます。
つまり、TBR + PAD + CRY の命令をセットにして使うと、「TBR(入力装置)と AC の加算」と言う命令が作り出せるのです。
さらに、先に書いた AC のクリアを一緒に使えば
CLL + CLR + TBR + PAD
で、「TBR(入力装置)の内容を、アキュムレータにコピー」できます。
(アキュムレータを 0 にしてから半加算するので、繰上りの処理は必要ありません)
制御命令では、このような調子で「必要とする命令」を自由に作り出すことが出来ました。
そりゃ、命令を組み合わせられるんだからプログラム可能なのは当たり前でしょ…なんて思わないでください。
この命令は、どんな組み合わせを行おうとも「1命令」、つまり1ワードしか使用しないのです。
当時のコンピューターはメモリが少ないですから、1ワードの中で多彩な処理ができるというのは、素晴らしい方法でした。
いくつかの命令を並列実行できる、VLIW とも違います。並列実行ではなく、1命令の中で順次実行しているのですから。(命令の実行優先順は決まっていて、変更できませんが)
制御命令は、アドレスが使えないためにメモリアクセスが行えない、と言う問題はありますが、それは基本命令に任せればよいのです。
メモリアクセスが必要な時だけ、基本命令が顔を見せて、あとはすべて opr 命令でまかなう。
これが TX-0 流のプログラム方法でした。