PIC

KM-Z80 mini + カセットテープインターフェース

2013年6月10日

KM-Z80 mini (PIC32MXを用いた、1チップMZ-80K互換機) で、カセットテープインターフェースが動くようになった。

下は、iPodから、Bug Fireを取り込んでいるところ。
2013-06-10-AUT17601.jpg

PIC32MX150F128Bと、接続されたiPod(古いiPodをKM-Z80専用に使っている)の拡大は、こちら。
2013-06-10-AUT17604.jpg

ロード終了後。
2013-06-10-AUT17605.jpg

このBug Fireは、以前制作したKM-Z80では、画面のちらつきがひどくて楽しめなかったゲームだ。 KM-Z80 miniでは、Z80からVideo RAMに書き込む際の画面のちらつきが起こらないため、綺麗に表示できた。

回路図は、以下の通り。以前のものに、若干修正を加えてある。
2013-06-10-kmz80mini019.png

カセットテープの再生端子と録音端子を、別にした。また、パイロットランプと、英数/カナインジケーターを兼ねたLEDを追加してある。これらのLEDと録音用の端子(図でTo recorderとなっている部分)は必須ではないので、省略することが可能。

この新しいバージョンの完成に5ヶ月かかったのは、電子工作になかなか時間が取れなかった事もあるが、カセットテープインターフェース部分の実装に手間がかかったためである。以下、どういう仕組みになっているか、メモしておきたい。

MZ-80Kにおいて、カセットテープからのデーターの読み込みは、次のような方法で行っているらしい。

2013-06-10-cmt.png

図では、長周期と短周期の2種類の信号が続けて送られてきた場合について書いてある。長周期は、464μ秒のHighシグナルに続けて、494μ秒のLowシグナルが続く。短周期では、240μ秒のHに続いて264μ秒のLである。データーの読み込みは、まず、シグナルの立ち上がりの検出から行う(READ EDGE)。立ち上がり検出から368μ秒後に、もう一度シグナルの検出を行う(READ POINT)。この時のシグナルが、HighかLowかで、長周期か短周期かを判断している。

MZ-80Kでは、この368μ秒という待ち時間をソフトウェアで行っている。従って、KM-Z80 miniでは、MZ-80KでのZ80 CPUの速度、2 MHzを正確に再現できれば、同じようにシグナルを読み取ることが出来る。現在(ver 0.182以降)では、KM-Z80 miniにおけるZ80 CPUのエミュレーションは2 MHzで動いている。しかし、この2 MHzという速度は、平均速度なのであって、常にこの速度でエミュレーション出来ているかというと、そうではない。特に、NTSCビデオシグナルの作成に忙しいときは、局所的にZ-80 CPUのエミュレーションが遅い速度で実行されているようだ。なので、MZ-80Kで行われているのと全く同じ方法でカセットテープからのデーターを読み込むことは、試してみたが、出来なかった。

READ EDGEの後、正確に368μ秒後(あるいは350μ秒後)にREAD POINTが来ればよいから、KM-Z80 miniでは、この部分の時間計測にPIC32MXに内蔵のタイマーを用いることにした。このPICは5個のタイマーを内蔵しているが、すでにすべて使ってしまっている。ただし、Timer3はサウンド用に使われている。この、サウンドであるが、MZ-80Kの性質上、カセットテープからデーターを読み込みながら音楽を奏でるということは不可能だ。したがって、Timer3は、データー読み込みの際は使われていないはず。そこで、Timer3を用いてREAD EDGEからREAD POINT迄の時間を決定することにした。

さて、READ EDGEのところ、MZ-NEW MONITORでは、次のように処理されている。
0601 3EF9     LD    A,F9
0603 3200E0   LD    (E000),A
0606 00       NOP
0607 0A       LD    A,(BC)
0608 E608     AND   08
060A C20F06   JP    NZ,060F // Continue if break-key is not pressed.
060D 37       SCF
060E C9       RET
060F 1A       LD    A,(DE)
0610 E620     AND   20
0612 C20706   JP    NZ,0607 // Repeat if signal is 1
0615 0A       LD    A,(BC)
0616 E608     AND   08
0618 C21D06   JP    NZ,061D // Continue if break-key is not pressed.
061B 37       SCF
061C C9       RET
061D 1A       LD    A,(DE)
061E E620     AND   20
0620 CA1506   JP    Z,0615 // Repeat if signal is 0
0623 C9       RET

また、READ POINTは、次のように処理されている。
0521 CD5506   CALL  0655
0524 1A       LD    A,(DE)
0525 E620     AND   20

05C3 CD5506   CALL  0655
05C6 1A       LD    A,(DE)
05C7 E620     AND   20

0635 CD5506   CALL  0655
0638 1A       LD    A,(DE)
0639 E620     AND   20

067D CD5506   CALL  0655
0680 1A       LD    A,(DE)
0681 E620     AND   20

068D CD5506   CALL  0655
0690 1A       LD    A,(DE)
0691 E620     AND   20

ただし、0655からは325μ秒の持ち時間時間ルーチンである。これらのルーチンに置いて、"LD A,(DE)"に続けて"AND 20"が実行されているところで、データーの読み込みを行っている。しかも、Monitor中、"AND 20"が実行されているのは、これらのルーチンだけである。従って、PC<0x1000で、かつ"AND 20"が実行された場合、カセットテープからのデーター読み込みと解釈して良い。

そこで、Z80エミュレーション中の"AND 20"の実行部分をPICのコードでオーバーライドし、「PC<0x1000で、かつ"AND 20"が実行された場合」に当てはまる場合にA/Dコンバーターからカセットテープからのデーター読み込みを行うようにした。また、A/Dコンバーターの値変換はTimer3によるトリガーで行う事とし、Timer3は350μ秒の周期で動くようにした。ただし、PC=0x0616もしくはPC=0x061Eの場合は、350μ秒を待たずに値を取得するようにしてある。

こういった修正により、READ EDGEの後、正確に350μ秒後にREAD POINTが行えるようになり、KM-Z80 miniでもカセットテープインターフェースからプログラムを読み込むことが出来るようになった。同様に、カセットテープへのデーター保存の方も、Timer3を利用して出力するようにしてあるが、まだ動作確認は取れていない。理論的にはうまくいっているように思われるが、録音するための環境が良くないせいか、セーブしたプログラムをロードできずにいる。ただ、KM-Z80 miniでデーターをセーブするようなことはほとんど無いだろうから(開発はKM-Z80 webで行える)、この部分の動作確認(及びプログラム修正)は後回しにしたい。

6/10現在の最新バージョン、ver 0193は、ここからダウンロード出来ます。
ライセンスは、とりあえず「転載不可」とします。ライセンスについてしっかり記述したver 0.2を、近日中に公開の予定です。私が作成した所は、LGPLとして公開します。
バージョン0.3は、こちら

コメント

いしかわきょーすけ (2013年6月12日 17:34:51)

はじめまして。石川と申します。
かつてMZ-80K/K2で遊んでいた自分にとって
KM-Z80 mini は非常に素晴らしいです!

早速追試をしたくて基板を作成中なのですが、もし宜しければ
PIC32のConfiguration Bitの設定を教えて頂けますでしょうか?
8MHz Xtalで48MHz動作とのことなので、PLLの設定は
divide4 の PLL x24かなあと思っているのですが...

hexファイルのみを書き込むことに慣れていないので
もしhexファイルにConfiguration Bitの設定が
含まれて降りましたら申し訳ありません。

今後の進展ならびにV0.2の公開を楽しみにしています。

Katsumi (2013年6月14日 23:09:50)

こんにちは、石川さん。制作者のKatsumiです。

ソースコードのmain.cを見て頂ければ分かりますが、Configurationの設定は主なところをピックアップすると次のようになっています。

// Primary oscillator setting, XT for 8 MHz (between 3 and 10)
#pragma config POSCMOD = XT
// Primary Osc with PLL
#pragma config FNOSC = PRIPLL
#pragma config FPLLIDIV = DIV_2
#pragma config FPLLMUL = MUL_24
#pragma config FPLLODIV = DIV_2
#pragma config FPBDIV = DIV_1

hexファイルにも、これらの設定が含まれているはずです。ご参考まで。

この週末に、ver0.2を公開できると思います。もうしばらくお待ちください。

いしかわきょーすけ (2013年6月15日 00:37:40)

Katsumiさん、こんにちは。石川です。
Configuration Bitの情報ありがとうございます!
早速試してみようと思います。

基板を作成してみたのですが、動作が確認出来ず
難儀しておりましたので、助かります。
http://www.asahi-net.or.jp/~qx5k-iskw/robot/mz-80k/mz-80k02.jpg

Ver0.2の公開、楽しみにしております!

Katsumi (2013年6月15日 16:47:37)

石川さん、こんにちは。

動作が確認できないとのこと。水晶発振はうまく行っていますでしょうか?

水晶発振が難しいらしく、私も試行錯誤しています。どうやら、NTSCのビデオシグナルを作成すると、水晶発振が不安定になるようです。ver 0.3辺りでは、ここの安定性を増したようなものに出来たらと思っています。

ver 0.2は、基本的にver 0.193と同等です。ライセンスをちゃんと記述しているだけです。回路図も、上記のものと同じです。

いしかわきょーすけ (2013年6月15日 22:50:02)

Katsumiさん、こんにちは。石川です。
情報ありがとうございます。
水晶発振は100Ωで他ポートに接続しているので
なるべく最短になるように心がけて配線しましたが...
発振を確認できるオシロとか無いので、ちょっと確認は難しそうです。
(ボードの動作確認用のLED点滅ファームは動いているのですが)

Ver0.2を楽しみにしています。
もし可能であればビルド可能な形で公開して頂けると大変嬉しく思います。

Katsumi (2013年6月15日 23:31:57)

Ver 0.2を公開しました。
http://www.recfor.net/blog/mycom/index.php?itemid=880

石川さん。ビルドできませんか?kmz80miniフォルダの中にソースコードが在りますので、試してみて下さい。

いしかわきょーすけ (2013年6月16日 06:23:28)

Katsumiさん、こんにちは。石川です。
Ver 0.2公開ありがとうございます!
こんなに早く公開して頂けるとは思ってもみませんでした。

早速MPLAB IDE v8.90でビルドし、先日作った基板に書き込んだところ
画面表示とカーソルブリンクが確認できました!
http://www.asahi-net.or.jp/~qx5k-iskw/robot/mz-80k/mz-80k03.jpg
http://www.asahi-net.or.jp/~qx5k-iskw/robot/mz-80k/mz-80k04.jpg
PS2キーボードは1個しか無いので、後ほど確認します。

Katsumiさんのおかげで懐かしいカーソルブリンクを堪能できました。
色々とありがとうございました!

Katsumi (2013年6月16日 08:03:02)

石川さん。

おお、無事動作のようで、良かったです!私の作ったプログラムが動いているのを見せて頂けるのは、嬉しいです。

キーボードを接続するのが、楽しみですね。

いしかわきょーすけ (2013年6月16日 09:19:05)

Katsumiさん、こんにちは。石川です。
先程PS2キーボードを接続してみました。

私の環境では、2文字より多く入力すると
キーリピートが延々続く状態になってしまいます。
リピート時に音が鳴るので、暴走、という感じでは無いのですが...
(暴走、という言葉がつい出てしまいました。懐かしいです。)

今回カーソルがブリンクしている様子を見ただけで
かなりコーフンすることが出来ました。本当にありがとうございます!
http://www.asahi-net.or.jp/~qx5k-iskw/darkside/

Katsumi (2013年6月16日 12:17:52)

石川さん、こんにちは。

PS/2キーボードとの通信に問題がある場合、キーボードとPICとの間の通信ライン(PB8とPB9)に、1-10 kΩぐらいのプルアップ抵抗をいれてみると、どうなりますでしょうか?一応、PIC内部のweak pull upを使っているのですが、環境によってはこのweak pull upではスピードに問題が出るかも知れません。

石川さんの環境では、水晶発振には問題がないようですね。よかったです。

いしかわきょーすけ (2013年6月17日 08:34:15)

Katsumiさん、こんにちは。石川です。
情報ありがとうございます。

アドバイスに従い PB8/PB9 に 3.3KΩでプルアップしてみました。
が、キーリピート状況は改善されませんでした...

とりあえずキー入力せず放置しておいても
カーソルブリンクは行われておりますので、
水晶発振の問題は私の環境では無さそうです。

他のキーボードをつなげてみたり、ソースを追ってみたり
すこし腰を据えて追っていきたいと思います。

Katsumi (2013年6月17日 19:36:25)

石川さん、こんにちは。

説明不足でどうもすみません。PB8/PB9のプルアップは、+5Vにつないで頂けていますか?もしかしたら、+3.3Vのプルアップだと、誤作動するキーボードがあるかもしれません(PS/2の規格だとTTLレベルの電気特性なので、+3.3 Vでも大丈夫のはずではあるのですが)。

うまく動くと良いですね。

いしかわきょーすけ (2013年6月17日 20:57:13)

Katsumiさん、こんにちは。石川です。
補足説明ありがとうございます。
PS2インタフェースなので5Vでプルアップしました。
ここまででも十分楽しめました。ありがとうございます。
特に元MZユーザとしてはあの市松模様のカーソルが
見られただけでも十分満足しました。
Katsumiさんのお陰です。ありがとうございます!

コメント送信