ワンボードマイコンをつくろう!(パソコンの原点はここから始まった)
TK80ソフトコンパチブル!8080、Z80マシン語からBASICまでこれ1台でこなせます
当記事は2009年11月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 2011.6.28
前へ
次へ
目次へ戻る
ホームページトップへ戻る
☆特注品Z80ボードND80ZHの機能説明
TK80コンパチブルで、その上中日電工オリジナルのND80Zとしても動作するというZ80CPUのワンボードマイコンを企画し、その開発準備をしていたところに、ND80Zの特注品の開発依頼をいただきました。製品名はND80ZHです。
新企画のZ80ボード(ND80ZV)はこのあとで製作することになりますが、基本的な機能はND80ZHと共通していますから、まずはND80ZHの機能を説明します。

[第19回]

●実行速度について

前回の終わりのところで、Z80版TK80(ND80ZH)とTK80との互換性について、「まだ問題が残っていた」と書きました。
それは何かといいますと、CPUクロックの違いなのです。

TK80は18.432MHzのクリスタルを9分周して得られる2.048MHzをCPUクロックにしていました。
それに対してND80ZHの方は8MHzのクリスタルを2分周して得られる4MHzをCPUクロックにしています。
[2011.6.28注記]ND80ZVのCPUクロックは6MHzです。

ND80ZHでTK80用に書かれたプログラムを実行させると、倍速で実行してしまうのです。
速ければいい、とは言いきれません。
プログラムによってはちょっと困る場合がでてきます。
たとえばMYCPU80のサンプルプログラムにもある、スピーカーから音を出すようなプログラムでは、音の高さが変わってしまいます。

ここまで書いてきて思い出しました。
当社がスタートするきっかけになった、TK80互換ボードND80のCPUクロックは2MHzだったのですが、その後にCPUを8080からZ80AにしたND80ZではCPUクロックを倍の4MHzにUPしました。
しかしボード上に設けたスイッチによって、CPUクロックの2MHzと4MHzを切り換えることができるようにしてありました。

むむむ。
ちゃんと互換性を確保していたのですねえ。
そんなことはすっかり忘れてしまっていました。

あ。MYCPU80はたまたまCPUクロックを2MHzにしましたので、この問題には遭遇することなく済んでしまいました。
ええ。MYCPU80の場合は、ほんとに、たまたま、でした。
当初は4MHzでスタートしたのですが、74HC03や74HC05の出力回路の遅れが原因で、クロックを半分の2MHzに落としたのですが、それはそういう理由からだったので、TK80との互換性を考慮したから、というわけではなかったのです。

まあ、しかし。
せっかく4MHzで実行できるZ80Aを、わざわざその半分の2MHzに落として使うというのも、なんだかなあ、という気がいたしますから、実行速度が関係するようなプログラムについては、CPUクロックに合わせてプログラムを書き換えていただく、ということで納得していただくことにいたしましょう。

それに。
Z80は8080の命令コードを全て実行できますが、実は命令によっては、実行クロック数が異なっているものもあるのです。
細かいことになりますが、そうすると、たとえCPUクロックをTK80と同じにしたとしても、CPUが8080からZ80になったことで、同じプログラムでも、実行速度が微妙に異なってくるということも有り得るのです。

そんな細かい点には全く気がついていなかったのですが、以下に説明する作業をする過程で、偶然ですが、そのことに気がつきました。

●チャタリングタイマー

さきほどの説明で、スピーカーから音を出すプログラムでは音の高さが変わってきてしまう、ということを書きましたが、そんなこと以前に、もっと根本的なところで、CPUクロックの違いが影響する部分があったのです。
TK80モニタプログラムにはカセットテープレコーダを使ってプログラムをSAVE、LOADする機能がありますが、その録音波形を生成するためのタイマールーチンがあって、その一部が、キーのチャタリング回避のタイマーとしても利用されていました。

TK80モニタプログラムのその部分のリストです。

              ;
              ;CHATTERING TIMER
              ;
                ORG $02DD
02DD 1624     D1:MVI D,24;WAIT 1/2 BIT TIME 4.5112MSEC
02DF 1E0C       MVI E,0C
02E1 1D         DCR E
02E2 C2E102     JNZ $-1
02E5 15         DCR D    
02E6 C2DF02     JNZ $-7
02E9 C9         RET
02EA 1648     D2:MVI D,48;WAIT 1 BIT TIME 9.0176MSEC
02EC C3DF02     JMP D1+2
02EF 16D8     D3:MVI D,D8;WAIT 3 BIT TIME 27.0176MSEC
02F1 C3DF02     JMP D1+2
[出典]NEC日本電気鰍sK80ユーザーズ・マニアル

アドレス02EAの9.0176MSECタイマールーチンがチャタリングタイマーです。
ここが倍速で実行されてしまうと、ちょっと都合が悪いことになります。
まあ、チャタリングタイマーとして9msecの時間が絶対に必要か、というとそうは言いきれないのですが、ここが余り短くなってしまうと、キーのチャタリングが回避できなくなってしまうかもしれません。

で、上のリストのコメントを参考にして、D2のルーチンが約9msecになるように、プログラムを変更しました。
ひょっとして、TK80用のアプリケーションプログラムで、この部分が(D2だけではなくて、D1やD3のタイマーも)使われているかもしれないということを考慮して、コアの部分の
02DF 1E0C  MVI E,0C 
のところを計算して変更することにしました。

そのようにしてタイマールーチンの部分を変更した、ND80ZHのモニタプログラムです。

              ;
              ;CHATTERING TIMER
              ;
                ORG $02DD
02DD 1624     D1:MVI D,24;=36 ck=7 127.75*36+(7+10)*0.25=4603.25microsec
02DF 1E23     D1_2:MVI E,23;=35 ck=7  7+14*35+14=511 0.25*511=127.75microsec
02E1 1D       D1_3:DCR E;       ck=4
02E2 C2E102     JNZ D1_3; ck=10
02E5 15         DCR D;    ck=4    
02E6 C2DF02     JNZ D1_2; ck=10
02E9 C9         RET;      ck=10
02EA 1648     D2:MVI D,48;=72  127.75*72+(7+10+10)*0.25=9204.75microsec
02EC C3DF02     JMP D1_2
02EF 16D8     D3:MVI D,D8;=216 127.75*216+27*0.25=27600.75microsec
02F1 C3DF02     JMP D1_2

CPUクロックを4MHzとして計算した結果、02DFのMVI命令でEに与える値を23(十進数の35)に決めました。
D1〜D3の実行時間はTK80の値より少し大きくなりますが、チャタリングタイマーという目的から考えて、ここは大き目の方が安全サイドであると考えました。
E=22(十進数の34)の方がオリジナルにより近い値になるのですが、そうすると、オリジナルよりも実行時間が短くなってしまいます。

●テストプログラムで確認してみました

変更したタイマールーチンが、計算通りの値なのかどうか、簡単なテストプログラムを書いて確認してみました。

そのプログラムリストは、[第16回]で紹介しました、逆アセンブルリスト出力機能を利用してプリンタに出力して作成しました。
プログラムは簡単なものなので、キーから16進コードを直接入力して作成しました。
アドレス8000〜8014の短いプログラムです。

そのプログラムの逆アセンブルリストを出力するには、7セグメントLEDのアドレス表示部にプログラムの先頭アドレスの8000を表示させて、データ表示部に終了アドレスの8014を表示させたあとで、[*I/O]に続いてデータキーの[B]([DA])を押します。

キーから[8][0][0][0][ADRSSET][8][0][1][4]と入力したところです。


このあと[*I/O]に続いてデータキーの[B]([DA])を押すと、下のリストがプリンタに出力されました。



02EAのサブルーチン(9.2msecタイマールーチン)をCALLするごとに82C55のAポートからFFと00を交互に出力するだけの簡単なプログラムです。

Aポートからの出力波形をオシロで観測してみました。



確かに9.2msecです。
プログラムに間違いがないことが確認できました。

ところで、今回変更したモニタプログラムのタイマールーチンとオリジナルのTK80モニタプログラムの変更前のタイマールーチンとを比較していて。

あれえ?

ちょいとおかしなことに気がついてしまいました。

変更を行ったのはただ1ヶ所、アドレス02DFのMVI E,0Cを、MVI E,23にしただけだったのですけれど…?

そのどこが、あれえ?なのか。
さて、みなさま。おわかりになりますでしょうか?

本日は、時間がなくなってしまいましたので、そのことにつきましてはまた次回に説明することにいたします。
CPUをつくろう!第451回(2010.3.8upload)を再編集

ワンボードマイコンをつくろう![第19回]
2011.6.28upload

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