CPU実験室

誰も見向きもしない古いCPUをいじって動かしてみようというプロジェクトです

探して~たら あるじゃない。

 

bitsavers.orgフェアチャイルドアーカイブを探ってみるとBipolarMicroprocessorDATABOOK(1976)に原典がありました。4706,9406 LIFOStack/ProgramCounterが同等品でしょう。それにしても製品ラインナップをみると興味深いものがいろいろあります。1976年だともうIntel8080も発表されているしCPUの機能はワンチップに集積する流れになっていたと思いますが、このころはまだALU、プログラムカウンタ、シーケンサといったバラの要素機能のICがあったということです。

 

f:id:O3I:20210223103710j:plain

 

この資料に示されている34706のブロック図はさらに詳細で、このままでQuartusⅡのスケマチック入力もできちゃいそうです。

 

f:id:O3I:20210223105418j:plain

 

アーカイブにはこの資料の前年1975年のPreliminary版も保存されていて、こちらは全面タイプ打ち、回路図やタイミングチャートは手書きです!

f:id:O3I:20210223105352j:plain

 

ぶらぶら見ていたら、さすが世界最初に集積回路を開発した企業。なんと1961年のTO-8CANパッケージに封入されたロジックICの資料まで出てきました。

f:id:O3I:20210223111147j:plain

 

かつてFAIRCHILDは「探して~るのにぃないじゃない」と云い、中の人の保存状態も良くないですが、こちらの方は探し物がすぐ見つかり保存状態もすばらしいです。

 

34706

さすがに型番の数字だけでは全くヒットしませんが、思いついて「34706 LIFO」とやったら一発でデータシートが見つかりました。なるほどPROGRAM STACKという名称でフェアチャイルド製です。

f:id:O3I:20210222214507j:plain

フェアチャイルドなら「F~」とかのプリフィックスが付きそうですが、全くの数字だけで正式型番みたいです。このIC自体の入手はまず無理ですがブロック図や機能表もあるのでCPLDインプリメントは簡単にできそう。

 

f:id:O3I:20210222214532j:plain

 

MC14516のソケットに挿すドータボードの部品配置までやってしまいました。

f:id:O3I:20210222214548j:plain

 

これも出来上がりの3Dイメージ。3個の16ピンDIPソケットは実際には連結ピンヘッダになります。

f:id:O3I:20210222214603j:plain

ただ考えてみると、ロジックとしては12ビットバイナリカウンタ+LIFO(12ビットレジスタ×スタック段数)+スタックポインタカウンタ分のレジスタが必要になり、マクロセル数が64のEPM7064に入れようとするとスタック段数は4段にできるかどうか、ということになります。パッケージも大きいEPM7128にしないとダメかもです

 

プログラムカウンタ

以前作ったボードを久々に動かすシリーズですが、今日はMC14500ボードです。

 

f:id:O3I:20210222174227j:plain

 

これも動作には問題ありませんが、すでに書いたようにこのボードは酷い設計ミスをしていてジャンパだらけなので見ているうちにリファインしたくなってきました。

配線ミス以外にも気になる部分があって、1つ目はプログラムカウンタMC14516のプリセットがクロック非同期なのでJMP時の挙動がおかしいこと、2つ目はスタックを持っていないためサブルーチンが使えないことです。前者はプログラムで対処できましたが後者は如何ともしがたく、ただでさえ単純な処理しかできないICUでは致命的です。もちろん逆に自由度が大きいICUだからこそハードの付加でなんとでもなります。プログラムカウンタ周りの見直しをしてみました。

 

マニュアルにはサブルーチンを実現するハードウェアとして、以下のようにプログラムカウンタにLIFOが付いたものが示されています。

 

f:id:O3I:20210222172527j:plain

 

こういう機能のICは単体であるのでしょうか。具体例として挙げられている回路図で使っているのが「34706」というICで、モトローラだから「MC34706」なのか判りませんが、これが全くもって検索でヒットしません。

 

f:id:O3I:20210222172544j:plain

 

ということでもともと基板に実装されているプログラムカウンタMC14516×3個を抜いてそのソケットに挿すCPLDが載ったドータボードを考えてみました。

 

f:id:O3I:20210222172741j:plain

 

部品配置

 NSC800ファミリだけで構成すればマルチプレックスバスを直結、アドレスデコードさえ不要のはずですが、汎用のROM/RAM、I/Oもつなげることを想定しグルーロジックで各種信号を生成します。最低限必要なのはアドレスラッチ、アドレスデコーダ、バス制御信号となります。

ここらへんは今まではPLDで生成するようにしてあとから自由にシステム設計できる・・というか基本設計のミスを誤魔化せる・・のですが今回3Vで動かすとするとGALが使えないので74HCシリーズの標準ロジックで決め打ちにしてしまいます。単純なロジックなのでまず大丈夫でしょう。

f:id:O3I:20210221190720j:plain


 ここまで構成が決まってくるとざっと基板上に必要部品を配置してみたくなります。配線は確定していないですが挿入部品だけを並べるとこんな具合。100*150mmでギリです

 

f:id:O3I:20210218225652j:plain

 

さらに3Dイメージです。ROMソケットの下にTSOPのSRAMが仕込んであるのがわかります。

 

f:id:O3I:20210218225707j:plain

 

ダフスデバイス

CMOCのマニュアルにある言語仕様を読んでいたら、サポートしない機能として
  ・Implementing Duff's device in a switch().

という記述に突き当たりました。「Duff's Device」とは何ぞ、何それおいしいの?

 

Wikipediaによると、「ダフスデバイスとは、C言語での可変長の連続的コピーをループ展開により最適化実装するときに直面する端数の問題を解決するための手法である。」とあります。

これってプログラミングの専門教育を受けると出てくる話なのかもしれませんが自分は生まれて初めて聞いた言葉です。例として示されていたコードをほぼそのまま持ってきてMSC/C++コンパイルできるようにしたのが以下のプログラムです。

f:id:O3I:20210213105059j:plain

関数scpy()はメモリ間で指定した長さをコピーしますがここにダフスデバイスの手法が使われているそうです。普通は*to++=*from++の1行を所定回数回せばいいわけですが毎周カウント数をチェックするのは煩わしい。ではループを完全に展開してしまって*to++=*from++を必要回数並べれば高速だけどコードサイズは大きくなるし回数が可変だと困る。両者いいとこどりをしてある程度まとまった回数だけループ展開しそのブロック単位でループカウントすれば判定回数は減るよね。ブロックサイズで割り切れない端数回数は何とかしましょう、という考えのようです。その端数処理がダフスデバイスのテクニックでソースコードにあるようにcase文の中にループの開始do、終了whileが紛れていてなんか非常に読みにくいですが、これでもちゃんとPC上でも8086ボード上でも動作しました。

 

f:id:O3I:20210213113343j:plain

まぁこの話題自体が数十年前からのもののようだし、今やCPU速度もメモリ領域も充分に大きいので小手先程度のテクニックは屁のようなものでしょう

CMOCコンパイラ

このCMOCはなかなかのスグレモノでCのサブセットとは謙遜していますが、サポートしてない点、C99規格との相違点も明記されていて通常の使い方では全く問題がありません。C標準ライブラリも必要最小限しかサポートしないとしていますがstr~mem~のストリング系関数の他、printf系関数もあるので組込み用途には充分です。

 

自前のLCD制御関数を含む簡単なプログラムを書いてみました。

f:id:O3I:20210212134232j:plain

 

これも問題なく動作しています

f:id:O3I:20210212134433j:plain

 

フルサポートしていないのは実数演算くらいでしょう。

FLOATDOUBLE型変数はコンパイラは受け付けますが演算の実体は本来のターゲットであるCoCoDISK-BASICのROM内ルーチンを使うとされています。

 

f:id:O3I:20210212134507j:plain

上のソースコードコンパイル、リンクはノーエラーで完了しますがボード上で実行させると当然のことながら必ず暴走します。リスティングファイルを見ると、確かに変数をスタックに積むところまではやっていますが加算のためにaddsinglesingleという外部ルーチンを実アドレスで呼んでいるのが判ります。

f:id:O3I:20210212141308j:plain







 

6809用Cコンパイラ

以前作ったCPUボードの開発環境整備を気が向いたときにしていますが、久々に6809ボードを引っ張り出してきました。酷い埃まみれ・・

 

f:id:O3I:20210211111229j:plain

6809用のクロスCコンパイラとしてMicro-Cというのがありましたが、今動かそうとするとありがちなエラー

f:id:O3I:20210210222617j:plain

が出てしまいます。古いCPUのアセンブラ/コンパイラMS-DOSコマンドラインで動いていたようなものはほぼ全滅ですね。

他に探すとCMOCというコンパイラがフォルダから発掘されました。これは米国Tandy社のTRS-80ColorComputer(通称CoCo)をターゲットにしたもので、どこかからか拾ってきてインストールしたのが2016年くらい。バージョンが0.1.32となっています。

これはもともとcygwin環境下で動かすものですがWin32用にビルドされたものを落としてきたようなのです。ところがこれも今動かすと何故かリンク未解決エラーが消せません。このボード用に活用していたかも覚えていないのですが、たしかコンパイラドライバがちゃんとWin32へ移植できてなくプリプロセッサアセンブラ、リンカを個別に呼び出すバッチを自分で組んでました。環境変数の設定に問題があるのかもしれません。

このコンパイラを現時点でさがすと今も開発は継続されていて直近バージョンが0.1.69になっていました。Win32用のパッケージもあったのでさっそくアップデートして簡単なソースをコンパイルしてみたらちゃんとバイナリまでできたので使えそうです

 

0xFFC0番地にあるパラレルポートにインクリメントデータを出力するいつものLチカテストをしてみます

f:id:O3I:20210210220515j:plain

 

起動させるのはコンパイラドライバcmocのみです。コマンドラインのオプションも  --srecでSフォーマット出力、--org=0x0000で先頭番地を0番地に指定するくらいです。

f:id:O3I:20210210220531j:plain

 

リスティングファイルをみると最適化の過程などいろいろコメントが埋め込まれてきますがちょっとそれをどけてやるとかなり質の良いコードを生成しているのがわかります

f:id:O3I:20210210220546j:plain

 

Sフォーマットの形でボードに転送して実行してみました。パラレルLEDのLSBで約43kHzでチカチカしています。

f:id:O3I:20210210220753j:plain