部品実装(1)はこちら 部品実装(2)はこちら 部品実装(3)はこちら
「RETROF-16三部作の比較」(別窓で開きます)はこちら
「汎用ロジックでコンピュータを作る」のトップページ(目次)はこちら 管理人のメインページはこちら
各種命令の実装開始
下記画像は「無条件ジャンプ命令」の試験時の基板(部品面と銅箔面)です。演算ユニット(ALUとアキュムレータ)は未実装です。
)
赤色の丸いシールを貼った部分は、ソケットのみの実装でまだTTLを挿していない所。マスクキングテープでソケットを保護(丸ピンソケットのため、ピンにハンダクズ等が入ると取れなくなる事がある)している。
無条件ジャンプ命令の実装(14-04-26)
分岐命令の試験は0番地に、0番地(すなわち自分自身)に分岐する命令を書き、0番地から実行することにより確認できます。
ソフトウェア的に言うと「無限ループ」に相当します。「無限ループ」が動くと、その実行時の内部波形は同じ制御波形が連続して生じますので、オシロスコープでの観察が可能になります。
無限ループの中に他の命令を入れると、その命令の動きをロジアナを使わずにオシロスコープだけで確認できます。2chオシロの場合、同時に観察できるのは2箇所のみですが、それでも試験の効率は大幅に向上します。HALT命令の次にJMP命令の確認を急ぐのはこの理由によります。
上記画像は、タイムカーソル(波形表示領域の左右にある黄色の縦線)間が1命令に相当します。上の黄色の波形がプログラムカウンタに与えるロードリクエスト(更新要求信号、負論理)で、青い波形がプログラムカウンタ等に常に与えられているクロックです。プログラムカウンタの更新(=分岐命令)は、ロードリクエスト信号がLの区間中にクロックが立ち上がった瞬間に行われます。(上記画像は1命令が1.22MHz周期、クロックは6.25MHz)
回路解説
分岐命令関係だけを抽出した回路図です。図の上にある74LS151は、分岐条件を選択するためのもので、各種フラグの出力に接続されているD0~D7の1つをA~Cで選択し、その反転値をWに出力します。但しストローブ(STB)がLでなければWは常にHになります。
入力D0だけは常にHであるためA~C(分岐条件指定コード)が000の場合は、フラグ状態に関わらず、第5ステージの間、W出力はLに0になります。
W出力がLで、インストラクションレジスタの内容(=命令コード)の上位3bitが100の時にプログラムカウンタのロードリクエストがLとなり、その間のクロックの立ち上がりに同期して(前述のオシロ波形参照)プログラムカウンタの値が更新されます。
痛恨の論理設計ミス
RETROFシリーズは1960年代のコンピュータ作成に倣い、回路設計後にあえて回路シミュレーションを一切行っておりません。回路図上にHとかLとかの文字を幾つも書きながら、頭の中で論理シミュレーションを繰り返して設計しました。当然、念には念をいれたつもりですが大きなポカがありました。
RETROF-Hのアドレッシングモードは「8bitリテラル」「レジスタ」「レジスタ間接」「24bitリテラル」の4種類があり、命令コードの8ビット目と9ビット目(上記回路図の74LS377のQ0とQ1)で指定します。しかし分岐命令における「8bitリテラル」は使い道がありません(0~255番地の間にしか分岐できない)。
そこで、分岐命令に限り、8bitリテラル指定(Q0=Q1=L)時は、プログラムカウンタの上位8bitは更新せず、下位8bitのみを指定されたリテラル値で更新するように細工を施しました。これにより上位8bitが同じアドレス範囲ならば、「8bitリテラル」で自由位置に分岐することが出来ます。
上記回路図のORゲート(74LS32)はこの細工を実現する為のもので、下位ロード信号(PC_L LD#)は命令デコーダ(74LS155)から直結されていますが、上位ロード信号(PC_H
LD#)は8bitリテラル指定(Q0=Q1=L)時にはアクティブにならないようにしたつもりでした。
ところがこれが大きな勘違いで、PCの上位は8bitリテラル指定の時のみ更新(論理が正反対)になっていました。
このミスは基板上にNOTゲートもしくはそれに準じるゲートが余っていればジャンパ線を飛ばせば済む話ですが、あいにく余っているゲートはなく、74ACT04を追加するしかありませんでした。(上記回路図は追加後の回路)。この修正に関しては別途詳細をアップします。
ロード命令の実装(14-04-29)
ALUとアキュムレータを含む全てのTTLのソケットを実装した所です。
各ソケットにTTLを挿しさえすれば、理論上は大半の命令が動くはずですが、理論通りに動くことは到底期待できません。ここでも1命令ずつ地道に検証を進めます。
HALT命令、無条件分岐命令の次に検証するのはロード命令です。
これはオペランドで指定された値を単にアキュムレータにセットするだけの命令です。
オペランドの指定方法(アドレッシングモード)は4種類ありますが、まず8bitリテラル指定から検証します。具体的な命令コードで表すと0010_0000_0101_0101(=0255H)となります。下位8bitの値は何でも良いのですが、0と1が交互に並ぶ解りやすい値ということで55Hとしました。
上記画像の丸いシールを貼った部分はまだTTLを挿入していないソケットです。赤はグラフィック回路とCPU回路とのバッファ、青はALUに演算コードを与えるためのデコーダとフラグレジスタ、黒丸は外部制御(USB接続によるプログラミング)用、そして緑がALUで黄色がAcc(アキュムレータ)です。
回路解説
LD命令関係だけを抽出した回路図です。
RETROF-16Hの命令は6ステージで処理されます。第1ステージで、命令の上位8bitがIR(インストラクションレジスタ、左記回路図右端)に、第2第3ステージで必要な値(この場合はロードする値)がMPR(多目的レジスタ、左記回路図左下)に格納されます。
命令の上位8bitが0010_0000の場合、第3ステージの期間中、回路図にある左側のORゲートの入力が共にLとなり、アキュムレータがゼロクリアされます。更に第5ステージが始まる瞬間にアキュムレータにクロック(立下りエッジ)が入り、MPRの値とアキュムレータの値との論理和がアキュムレータ自身に格納されます。
このとき、アキュムレータは事前にゼロクリアされていますので、結果的に論理和演算の結果はLD命令と同値になります。
試験に用いた命令(ニモニックは「Z80風」に書いています)
START: 2055 LD A,55H // アキュムレータに55Hをセットする
END : 5000 HLT N // アキュムレータの値をデータバスに放出した状態で停止する。
HALT命令はアキュムレータの出力がデータバスを占有している状態で停止します。このHALT命令の機能により、停止時に基板上のLEDを見ることによってアキュムレータの内容を知ることができます。
結果は回路設計、パターン設計共に多々の不具合がありましたが、結果的には無事終了しました。
2014年度のゴールデンウィークについて
物凄く長い連休をとりました。本件も一気に完成まで運ぶつもりでしたが、実際に作業らしきものをしたのは初日だけで、連休が終わってみると何も進んでいない状況でした。原因は「他にもしたいこと」「他にもせねばいけないこと」などが多々あったためです。
やはり本件の様な工作は「普通の日」に時間を気にしながら少しずつ進める方が性に合っている様です。(14-5-8記)
その他の演算命令の実装(14-05-10)
LD命令が正しく動いたという事は、論理和演算が正しく動いている事を意味します。あとは74LS382に与える演算コードを変化させるだけで、様々な演算が実現できます。
演算コードを変化させるためには、IR(インストラクションレジスタ)の演算指定bitを直接74LS382の演算指定端子に接続するのが一番簡単なのですが、ロード命令(単にメモリの値をAccに格納する)、インクリメント命令(メモリの値に1加えてAccに格納する)、デクリメント命令(メモリの値から1引いてAccに格納する)なども実装するために、実際の回路は、IRの演算指定bit(3bit)で示される値を一度74LS138でデコードし、再度ダイオードマトリクスでエンコードし74LS382に渡しています。
左は上記回路図のダイオードマトリクス部分の画像です。
青色の部品がショットキーバリアダイオードBAT43で、これを16本使用しました。
より安価な1N4148等ではなく、BAT43を使用した理由は順方向電圧降下が格段に後者の方が低いからです(注1)。
尚、回路図には記してませんがプルアップ抵抗は2KΩを使用しています(注2)。
(注1)電圧降下が大きいいと、74LS138の出力がLの時でも74LS382へ加わる電圧がより0Vから離れ、僅かなノイズでLと見做せない電圧まで上昇し不安定となると考えたためです。但しIN4148との比較実験は行っておりませんので、優位性は断言できません。
(注2)当初は10KΩでしたが、立ち上がりが鈍いので2KΩに変えました。このため74LS138の出力の吸い込み電流が一部定格ギリギリ(オーバーの可能性もあり)になっています。この件は後日再考します。
動作確認ができた演算関係命令コード一覧 (実装はリテラルアドレッシングモードのみ、XXは0~255の任意の値)
命令コード(2進) | 同(16進) | 動作 | Z80風ニモニック | R-16Hニモニック |
---|---|---|---|---|
0010 0000 XXXX XXXX | 20XXH | XXをアキュムレータにセットする | LD A,XX | LDI XX |
0010 0100 XXXX XXXX | 24XXH | XX+1をアキュムレータにセットする | 対応なし(※) | ILI XX |
0010 1000 XXXX XXXX | 28XXH | XXー1をアキュムレータにセットする | 対応なし(※) | DLI XX |
0010 1100 XXXX XXXX | 2CXXH | XXをアキュムレータに加える | ADD A,XX | ADI XX |
0011 0000 XXXX XXXX | 30XXH | XXをアキュムレータから引く | SUB A,XX | SBI XX |
0011 0100 XXXX XXXX | 34XXH | XXとアキュムレータの論理積をアキュムレータにセットする | AND A,XX | ANI XX |
0011 1000 XXXX XXXX | 38XXH | XXとアキュムレータの論理和をアキュムレータにセットする | OR A,XX | ORI XX |
0011 1100 XXXX XXXX | 3CXXH | XXとアキュムレータの排他的論理和をアキュムレータにセットする | XOR A,XX | XOI XX |
(※)XX+1とXX-1はリテラルアドレッシングモードでは殆ど意味を持ちません。XXがレジスタ、もしくはメモリの内容を示すアドレッシングモードの場合にのみ実用的な意味(ロードとインクリメント/デクリメントが1命令で可能となる)を持ちます。
但し、ILI 255は、アキュムレータに256(=0100H)が、DLI 0はアキュムレータに-1(=FFFF)がセットされます。
この2つの命令に限り、リテラルアドレッシングモードでのロード命令では格納できない値をセットできますので、実用性が皆無というわけではありません。
試験に用いた命令(ニモニックは「Z80風」に書いています)
例えば1+1の試験は以下のコードになります。同様に全ての演算に様々な値を与え、結果を確認することで検証完了としました。
START: 2001 LD A,1 // アキュムレータに1をセットする
2C01 ADD A,1 // アキュムレータに1を加える
END : 5000 HLT N // アキュムレータの値をデータバスに放出した状態で停止する。
まだまだ続きます。
RETROF-16Hの部品実装(その1)へ戻る RETROF-16Hの部品実装(その2)へ戻る RETROF-16Hの部品実装(その3)へ戻る