2020.4.6
前へ
次へ
ホームページトップへ戻る

トランジスタで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

前へ
次へ
ホームページトップへ戻る