C and the AT&T Unix Port -- A Personal History
C言語と AT&T Unix の移植

Stephen C Johnson
Transmeta Corp


Porting Unix from the 16-bit PDP-11 to the 32-bit Interdata 8/32
had a profound effect on the C language and the way it was used in Unix.
16 bit の PDP-11 から 32 bit の Interdata 8/32 への移植は
C言語とその Unix での使用方法に深い影響を与えました。


Background
背景

I got involved in compilers by a backdoor route -- Dennis Ritchie had written a compiler for a language called B, a typeless language that was very effective on word-addressed machines. He had originally written this compiler on the Honeywell 645, a 36-bit word-addressed machine. Everything was a word - integers, characters, pointers, functions, arrays (the latter two were pointers to the code and the data, respectively). Ambiguity was broken by the operator type -- if you applied unary `*' to something, it had better be a pointer. If you applied binary `*' to something, it had better not be. It was up to the programmer to decide. There were no structures and no type checking.
私は裏口経由でコンパイラーに巻き込まれました -- Dennis Ritchie は B と呼ばれる型のない言語のコンパイラーを書きましたが、 それはワードマシンでは大変効果的でした。 彼は当初このコンパイラを 36 bit マシンだった Honeywell 645 の上で書きました。 整数、文字、ポインタ、関数、配列 (後の2つは、コードおよびデータへのポインターです) など、全てワード単位でした。 曖昧さはオペレーターのタイプによって排除されました -- 単項の何かに '*' をつけた場合はポインタとして、 2項の何かに '*' をつけた場合はポインタでないと認識しました。 その決定はプログラマの責任でした。 構造体も型チェックもありませんでした。

The ability to control memory usage was crucial in those days -- our mainframes allowed only 128K (9-bit) bytes for each user program, and that included code and data. System call interfaces, which were considerable, also had to fit in that space. This was a multi-million dollar machine, one of a couple that did all the central computing at the Murray Hill Bell Labs location.
メモリ使用法をコントロールする能力は当時重大でした -- 私たちのメインフレームは、各ユーザ・プログラムの128K(9ビット)バイトだけを許可しました。また、それはコードおよびデータを含んでいました。 システムコール・インターフェース(それらは相当だった)は、さらにそのスペースに入らなければなりませんでした。 (多重1000000)これは100万ドル機械(マリーヒル・ベル研究所の位置での中央に計算することをすべて行ったカップルのうちの1つ)でした。

When Dennis started spending all his time with the new PDP-11, the Honeywell compiler became an orphan. I was writing some system code (a dynamic loader) and was seriously hampered by some missing operators, notably XOR. There were also a couple of bugs. Dennis has a way of saying very profound things in a very simple way. One day he urged me to fix the compiler myself. "After all," he said, "it's just a program".
デニスが新しいPDP-11を備えた彼の時間をすべて過ごし始めた時、ハネウェル・コンパイラーは孤児になりました。 私はあるシステム・コード(動的なローダー)を書いており、何人かの行方不明のオペレーター、顕著にXORによって真面目に妨げられました。 2、3(さらに)のバグがいました。 デニスは、非常に単純な方法で非常に深遠な考えを言う方法を持っています。 ある日、彼は、コンパイラーを私自身修理するように私に促しました。 「結局、それは単にプログラムです」と彼が言いました、

This doesn't sound too profound now, but at the time most compilers (and operating systems) were written in assembler -- the compilers were hard-wired into the operating system somewhat the way device drivers are now. Once I appreciated that the compiler was just a program, and could be understood by ordinary mortals, I found myself hooked into what has been a 25-year career.
今日では、これはあまり深遠には聞こえませんが、 その当時ほとんどのコンパイラ (とオペレーティングシステム) はアセンブラで書かれていました -- コンパイラは 現在のデバイスドライバのような方法で オペレーティングシステムに 固く組み込まれていました。 かつて、 私は コンパイラが単なるプログラムであり、 普通の人間によって理解されるかもしれないことを 認識していました。 25年間引っかかってきたことを、今、私は確認しています。


Yacc is Born
Yacc の誕生

Dennis' compiler was a superb introduction to the craft -- both the statement parsing and the code generation were elegant and powerful. However, the expression parsing was a horrible kluge. One of the things I wanted to do was to add an XOR operator, but my first several tries ended in failure. The method, operator precedence, required all sorts of kluges for function calls and parentheses, and adding a new precedence level in the middle required rewriting a major part of the expression parser. I was complaining about this after my third or fourth failure, when Al Aho suggested that there were some new methods recently published that would allow parsers to be generated from BNF. Al introduced me to LR parsing, and within a few months Yacc was born. It was written on the Honeywell, in B, and its early history is worth a paper in itself.
Dennis のコンパイラーはその手法に関する優れた手引きでした -- 構文解析とコード生成のいずれもエレガントで強力でした。 しかしながら、式の解釈は恐ろしく厄介なやり方をしていました。 私が行いたかったことのうちの1つは XOR オペレーターを加えることでしたが、 私の初期のいくつかの試みは失敗に終わりました。 オペレーターを優先する手段には 関数呼び出しと挿入に関する数々の厄介な方法を必要としました。 また、その中に新しい優先レベルを追加するためには 式解釈のほとんどの部分を書き直す必要がありました。 Al Aho が BNF からパーザを生成することを可能にする 最近公表されたいくつかの新方式があることを勧めてくれた時には、 私は3度目か4度目の試みが失敗に終った後で、 この問題について不満を漏らしていました。 Al は私に LR 解析を手ほどきし、 数か月の内に Yacc が生まれました。 それはハネウェルの上で B を使って書かれたもので、 その初期のころの歴史は本質的に論文にする価値があります。

But by late 1972, Yacc had been ported to the new Unix system -- there was a B interpreter, and later a compiler, for it. Yacc was a notorious processor hog, taking 20 minutes to process a 50-statement grammar on the PDP-11 ("Oh crap, Johnson's running Yacc again" people would say when their terminal stopped responding).
しかし 1972 年の末に、 Yacc は新しい Unix システムに移植されました。 -- のちにコンパイラになりましたが、 そこで使われた B はインタープリターでしたから、 PDP-11 の上では Yacc は悪名高いプロセッサー喰いになり、 50 ステートメントの文法を処理するために 20 分もかかりました。 (端末の反応がなくなるたびに、 皆は「また Johnson が Yacc を実行している」と言いました)

The PDP-11 at that time had 32K bytes of memory -- the system got 16K and the users got 16K. The B compiler also ran in 16K. An amusing incident shows just how close to the wall we were. One day Yacc did not compile -- it had compiled just fine the previousday. It turns out that Dennis had added the `for' statement, in essentially the form we know it today, to B. The word `for' took up a symbol table slot, and, unknown to me, Yacc had been filling every symbol table slot when it compiled. So when the `for' statement came in, I had to rewrite a routine in Yacc to use one fewer local variable.
その時の PDP-11 はメモリを 32K バイト持っていました -- 16K はシステムに、そして残りの 16K はユーザに割り当てていました。 B コンパイラーも 16K で動作しました。 私たちがどれくらい壁に接近していたかについて、 面白い出来事が明らかになりました。 ある日 Yacc はコンパイルできなくなりました -- 前日には無事コンパイルできていたものです。 Dennis が B に本質的に今日私たちが知っている形式で `for' ステートメントを付け加えたことが判明します。 `for' という単語はシンボル・テーブルのスロットを奪い取り、 Yacc はコンパイルの際、 私にはわからないようにすべてのシンボル・テーブルのスロットを満たしました。 したがって `for' がやってくると、 私は Yacc の中のルーチンを書き直して、 あるごく少数のローカルの変数を使用しなければなりませんでした。

Around this time, we got another memory board for the PDP-11. I recall it being 16K bytes, which once again was split between the OS and the users, and costing in the neighborhood of $20,000 (1972 dollars). It was hard to say who was happier, the OS writers or the users, at going from 16K to an entire 24K.
概ねこの時期に、 私たちは PDP-11 のために別のメモリ・ボードを得ました。 私はそれを 16K バイトでリコールします。 それは再び OS とユーザの間で振り分けられたもので、 (1972 年時点での) 20,000 ドルぐらいのコストがかかっています。 16K がフル実装の 24K に増えたことで、 OS の開発者とユーザーの誰がより幸福だったか言うことは困難でした。

In early 1973, I went on a 9-month sabbatical to the University of Waterloo. When I returned, B was dead -- long live C. An MIT coop student named Al Snyder had rewritten Yacc from B to C, and used it as the basis for a C compiler that would run on both the Honeywell and the PDP-11. It had a Yacc grammar for the language. Neither implementation was especially compelling -- it took four passes to run on the PDP-11, so it was horribly slow, and the code generator on the Honeywell had numerous bugs. But it was a very impressive few months work.
1973年の前半、私は9カ月の有給休暇で University of Waterloo に行きました。 私が戻った時、B は死んでいました -- C 万歳。 Al Snyder という名前の MIT の学生は B で書かれていた Yacc を C に書き直しており、 Honeywell と PDP-11 の両方の上で 動作する C コンパイラーの基礎として使用しました。 それは、言語の Yacc 構文規則を持っており、 どちらの実装にも特に強制されることはありませんでした -- PDP-11 の上で実行する場合には4パスを取りましたので恐ろしく遅く、 また Honeywell のコードジェネレータには数々のバグがありました。 しかし、それは大変印象的な数カ月の作業でした。

When I returned from Canada, it was strongly suggested that I take this over -- Al was returning to school. Over the course of the next six months, I replaced nearly everything but portions of the grammar, and it became the first Portable C compiler. The number of passes on the PDP-11 was reduced to two, and the code quality on the Honeywell got good enough that some people in the computation center started to use it to write system code. Working with Tom Petersen, we got a version going for the IBM-370, and also for a Bell Labs switching machine called the 3A.
私がカナダから戻った時、私はこれを引き継ぐことを強く勧められました -- Al は学校へ戻っていました。 次の6カ月の間に、 私は構文規則以外のほとんど全ての部分を書き直し、 それが最初のポータブル C コンパイラになりました。 PDP-11 の上で動作するパスの数は2パスまで減らされていました。 また Honeywell の上でのコードの品質は改善され、 計算センターの何人かがシステムコードを書くために使用し始めました。 Tom Petersen と共同で、 IBM-370 と 3A というベル研の交換機のための バージョンも作成しました。

Over the next year or two, I was able to get the front end to be relatively machine independent -- I parameterized some things like byte order and the widths of integers, as well as some code like array initialization that had to be done in the front end due to lack of space in the compiler. As I made the frontends more similar and more machine independent, I wanted a way to test that the frontend could really `understand' C. I realized that I could write a simple back end that would just make a table of where the functions were defined, with the file and line numbers. Before long, I realized that I could also find uses, and, with some simple sorting and a back-end table, I could check number and type of function arguments -- lint was born.
翌年から翌々年わたって、 私は比較的マシン依存の少ないフロントエンドを作成できました -- コンパイラーのスペース不足により フロントエンドの中で行われなければならなかった 配列の初期化だけでなく、バイトオーダーや整数の長さといったものも パラメータ化しました。 フロントエンドをより同様でよりマシン非依存にするため、 私はフロントエンドが本当に C を「理解」できていることを テストする方法を欲していました。 関数がどこで定義されているかをファイルと行番号つきで記録した テーブルを作る単純なバックエンドを書くことができることを私は悟りました。 やがて私は、さらに関数を使用している場所、 バックエンドのテーブルをソートすること、 そして関数の引数の数と型をチェックすることが できることを悟りました -- lint が生まれました。

The back end code generation was quite different. It took quite a while to bring the code generators under one umbrella, based on a template rewriting model and strongly influenced by the Sethi-Ullman method that Dennis had used in the Honeywell B compiler. The Portable C Compiler (PCC) began to appear in a useful form.
バックエンドのコード生成は全く異なっていました。 かなり長い間、 テンプレートを書き直すモデルに基づき、かつ、 Dennis が Honeywell の B コンパイラで使っていた Sethi-Ullman 法にも強く影響を受けた、 コードジェネレータを使っていました。 ポータブル C コンパイラー (PCC) は便利な姿で登場し始めました。


To Port a System

Then Dennis said another one of those simple, profound things, "Given the complexity of some of the applications in the Bell System, it would be easier to port the operating system to a new machine than to port the application to a new operating system." The existing operating systems at the time were mostly still punched card based (or based on card images copied to tape or disc), mass storage organization and command line syntax was completely unique for each system, interactive and back-ground jobs had different system calls to accomplish the same tasks, there was effectively no networking, and word-sizes of 16, 24, 32, 36, 60, and 64 were in use in the Bell System (not to mention several different byte orders). He didn't actually say "Unix is just a program", but I got the idea. He asked me if I could help evaluate machines for a 32-bit port of Unix, and build the compiler for the resulting port, and I enthusiastically agreed.
その時 Dennis は深遠な事柄を簡単に言い換えました。 「既にあるベルシステムの中のいくつかアプリケーションの複雑さを考えれば、 新しいオペレーティング・システムへアプリケーションを移植するより、 新しいマシンへオペレーティング・システムを移植する方がより簡単であろう」 当時の Bell System の 既存のオペレーティング・システムのほとんどは まだパンチカード (あるいはテープやディスクにコピーされたカード・イメージ) に基づいたもので、 大容量記憶装置の構成やコマンドラインのシンタックスは 各システムごと全く互換性がなく、 同じタスクを遂行するのでも 対話形式とバックグラウンドジョブでは 異なるシステムコールを使用し、 役にたつネットワークはなく、 ワードサイズは 16、24、32、36、60、64 が使用されていました。 (バイトオーダーが異なっていたことは言うまでもありません) 実際には彼が「Unix は単にプログラムである」 と言ったわけではありませんが、 私はアイデアを思いつきました。 彼は私に Unix の 32-Bit 版のマシンでの評価を手助けを求めましたし、 その移植の成果としてコンパイラを作成することに、 私は熱狂的に同意しました。

There was an organization at Bell Labs that very much wanted us to use an IBM 360 -- they offered to buy us one if we would port Unix to it. I hated compiling for that machine, and Dennis didn't like the I/O structure, so we declined. The Dec 10 was another machine we investigated, but it was 36 bits wide -- Dennis said he would consider it if we could get 10 track tape drives for backup. At the time, the Dec 10 was the dominant University research machine, and we worried that we would cut ourselves off from universities by not using that machine. We settled on the Interdata because it was 32 bits, resembled a 360, but had a much nicer instruction set, easier to compile for.
ベル研には私たちに大変 IBM 360 を使わせたがっている組織がありました -- もし私たちが Unix を移植するのであれば、 私たちに1台買い与えても良いと申し出ていました。 しかし、私はそのマシンでコンパイルすることが嫌いでしたし、 Dennis はその入出力の構造が好きではありませんでしたので、 私たちは辞退しました。 DEC-10 は私たちが調査したもう1台のマシンです。 しかし、それはワード長が 36-Bit でした -- もしバックアップのために 10 トラックのテープドライブが手に入れられるなら、 それを考慮すると Dennis は語ってました。 その当時、DEC-10 は大学での主要な研究用のマシンだったので、 このマシンを使用しなければ私たち自身が大学から切り離されてしまうことを 私たちは心配しました。 32-Bit だったことから、 私たちは Interdata に決めました。 それは 360 に似ていましたが、 コンパイルするのがより容易な、 はるかによい命令セットを持っていました。


The Impact on C
C に対する影響

Dennis and Ken set to work on the OS, to make it truly portable. It was necessary to clean up C quite a bit in order to write the OS. In the evolution from B to C, a lot of old B code had been carried over unchanged. This meant that the uses of types were very fast and loose, or missing altogether. Before C had the unsigned data type, people would assign values to character pointers to get unsigned arithmetic, for example.
Dennis と Ken は OS を本当にポータブルにするための作業に着手しました。 OS を書くために、かなり多くの C を整理する必要がありました。 B から C へ発展する過程で、多くの古い B のコードは 変更されることなく繰り越されていました。 これは型の使用が大変いい加減である、 あるいは全く欠落していることを意味していました。 例えば C が符号なしのデータ・タイプをサポートする以前は、 符号なしの演算を行うために、 文字のポインタに値が割り当てられていました。

Structures had been in the language for several years, almost from the beginning of C, but all structure members were in the same name space. By the time we started the port, there were structures heavily used in the operating system and the interfaces to it, but it was still common to see people doing I/O by writing things like:
構造体は C の初期のころから何年もの間、言語の中に存在していましたが、 構造体の全てのメンバーは同じ名前空間にいました。 私たちが移植を開始するまでは、 構造体はオペレーティングシステムや そのインターフェースの中で頻繁に使用されました。 しかし、まだ下記に書かれたような入出力操作を行うことが一般的でした:

* 0177320->enable=1; 

As long as you had exactly one structure with the member `enable', this was unambiguous. But clearly the handwriting was on the wall -- the number of names a programmer had to avoid in structure members was into the hundreds.
'enable' というメンバーを持つ構造体が1つしかなければ、 これは曖昧ではありません。しかし、明らかに災いの前兆がありました -- プログラマが回避しなければならなかった構造体のメンバー 構造体のメンバーとして回避しなければならなかった名前の数は 何百にもなりました。

The solution was to adopt the semantics we have now -- each structure has a separate name space, and the type of the structure or structure pointer determines the offset and type (and legality) of the reference. But, because we had all this `legacy' code, we decided to make an interim version of the compiler that would allow references that were unique, so old code would work, but with a warning.
解決は私たちが現在使っているセマンティクスを採用することでした -- 個々の構造体は個別の名前空間を持っており、 構造体の型や構造体へのポインタは 参照のオフセットや型 (また適法性) を決定します。 しかし私たちには「レガシー」コードが残っていたので、 ユニークな参照を許す暫定バージョンのコンパイラーを作ることを決めました。 したがって古いコードは動作しますが、ワーニングが発生しました。

The symbol table handling of PCC was never especially profound, and this change brought it to its knees. Probably half of the bugs that turned up in the porting involved really nasty problems with structure members. I had sanity checks littering the code, amusing myself by inventing synonyms for `bad' and `illegal'. I recall Ken Thompson handing the limping compiler a structure that contained an array whose dimension was an expression that contained a sizeof of another entire structure declaration. The PCC front end rode bravely into battle but returned on its shield. I still remember the look on Ken's face as he showed me the error message and mildly asked, "What is a gummy structure ?".
PCC のシンボル・テーブルの操作は特に高尚ではありませんでしたが、 この変更はそれを屈服させました。 恐らく、移植中のチューンナップで発生したバグの半分は 構造体のメンバーに関わる実に厄介な問題が含まれていました。 私は `bad' と `illegal' の同義語を発明することにより私自身が楽しみながら、 散乱するコードの健全性のチェックを行いました。 私は Ken Thompson が他の構造体宣言の sizeof が含まれている式で 次元を示す配列が含まれている構造体を足を引きずるコンパイラに 渡していることについてリコールしました。 PCC フロントエンドは勇ましく戦いへ臨みましたが、 そのシールドに跳ね返されました。 私にエラーメッセージを見せ、 穏やかな調子で「gummy structure って何?」と 尋ねた Ken の顔を私は未だに思い出します。

In order to deal with a lot of the I/O device code, we needed casts in the worst way. Unfortunately, every syntax we could come up with was appalling. Generally, I stuck by the credo that the C language was Dennis', and he made the language decisions, although a few things came up on other machines (such as the interaction of byte order and bitfields, or the whole issue of alignment of structures) and I had to try to do something sensible. But in this case, we just needed casts too badly, so I implemented what we now know. The simple stuff was easy enough to write and understand that we were hooked before we realized the full horror that lurked behind that syntax.
多くの入出力デバイスのコードに対処するために、 私たちは最悪の方法でキャストすることが必要でした。 不幸にも、私たちが見つけ出した文法は恐るべきものばかりでした。 概ね、C 言語は Dennis であり、 (バイトオーダとビットフィールドの相互作用、 あるい構造体のアライメントに関わる全てのことといった) 他のマシンで発生するであろう些細なことであっても 彼が言語上の決定を行うべきであるという信条に私は捕らわれて、 私が何か賢明な何かを試みなければなりませんでした。 しかしこの場合には、単にキャストを必要としていたので、 今日知られるものを私が実装しました。 単純なものは その文法の背景に潜む恐怖が現れる前に フックすることを記述し/理解するには十分簡単でした。

Bitfields had entered C, but faced profound challenges when we moved programs to machines with different word sizes. One issue was the relationship between a bitfield of size 8 bits, and a byte of the same size. I felt they should have the same semantics, and this led to the decision to allocate bitfields in the same order as the bytes were laid out in the machine. On any given machine, this was the right answer, but this made bitfields next to useless in doing communication software.
BitfieldsはCを入力したが、 私たちが異なる単語サイズで機械にプログラムを移動させた時、 深遠な挑戦に直面しました。 1つの問題はサイズ8ビットのbitfieldの間の関係および同じ大きさのバイトでした。 私は、それらが同じ意味論を持っているべきであると思いました。 また、これは、バイトが機械の中にレイアウトされたのと 同じ順にbitfieldsを割り付ける決定に結びつきました。 所定の機械においては、これが正解でした、 しかしこの作られたbitfields、の隣りに、通信ソフトを行うことにおいて役立たない

One of the most profound changes in the way we did business had to do with header files. Previously, header files for system structures had been printed in the manual. If you wanted to use an I/O device or do a system call, you copied the structure out of the manual into your source file and went at it. This clearly was a disaster when it came to a radically different machine. Even sizeof was not much help. We concluded that we needed to have a central repository of system header files, and use #include to access them. I believe that typedef was invented about this time as well so we could have symbolic names for system quantities that might be represented differently on different systems.
私たちが取引した方法の最も重大な変化のうちの1つは、ヘッダーファイルと関係しました。以前に、システム構造用ヘッダーファイルはマニュアルの中で印刷されました。I/O装置を使用したかったか、システムコールを行いたかったならば、ソース・ファイルにマニュアルからの構造をコピーし、それで行きました。それが根本的に異なる機械に来た時、これは明らかに災害でした。sizeofさえあまり支援ではありませんでした。私たちは終えました。私たちは、システム・ヘッダーファイルの中央の容器を持ち、それらにアクセスするために#includeを使用する必要がありました。私は、私たちが異なるシステム上で異?ネって表わされるかもしれないシステム量の記号名前を持つことができたように、typedefがこの時期に同様に発明されたと信じます。

Lint was used in a clever way to help us find all the commands that had local copies of the system structures. Lint would complain if two calls to the same routine used physically different structure definitions, even if the declarations were identical. A summer student from Princeton, Tom Lyon, did most of the grunt work of finding and fixing the system call declarations. This was especially important because older versions of Unix had returned -1 (0177777 in PDP-11-ese) when they failed, while the new system calls would typically return 0. We had to find them all.
lint は私たちがシステムの構造体のローカルのコピーを持っている コマンドをすべて見つけるための手助けをする賢いやり方として使用されました。 同じルーチンに対する2つの呼び出しが 物理的にことなる構造体の宣言を使う場合、 宣言が同一のものだったとしても、 lint は苦情を言うでしょう。 Princeton から来た夏期研修生の Tom Lyon が システムコールの宣言を見つけ修正する不満の多い 仕事の大部分を行いました。 新しいシステムコールが主に 0 を返すのに対し、 古いバージョンの Unix は失敗した時に -1 (PDP-11 では 0177777) を返すので、 これはとくに重要です。私たちはそれを全て見つけなければなりませんでした。


The Port
移植

The Interdata arrived, as a bare machine. There were some self-loading diagnostics, but we never put a bit of the manufacturer's software on the machine. We had a disc and a tape drive, but no networking. Bootstrapping involved entering a tape boot program from the console, reading a record, and then jumping to it.
Interdata は最小限の校正のマシンとして到着しました。 自動的に起動される診断プログラムがありましたが、 私たちはマシン上にメーカーが提供するソフトウェアを置くことはありませんでした。 ディスクとテープドライブはありましたが、ネットワークはありませんでした。 起動はコンソールからテープ用のブートプログラムを入力し、 レコードを読んだのちに、それにジャンプする方法を取りました。

The Interdata was big-endian, while the PDP-11 of course was little-endian -- this was an endless source of headaches. Also, this was the first machine either Dennis or me had used that spoke hex, and we both had trouble adapting after a decade of octal. I had to do I/O character by character to the console (it typed on real paper, youngsters!). In a day or so, I had putc working, then wrote puts. Then I started running compiler tests. In each case, I had to write a tape on the PDP-11, dismount it, carry it to the Interdata, mount it, copy it in to memory, and execute it.
もちろん PDP-11 がリトル・エンディアンだったのに対し、 Interdata はビッグ・エンディアンでした -- これは絶えず頭痛のタネとなっていました。 また、これは Dennis にとっても私にとっても16進数を話す最初のマシンでした。 10年間8進数を使い続けてきた、我々は適合するのに苦労しました。 私はコンソールに1文字ずつ入出力させなければなりませんでした。 (若者よ、それは本物の紙にタイプされたのだよ) 一日程度で、putc を動作させました。次に puts を書きました。 そしてコンパイラのテストを始めました。 以上の作業は全て、 PDP-11 でテープを書き、 ディスマウントして、 Interdata に運び、 マウントして、 メモリにコピーして、 実行しなければなりませんでした。

There was one amusing incident. Just when it seemed things were really starting to work, I tried a somewhat bigger test, and it failed. I spent a couple of days single stepping the program, and finally concluded that we had a bad location in memory -- no matter what I stored into it, it always returned 0. To make a long story short, I had been loading my programs at location 0, and had finally loaded a long enough program that I ventured into the region of the memory address space where the relocation hardware was located. It turns out I had been executing, and even single stepping, through relocation registers just fine, but the page-fault status register was read-only, and that was the location that always appeared to be 0.
ある面白い出来事がありました。 ちょうど実際に動き始めていたように見えた時、 私はそれまでより多少大きなテストを試みましたが、失敗しました。 私はプログラムをステップ実行するために2、3日を費やし、 最終的にメモリに bad location があるという結論に達しました -- 記録する値に関わらず、常に0を返しました。 手短に説明すると、 再配置ハードウェアが存在する、メモリのアドレス空間の危険な領域で、 私のプログラムを location 0 から十分に長いプログラムがロードしました。 プログラムを実行すると、それがステップ実行であっても、 再配置レジスタは正常に動作するのに、 ページフォルト状態レジスタは read-only になって、 アドレス 0 と思われる location になる結果になりました。

Within two weeks, I had a stable cross compiler from the PDP-11 to the Interdata working, and we could begin the job of porting. Ken would produce the kernel and get it working on the PDP-11, Dennis did most of the porting work (especially the device drivers and getting the shell to work), and I helped with the debugging.
2週ぐらいで、私は PDP-11 から Interdata への 安定したクロス・コンパイラを用意し、 移植作業を始めることができるようになりました。 Ken はカーネルを作り、それを PDP-11 で動作させました。 Dennis はほとんどの移植作業 (特にデバイスドライバとシェルを動作させる作業) を行いました。私はデバッグを手伝いました。

The tape drive continued to be a major bottleneck. Because of the byte swapping, Dennis had to create a proto file image on the PDP-11 that could be copied to tape on the PDP-11, copied from tape to the Interdata, then copied to the Interdata disc. Depending on the datatype and the alignment, the data on the PDP-11 had to have the bytes swapped in one of several ways to survive this. The first thing Dennis did was to put a checksum in tar so we could tell if we had the bytes swapped. This saved time. Then he put a byte-swapper in tar so if we had the bytes wrong we could swap them as we read them. This saved more time. Then, in a stroke of brilliance, he combined the two ideas -- the tape would be read, and if the checksum failed the tape would be rewound and read again with the bytes swapped. Overnight, byte swapping on the tape drived is appeared as an issue...
引き続き、テープドライブは主なボトルネックでした。 バイト変換のために、 Dennis は PDP-11 でテープにコピーし、Interdata ではテープからコピーし、 そして Interdata のディスクへコピーするプロト・ファイル・イメージを PDP-11 の上で作成しなければなりませんでした。 データタイプとアライメントに依存するするため、 これを切り抜けるため PDP-11 の上で、 前例の無いようなデータのバイトスワップを しなければなりませんでした。 Dennis が最初に行ったことは バイト変換をしたかどうか分かるように、 tar にチェックサムを入れることでした。 これで時間を節約できました。 次に tar にバイトスワップ機能を入れました。 これで、バイトが間違っていれば、 リード時にスワップさせることができます。 これでさらに時間を節約できました。 そして瞬く間に、彼は2つのアイデアを組み合わせました -- テープをリードして、もしチェックサムに失敗すれば、 テープを巻き戻して、バイトスワップをしながら、 もう一度リードしなおします。 問題は、一晩中、テープドライブでのバイトスワップが発生することですが...

After a couple of months (and some hardware problems that caused the machine to be sent back to the factory for a couple of days) we were ready to dispatch to the first user program. The routines, saveu and retu, were elegant and simple on the PDP-11, but wouldn't work for anything on the Interdata. Dennis and I had many late-night phone calls about this, and finally he totally rewrote these routines and we were able to make progress. These were the notorious `you are not expected to understand this' routines -- I don't ever recall seeing that comment when I was staring at them, and it was 15 years before I saw the comment, and the routines, on a T-shirt and realized that these were the routines I had lost so much sleep over.
2、3カ月 (およびハードウェアの問題でマシンを工場へ送り返すことになった2、3日間) の後に、私たちは最初のユーザ・プログラムに送る準備ができていました。 PDP-11 の上では saveu/retu ルーチンはエレガントでシンプルでしたが、 Interdata の上では全く仕事をしませんでした。 これについて、Dennis と私は夜遅くに多くの電話をしましたが、 結局、彼がこれらのルーチンを全部書き直し、 作業を進めることができるようになりました。 悪名高い `you are not expected to understand this' ルーチンがあります -- 私はまだそのコメントに出くわしたことはないのですが、 私が始めた当時、 私がそれらを凝視していた時 そのコメントを見ることを常に思い出さず、 私がTシャツの上で、 コメントおよびルーチンを見て、 これらが、 前に、 15年でした。 私は多くの睡眠を失ったルーチンであることを悟りました。

As with any complex project, it was hard to say exactly when it first `worked'. We had some lingering bugs (especially in the floating-point area). The numerical analysts in the department were very interested in the machine, because the PDP-11 address space was so small it was difficult to solve practical numerical problems.
どのような複雑なプロジェクトでも、 それがいつ最初に「作動したか」を正確に言うことは困難です。 私たちは何匹かの長引くバグ (特に浮動小数点式のエリア中の) を飼っていました。 PDP-11 のアドレス空間が非常に小さかったため、 実際的な数値問題を解決することが困難だったので、 部門の数値アナリストはマシンに非常に興味を持っていました。

As a hardware platform, the Interdata was rather nice -- its architecture was reasonably clean. Unfortunately, the implementation had a couple of serious problems. None of the Interdata `native' software did paging, and there were some failures in this area that compromised Unix stability. The one that was most painful was doing a word indirection through -1 (the old failure return, remember...). This caused both a memory protection fault and analignment fault, which curdled the microcode so badly the system could not recover -- it actually made the next several instructions execute incorrectly. Since this happened even in user mode, we needed to have this fixed.
ハードウェア・プラットフォームとしては、 Interdata はかなり良い方でした。 -- そのアーキテクチャーは合理的で簡潔でしたが、 不運にもその実装は2、3の重大な問題を持っていました。 Interdata のネーティブソフトウェアでもページングを行うものはなく、 Unix の安定性を危うくする、いくつのこの領域での失敗がありました。 最も痛かったものは -1 によるワード間接(参照?)を行うことです。 (古い失敗時のリターンを思い出します...) これは memory protection fault と analignment fault の両方を引き起こし、 それはマイクロコードを腐らせるので、システムは回復することができません -- 実際に次のいくつかの命令が正しく実行されませんでした。 これはユーザー・モードでさえ起こったので、 私たちはこれを解決する必要がありました。

At a high-level meeting that included Dennis and me, many of our bosses, and many bigwigs from Interdata, we painted a glowing picture of how many machines they could sell to the Bell System if they would just fix a few small problems. They thought about it and said no. Six months later, the VAX was announced and the rest was history. . . .
Dennis と私、多くの上司、そして Interdata からの 多くの重要人物が参加したハイレベルのミーティングで、 ごく少数の小さな問題を解決すれば、 彼らが Bell System に何台マシンを売ることができるのかについて、 私たちは強烈な絵を描きました。 彼らはそれについて検討し、ノーと答えました。 6か月後に VAX が発表され、残りは過去のものになりました...