トランジスタでCPUをつくろう!
トランジスタで8080をつくってしまおうというまさにびっくり仰天、狂気のプロジェクトです!
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
見事にできましたら、もちろんTK−80モニタを乗せて、それからBASIC、CP/Mを走らせましょう!
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
[第211回]
●命令デコード回路(13)DECODE3テストプログラム
緊急事態宣言が出されるそうですね。
皆様どうか健康には十分留意してお過ごしください。
幸い私の周りはまだ落ち着いていますが、私も無理をしないように注意しつつ過ごしたいと思っております。
さて。
命令デコード回路のテストプログラムとしてはこれまでDECODE1、DECODE2をテストするためのプログラムを作りました。
DECODE1もDECODE2も入力コードをデコードして1本の出力をアクティブにするものでしたが、そこで出力される信号は命令コードに直結するものではなくてその前段階の信号でした(一部の信号は命令回路に直結しています)。
これに対してDECODE3はDECODE1に入力される「命令コード」に対応した信号をアクティブにします。
もっともまだ命令回路はありません。
命令回路はこれから作っていきますが、ここでそのための準備が整うことになります。
ということで今回のテストプログラムは今まで作ったプログラムとはちょっと趣が変わっています。
下がそのプログラムリストです。
10 OUT $83,$8B 20 D%=$C3:GOSUB 310:OUT $80,A% 30 B%=IN($81):GOSUB 420 40 PRINT "JMP C3",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 50 D%=$CD:GOSUB 310:OUT $80,A% 60 B%=IN($81):GOSUB 420 70 PRINT "CALL CD",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 80 D%=$D3:GOSUB 310:OUT $80,A% 90 B%=IN($81):GOSUB 420 100 PRINT "OUT D3",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 110 D%=$DB:GOSUB 310:OUT $80,A% 120 B%=IN($81):GOSUB 420 130 PRINT "IN DB",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 140 D%=$E3:GOSUB 310:OUT $80,A% 150 B%=IN($81):GOSUB 420 160 PRINT "XTHL E3",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 170 D%=$EB:GOSUB 310:OUT $80,A% 180 B%=IN($81):GOSUB 420 190 PRINT "XCHG EB",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 200 D%=$F3:GOSUB 310:OUT $80,A% 210 B%=IN($81):GOSUB 420 220 PRINT "DI F3",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 230 D%=$FB:GOSUB 310:OUT $80,A% 240 B%=IN($81):GOSUB 420 250 PRINT "EI FB",HEX$(A%,2),BI$(A%),HEX$(E%,2),BI$(E%) 260 INPUT "B1 to out1-2,ok?"Y$ 270 D%=$C9:GOSUB 310:OUT $80,A% 280 B%=IN($81) 290 PRINT "RET C9",HEX$(A%,2),BI$(A%),HEX$(B%,2),BI$(B%) 300 STOP 310 'code change d0-d7 to PA 320 A%=0 330 IF BIT(D%,6)=1 THEN A%=A%+1 340 IF BIT(D%,7)=1 THEN A%=A%+2 350 IF BIT(D%,4)=1 THEN A%=A%+4 360 IF BIT(D%,5)=1 THEN A%=A%+8 370 IF BIT(D%,1)=1 THEN A%=A%+16 380 IF BIT(D%,0)=1 THEN A%=A%+32 390 IF BIT(D%,3)=1 THEN A%=A%+64 400 IF BIT(D%,2)=1 THEN A%=A%+128 410 RETURN 420 'code change PB to out0-out7 430 E%=0 440 IF BIT(B%,6)=1 THEN E%=E%+1 450 IF BIT(B%,7)=1 THEN E%=E%+2 460 IF BIT(B%,4)=1 THEN E%=E%+4 470 IF BIT(B%,5)=1 THEN E%=E%+8 480 IF BIT(B%,2)=1 THEN E%=E%+16 490 IF BIT(B%,3)=1 THEN E%=E%+32 500 IF BIT(B%,0)=1 THEN E%=E%+64 510 IF BIT(B%,1)=1 THEN E%=E%+128 520 RETURN |
ちょっと見には複雑そうに見えますが、やっていることは極めてシンプルです。
Aポートから8ビットの命令コードを出力してその結果をBポートに入力してそれを出力するだけのプログラムです。
もっともそれをシンプルに行なうためにはちょいとした工夫が必要です。
今までのプログラムは「生の」データを出力して、結果の出力も「生のまま」表示するものでした。
今回は命令コードそのものを入力します。
命令コードはAポートから出力してDECODE1に入力されます。
ここで問題になるのはAポートのビットの並びがDECODE1の入力コネクタのビットの並びとは異なっているという点です。
このことについては今までのところにも書いてきました。
今まではその並びの違いはそのままにしてなんとかこなしてきました。
今まではAポートから出力するデータを順番に特定の1ビットのみを0、または1にすることで、そのときの結果の出力データとを照らし合わせて回路が正しく動作しているかどうかを判断してきました。
今回はその手は通用しません。
一定のルールはありますがDECODE1に与えるデータ(命令コード)は特定の1ビットのみが1か0であるというほど単純ではありません。
たとえばJMPならC3、CALLならCDというコードを与えなければなりません。
何が問題かというと、Aポートのビットの並びとDECODE1の入力コネクタのビットの並びが異なっているために、AポートからC3を出力してもDECODE1にはC3としては入力されないという点です。
Aポートから出力するデータはDECODE1に入力されるときに正しい命令コードになるようなデータでなければならないのです。
つまりコード変換が必要ということです。
今までのテストプログラムではそこまでしなくてもなんとかなりました。
言ってしまえば手抜きのプログラムでしたけれど、今回は手抜きというわけにはいかないようです。
面倒臭いなあと思いながら作り始めたのですけれど、考えてみたら「なんだ。簡単じゃないの」。
意外と簡単にできてしまいました(何をやっているのかわかります?)。
こういうのは最もコンピュータ的(機械的)なプログラムです(前回のコネクタ接続図を見ながら考えてみてください)。
実際はDECODE1に与えるデータのみを命令コードになるようにコード変換すればよいのですが、どうせついでですのでDECODE3から出力される結果についても出力コネクタのビット並びの通りになるようにデータ変換をするようにしました。
310−410が命令コード変換サブルーチンで420−520が出力データ変換サブルーチンです。
メインプログラムの260で異なことをやっていますがそれについては後ほど説明します。
下が実行結果です。
>r. JMP C3 33 00110011 01 00000001 CALL CD E3 11100011 02 00000010 OUT D3 37 00110111 04 00000100 IN DB 77 01110111 08 00001000 XTHL E3 3B 00111011 10 00010000 XCHG EB 7B 01111011 20 00100000 DI F3 3F 00111111 40 01000000 EI FB 7F 01111111 80 10000000 B1 to out1-2,ok? RET C9 63 01100011 02 00000010 break in 270 |
ここで必要なのは与えた命令コードに対して、DECODE3から出力されるデータの対応する出力ビットのみが1になることが確認できさえすればそれでよいということです。
上の結果の表示のうち途中のコードはデバッグが必要になったときのためのもので最後の8ビットの並びがビット0から7に向かって順に1になっていれば回路は正しく機能していることになります。
結果を見ると実際そのようになっていることが確認できます。
そこで最後のところ(RET)は何をやっているのか、ということですが。
実はDECODE3からの出力は8ビットではなくて9ビットあります。
その最後の9ビット目はRETコード(C9)に対する出力です。
その信号をDECODE3の出力用10pinコネクタの1pinに配置しました。
[第209回]の回路図と[第210回]の接続図を参照してください。
トランジスタCPU回路の一般的な10pinコネクタでは1pinには+5Vを配置しています。
それに対してこのところテストで用いている26pin→10pinケーブルではCポートについては1pinを+5VにしていますがAホート、Bポートの1、2pinは空きになっています。
ですからDECODE3の出力用10pinコネクタの1pinにRETセレクト信号を配置してもそこにCポートをつながない限りは問題はありません。
しかしそのままではそこにBポートの10pinコネクタを接続しても1pinは空いていますからRETセレクト信号を読み込んで確認することはできません。
そこで下のように接続することを考えました。
図の上側は通常の接続です。
それを下側のように1pinが逆位置になるように接続します。
もちろんこのように接続すると他の信号出力の並びは変わってしまいますが、RET回路のためのセレクト信号(Y1−2)はPB1から読み込まれることになります。
さきほどのプログラムの実行結果の表示ではビット1のみが1になりました。
そのことでRETのためのセレクト信号回路も正しく機能していることが確認できます。
トランジスタでCPUをつくろう![第211回]
2020.4.6upload
前へ
次へ
ホームページトップへ戻る