CPM80の高速化を企む? 2020.11.20

CPM80とCPM68Kの両方で遊んでいると、ソフトの多さではなんといってもCPM80に軍配が上がりますが、
しかし速度的な面でいえば、やはりCPM68Kが上です。この差は使用しているCPUがZ80(8Bit/20MHz)、MC68HC000(16Bit/33MHz)の
バス幅とクロック周波数の違いではありますが、一番大きいのはCPUのアーキテクチャーの違いが大きいだろうと思います。
というのもZ80をCPM80で動かすとなると、i8080の命令しか使えませんが、そうなるとメモリーのアドレッシングの種類が極めて貧弱です。
そのためC言語で書いたプログラムをコンパイルしたアセンブラを見てみると、もう無駄だらけに思えてきます。それに対して、
CPM68KのMC68000はアドレッシングモードが豊富なためC言語との親和性もよいようで、アセンブラの生成効率も高いようです。
すなわち、実行命令数がかなり減っています。実際に、C言語で書いたプログラムをアセンブラでかきなおすと、CPM80(Z80)の場合は
数10倍も速くなりますが、CPM68K(MC68000)では2倍も速くならなかった経験があります。
 そういったこともあり、最近はPCM68Kで遊ぶことが多いのですが、でも、ソフトの豊富なCPM80も捨てがたい。
そのためCPM80ももう少し速くなれば、もっと使ってみようという気がおきるのにな〜と思って、CPM80の高速化を企んでみることにしました。

高速化のポイントは2つ

1.CPUのクロックアップはどうするか
 現在使っているZ80は20MHz品ですが、もっとオーバクロックができるはずです(希望的観測)。というのも、16MHzのMC68HC000も
50MHzで動きました。なんと3倍の高速化が可能でした。それを考えると、Z80もひょっとして40MHzくらいで動くかもしれません。
オーバクロックについては、以前に試したことがあるのですが25MHzで動作しなかった記憶があります。というのも、いままでに作成した
CPM80につかったメモリーは55nsのアクセスタイムのものだったので、メモリーが問題だった可能性があります。もっと速いメモリーを
使えば、もっと速くなるかもしれません。そこで、こんどはメモリーに12nsのものを使って試してみようと思います。


今度はこれ(12ns)をつかえばCPM80も速く動くかな?

 本来はCPUも高速品を使うべきです。探すとZ8S180というものがあって、これは33MHzでも動作するようです。ただしパッケージがPLCCしかないので
ちょっと扱いにくい。それに、すこしお高いです(1200円ほどする)。これについては、機会があれば注文するとしてまずは手持ちのDIPパッケージの
Z80の20MHz品で試してみましょう。Z8S180を入手したら、変換ソケットを作って載せ換えて試してみればいいでしょう。

機会があれば、これも使ってみましょう!33MHzでも動作するようです。でもPLCCは扱いにくい。

2.ディスクの高速化を考える
 CPM80はSDカードをディスクに見立てて動かしていますが、SDカードのアクセス速度はあまり速くありません。もちろんSDカードの理論的転送速度は
極めて早いのですが、フリーで使えるデータ転送プロトコルは3線のSPI制御だけなので知れています。さらにSPIをソフトウエア制御としているのでなおさらです。
そのために、SDカード上でコンパイルなんかしようものなら、余裕でコーヒなんかが飲めたりします。CPM68Kのときだと、カップラーメンができるような速度です。
で、実用的にはメモリーディスクが必要になります。これによりディスクアクセスは格段に速くなります。
 しかし、メモリーディスクのアクセス速度もまだまだ改善の余地がありそうです。

a)現状:リニア空間に配置してPICを介してデータ転送
 いままでCPM80にメモリーディスクを搭載したときは、下図のように2MB程度のメモリーを構成して、一部にZ80用の64kBを割り当て、残りをメモリーデイスク
として使っていました。そして、メモリーはPICのI/Oにぶら下げます。これが、一番ハード的には簡単な方法です。でも、PICをつかってメモリー内でデータを移動
とした場合には、同時に2アドレスをアクセスできませんから、一旦ソース側のアドレスのデータをPICに読み込んで、次にターゲットとなるアドレスに
書き込むという作業が必要になります。このため、1データを転送するにはアドレスの設定やデータの読み込み、書き込みなどを含めると
数10サイクルから100サイクル程度の命令数が必要になります。
 たとえば50サイクルだとすると32MHzのPICで動かすと1命令サイクルは8MHz(125ns)になりますから、データ転送速度は125ns*50=6.3us/Byteです。
すなわち160kByte/s程度(ピーク値)の速度です。まあ、これでも十分かもしれませんが、もっと速くできるはずです。
色々と考えてみましょう。


現状の構成です。1つのRAMエリアをつかっているので、
メモリー間でのデータ転送は一旦PICを介する必要があり、時間がかかります。


b)案1:メインメモリとメモリーディスクのアドレス空間を分ける
 高速化案として、データを一旦PICを介さないようにすれば速くできます。すなわち、メインメモリーとメモリーディスクのアドレス空間を物理的に分けて、
片方を読み出し、片方を書き出しとして同時に動かしてやればいいわけです。こうすれば、大体20命令サイクル程度で1バイトのデータの転送が可能なはずです。
こうなれば現状の倍程度の速度アップになります。ちなみに、20命令サイクルかかる理由は、メインメモリーとメモリーディスクのアドレスの設定です。
1データを転送するごとに、アドレスを+1加算して、それをアドレス用のデータラッチに書き込む作業が必要になるためです。
 この作業をハードウエアのロジック回路で行えばもっと速くなるはずです。ということで、さらに案2を考えます。


案1ではメモリードライブとシステムメモリーのメモリー空間を独立にします。そうすればデータはPICを介する必要ありません。
ただし、アドレスラッチの設定の時間はのこります。



c)案2:メインメモリとメモリーディスクのアドレス空間を分ける+アドレスカウンターを追加する
 アドレスの+1加算をハード的にやればもっと高速になるはずです。ということで、下図のような構成を考えます。
 このようにすれば、システムメモリーとメモリーディスクのカウンターを設定さえしておけば、あとはカウンターのクロックを叩くだけです。
クロックを叩く(L→H)だけなら2命令サイクルで済みます。32MHz品のPICだと250ns/Byte、64MHz品のPICだと125ns/Byteで転送ができます。
すなわち、それぞれ4MB/s、8MB/sのデータ転送速度になります。これならば、現状のものから50〜100倍程度のデータ転送速度が得られます。
いわゆるハードロジックでのDMAコントローラみたいなものです。
ただし、50〜100倍というのはあくまでもピーク性能なので、付帯処理を含めると、差は小さくなりますが案外期待できるかもしれません。


案2としてアドレスラッチではなくアドレスカウンターにします。そうすれば、PICからクロックを叩くだけでデータ転送ができます。
おそらくこれがもっとも高速な方法です。


 ちなみに、メモリーディスクに使うRAMは安価な4Mbitで55ns品の選択になるので、アクセス時間の実力値を考えるとPICを80MHzのオーバクロックで
動かしてもいけそうです。80MHzだと、書き込み信号のパルス幅は50nsになるので、なんとか間に合います。そうすればデータ転送速度は
10MB/sまで向上しそうです。

さっそく回路図を描いてみる!

 アドレスカウンターとしては、メインメモリー用は64kB空間のどこにアクセスするかわからないので16Bit必要ですが、
データの転送は128Byte単位なのでメモリーディスク用は上位は固定として、下位の7ビット分だけのカウンタをつかいます。
なお、カウンターには値のプリセットができることが必要なのと、高速動作ができるようにと同期型のものを並べることにします。
メモリーディスク用ではプリセットは不要なので、非同期カウンターの74393あたりが使えたら1個でICが済みますが、
非同期ならではの時間遅れが気になったので、2個の同期カウンターをつかうことにしましょう。

 
回路図はこんな感じです(PDFはこちら)。自分用なのでお世辞にも見やすいとは思えませんが・・・・

大きめの基板に組み立てましょう
 結構部品点数も多いので、大きめのユニバーサル基板で組み立てることにしました。
まずは部品の配置を考えます。
 メモリーディスクはすこし大きく4MBiteは確保するつもりなので、4Mbit品のSRAMを計8個つかいます。
すべてを平面に配置するには基板サイズがすこし足りないので、2階建てにすることにしました。
すこし見栄えを考えて、SMDタイプのメモリー素子を変換基板に載せた上で、2階建てにします。
そして、全体の高さを抑えるために、メモリーディスクはICソケットを使わずに、基板直付けです。
でも、これが大失敗の原因でした。


まずはICの配置を検討です。すこし大きめのユニバーサル基板をつかうことにしました。

夜な夜な作業!
 回路図もひけているので、あとは夜な夜なの配線作業です。ビールを片手に酔っ払いモードでの半田付けは日頃のストレス解消に最適です(笑。
まあ、人によっては反対にストレスが溜まるだけかもしれませんが・・・・
 しかしCPM80って8ビットなので配線が少なくても済むもので意外と簡単です。それに比べてCPM68Kだと配線数がほぼ倍になるので結構大変です。

夜な夜な作業を進めて、ようやく完成です。


φ0.29mmの太目のポリウレタン線なので、すこし線が盛り上がっています。


完成した状態です。まだICは挿していません。


メモリーディスクのRAM(左側)は2階建てで基板に直付けです。システムメモリーはソケットをつかいました。


動かしてみる!あああ・・・・

 いままでにCPM80用のシステムソフトはいくつか書いていたので、今回のチェックのメインはメモリーアクセス回路の動作確認程度です。
正常にメモリーにアセスできているかを確認するための、チェックプログラムを書き込んでテストしますが・・・・なぜかうまく動きません。

不具合の現象はメモリーディスクの1本のデータライン(D6)がHIGHレベルに固定されている・・・・・

この手の不具合は、大体は配線の間違えとか他の線との接触とか相場が決まっています。ということで、配線を入念に調べますが
どこも異常ありません。テスターでチェックするも、電源ラインへの接触はもとより、近接する線との接触もありません。いったい何が
おこっているのだろう??????

原因を特定するために、4個に接続されているメモリーへのデータラインを一つづつ切り離して、どこで異常が発生しているかをチェックです。
そうしたところ、特定のメモリーへの配線を切り離すと不具合が消えました。どうやらメモリー素子の1つが動作不良を起こしているようです。
半田不良や短絡などによる現象とは違うようなので、おそらく素子の不良でしょう。
問題は、不良がおきている素子の位置です。

なんと、不良箇所は2階建てのRAMの1階部分です。

2階部分ならば、素子を破壊してでも交換できますが1階部分だと手がだせません。2階部分をとりはずすのも至難です。
さらに1階部分への配線が2階部分へのつながっていますから、1階部分の配線を切り離したら2階部分も動作しません。
1階と2階部分を接続する線を切り離すにも狭くてニッパーも入りません。
しかたなく、8個あるうちの2個のメモリー素子は使わないことにします。そのためメモリーディスクは当初予定の4MBから3MBに
減ってしまうことになります。

しかし、いままで2階建てだけでなく4階建てもよくやりましたが、これからはちょっと躊躇してしまいそう・・・。
なんせ、RAMの素子が1個でも不良なら全滅です。


動くようになりましたが、メモリ−ディスク用の8個の素子のうち、2個は死んでいます。
白く見えるのは、ピンの番号と機能を書いたシールです。これがあるとデバッグがしやすいです。


具体的成果は?
 さて、ようやく動くようになりましたが本当に速くなるかな?・・・・・


CPU速度は期待はずれ・・・・ 2020.11.21

さて、まず最初はCPUのオーバクロック調査です。手元に20MHz以上の発振器は25MHzと33MHzがあるので、まずはそれらに差し替えて
テストです。結果は

25MH・・・○
33MHz・・・×

です。なんだ、以前のテスト結果とあまりかわらないじゃん。33MHzもクリアーすると思っていましたが・・・・
ちなみにどのように動かないかといえば、33MHzにするとZ80にリセット信号を送っても、何も反応がありません。
メモリーアクセス以前の問題です。

さて、25MHzで動くとのはいいとしてどのくらいの余裕があるかです。ひょっとして26MHzでは動かないかもしれません。
余裕をもたせるためにも、上限から2割落とした程度で動作させたいものです。

ということで、Si514をつかった可変発振器で調査です。25MHzから1MHzづつ周波数を上げて動作テストです。


可変発振器を差し込んで上限周波数のテストです。


結果は
 25MHz・・・・○
 26MHz・・・・○
 27MHz・・・・○
 28MHz・・・・○
 29MHz・・・・○
 30MHz・・・・○
 
31MHz・・・・×

となりました。動作上限は30MHzであることかがわかりました。ということは25MHzは2割余裕には若干届きませんが
まあ、25MHzなら安定した動作ができるでしょう。ということで、動作には25MHzの水晶発振器をつかうことにしましょう。

発振器はこれ(25MHz)をつかうことにしましょう。ちょっとだけオーバクロックです。

しかし、33MHzくらいで動いてくれると思いましたが、CPU速度についてはちょっと期待はずれです。
こりゃ、早々に33MHz動作のZ8S180を入手しないとだめだなあ〜。

ディスク速度はかなり効果あり

次のCPM80高速化の主題はディスク速度なので、こちらのテストにかかりましょう。
テストプログラムは簡単に128バイトの配列を1024回ファイルに書き出すものです。
すなわち約131kBのファイルを作る時間を測定します。プログラムでは任意の回数を
繰り返せるようにしています。あまり、回数が多いと測定時間がかかるのと、反対に短いと
計測誤差が大きくなため回数は調整できるようにしました。


テストプログラムでは約130kBのファイルを作ります。
ループする回数を指定できるようにしています。

結果は従来比2.72倍の高速化

測定結果は次の通りになりました。
ついでに、2つのCPM80でSDカード上での実行速度も調べておきましたが、これに大きな差があるのは
PICに搭載したSDカードのアクセスルーチンが違うためです。

で、肝心のメモリードライブ上での実行速度ですが、今回試作機では実効速度が116kB/sと3号機の42.7kB/sに
比べて約2.72倍速くなった結果になりました。かなり効果があるようです。よかった〜!!
これで、コンパイルやリンクなどもすこしは速くなるでしょう(こちらはZ80CPUの演算が主体なので、ここまでは効果はでないでしょう)。
ただし比較した3号機とのPICのCPU速度が80MHzと32MHzで2.5倍ちがうので、
同クロックで動いたらどの程度の差になるかは、すこし検証する必要があります。

機種 条件 実行時間
(1回あたり130kB)
実効速度 備考
今回の試作機
 Z80(25MHz)
 PIC(80MHz)
SDカード上で実行 10.3秒 12.7kB/s
メモリードライブ上で実行 1.13秒 116kB/sec 3号機に比べて2.72倍早い。
今回の試作機
 Z80(20MHz)
 PIC(80MHz)
メモリードライブ上で実行 1.4秒 93.6kB/sec 同一Z80CPU速度でも
3号機に比べて2.19倍早い。
3号機
 Z80(20MHz)
 PIC(32MHz)
SDカード上で実行 7.0秒 18.7kB/sec SDカードのアクセスルーチンは
高速化したものを使用
メモリードライブ上で実行 3.07秒 42.7kB/sec

しかし、早いといってもデータ転送の実効速度が116kB/sというのはやはり遅いですね。メモリードライブ上での理論的な転送速度(10MB/s:ピーク値)を
考えると1/100程度の速度しかでていません。付帯する処理に時間がかかりすぎて、メモリードライブ上でのデータ転送速度の変化の効果が
現れなかったのでしょう。こりゃ、ちょと確認テストが必要です。

確認テスト
 メモリードライブの転送速度はPICの速度にのみに依存しています。そこで、Z80の動作クロックを変更したときの実効速度を
測定すれば、メモリードライブでの転送処理の割合がみえてくることになります。
そこで、手持ちの水晶発振器の範囲で取り替えてテストしてみました。

結果は次のとおりです。

機種 条件 CPU(Z80)
周波数
実効速度
今回の試作機
 Z80(25MHz)
 PIC(80MHz)
メモリードライブ上で実行 25MHz 116kB/s
20MHz 93.6kB/s
12MHz 57.2kB/s
9.6MHz 46.1kB/s

これをグラフにするとわかりやすいです。ほぼプログラムの実行時間(処理時間)はZ80のCPUの速度に比例しています。
このことから、PICが関与しているメモリーディスクへの書き込み時間はかなり小さいということの確認になります。
グラフのY切片が2.65ですから、CPU(Z80)が25MHzで動作しているときの、ディスク書き込みに費やす割合
は2.65/116=2.28%という値がでてきました。ここからメモリーディスクへの書き込みのデータ転送速度は
ネット値として116/0.0228=5.1MB/sの値がでていることがわかりました。ピーク性能が10MB/sですから、良い感じの値です。

ほとんど実効速度はCPU速度に比例しています。ということはPICが関与して時間は極わずかということですね。

従来機との転送速度の比較

 今回試作機でZ80が20MHzで動作したときの、メモリーディスクへの書き込み時間の割合は2.65/93.6=2.83%になります。
言い換えれば残りの97.2%がZ80が動いている時間です。従来機に比べて同一Z80速度で全体で2.19倍早いわけですから、
従来機の動作時間は今回試作機の219%分にあたります。処理におけるZ80の動作時間自体は同じなので、従来機のメモリードライブ
に費やす時間は219-97.2=121.8%分です。この値から今回試作機でのメモリーディスクへの書き込み時間の高速化率は
121.8/2.83=43になります。すなわちメモリーディスクへの書き込み速度は43倍向上ということになります。
かなりの効果が得られましたね。ほぼ想定どおりです。

 ちなみに、従来機のPICの動作周波数を、もし32から80MHzまで向上させることができれば、メモリーディスクへの書き込み時間は
121.8/80*32 = 48.72%分になります。Z80CPUの動作時間とあわせると48.7+97.2=146%になります。すなわち、全体の速度でいけば
もともと2.19倍の差が1.46倍程度の差にまで縮まるということですね。面倒なハードを組むよりも、高速なPICをつかったほうが、効率は
良さそうということでしょうが・・・・。まあ、とりあえず、今回の目的の高速化は無事達成できました。

チャンチャン!

(おしまい? Z8S180を入手したら再開かな〜)