PDP-8

PDP-8は、世界で初めて商業的に成功した12ビットミニコンピュータであり、1960年代にディジタル・イクイップメント・コーポレーション  が製造した。1965年3月22日に登場し、5万システムを売り上げ、DECのPDPシリーズでも当時最も成功したコンピュータとなった。最初のPDP-8の設計を指揮したエドソン・デ・カストロは、後にデータゼネラルを創業した。PDP-8 は、PDPシリーズとしては、PDP-5 の後継である。

最初のPDP-8機種は diode-transistor logic  を採用したフリップチップ基板で構成されており、小型冷蔵庫ほどの大きさだった。

その後、デスクトップ型とラックマウント型のPDP-8/Sが登場。1ビット直列ALU実装で、小型化と低価格化を実現したが、最初のPDP-8に比べると性能がかなり低い。PDP-8/Sに接続可能な唯一のストレージがDF32というディスク装置だった。

その後のシステムは並列実装で高速になったが、TTLICを使用し、DTLより安価になっている。現存date=2013年10月}}するPDP-8の多くはこの世代の機種である。中でもPDP-8/Eは豊富な各種周辺機器が接続可能で、よく使われていた。汎用コンピュータとしてもよく使われていた。

1975年、安価なマイクロプロセッサを使った Altair 8800 などの初期のパーソナルコンピュータが登場し、その後 TRS-80 や Apple II が登場すると、小型汎用コンピュータの市場はそれらに奪われることになった。

1979年にリリースされた PDP-8 の最後の機種は特製のCMOSマイクロプロセッサを使用しており、"CMOS-8s" などと呼ばれた。価格は他のマイクロプロセッサを使ったコンピュータと競合するような設定ではなく、市場には受け入れられなかった。1981年に登場した IBM PC がCMOS-8sにとどめを刺した。インターシルがこの集積回路を1982年まで Intersil 6100 として販売していた。CMOSであるため低電力であり、いくつかの軍用組み込みシステムに採用された。

1. 概要
-----

技術史的観点からもPDP-8は重要な位置を占めている。入出力機構、ソフトウェア開発、オペレーティングシステム設計などに影響を与えた。Apple IIのようなマイクロコンピュータが一般化するまで、PDP-8は世界で最も販売台数の多いコンピュータであった。

PDP-8はいくつかの12ビット機の先例を参考にしており、特に W.A. Clark と C.E. Molnar が設計したLINCに影響を受けている。LINC自体は、シーモア・クレイが設計したミニコンピュータ CDC 160 に影響を受けている。

単純なプログラムドI/O  バスを備え、それに加えてDMAチャネルがある。PIOバスは、プリンター、テレタイプ端末、紙テープパンチ/リーダーといった低速から中速の周辺機器を接続するのが一般的で、一方DMAはライトペン付きのブラウン管スクリーン、アナログ-デジタル変換回路、デジタル-アナログ変換回路、磁気テープドライブ、ディスクドライブなどで使用する。

ワード長は12ビットで、符号なし整数で0から4095までの範囲を扱え、単純な機械の制御には十分である。また、符号付整数なら -2048 から +2047 まで扱える。これは計算尺より高精度だし、多くのアナログコンピュータにも引けを取らない。12ビットはまた、ASCIIのサブセットを6ビットで表せば、1ワードに2文字を格納できる。

コスト削減のため、他のコンピュータならフリップフロップで構成するレジスタも安価な主記憶を使う設計になっていた。

PDP-8の基本構成では、主記憶容量は4,096ワードで、オプションのメモリ拡張ユニットでさらに拡張する場合は、後述のIOT命令でバンク切り換えをして使用する。

当初、ソフトウェアから見てPDP-8は8種類の命令しかなく、レジスタも2本しか持たない。主記憶は磁気コアメモリでクロックサイクルは1.5μ秒である。典型的には1命令で命令とデータにアクセスするため2サイクルかかり、性能は0.333MIPSとなる。1974年の Pocket Reference Card では基本命令実行時間は1.2μ秒、メモリ参照命令の場合は2.6μ秒となっている。後期の機種では新たなレジスタが追加され、乗算命令と除算命令が追加された。

PDP-8は設計の単純さを重視して設計が最適化されている。直列化ALUを採用したPDP-8/Sでは、論理ゲートを519個しか使っていない。2008年現在、最も規模の小さいマイクロコントローラでも1万5千ゲート以上使っている。他のマシンと比較すると必須ではない部分がそぎ落とされ、可能な限り論理回路を共用する設計になっている。命令は自動インクリメントや自動クリアや間接アクセスを利用して性能向上を図りつつメモリ使用量を削減している。PDP-8のCPUには12ビットレジスタが4本しかない。これらのレジスタは処理サイクルの各時点で様々な用途に使われている。例えば、メモリバッファレジスタは算術演算のオペランドを供給し、磁気コアメモリに書き出すべきデータを一時的に保持する。このように基本は単純にもかかわらず、モジュールを小型化するために価格は高くなった。PDP-8/Sは電源電圧を2種類使っているが、これは diode-transistor logic  でのファンアウト数を大きくする安価な技法である。

2. PDP-8のバージョン
--------------

PDPシリーズのベストセラーPDP-8ファミリーの正確な総売上台数を表すデータは存在しないが、50,000台程度であろうと推定されている。 PDP-8を含む12bitのコンピュータとして、以下のような機種が製造された。

PDP-8 - 16,000ドル、机上据え置き型
PDP-8/S - Small
PDP-8/I - PDPシリーズ初IC化
PDP-8/L - Low Cost
PDP-12
PDP-8/E - Economy。日本では1970年に理経産業より$4,990で発売。
PDP-8/F
PDP-8/M
PDP-8/A
Intersil 6100 はシングルチップのPDP-8互換マイクロプロセッサ
Harris 6120 は、CMOS版シングルチップのPDP-8互換マイクロプロセッサ

2.1. 後の実装例
----------

PDP-8のアーキテクチャは非常に単純なので、それをエミュレートするのは容易である。愛好家がPDP-8全体を1個のFPGAで実装した例もある。

インターネット上にはPDP-8をシミュレート/エミュレートするソフトウェアもいくつか存在する。うまく実装されたものはDECのOSや診断プログラムを実行可能である。後期のPDP-8に可能な限りの周辺機器を接続した状態をシミュレートすることが多い。そこまでしても、現代のパーソナルコンピュータのリソースのほんの一部しか占めない。

3. 入出力
------

I/OシステムはPDP-8の頃に大きな変化を迎えた。初期のPDP-8の入出力は、フロントパネル、紙テープリーダー、テレタイププリンタ、そしてオプションの紙テープパンチャーで構成されていた。その後、磁気テープ、RS-232Cなどによるダム端末、パンチカードリーダー、固定ヘッド式磁気ディスク装置などが追加されていった。最後のころにはフロッピーディスクやハードディスクが一般的になっていた。最近date=2013年10月}}の愛好家はIDEアダプターをPDP-8に接続している。

I/Oは以下のようないくつかの手段でサポートされている:

バックプレーン上の専用I/Oコントローラ
"Negative" I/Oバス
"Positive" I/Oバス
Omnibus がPDP-8/Eで導入された。基本的なDMA方式  がサポートされている。これにはプロセッサの支援が必要だった。本来ならば各I/Oデバイスが持つべき回路を共通化してプロセッサ側に置き、プロセッサがDMAアドレスレジスタとワードカウントレジスタを設定する。その後の3メモリサイクルでプロセッサはワードカウントを更新し、転送アドレスを更新し、最後に実際のI/Oデータワードをやりとりする。初期のPDP-8から備えられていた機能であるが、PDP-8/Eのころにはこの回路は非常に安価になったので、"one-cycle data break"が一般化した。これは個々のI/Oデバイス側にハードウェアによるDMAアドレスレジスタとワードカウントレジスタを持たせ、ディスクドライブや磁気テープなど高速I/Oデバイスとメモリ間でプロセッサを介さず直接メモリへの読み・書きをするDMAを行うものであり、実質3倍の転送性能となった。

4. プログラミング環境
------------

PDP-8の最も基本的なソフトウェア開発システムは、機械語をバイナリ形式でフロントパネルから入力するものであった。その後、PAL-8アセンブリ言語のソースコードを紙テープに格納し、メモリにロードし、紙テープにセーブし、紙テープからアセンブルされてメモリに格納されるようになった。紙テープ方式のプログラミング言語としては他に FOCAL インタプリタや 4K FORTRANコンパイラなどがある。最終的には OS/8 や COS-310 といったオペレーティングシステムによって、ラインエディタやコマンドラインコンパイラといった開発システムが構築された。サポート言語としては、PAL-IIIアセンブリ言語、FORTRAN、BASIC、DIBOLなどがある。

初期のPDP-8システムにはオペレーティングシステムがなく、フロントパネルのスイッチしかなかった。様々な紙テープ式「オペレーティングシステム」が開発されたが、いずれもシングルユーザー方式であった。最後期には先進的なRTOSやプリエンプティブ・マルチタスク/マルチユーザーシステムが利用可能となった。例えば RTOSの RTS-8、マルチユーザーシステムの COS-300 や COS-310、シングルユーザー用ワードプロセッシングシステム WPS-8 などがある。

タイムシェアリングシステム TSS-8 も使用可能であった。TSS-8 では複数のユーザーが110ボーの端末からシステムにログインすることができ、プログラムのエディット/コンパイル/デバッグが同時にできた。言語としては、BASICの特別バージョン、FORTRANのサブセット、ALGOLのサブセット版、FOCAL、PAL-Dアセンブラなどが利用可能である。

DECUS  はPDP-8用にユーザーが寄贈した相当量のソフトウェアを保有している。

5. 命令セット
--------

12ビットの命令ワードの先頭3ビットが命令コードである。ビット5から11までの7ビットのオフセット部でアクセスするメモリを示す。ビット4がセットされていたら、プログラムカウンタ  の上位5ビットとオフセットを連結してアドレスを完成させる。そのビットがゼロならアドレスの上位はゼロとする。ビット3は間接かどうかを示す。セットされていたら、それまでに得られたアドレスはメモリ上にある実効アドレスのある位置を示していることになる。JMP命令は、間接指定されていない場合はメモリワードを読み込むわけではないが、命令のフォーマットは同じである。



5.1. メモリページ
-----------

このように命令はアドレスの下位7ビットだけを直接指定するので、4,096ワードのメモリは128ワードの「ページ」に分割されることになり、命令のビット4でカレントページかページ0を指定する。ページ0に変数を置くと、どのページを実行中でもそれにアクセスできるため、ページ0のメモリは特別である。また、アドレス 0000 は割り込み処理ルーチンのスタートアドレスでもある。また、アドレス 0010 から 0017 までは自動インクリメント機構という特殊性がある。

標準的アセンブラは算術用定数をカレントページに置く。同様に、ページ間ジャンプやサブルーチンコールはカレントページ内から間接アドレス指定で行う。

ページをまたいだ参照や分岐は余分なワードを必要とするため、ルーチンを128ワードのページ境界に収まるように書くか、なるべくページからページへの移行が少なくなるように書くことが重要だった。そのため、何ワードかをいかに節約するかに頭を悩ませることが多かった。PCのインクリメントで自動的に次のページに移行できるため、プログラムを意図的にページの最後尾に置くことが多かった。

5.2. 基本命令
---------

000 - AND - メモリオペランドと AC の AND 001 - TAD - メモリオペランドと <L,AC>の加算010 - ISZ - メモリオペランドをインクリメントし、結果がゼロならば次の命令をスキップする011 - DCA - ACをメモリオペランド位置に保存し、ACをクリアする100 - JMS - サブルーチンへジャンプ101 - JMP - ジャンプ110 - IOT - 入出力転送111 - OPR - マイクロコード化操作

5.3. IOT命令
----------

PDP-8はIOT命令をほとんど定義せず、単に枠組みを提供している。多くのIOT命令がどう作用するかは個々の周辺機器によって異なる。

 Device IOT命令のビット3からビット8でI/Oデバイスを指定する。一部は利便性のために標準化されていた。
00 - プロセッサが処理し、I/Oデバイスには送られない。例えば ION  は割り込み処理のイネーブル、IOFF  は同処理のディセーブルである。
01 - 通常、高速紙テープリーダー
02 - 高速紙テープパンチ
03 - コンソールのキーボード
04 - コンソールのプリンターFunction IOT命令のビット9からビット11までで、そのデバイスで実行すべき機能を指定する。紙テープリーダー/パンチやコンソールなどの単純な機器では、次のように解釈する。
ビット11 - 指定した周辺機器がレディ状態なら次の命令をスキップする。
ビット10 - AC をクリア
ビット9 - その周辺機器とACの間で1ワードを転送し、次のI/O転送を開始し、機器のレディフラグを落とす。 複数のビットをセットすると、適切な順序でそれらが行われる。 ディスクドライブなどのより複雑な周辺機器では、それぞれ固有の機能をこの3ビットで表す。一般に8種類の機能コードを設定できる。

5.4. OPR  命令
---------------------

条件付き操作のほとんどを含め、多くの操作はOPR命令として実行される。OPR命令ではメモリ位置をアドレスで示すということがない。条件付き操作は1命令をスキップするか否かを判断する命令であり、通常はその1命令をJMP命令とすることで条件分岐として機能させる。

OPR命令はマイクロコード化されている。これはマイクロプログラム方式だということを意味しているのではなく、命令語の各ビットがそれぞれ特定の動作に対応しており、複数のビットをセットすることでそれらを1命令で実行できる場合があることを意味している。アセンブリ言語で記述する際には複数のニーモニックを並列に書く。するとアセンブラがそれらのコードをORして1命令にする。上述のIOT命令も周辺機器がマイクロコード化している。

マイクロコード化された動作の実行順序は決まっており、多くの組合せが最も便利になるような順序で実行される。

OPR命令にはいくつかのグループがある。ビット3、ビット8、ビット11 でグループが識別され、異なるグループのマイクロコード化操作は1命令で指定できない。

5.4.1. グループ1
------------

00 01 02 03 04 05 06 07 08 09 10 11 ___________________________________ | 1| 1| 1| 0| | | | | | | | | |__|__|__|__|__|__|__|__|__|__|__|__| |CLA CMA RAR BSW CLL CML RAL IAC

Execution order 1 1 2 2 4 4 4 3

7200 – CLA - AC クリア7100 –­ CLL - L ビットのクリア7040 – CMA - ACの 1の補数7020 – CML - L ビットの反転7010 – RAR - <L,AC> の右ローテート7004 – RAL - <L,AC> の左ローテート7002 – BSW – 6ビットの「バイト」のバイトスワップ7001 – IAC - <L,AC>のインクリメント7012 – RTR - <L,AC> の右ローテート7006 – RTL - <L,AC> の左ローテート多くの場合操作は順次行われ、多くの組合せが最も便利な形で可能である。例えば CLA  と CLL  と IAC  を組み合わせると、まずACとLINKをクリアし、次にアキュムレータをインクリメントするので、ACの値は1になる。これにさらに RAL を加えると、アキュムレータをクリアし、インクリメントし、左にローテートするので、ACの値は2になる。このようにしてアキュムレータに小さい整数定数を1命令で置くことができる。

CMAとIACを組み合わせると、アセンブラではこれをCIAと略記できるが、ACの値を算術的に符号反転できる。PDP-8には減算命令がなく符号付加算命令  しかないので、2つの数の差を求めるには一方の数の符号を反転させるしかない。

グループ1のOPR命令で、マイクロコード化されたビットを全くセットしない場合、何も行われない。そういった命令をNOP命令として使用することができる。

5.4.2. グループ2、Orグループ
-------------------

00 01 02 03 04 05 06 07 08 09 10 11 ___________________________________ | 1| 1| 1| 1| | | | | 0| | | 0| |__|__|__|__|__|__|__|__|__|__|__|__| |CLA SZA OSR SMA SNL HLT

2 1 1 1 3 3

7600 – CLA - ACをクリア7500 – SMA - AC < 0 のとき次命令をスキップ 7440 – SZA - AC = 0 のとき次命令をスキップ 7420 – SNL - L ≠ 0 のとき次命令をスキップ 7404 – OSR - ACとフロントパネルスイッチの間の論理和7402 – HLT - 停止ビット8がセットされていない場合、指定された条件のいくつかが真ならばスキップを行う。例えば、"SMA SZA" 命令コード 7540 の場合、AC ≤ 0 ならスキップする。

グループ2のOPR命令もマイクロコード化ビットが全くセットされていない場合、NOP命令として扱われる。

5.4.3. グループ2、Andグループ
--------------------

00 01 02 03 04 05 06 07 08 09 10 11 ___________________________________ | 1| 1| 1| 1| | | | | 1| | | 0| |__|__|__|__|__|__|__|__|__|__|__|__| |CLA SNA OSR SPA SZL HLT

2 1 1 1 3 2

7410 – SKP - 無条件に次命令をスキップ7610 – CLA – ACをクリア7510 – SPA - AC >= 0 のとき次命令をスキップ 7450 – SNA - AC ≠ 0 のとき次命令をスキップ 7430 – SZL - L = 0 のとき次命令をスキップ ビット8がセットされている場合、スキップ条件はOrグループのときと逆であり、いずれかの条件が真でないときスキップは行わない。つまり、指定された条件が全て真となる必要がある。例えば "SPA SNA" 命令コード 7550 は AC > 0 のときスキップする。ビット5からビット7が全くセットされない場合、無条件でスキップする。

5.4.4. グループ3
------------

これまでのグループで使われていないビットの組合せのOPR命令はグループ3に分類され、多くは MQ  レジスタに関連する。

00 01 02 03 04 05 06 07 08 09 10 11 ___________________________________ | 1| 1| 1| 1| | | | | | | | 1| |__|__|__|__|__|__|__|__|__|__|__|__| |CLA SCA \_ _/ | MQA MQL CODE

1* 2 2 2 3

7601 – CLA – ACをクリア7501 – MQA – Multiplier/Quotient を AC にORする7441 – SCA – ステップカウンタをACにロード7421 – MQL – AC を Multiplier/Quotient にロードし、ACをクリア7621 – CAM – CLA + MQL なので、ACとMQを共にクリア通常、CLAとMQAを組み合わせてMQの中身をACに転送する。MQAとMQLの組合せも便利で、ACとMQの中身を交換する。

ビット8からビット10までの3ビットで以下のいずれかの命令が実行される。

7401 – 何もしない7403 – SCL – ACからステップカウンタへのロード7405 – MUY – 乗算7407 – DVI – 除算7411 – NMI – 正規化7413 – SHL – 左シフト7415 – ASR – 算術右シフト7417 – LSR – 論理右シフト

6. メモリ制御
--------

12ビットワードは4,096種類の値をとることができ、それは最初のPDP-8がワードポインタで間接的にアドレス指定できる最大のワード数でもあった。プログラムが複雑化し、メモリ価格が下落してくると、この制限を拡張することが望ましくなってきた。

既存プログラムとの互換性を保つため、当初設計になかった新ハードウェアはプログラムが生成する実効アドレスにさらに上位のビット群を追加した。メモリ拡張コントローラはアドレス指定範囲を8倍にし、32,768ワードまで扱えるようにした。当時の磁気コアメモリは1ワード当たり50セントのコストであり、32Kワードを実装するとCPUと同程度のコストになるため、この程度の拡張で十分だとされた。

4Kワードぶんのメモリをフィールドと呼ぶ。メモリ拡張コントローラは、DF  と IF  という2つの3ビットレジスタを備えている。それらのレジスタはデータアクセスや命令フェッチの際にどのフィールドにアクセスするかを指定するもので、アドレスは実質15ビットに拡張される。IFレジスタは命令フェッチと直接メモリ参照の際のフィールドを指定する。DFレジスタは間接データアクセスの際のフィールドを指定する。あるフィールドで動作中のプログラムは、直接アドレッシングでは同じフィールドにアクセスし、間接アドレッシングでは別のフィールドにアクセスできる。

IOT命令の 6200 から 6277 までの範囲がメモリ拡張コントローラに対応しており、DFレジスタとIFレジスタへのアクセスが可能である。62X1 命令  はDFレジスタの値をXにする。同様に62X2  命令はIFレジスタの値をXに、62X3 命令は両方をXにセットする。既存プログラムはCIFもCDFも実行しない。DFもIFも同じフィールドを指すので、既存プログラムは単一フィールドだけで動作する。CIF命令の効果は、次のJMPまたはJMS命令まで遅延されるので、CIF命令によって即座にジャンプするわけではない。

フィールド境界とDF/IFレジスタの関係を考えると、複数フィールドを使うプログラムはさらに複雑化する。単純に15ビットのアドレスを生成するのではなく、12ビット・アーキテクチャとの一貫性と互換性を保つよう設計されているためである。後の Intel 8086 では、Intel 8080 で16ビットだったアドレスを20ビットに拡張したが、拡張部分はセグメントレジスタで指定する方式だった。

このメモリ拡張方式により、既存のプログラムを少し修正するだけで扱えるメモリ範囲を拡大することができた。例えば、4K FOCAL は、自身のコードが3Kあってユーザープログラムやデータに使えるメモリは1Kしかなかった。そのFOCALに若干パッチを当てるだけで、ユーザープログラムとデータに別の4Kフィールドを割り当てることができる。さらに、4Kフィールドを別のユーザーに割り当てることもでき、マルチユーザーのタイムシェアリングシステムを構成できる。

6.1. 仮想化
--------

PDP-8/Eとその後の機種では、メモリ拡張コントローラは仮想化も可能なように拡張された。PDP-8の全リソースを使用するようなプログラムが1台のPDP-8上に複数並存でき、仮想機械マネージャの制御下で動作可能だった。このマネージャは全IO命令に対してトラップが可能である。そのようにしてマネージャがデータや命令のフィールドのマッピングを制御でき、入出力を他のデバイスにリダイレクトできる。それぞれのゲストプログラムは、マネージャが提供する「仮想機械」への完全なアクセスを持つ。

新たなIOT命令で、メモリ拡張コントローラのDF/IFレジスタの現在値を読み出すことができ、トラップ前後のマシンの状態をセーブ/リストアできる。しかし、CIF命令の効果が遅延している状態かどうかは判別できない。マネージャは完全なPDP-8エミュレータを含んでいる必要がある。CIF命令をトラップした際、マネージャは次のジャンプ命令までの命令列をエミュレートする必要がある。実際、ジャンプ命令はCIF命令の直後にあるのが一般的で、エミュレーションで性能が大きく低下することはないが、小さな設計上の欠陥への対策としては大きい。

PDP-8/Aのころメモリ価格はさらに下落し、32Kワード以上も可能なレベルとなった。そこでPDP-8/Aでは8フィールド以上を扱える新たな命令群が追加された。フィールド番号は命令にハードコーディングされるのではなく、ACで指定できるようになった。しかし、そのころにはPDP-8は市場から消えつつあり、この新機能を使うよう修正された主要ソフトウェアはごく一部だけだった。

7. コーディング例
----------

PDP-8のアセンブリ言語プログラムを例として示す。以下のコード例はPAL-IIIアセンブラによる。

7.1. 2つの数の比較
------------

単に2つの数を比較するだけでどれだけのコードが必要となるかを示したコード断片。

/Compare numbers in memory at OPD1 and OPD2 CLA CLL /Must start with 0 in AC and link TAD OPD1 /Load first operand into AC ; link is still clear CIA /Complement, then increment AC, negating it TAD OPD2 /AC now has OPD2-OPD1; if OPD2≥OPD1, sum overflows and link is set SZL /Skip if link is clear JMP OP2GT /Jump somewhere in the case that OPD2≥OPD1; /Otherwise, fall through to code below.

見ての通り、PDP-8の典型的なプログラムは作者が意図したアルゴリズムよりも低レベルな機構に集中する傾向がある。また、可読性を損なうもう1つの問題として、条件分岐部分のコーディングがある。上の例で判るとおり条件判断命令は、注目している条件とは反対の条件判断をしなければならない。

7.2. 文字列出力
----------

PDP-8で "Hello, world" をテレタイプ端末に出力するアセンブリ言語のプログラム。

10 / Set current assembly origin to address 10,STPTR, STRNG-1 / An auto-increment register 

200 / Set current assembly origin to program text areaHELLO, CLA CLL / Clear AC and Link again  TAD I Z STPTR / Get next character, indirect via PRE-auto-increment address from the zero page SNA / Skip if non-zero  HLT / Else halt on zero  TLS / Output the character in the AC to the teleprinter TSF / Skip if teleprinter ready for character JMP .-1 / Else jump back and try again JMP HELLO / Jump back for the next character

STRNG, 310 / H 345 / e 354 / l 354 / l 357 / o 254 /, 240 /  367 / w 357 / o 362 / r 354 / l 344 / d 241 / ! 0 / End of string $HELLO /DEFAULT TERMINATOR

7.3. サブルーチン
-----------

PDP-8では汎用スタックをアーキテクチャ上サポートしていないため、サブルーチンを呼び出すときや割り込みが発生したときのコンテキストをセーブする方法が確立されていない。その代わり、リターンアドレスとしてのプログラムカウンタ値がターゲットサブルーチンの先頭ワードに格納される。従って、間接ジャンプ命令でサブルーチンから戻ることができる。

以下のプログラムはサブルーチンを使うように改造した "Hello world" である。JMS命令でサブルーチンに飛び込むと、OUT1:の位置にある0が書き換えられる。

200 / Set assembly origin HELLO, CLA CLL / Clear the AC and the Link bit TAD  / Point AC just *BEFORE* the data  DCA 10 / Put that into one of ten auto-pre-increment memory locations LOOP, TAD I 10 / Pre-increment mem location 10, fetch indirect to get the next character of our message SNA / Skip on non-zero AC HLT / Else halt at end of message JMS OUT1 / Write out one character JMP LOOP / And loop back for more

OUT1, 0 / Will be replaced by caller's updated PC TSF / Skip if printer ready JMP .-1 / Wait for flag TLS / Send the character in the AC CLA CLL / Clear AC and Link for next pass JMP I OUT1 / Return to caller

DATA, "H / A well-known message "e / "l / NOTE: "l / "o / Strings in PAL-8 and PAL-III were "sixbit" ", / To use ASCII, we'll have to spell that out, character by character " / "w / "o / "r / "l / "d / "! / 015 / 012 / 0 / Mark the end of our .ASCIZ string 

リエントラント性や再帰呼び出しを実現しようとすると、プログラマは自分でコールスタックを用意し、リターンアドレスをスタックにセーブしなければならない。また、ROMを使うのも困難である。ROMにプログラムを格納する場合、以下のような回避方法があった。

実行時にはRAMにコピーする
RAMも一部内蔵したROMを使い、各ワードにフラグを設定してRAMを代替に使用するかどうかを指定する。
サブルーチンを全く使わない。またはJMS命令の代わりに次のようなコードを使い、書き換え可能なメモリにリターンアドレスを置く。 JUMPL, DCA TEMP / Deposit the accumulator in some temporary location TAD JUMPL+3 / Load the return address into the accumulator: hard coded JMP SUBRO / Go to the subroutine, and have it handle jumping back JUMPL+4 / Return address

JMS命令を使用するとデバッグが難しくなる。例えば、リターンアドレスの書き換えによって無限ループに陥ることもあるし、サブルーチンのアドレスを間違うとサブルーチンの先頭ではないワードをリターンアドレスで書き換えてしまうこともある。こういった誤りは実行してみないとわからないこともある。

7.4. ソフトウェアスタック
---------------

PDP-8 はスタックをハードウェアでサポートしていないが、ソフトウェアでの実装は可能である。以下はPUSHとPOPというサブルーチンの実装例だが、単純化するためスタックのオーバーフローやアンダーフローはチェックしていない。

PUSH, 0 DCA DATA CLA CMA / -1 TAD SP DCA SP TAD DATA DCA I SP JMP I PUSH /Return

POP, 0 CLA CLL TAD I SP ISZ SP JMP I POP

DATA, 0 SP, 0

以下は、"Hello World" を "OUT" というサブルーチンとこのスタックを使って実装したものである。

200MAIN, CLA CLL /Set the message pointer TAD  DCA SP

LOOP, JMS POP SNA /Stop execution if zero HLT JMS OUT /Otherwise, output a character JMP LOOP

MESSG, "H "e "l "l "o ", " "w "o "r "l "d "! 015 012 0

OUT, 0 / Will be replaced by caller's updated PC TSF / Skip if printer ready JMP .-1 / Wait for flag TLS / Send the character in the AC CLA CLL / Clear AC and Link for next pass JMP I OUT / Return to caller

7.5. 連結リスト
----------

PDP-8での連結リストの実装例。

GETN, 0 /Gets the number pointed to and moves the pointer CLA CLL /Clear accumulator TAD I PTR /Gets the number pointed to DCA TEMP /Save current value ISZ PTR /Increment pointer TAD I PTR /Get next address DCA PTR /Put in pointer JMP I GETN /return PTR, 0 TEMP, 0

8. 割り込み
-------

PDP-8の入出力バスには1本の割り込みラインがあり、割り込みが発生すると割り込み不可状態となって 0番地のサブルーチンを呼び出すように動作する。サブルーチンと同様、割り込みもリエントラント性は無く、割り込みを不可とした状態で割り込みハンドラが動作し、JMP I 0 命令で割り込まれた箇所に戻るとき割り込み可とする。

I/Oバスの割り込みラインが1本なので、割り込み発生源が何かということは分からない。そのため、割り込み処理ルーチンは順に各デバイスのステータスをポーリングしてチェックし、割り込み元を識別した。この処理は条件スキップ命令が並ぶので "skip chain" と呼ばれた。skip chain の最後まで実行しても割り込み元が見つからないことは珍しいことではなかった。相対的な割り込みの優先順位は skip chain でチェックする順番で決定され、先に見つかった割り込みの処理が優先される。

9. 脚注
-----

10. 参考文献
--------

11. 外部リンク
---------

[1] and others are available from Simon Fraser University
[2], FAQS.ORG
[3] has a running PDP8 that anyone can control through a Java applet, plus a webcam to show the results
[4] ポータブルなPDP-8クロスアセンブラ
[5] PDP-8互換マシン販売サイト
[6] in a German computer museum
[7] for Macintosh 
Willem van der Mark's [8] in Java
[9] 各種OSで動作する非常にポータブルなPDP-8シミュレータ
[10] - スミソニアン博物館のコレクション
[11] Blogs the restoration of PDP-8 computers
[12] Steve Gibson's explanation on how the PDP-8 works and how to program it.
[13] has a video series showing the PDP-8