標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第360回]

●続いてお二人の方が完成されました

お一人は、ブログを何回か紹介させていただいているYT様です。
FIAT500と洗車の日々・・・(http://plaza.rakuten.co.jp/flyback/)

本日訪問させていただきましたら、[13]TK80回路も出来上がっていました。
完成です。
YT様おめでとうございます。
お疲れ様でした。

あとはシリアル通信関係のパーツ待ちです。

はい。あと、ほんとにもうちょいのところですので、もう少しだけお待ちください。

もうお一人は[第355回]で説明書のミスをご指摘いただいたNN様です。
「完成しました。テストプログラムも問題なく動いています」というメールをいただきました。
そうですか。
動いているのですね。
いやあ。うれしいですねぇ。
NN様。おめでとうございます。
お疲れ様でした。

残りのパーツももう少しでお送りすることができますので、今しばらくお待ちください。

☆☆☆昔話の続きです☆☆☆

雑誌広告ははじめは「I/O」だけだったのですが、しばらくして「マイコン」にも掲載するようになりました。
そのうちだんだんと自信がついてきて、とうとう、この道に入るきっかけになった、あの「トランジスタ技術」にも広告を出すようになりました(私と「トランジスタ技術」との出会いについては[第1回]をお読みください)。
「トランジスタ技術」にも広告を掲載するようになってから、半年も過ぎたころでしたでしょうか。そこのところは、はっきりとは覚えていないのですが…。

●出版社から執筆依頼が…

「トランジスタ技術」の編集者が、わざわざ名古屋まで、私をたずねてきました。
「トランジスタ技術」に連載記事を書いてみないか、という話でした。

うち(中日電工)の広告にある、パーソナルコンピュータの組立キット、それを雑誌の読者向けに新規に設計して、その解説記事を連載すると同時に、希望者に組立キットとして記事で紹介したものと同じものを供給する、という企画でした。

出版社としては、原稿料以上のものは出せないので、キットの供給は中日電工の責任でやってほしい。つまり、それについての出版社としての保証はありません。

その保証は無いけれど、しかし、中日電工としてもこれはいい宣伝になるかもしれないと思いましたし、なんたってあこがれの「トランジスタ技術」に連載記事が書ける、というのですから、それは、一人前の技術者として認知された、という意味でも、これはもう、書くしかない。いえ。つつしんで、書かせていただきます。ハイ。そりゃあもう、喜んで。

しかし、落ち着いて考えてみると、これは大変なことです。
それこそもう寝るひまもないくらいメチャメチャ忙しかったときでしたから、毎号締め切りのある記事を書くこと自体できるかどうか、それもちゃんと技術的な裏付けをとって書かなければいけません。
それこそ大手メーカーの技術者も皆が読んでいるというほどの一流技術誌ですから、いいかげんなことを書くわけにはいきません。そこへもってきて、さらに毎号(実際には毎号は無理なので2〜3号ごとにでしたが)新しい機能基板を作って、それを読者に組立キットで供給するなんて、そんな恐ろしいことができますでしょうか。

当方の戦力といたしましては、主力はもちろんこの私ひとり。
あとはまだ入園前の子供二人を抱えて今三人目がおなかの中にいるわが妻と、そして非常事態ともなれば召集されてくる、おじいさん、おばあさん、の総勢4人。
そりゃあ、できるわけがない。あまりに無謀。

いや。私が無謀なのはわかる。
本人はいたってノーマルだと思っているけれど、周りはそうは認めてくれない。
みんなよってたかって非常識だと責めるのが常ですから、ひょっとすると、そうかも知れません。

ですけれど、そんな私に執筆を依頼しにきた編集者は大丈夫か?
マンションの一室で、子供を抱えておなかの大きい妻と二人で日夜奮戦している超零細企業の現状を十分認識した上で。
「アンタはそれで大丈夫?」
こっちが心配になって、つい聞いてしまいました。

見ての通りのこういう状態なのだから、途中で、続けられなくなって、バンザイしてしまったら、アンタ、どうします?

「そうなれば、当然私は責任をとらなきゃならないでしょうね。ですから、穴をあけないようにがんばってください」
この編集者さんは、それからしばらくして、なんと編集長になってしまわれました。

●そしてついに連載開始です


第1回は保存がいいかげんだったものですから、もうぼろぼろでお見せすることができません。これは連載第2回のトップページです。ちょっとみにくいですが左下に Feb. 1984とあります。1984年2月号です。

それはもう、想像をはるかに上回る状況でした。
読者からの資料請求に応えるだけでも一仕事でした。
申し訳ないけれど、問い合わせにいちいち返事をつける余裕などとてもありません。
ひたすら急ごしらえのカタログ資料を封筒に入れて投函するのが精一杯でした。
なかには応対が悪いというので、編集部に苦情のハガキまで来る始末。
そんなこといったって、どーしようもなかったんですよぉ。かんべんしてくださいよー。大変だったんですから。

そのうち注文もけっこう入ってくるようになって、もう毎日それこそ朝から晩まで戦場の忙しさでした。
それでも、なんとか穴をあけることなく、無事連載を終えることができました。

連載第17回、最終回です。

連載17回ですから、約1年半続いたことになります。
1984年1月号からはじまって1985年5月号までです。
記事ではカラーグラフィックディスプレイの製作や、5インチフロッピーディスク装置のインターフェースまでも製作し、CP/Mのシステムを走らせるパーソナルコンピュータを作り上げるところまでを紹介しました。
連載をはじめたときにはまだおなかにいた3人目の子供の満一歳の誕生日が、連載を終わったときには、もうとうに過ぎていました。

こんな昔の連載記事など、ずっと忘れて本棚の隅でほこりをかぶっていたのですけれど、こうやってコピーを取ったときに、最終回の最後のページに目がいきました。
おやまあ、こんなことを書いていました。

一流の専門誌に、なんとまあ、すごいことを書いちゃっていますねぇ。
こうやって読んでみると、私はこのころから、そういう考えをもっていたようです。

なんたってデジタル回路なんだから、余裕はたっぷり十分すぎるくらいあるのだから、誤動作などするわけがない。
誤動作なんかしたら、そりゃあ、あなた。よっぽど設計にアナがあるのですよ。

まあなんと、恐れ多くも、天下の技術者諸氏に向かって、そのように堂々と宣言してしまっているのですよねぇ。
厚顔無恥といいますか、恐れを知らないといいますか、ほんとうに、困ったものです。
あんまり大見得を切ると引っ込みがつかなくなって恥をかくのが落ちですから、大きいことは言わない方がよろしいのですけれど。

でも、本当のところ、このころから、私はアナログはともかくとして、デジタル回路の設計というものはそういうものなのだ、という考えで、やってきたように思います。
(次回に続きます)

☆☆☆TK80回の操作説明の続きです☆☆☆

●MYCPU80(TK80回路)操作説明書 3章  プログラムデバッグの仕方

●1. はじめに

デバッグ(Debug) は虫取りと訳したりします。
自分で作ったプログラムは、考え方の間違いや色々不注意によるミスのため、中々一度では期待通りに動いてはくれないものです。
このようなミスをバグ(Bug, 虫) といいます。
毛の奥深くに、もぐりこんでいる虫を一匹ずつ、文字通り「シラミツブシ」にみつけ出す作業は、根気のいる仕事です。
特にマシン語のプログラムは、なにか手助けになるようなソフトがなければ、まずお手上げです。
このTK80回路のもっているステップ動作機能とブレイク動作機能は、そんなとき強力な助けになります。

●2. ステップ動作

2章の終りのところで、CPUは非常に速いスピードでプログラムを実行するので確認できない、と書きました。
このステップ動作の機能を使うと、プログラムを1ステップずつ進めることができるので、その途中の状態を確認することができます。
2章で作ったプログラムを実行させてみます。念の為リスト2-1 の通りにメモリに入っていることを確認しておいて下さい。
(2章の終わりのところで8001番地を12に直した人は、00に戻して下さい)
以下に操作方法を説明します。(図3-1 参照)


@まずリセットします。(必ずリセットして下さい)
A普通のプログラム実行のときと同じように、アドレスをセットします。
このあと(@のあとでもよい)RUNを押す前にディップスイッチDS3−1(TK80STEP)をON(下側)にします。

BRUNキーを押すと、CPUはあっという間に、8000番地の命令を実行して、次のステップのアドレス(8002番地)を表示して止まります。
C次からはRETキーを押します。するとさらに次のアドレス(8003)が表示されます。
Dもう一度RETを押すとアドレスは8002に戻ります。
EこのあとはRETを押す度に8002と8003が交互に表示されます。
またこのときデータ表示部の上2桁はアドレスが8003になる度に、00、01、02と+1ずつ増えて行きます。
じつはこのときデータ表示部の上2桁にはAレジスタの内容が表示されているのです。(下2桁にはフラグ(F)レジスタの内容が表示される)

〔注意1〕ステップ動作は、モニタROM内のプログラムにも働きますが、ステップ動作そのものがモニタROM内のプログラムや機能を使っているために、期待した通りには動作してくれません。
〔注意2〕ステップ動作は割り込み(RST7)を利用しています。したがってもしユーザープログラムの中で、割り込み禁止命令(DI)を使うと、それ以後は割り込みが禁止されるため、ステップ動作ができなくなります。

●3. ブレイク動作

上で説明したステップ動作は、作ったプログラムの動きをチェックするのにとても便利な機能ですが、さらに、あるところまでは普通に実行しておいて、指定したアドレスからはステップ動作になると便利な場合があります。これをブレイク動作と言います。
このTK80回路のモニタはブレイクするアドレスを記憶するブレイクアドレスレジスタと、ブレイクするまでの繰り返し回数を記憶するブレイクカウンタをもっていますから、指定したアドレスでいきなりブレイクするのではなく、そのアドレスを指定回数繰り返し通過したのちにブレイクするという、きめ細かい処理が可能です。
今回もステップ動作と同じく、2章で作ったプログラムをブレイクさせてみます。
8002番地を50回実行したあとステップ動作に移る( ブレイクする)ようにセットします。
図3-2 を参照しながら、以下の説明を読んで下さい。

@まずリセットします。(ブレイクの時は必ずしもリセットから始めなくてもよいのですが、この方が確実です)
ABブレイクアドレスをセットします。
[F][F][F][0][ADRSSET]の順にキーを押してください。
 アドレス表示部にFFF0と表示され、データ表示部は0000になります。
CFFF0にはプレイクアドレスの下位2桁が入るのですがリセツト後は0000になっています。
 ここにブレイクしたいアドレスの下位2桁を入れます。今回は8002をセットしますから、その下位2桁の02を書き込みます。
 [0][2]の順にキーを押してください。
D[WRINC]キーを押します。
 FFF0に02が書き込まれ、アドレス表示部にはFFF1が表示されます。
EFFF1にはプレイクアドレスの上位2桁が入るのですがリセツト後は0000になっています。
 ここにブレイクしたいアドレスの上位2桁を入れます。今回は8002をセットしますから、その上位2桁の80を書き込みます。
 [8][0]の順にキーを押してください。
F[WRINC]キーを押します。
 FFF1に80が書き込まれ、アドレス表示部にはFFF2が表示されます。
GFFF2にはプレイクするまでの繰り返し回数を入れます。
FFF2はダウンカウンタの役目をしていて、ブレイクアドレスを実行するたびにダウンカウントされます。
リセット後は0000になっています。
今回は繰り返し回数を50回にします。10進の50は16進では32になります。
そこで32と入力します。
[3][2]の順にキーを押してください。
H[WRINC]キーを押します。
FFF2に32が書き込まれます。
これでブレイクカウンタのセットができました。
[注記]ブレイクカウンタは16進2桁です。01〜FFつまり1回から255回の繰り返し回数をセットすることができます。

Iプログラムの開始アドレスをセットして下さい。8000です。
JディップスイッチDS3−1(TK80STEP)がON(下側)になっているか確認して下さい。(OFFのままですと、ブレイクできません)
RUNキーを押すと瞬間にプログラムが50回実行されて、ブレイクします。50回実行した証拠に、データ表示部の上2桁にはAレジスタの値、32(十進の50)が表示されています。
これ以後はステップ操作と同じです。RETキーを押すと1ステップずつ進みます。
なおブレイクカウンタはブレイク時点で0になります。ブレイクアドレスはRESETキーを押さない限りクリアされないでそのまま残ります。


〔注意3〕ブレイクカウンタが0になっている時は、ブレイク動作ではなくてステップ動作になります。
〔注意4〕ブレイクアドレスは各命令の1バイト目でなければいけません。今回の例では8000、8002、8003は指定できるが、8001、8004、8005を指定してはいけません。
〔注意5〕ブレイクアドレスを設定した場合、ブレイクするまでの間のプログラム実行時間は、通常処理の場合の数十倍かかります。これはブレイクアドレス以外のプログラム部分でも1ステップ実行する毎に、ブレイク処理プログラムが実行されているためです。
〔注意6〕ブレイク動作もステップ動作の機能を利用しています。そのためステップ動作についての注意事項(注意1、注意2)はブレイク動作の場合でも同じように当てはまります。

●4. レジスタの確認

 以上ステップ動作とブレイク動作の基本的な操作について説明してきましたが、じつは両動作をさらに効果的にする機能が備わっています。
いままで説明したブレイク動作、ステップ動作では、ブレイクしたときの、またはステップごとのプログラムカウンタの値とAレジスタおよびフラグの状態を確認することができました。
じつはAレジスタだけではなくてそのほかのレジスタ、B、C、D、E、H、Lの各レジスタの値とスタックポインタの値についても確認することができるようになっているのです。
確認するだけではなくて、Aレジスタを含め、各レジスタの値を強制的に変更してから、ブレイクしたあるいはステップ動作中のプログラムの続きを実行させることもできます。
プログラムの続きからではなくても、レジスタに値を設定してからプログラムをスタートさせることもできます。
具体的な操作方法について説明する前に、まずMYCPU80(8080)のレジスタについて簡単に説明しておきます。

●4.1 MYCPU80(8080)のレジスタ

MYCPU80(8080)は内部に下記のレジスタを持っていて、これらのレジスタはプログラムの中で色々な処理に利用されます(図3−3)。



[A]
 一般にアキュムレータ(加算器)と呼ばれているように、演算命令はこのレジスタを中心に行われる。
[F]
 フラグレジスタ。命令の実行により現れる色々な状態を1ビットずつに記録して保持する。各ビットの意味は4.2で説明する。
[B][C]
 共に8ビットのレジスタとして、独立して使うことが多いが、つないで16ビットのレジスタ[BC]として使うこともできる。その場合には[B]が上位8ビット、[C]が下位8ビットになる。
[D][E]
 B、Cと同じ。
[H][L]
 B、Cと同じだが、16ビットレジスタ[HL]はメモリ[M]を間接的に示す間接アドレッシングでのメモリアドレスを入れて使うことが多い。また[HL]は16ビットの加算命令(DAD)で加算器(アキュムレータ)としても使われる。
[SP]
 スタックポインタ。現在のスタックのトップ・アドレスを示している。スタックについては、5.3で説明する。
[PC]
 プログラムカウンタ。現在実行中のアドレスを管理している。( 正しくは、次に実行する予定のアドレスを示している)

●4.2 MYCPU80(8080)のフラグ

 フラグは8ビットのフラグレジスタに、図3−4のように割りつけられています。


 
各記号の意味は下の通りです。(ビット1、3、5は使用されない)
なお、フラグがセットされたときは、そのビットが1になり、リセットされたときは0になります。


 キャリ・フラグ。計算の結果、上位桁へのキャリー、ボローが発生したときにセットされる。ローテイト命令でもセット、リセットされる。

 パリティフラグ。論理、算術演算およびINR、DCR命令を実行した結果、1のビットが偶数個あるときにセットされ、奇数個のときはリセットされる。

 ハーフ・キャリ・フラグ。算術演算でビット3からビット4へのキャリーや、ビット4からビット3へのボローがあったときセットされる。このフラグはCフラグとともに、BCD演算後のDAA命令で利用される。

 ゼロ・フラグ。結果がゼロのときセットされる。

 サイン・フラグ。結果が負のときセット、正またはゼロのときリセットされる。

[参考]2進数の正数と負数
8ビットの数00〜FFは符号なしでは10進の0〜255として扱われるが、符号付の数として扱ったときには、−128〜+127の数になり、これは16進では80〜7Fになる。(ビット7が0のときはその数は正で、ビット7が1のときは負になる)

●符号付8ビットの数の大小


●4.3 スタック

大きなプログラムになると、レジスタもたくさん必要で、とても4.1で説明した数では足りません。そこでレジスタの値をひとまずメモリのワークエリアにしまっておいて、そのレジスタを次の用途に使う、ということが簡単にできると便利になります。
ところがレジスタの値をしまうときに、一々異なるメモリアドレスに割りつけていくのでは大変です。
そんなときにこのスタックを使えば、一々メモリアドレスを指定しなくても簡単な操作でレジスタの値を保存することができます。
スタックとは積み重ねるという意味です。
ちょうど本などを積み重ねるように、メモリの中にレジスタの値を順番にしまうことができます。(PUSH命令を使います)
取り出すときは、入れたときと逆の順番で取り出します。(POP命令を使います)
そしてそのスタックの現在の位置を管理しているのがSP(スタックポインタ)です。
(例) SP=8300、BC=1234、DE=5678のとき、
    PUSH B
    PUSH D
 を実行すると、メモリ内容は下のようになります。



こうなってしまった後で、POP Dを実行してもDにはもとの値は戻りません(1234が入る) 。
 PUSH、POPは常に順番を覚えておいて、間違わないように使う必要があります。

〔注意7〕スタックの操作はPUSH、POPだけではなくCALL、RET命令や割り込み処理でも使用されます(アドレスがスタックに入れられる) 。
〔注意8〕スタックはメモリ上のどこにでも設定することができます(LXI SP命令を使う) 。
しかし指定場所によってはプログラムやデータの入っている領域と重なってしまい、その結果プログラムやデータが壊されてしまうことがあるので、充分注意が必要です。
 マシン語プログラムでは、普通はその先頭部分でスタックポインタのセットが必要ですが、TK80回路はモニタプログラムによってリセット後はSP=FFC7にセットされるのでユーザーがあらためてスタックポインタをセットする必要はありません。

●4.4 ブレイク、ステップ操作でのレジスタの値の設定、確認方法

[ブレイク、ステップ動作時に各レジスタが格納されるメモリアドレス]

ブレイクしたとき、またはステップ動作時には、各レジスタは下記メモリアドレスに格納されます。
[RET]または[RUN]を押すと、下のメモリアドレスの値がそれぞれレジスタに入れられたあとでユーザープログラムにジャンプします。
[RET]キーを押したときにはFFE0、FFE1の値がPCに入りますが、[RUN]を押したときには、LEDのアドレス表示部に表示されている値がPCに入り、SPにはFFC7が入れられます。



上のメモリアドレスはブレイク後やステップ動作のとき以外でも、その中身を確認したり、書き換えたりすることができます。

ここでは参考までに、HLに1234を、BにEFを書き込んでみます。
Hレジスタに12を、Lレジスタに34を書き込みますが、WRINCは書き込み後にアドレスがインクリメント(+1)されることを考慮して、さきにLレジスタ(アドレスFFE4)から書くのが効率的です。

@ALレジスタのセーブアドレスをセットします。
[F][F][E][4][ADRSSET]の順にキーを押してください。
 アドレス表示部にFFE4と表示されます。ブレイク後やステップ動作のときはプログラムの実行によりそのときのLレジスタの値がデータ表示部の下位2桁に表示されます(リセットしてもFFE4の値はクリアされずに残ります)。
Bこのデータを書きかえることによって、Lレジスタに任意の値を与えてからユーザープログラムに戻るようにすることができます。
今回は操作例として34をLレジスタに与えることにします。
[3][4]の順にキーを押してください。
C[WRINC]キーを押します。
 FFE4に34が書き込まれ、アドレス表示部にはFFE5が表示されます。
DFFE5はHレジスタのセーブアドレスです。ブレイク後やステップ動作のときはプログラムの実行によりそのときのHレジスタの値がデータ表示部の下位2桁に表示されます(リセットしてもFFE5の値はクリアされずに残ります)。
 Hレジスタの値を12にしてみます。
 [1][2]の順にキーを押してください。
E[WRINC]キーを押します。
 FFE5に12が書き込まれ、アドレス表示部にはFFE6が表示されます。
FGHアドレスがFFE9になるまで[RDINC]キーを押します。
またはここで[F][F][E][9][ADRSSET]と操作することもできます。
IFFE9はBレジスタのセーブアドレスです。ブレイク後やステップ動作のときはプログラムの実行によりそのときのHレジスタの値がデータ表示部の下位2桁に表示されます(リセットしてもFFE9の値はクリアされずに残ります)。
 Bレジスタの値をEFにしてみます。
 [E][F]の順にキーを押してください。
J[WRINC]キーを押します。
 FFE9にEFが書き込まれます。
書き込んだ値を確認するには[RDDEC]キーを押して戻るか、[ADRSSET]キーを使って確認したいアドレスを指定します。必要ならば[RDINC]キーを使うこともできます。
上記例のような作業がブレイク後またはトレース後に行われたときは、このあとでRETキーを押すことによって、上の作業で最終的に書き換えられたデータを各レジスタにセットしたあと、ユーザープログラムに復帰します。
またブレイク動作やトレース動作以外の普通の処理でも、上記例のような操作で必要な値をセットしたあと、RUNすることにより、CPUレジスタに特定の初期値を持たせてユーザープログラムを開始させることができます。
実行途中のCPUレジスタの値を参照できるばかりではなく、必要ならば途中で各レジスタの値を変更することもできるため、非常にきめ細かなデバッグ作業が行えます。


[注意9]プログラムカウンタ(PC)やスタックポインタ(SP)の値を不用意に変更すると、以後のユーザープログラムがまともに実行されなくなることがあります。
[注意10]上の操作例では、FFE4〜FFEAのアドレスが指定されたときに、そのメモリの値がすべて00で表示されていますが、実際には、ここにはこのとき以前にブレイク操作かステップ操作を行ったときに入れられた各レジスタの値が表示されます。レジスタセーブエリア(FFE0〜FFEB)はリセットしてもクリアされません。

●5. プログラムの終わり方

いままでのところで説明に使ったサンプルプログラムは、終わりのないプログラム(これを無限ループといいます)でした。
しかし普通は、何かの処理をしたあとは、そこでストップするというプログラムが多いはずです。
マシン語のプログラムは必ず終わりをしめくくっておかなければいけません。(やりっぱなしにすると、暴走してしまいます)
終わり方には、次のような方法があります。プログラムを書く場合の参考にして下さい。

@HLT命令(コードは76)
最後にHLT(76)を書いておくと、そこで停止したままになります。このときZ80Aの18番ピン(HALT)はLレベルになります)
この状態から、通常のキー操作に戻るためにはリセットをする必要があります。
ARST 0命令(コードはC7)
最後にRST 0(C7)を書いておくと、モニタの0000番地に戻ります。つまりリセットが最後にかかったのと同じ状態になります。LED表示はオール0になり、システムワークエリアはクリアされます。
BRST 1命令(コードはCF)
 最後にRST 1(CF)を書いておくと、モニタの0008番地に戻ります。
0008番地にはモニタのリスタートアドレス(0051)へのジャンプ命令が書いてあります。モニタが0051からリスタートするとLEDの表示はクリアされませんが、スタックポインタなどは初期セットされます。
CRST 7命令(コードはFF)
最後にRST 7(FF)を書いておくと、その次のアドレスをLEDのアドレス表示部に表示してブレイクします。このときレジスタの内容はレジスタセーブエリアに保存されますから、処理終了時点のレジスタの値を確認することができます。
 なお、プログラムミスなどでCPUが暴走した結果、ROMの何も書かれていないアドレスやRAMのたまたまFFが書かれているアドレスにジャンプしてしまった場合にも、このRST 7が実行されます。
正規に終了してブレイクしたのか、暴走の結果なのかは、表示されたアドレスによって判断できます。
2009.10.12upload
2009.10.13一部修正

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