これがCPUとクロックジェネレータやバスバッファなどが搭載された基板です。このCPUにはNational
Semiconductor社製のINS8080ADが使われています。その左上にある金属の四角いものが水晶発振子で18.000
MHzが使われています。クロックジェネレータはCPUの直上に2個あるうちの左側のプラスチックパッケージのICで同じくNS社製のDP8224が使われています。クロック周波数は水晶発振子の周波数の1/9で2
MHzちょうどです。
電子部品を見慣れている人ならおわかりでしょうが、使用されている抵抗のサイズが必要以上に大きいですね。当時でも、たとえば国産のEMIC
SI/Oボードを見ればわかりますが1/4 Wサイズの抵抗器が使われていました。ここで使用されているのは1/2
Wサイズではないかと思われる大きさで、デジタル回路に使用される抵抗器としては必要以上に大きめです。たとえば5
Vにプルアップしている2.2 kohmの抵抗の消費電力はせいぜい0.012 Wで1/16 Wの抵抗でも使用可能ですが、当時使用されていた抵抗は1/4
Wが普通で1/8 Wが特殊な小型用途という状況でしたから、1/4 Wを使うのが普通です。まさかアメリカ人一般の器用さに合わせて大きめの部品を使用したわけではないとは思いますが、でも、もしかしたらそうかもしれないなどと考えたくなってしまいます。
あと、プリント基板のパターンは手貼りなのですが、このCPU基板といい、下のC/Dインターフェース基板といい、パターンの引き回しが気持ち悪いねぇ。こちらの感覚ではイヤ。定規で線を引いてパターンを作りながら、ほかのパターンと当たりそうになると、その場でちょこちょこっと変更してなんとか接続しているという感じで、直線的なんだけど細かいところはいいかげんに曲がっていて、しかも曲がり方が美しくない。他のパターンとぶつかりそうだったから曲げて修正してあるけど、後でパターンを見直してぶつかるはずのパターンが取り去られた後でも、回避したパターンを直線に直しておこうなんてこともしてないし、多数の線が並行に走っているところで後の方で隙間がなくなってくると、その線だけ細く描いて納めようとしてるし。写真はJPEG圧縮で細かいところがつぶれているけど、線の太さが一部変になっているくらいはわかるかな。
電源ラインにフェライトビーズを挿入するのは悪い習慣ではないのですが、入れ方が誤っている場所があったりして、少々技術レベルに疑問を持ってしまいますね。まぁ、バスのGND端子が背中合わせの2端子しか存在しないというあたりから問題なんですけど。
これがCPUボードとコンソールパネルを結び付けるインターフェース基板です。
CPUボードも、この基板も、どちらも写真からはわかりませんが、かなり反っています。おまけに組み立てに使用されたフラックスの品質が悪くて塩素分が多かったためか、部品の足や半田に腐蝕が見られます。品質管理はちょっと不得意だったようで。あ、外部のところに書いたけど、このALTAIR
8800bは組み立てられたものを輸入したので、品質管理はすべてMITS社の側の責任ですから。
やはりフェライトビーズの挿入位置に問題があります。カードエッジコネクタの右端のそばにあるL3というフェライトビーズは、バスのGND端子とカード内のGND配線の間に入れられているのだけど、こうすると共通インピーダンスを高め高周波的なノイズマージンが下がって、良いことはひとつもありません。実質的に誤動作を導くほどの悪影響もないのだけど、結局は役に立たないフェライトビーズが入っているというだけで、コスト的観点からも無駄。
コンソールパネルのスイッチやLEDを取り付ける基板は、分解するのが手間なので、マニュアルの図をスキャンしてしまいました。単にスイッチやLEDとLEDの駆動回路くらいが搭載されているのではなく、Display/Controlボードという名称のようにコンソールパネルからの指令をCPUに実行させるための凝った回路が載っています。47個ものICが取り付けられていますからね。残りの2枚の基板を合わせたよりもICの個数が多いくらいです。
左上から2番目のICはUVEPROMの1702Aです。残りの24ピンのICは8212で、便利な8
bitラッチとして使われています。このコンソールパネルの動作は技アリで大変に興味深く、基本設計の悪さを指摘してきた私も誉めたくなるくらいの回路です。簡単に表現すると、1702Aの中にパネル回路を制御するマイクロプログラムとCPUへの命令が交互に書き込まれていて、パネル回路とCPUが協調してメモリの読み書きなどのコンソールパネル指令を実行しています。
あと、私の所有するロットでは、このDisplay/Controlボードに問題があって、長時間使用すると特定のICが破損します。なんと普通のLS
TTL回路のプルアップ抵抗が5 Vに接続されずに8 Vの非安定電源に接続されている場所が1ヶ所あって、74LS04の入力がじきに破壊します。修正箇所はわかっていますから、製造番号の近い8800bを使用している方は連絡してください。
このALTAIR 8800bのようなコンソールパネルを持つ8080Aを使用したコンピュータを作ろうとすれば、普通はコンソールパネルからのメモリの読み書きにDMAを使用します。CPUをHALT状態にして、普段CPUボードが出力しているアドレスバスやコントロールバスなどをハイインピーダンスにしてCPUボードをバスから論理的に切り離してから、コンソールパネルのアドレススイッチの状態をアドレスバスに接続します。その上でメモリの読み出しの際にはコントロールバスに含まれるメモリからの読み込みストローブ信号を有効にして、その際にデータバスに出力されるメモリの内容をコンソールパネルのランプに表示します。メモリにデータを書き込む場合には、アドレスに加えてコンソールパネルのデータスイッチの状態をデータバスに出力しておいて、コントロールバスにメモリへの書き込みストローブ信号を出力します。
おっと、ALTAIR 8800bではアドレススイッチとデータスイッチが独立していませんでした。アドレスを内部に設定してから、同じスイッチで書き込みデータの指定もやっています。おまけに操作対象のアドレスをオートインクリメントする機能もありますね。このような機能を実装しようとすれば、74193のようなデータをセット可能なアップダウンバイナリカウンタをアドレスポインタに使用することでしょう。まずカウンタにスイッチの値をロードし、そのカウンタの値をアドレスバスに出力するようにします。あとのデータの読み書きの手法は前と同じです。アドレスの値はアップダウンカウンタに記録されていますから、パルスひとつで次のアドレスや前のアドレスに変化させられます。単純にアドレススイッチを使うよりは使い易そうですね。
ALTAIR 8800bも同じようなことをやっているのでしょうか。いや、回路図にはそんなカウンタが並んでいませんし、それでは8800bのようにRUNスイッチでアドレス表示のアドレスからプログラムの実行開始ができません。実はALTAIR
8800bはアドレスカウンタの代わりに8080A内部のプログラムカウンタを使用するという離れ業を行っています。CPUが命令をフェッチするときにREADY信号を操作して、あたかもメモリがおそろしく遅いように扱えば、CPUのメモリアクセスサイクルがずっと続きます。その間はアドレスバスにCPUのプログラムカウンタの値が出力されています。これがアドレスカウンタの代わりになります。同時に命令を読み出すためのメモリ読み込みストローブ信号も出され続けていますから、データバスにはメモリの内容が出力され続けていて、それをコンソールパネルに表示することができます。
EX NEXT機能はCPUにNOP命令を読み込ませるだけで実現できます。NOP命令なら、プログラムカウンタ以外のCPUの内部状態を変化させずに、プログラムカウンタの内容がインクリメントされるためです。8800b
busと8080Aの間にある双方向バッファをハイインピーダンスにして外部バスと8080Aを切り離し、8080Aのデータバスに直接NOP命令のオペコードをパネルの制御回路から出力して、外部バスとは無関係にCPUにNOP命令を強制実行させます。そして、元と同じ状態になれば、次のアドレスのメモリ内容が表示されることになります。EXAMINE機能はどうするかといえば、JMP命令を読み込ませることで実現しています。JMP命令は3
Byte命令ですが、2 Byte目にはコンソールパネルのスイッチの下位バイト相当の値を、3
Byte目には同じく上位バイト相当のスイッチの値を読み込ませます。すると、プログラムカウンタにパネルスイッチの値をロードしたことになります。
DEPOSIT機能はメモリの読み出しストローブの出力を禁止してスイッチの内容をデータバスに出力すると同時にパネルの制御回路から書き込みストローブ信号をパルス出力することで実現できます。DEP
NEXT機能はCPUにNOP命令を読み込ませてからDEPOSITと同じことを行います。
RUNやSINGLE STEPやSLOW実行などに関しては、CPUのWAIT条件を適切に操作するだけで実現できます。プログラムカウンタとアドレス表示が一致しているわけですから、単にWAITをはずしてメモリからのデータをフェッチできるようにすれば、表示されているアドレスから実行を開始できます。その直後に強制的にWAIT状態にしてしまえば、ステップ実行です。WAIT解除と強制WAITを定期的に行えば、SLOW実行になります。
残りのパネル操作のアキュムレータ操作関係は大技の力技が必要です。特定の命令列をCPUに入力すれば、アキュムレータの内容をデータバスに出力したり、入出力命令を実行することができます。ただし、そんなことをしてはプログラムカウンタがいくつも変化してしまいます。そのため、表示しているアドレスデータ、つまりプログラムカウンタの内容を2個の8212にラッチしておき、読み込ませる命令列の最後でJMP命令のオペコード、以前のプログラムカウンタの下位アドレスを保持している8212のデータ、同じく下位アドレスを保持している8212のデータの順でCPUに読み込ませます。これでコマンドを実行する前の状態にプログラムカウンタを復帰できるというわけです。
これらのシーケンスを実現するのは、簡単そうに書いてしまいましたが、特定の命令をCPUである8080Aのデータバスに出力すると同時にバスに接続された各種バッファを制御しつつコントロールバスに適切なストローブパルスを出力したり、パネルスイッチの内容をデータバスに出力して同様のバッファやバス制御を行ったり、結構複雑なシーケンス制御を続けて行う必要があります。そのための制御にマイクロプログラム方式を利用しています。ROMの1702Aには、偶数アドレスにマイクロプログラムが、奇数アドレスにCPUに読み込ませる命令コードが、書き込まれています。マイクロプログラムのあるビットが1なら奇数アドレスの命令コードをデータバスに出力してCPUに読み込ませるとか、別のビットが1ならパネルスイッチの下位バイト相当をデータバスに出力してCPUに読み込ませるとか、また別のビットでメモリへの書き込みストローブパルスを生成するとか、8
bitのデータのそれぞれが別の意味を持たされています。そうして、バス制御などの複雑なシーケンス操作を単純化しているわけです。パネルのコマンドスイッチを操作すると、そのコマンドに応じて1702Aに与える上位4
bitのアドレスが決定され、同時に下位4 bitのアドレスを与えるべきカウンタがリセットされます。内部クロック信号によって下位4
bitのアドレスが順次インクリメントされながら、ROMに納められたシーケンス列が実行されています。ROMにはシーケンスの末尾を表すデータも格納されていて、そのビットパターンが検出されるまで、シーケンスが連続実行されているという仕組みになっています。
なお、RUN, STOP, SINGLE STEP, SLOWのコマンドに関しては、ROMを使用せずにCPUに与えるREADY信号をコントロールしているシングルステップ制御回路だけで実現しています。このシングルステップ制御回路は、他のコマンドを実行するときにはもちろん1702Aの中のマイクロプログラムによって制御されます。
これがALTAIR 8800bのコンソールパネル制御の概要です。
8800 busの仕様を以下に整理してみます。まずはバスの信号配列の表です。
番号 記号 意味
番号 記号 意味
1 +8V +8
V unregulated 51
+8V +8 V unregulated
2 +18V +18 V unregulated
52 -18V -18 V unregulated
3 XRDY External
Ready 53
SSWI* Sense Switch Input
4 VI0 Vectored
Interrupt #0 54 EXT CLR* External Clear
5 VI1 Vectored
Interrupt #1 55 RTC
$ Real Time Clock
6 VI2 Vectored
Interrupt #2 56 STSTB* $ Status Strobe
7 VI3 Vectored
Interrupt #3 57 DIG1 $
Data Input Gate #1
8 VI4 Vectored
Interrupt #4 58 FRDY $
Front Panel Ready
9 VI5 Vectored
Interrupt #5 59
10 VI6 Vectored
Interrupt #6 60
11 VI7 Vectored
Interrupt #7 61
12 XRDY2 $ External Ready #2
62
13
63
14
64
15
65
16
66
17
67
18 STAT DSB* Status disable
68 MWRITE Memory Write
19 C/C DSB* Command/Control disable 69
PS* Protect Status
20 UNPROT Unprotect
70 PROT Protect
21 SS Single
Step
71 RUN Run
22 ADD DSB* Address disable
72 PRDY Processor Ready
23 DO DSB* Data Out disable
73 PINT* Interrupt Request
24 CK2 Phase 2
clock
74 PHOLD* HOLD
25 CK1 Phase 1
clock
75 PRESET* RESET
26 PHLDA Hold Acknowledge
76 PSYNC SYNC
27 PWAIT WAIT
77 PWR* Write
28 PINTE Interrupt Enable
78 PDBIN Data Bus IN
29 A5 Address
Line #5 79
A0 Address Line #0
30 A4 Address
Line #4 80
A1 Address Line #1
31 A3 Address
Line #3 81
A2 Address Line #2
32 A15 Address
Line #15 82 A6
Address Line #6
33 A12 Address
Line #12 83 A7
Address Line #7
34 A9 Address
Line #9 84
A8 Address Line #8
35 DO1 Data Out
Line #1 85 A13
Address Line #13
36 DO0 Data Out
Line #0 86 A14
Address Line #14
37 A10 Address
Line #10 87 A11
Address Line #11
38 DO4 Data Out
Line #4 88 DO2
Data Out Line #2
39 DO5 Data Out
Line #5 89 DO3
Data Out Line #3
40 DO6 Data Out
Line #6 90 DO7
Data Out Line #7
41 DI2 Data In
Line #2 91
DI4 Data In Line #4
42 DI3 Data In
Line #3 92
DI5 Data In Line #5
43 DI7 Data In
Line #7 93
DI6 Data In Line #6
44 SM1 Machine
Cycle 1 94
DI1 Data In Line #1
45 SOUT Output
95 DI0 Data In Line #0
46 SINP Input
96 SINTA Interrupt Acknowledge
47 SMEMR Memory Read
97 SWO* Write Out
48 SHLTA HALT Acknowledge
98 SSTACK Stack
49 CLOCK* Clock (Inverted CK2)
99 POC* Power On Clear
50 GND Ground
100 GND Ground
端子1から端子50までが部品面の左から右へ並んでいて、端子1の裏にあたるハンダ面側に端子51が、端子50の裏面に端子100が並んでいます。意味の2文字前に$マークが付けられている信号は、8800bで新設された端子で、ALTAIR
8800aなどにはありません。記号が記入されていない端子は未使用です。
A0からA15までがアドレスバスで、8080Aの端子がバッファリングされて出力されています。CPUボードのアドレスバス出力を禁止するのがADD
DSB*信号で、この信号がLになると他の信号や回路の状態とは無関係にCPUボードのアドレスバス出力がハイインピーダンスになります。
データバスは双方向バスでなく、入力と出力が別れた単方向バスになっています。これは、ALTAIR
8800開発当時に双方向性バスバッファの安くて使いやすいICがなかったのと、メモリボードに使用されると思われた2102というメモリLSIが入出力分離で単方向バスに接続するのも容易だったからだということです。まぁ、当時入手できる部品で安価に済まそうとしたわけですね。DO0からDO7までがCPUボードから見て出力で、メモリやI/Oへの書き込みに使われます。DI0からDI7までがCPUボードから見て入力で、メモリやI/Oからの読み込みに使われます。このような単方向バスを採用したため、以後に高度なDMA転送を利用した基板を設計する際に手間が増えることになりますし、双方向バスを使用しているマイクロプロセッサ周辺入出力LSIを接続する際にも部品が増えてしまうことになります。初期の設計時には周辺入出力LSIなんて存在しなかったので、しかたないとも言えるんですが。DO0からDO7のCPUボードの出力を禁止する信号がDO
DSB*で、ADD DSB*と同じく周囲の信号や回路の状態とは無関係にデータバス出力をハイインピーダンスにします。
記号で先頭にPが付いているのはマイクロプロセッサの端子に直接対応する信号です。PINT*とPHOLD*が入力で、PWR*,
PDBIN, PWAIT, PSYNC, PHLDA, PINTEが出力です。この6本の出力を切り離すのがCC
DSB*信号となっています。例によって他の信号とは無関係にコントロールラインの出力をハイインピーダンスにしてしまうので、下手な制御はできません。ところで、よく見るとDMAの際にCC
DSB*や他の出力禁止端子の制御に使うべきPHLDAまでCC DSB*でハイインピーダンスになってしまいます。CPUがバス操作を止めて別回路にバスを明け渡しているという意味の信号だから、各種バスバッファもこれに合わせてハイインピーダンスにすべきなんですけど。幸い、PHLDAは正論理でプルアップしておけばハイインピーダンスになってもHレベルと他の回路から認識されるので、PHLDAがHになってからCC
DSB*を有効にしてハイインピーダンスにしてもなんとかなるんですけど。ちょっと回路がややこしくなってやだかな。しかも偶発的にCC
DSB*が有効になると、他の回路がPHLDAが出力されて正規にCPUにDMA許可を取ったのだと認識してしまうのも、偶発的にそんなことになるなんて故障しているか回路設計の誤りだという点を差し引いても、やな感じです。PINT*は本物の割り込み入力です。VI0
- VI7はオプションの基板でPINT*やSINTAを用いて実装されるもので、標準のALTAIR
8800bでは使用できません。
記号で先頭にSが付いているSMEMR, SINP, SM1, SOUT, SHLTA, SSTACK, SWO*,
SINTAの8本の信号はCPUが出力するステータス情報出力です。この信号を用いてメモリやI/Oの制御をすることが期待されますが、これを使用せずにメモリやI/Oボードの中でDO0
- DO7の情報をSTSTB*でラッチして同じ信号を得ることもできてしまうのが8800
busの問題点です。SMEMRやSOUTなどを使ってメモリやI/Oアクセスを制御するなら、Z80
CPUなど別種類のCPUを用いたシステムを構築できますが、データバスに出力されるステータス情報をSTSTB*でラッチするのを別種類のCPUで模擬する回路を設計しても、その送出時間の分だけ性能が落ちてしまうし、実現できないかもしれません。これらの信号出力を禁止するのがSTAT
DSB*信号ですが、これも例によって他の信号や回路の状態とは無関係にステータス出力をハイインピーダンスにするので注意が必要です。
リセット信号にはPOC*, PRESET*, EXT CLR*の3種類の信号があります。POC*は電源投入時のオートリセット信号で、PRESET*は8080Aをリセットする信号、EXT
CLR*は8080Aには無関係にI/Oデバイスのクリアに使用するということです。まぁ、I/Oデバイスではすべてのリセット信号のORを使ってリセットすればよいのでしょう。POCはCPUボード、PRESET*とEXT
CLR*信号はD/Cインターフェースボードで駆動しています。オープンコレクタ出力ではないので、他の基板からは出力することはできません。
CPUにWAITサイクルを要求する信号はリセット以上に数が多く、XRDY, XRDY2,
PRDY, FRDYの4端子があります。CPUボード内でただちに4入力NAND回路に接続されて、どれか1本でもLならWAITが入るようになっているという点で、同等です。しかし、FRDYはD/Cインターフェースボードが占有していて、パネル操作のために駆動しています。
SSWI*はI/Oアドレス0FFHをCPUが読み込んだとき、その他パネル操作の都合でCPUのデータ入力を使用するときに有効となりますが、CPUボードでも使用していないし、特に別回路で使用することもないでしょう。RTCは60
Hzのリアルタイムクロック信号が出力されているはずの端子ですが、これはオプションのReal
Time Clock/Vectored Interrupt Boardがないと未使用端子でしかありません。STSTB*はステータス情報がデータバスに出力されるタイミングを表す信号ですが、前述のように互換性のためには使用すべきでない信号です。DIG1はフロントパネルからの制御のためにCPUボードに与えるべき信号で、他のボード類には無縁です。
MWRITEはメモリへの書き込みタイミングで、メモリボードではこの信号を使用しないといけません。PWR*やステータス情報から同じ信号を作成できますが、8800bのフロントパネルからのデータの書き込み時にはPWR*やステータス情報が正しく変化せず、MWRITEだけが出力されるためです。しかし、初期のTDL社のZPU(Cromemco社にあらず)やIMSAIのCPUボードはMWRITEを正しく作成せず、トラブルの元でした。
UNPROT, PROT, PS*信号はメモリの書き込み保護に関する信号で、対応メモリボードでないと使えません。簡単にいえば、メモリボードにはバンクごと(1
KByteとか4 KByte単位のメモリブロック)にメモリの書き込み保護フリップフロップ(FF)があり、コンソールパネルから特定のメモリアドレスを参照しているときにUNPROT信号が有効になれば、そのメモリアドレスを含むバンクの書き込み保護FFがクリアされます。逆に同じ状態でPROT信号が有効になれば、そのメモリアドレスを含むバンクの書き込み保護FFがセットされます。書き込み保護FFがセットされていると、MWRITE信号は無視されて書き込みが行えず、読み出しだけが行えるROMのようになります。これでプログラムの暴走や誤操作で書き換えたくないメモリ領域を保護できるわけです。これだけでは、あるメモリバンクがプロテクト状態かどうかわかりませんから、その表示のために存在する信号がPS*信号です。特定のメモリアドレスが参照されているとき、そのアドレスを含むバンクの書き込み保護FFの状態がPS*信号に出力されます。フロントパネルでは、PS*信号に応じてパネル面のPROTECT
LEDを点灯させますから、書き込み保護FFの状態を知ることができます。
SSとRUNはフロントパネルの内部状態を表す信号ですが、特に意味のある使用法があるわけでもありません。CK1,
CK2, CLOCK*は2 MHzのクロック信号です。一定周期のクロック信号が必要な場合には、CLOCK*信号を使うとよいでしょう。この信号はIEEE-696でも2
MHzクロック出力が保証されていますから。
バスの信号を観察するだけでも、ある種のでたらめさが読み取れると思います。アドレスバスとデータバスと合わせて、配列順序の規則性がみられません。CPUボードのパターンを作成するとき、配線しやすい順序だったのだろうとしか思えませんね。FRDY端子やDIG1信号のように、CPUボードとD/Cインターフェースボードの間でだけ意味のあるものまでバスに出ています。これらの基板間にさらに別のコネクタで配線するのを避けているだけのようです。VI0からVI7までのベクトル付き割り込み信号やRTC信号がサポートされていれば立派ですが、じつはこれらはオプションの制御基板を取り付けなければ使用できません。定義だけです。制御信号には正論理と負論理が入り交じっていて、問題になりそうです。
最大の問題点はグラウンドや電源回りで、GND端子が2本しかないというのは困ったことです。高速の信号伝送にはストローブ系の信号の隣にGND端子があった方が有利ですし、2端子だけでは少し消費電流の大きい基板では端子の直流抵抗による電圧降下によって他の基板とのGND電圧の関係が変化してしまい、0.4
VしかないTTL信号のノイズマージンがほとんどなくなってしまいます。
もうちょっと良く考えて設計しろよ、と、言いたくなってしまいますが、そもそもは1機種限りの低価格コンピュータキットのつもりで設計したはずで、何十社から多数の製品が発表され全世界で使われることになる標準バス規格の原形を設計しているつもりはまったくなかったでしょうから、お門違いの文句ではあるでしょうね。
ただ、これがアメリカを中心に一時代を築いたパーソナルコンピュータバスアーキテクチャの原形なんです。はい。
Return to IC Collection