KM-Z80C miniの紹介
2014年5月19日
KM-Z80C miniは、Microchip社のPIC32MX350F256Hを用いた、1チップMZ-80C互換機です。KM-Z80 mini (ver 0.3)では、24 KBのRAMを搭載していましたが、KM-Z80C miniでは、48 KBになりました。また、カセットテープインターフェースに加えて、SDカードを用いたプログラムのLOAD/SAVEが行えます。
フロントパネル(写真左)には、左から順にカセットテープインターフェース用のジャック(再生・録画兼用)、パイロットランプ(緑・赤)、PS/2キーボードコネクタ、電源スイッチがあります。リアパネル(写真右)には、サウンド・ビデオ用のコネクタに加えて、SDカードの差し込み口があります。
ふたを開けると、こんな感じです。
TQFPのチップを使っているので、筐体の中はシンプルです。DIPほどの存在感が無く、すかすかした感じですね。
LOAD命令を実行すると、SDカードを装着している場合は、ファイル選択画面になります。
キーボードのカーソルキー(PS/2キーボードでは、ALT/CTRLキー;上・左への移動は、shiftキーを使う)でファイルを選択した後に、spaceキーで選択できます。その他は、MZ-80Cと同様に使えます。
回路図は、以下の通りです。
KM-Z80C miniver 0.5.3.1は、ここからダウンロードできます。
KM-Z80C miniver 0.5.3.7は、ここからダウンロードできます。
ライセンスは、基本的にはLGPLですが、ソースコードの中には異なるライセンスのファイルも含まれていますので、注意して下さい。
フロントパネル(写真左)には、左から順にカセットテープインターフェース用のジャック(再生・録画兼用)、パイロットランプ(緑・赤)、PS/2キーボードコネクタ、電源スイッチがあります。リアパネル(写真右)には、サウンド・ビデオ用のコネクタに加えて、SDカードの差し込み口があります。
ふたを開けると、こんな感じです。
TQFPのチップを使っているので、筐体の中はシンプルです。DIPほどの存在感が無く、すかすかした感じですね。
LOAD命令を実行すると、SDカードを装着している場合は、ファイル選択画面になります。
キーボードのカーソルキー(PS/2キーボードでは、ALT/CTRLキー;上・左への移動は、shiftキーを使う)でファイルを選択した後に、spaceキーで選択できます。その他は、MZ-80Cと同様に使えます。
回路図は、以下の通りです。
KM-Z80C miniver 0.5.3.7は、ここからダウンロードできます。
ライセンスは、基本的にはLGPLですが、ソースコードの中には異なるライセンスのファイルも含まれていますので、注意して下さい。
コメント
Katsumi (2014年10月14日 21:45:17)
BASICプログラムをロードした際に、意図しないアドレスに配置されてしまうバグを解消した、ver 0.5.3.7をアップしました。
nikohon (2019年3月16日 23:57:27)
公開されて5年近く経つのですが、ようやく自分で組み立てて見ました。
いきなり完成させるより、段階を追ってトラブルに対処しながら組みました。
ICSP周辺を組み、ファームの書き込みができることを確認。
画面出力を組み、画面が表示されるのを確認。
PS2ポートとSDカード部を組み立て、キー入力ができることを確認。
私が初めて買ったのは完成品形態のK2Eだったので
80Kの組み立てを体験してる様で楽しかったです。
何もできなくても、画面表示がでる段階でもう完成したような嬉しさでした。
IO誌に掲載されていたCLOCKVADERを動作させたところ
正常に動作しない問題にぶち当たり、原因を探した結果。
Z80のレジスタRの処理に不備を見つけました。
レジスタRはDRAMのリフレッシュカウンタで
エミュレーション上は無意味と思われたのだと思いますが
疑似乱数の生成に利用されるケースがありますので
ゼロや定数が返されると、意図した動作につながらないようです。
KMZ80GameのZ80エミュレーション部も同じようですので
改訂版を出されるようなら修正することをお薦めします。
いきなり完成させるより、段階を追ってトラブルに対処しながら組みました。
ICSP周辺を組み、ファームの書き込みができることを確認。
画面出力を組み、画面が表示されるのを確認。
PS2ポートとSDカード部を組み立て、キー入力ができることを確認。
私が初めて買ったのは完成品形態のK2Eだったので
80Kの組み立てを体験してる様で楽しかったです。
何もできなくても、画面表示がでる段階でもう完成したような嬉しさでした。
IO誌に掲載されていたCLOCKVADERを動作させたところ
正常に動作しない問題にぶち当たり、原因を探した結果。
Z80のレジスタRの処理に不備を見つけました。
レジスタRはDRAMのリフレッシュカウンタで
エミュレーション上は無意味と思われたのだと思いますが
疑似乱数の生成に利用されるケースがありますので
ゼロや定数が返されると、意図した動作につながらないようです。
KMZ80GameのZ80エミュレーション部も同じようですので
改訂版を出されるようなら修正することをお薦めします。
Katsumi (2019年3月18日 10:11:49)
動作報告、どうも有り難うございます。ユーザーが増えるのを知るのは、嬉しい限りです。
Z80エミュレーションの不具合の指摘、どうも有り難うございます。なるほど、そういう使い方が有るのですね、知りませんでした。調査して、アップデートします。
Z80エミュレーションの不具合の指摘、どうも有り難うございます。なるほど、そういう使い方が有るのですね、知りませんでした。調査して、アップデートします。
Katsumi (2019年3月18日 10:17:25)
もし宜しければ、その、レジスタR周りを用いている辺りのマシン語かなにかを教えて頂けませんか?修正する際の動作確認にしたいので。
以下に、修正ポイントをまとめてみました。お気づきの点など有りましたら、コメントください。
https://twitter.com/kats_me/status/1107692757399666688
以下に、修正ポイントをまとめてみました。お気づきの点など有りましたら、コメントください。
https://twitter.com/kats_me/status/1107692757399666688
nikohon (2019年3月18日 20:09:04)
(リンクを削除しました)
clockvader.mztです。正常なら「PUSH S」でSキー入力するとワープ後マップ表示されてゲームスタートですが、問題ありの場合 ワープ後キー入力を受け付けなくなります。
(リンクを削除しました)
逆アセンブルソースです。$50D0からのルーチンが問題の箇所です。
当初、キー入力待ち、Vブランク待ちが原因のフリーズかと8255周辺を調べたのですが意外な伏兵でした。
clockvader.mztです。正常なら「PUSH S」でSキー入力するとワープ後マップ表示されてゲームスタートですが、問題ありの場合 ワープ後キー入力を受け付けなくなります。
(リンクを削除しました)
逆アセンブルソースです。$50D0からのルーチンが問題の箇所です。
当初、キー入力待ち、Vブランク待ちが原因のフリーズかと8255周辺を調べたのですが意外な伏兵でした。
Katsumi (2019年3月19日 10:14:44)
スミマセン、ご指定のリンク先を試してみた所、色々問題があるようなので、リンクを削除させて頂きました。宜しければ、逆アセンブルの該当箇所当りを、ここに貼り付けて頂けませんか?
nikohon (2019年3月19日 12:55:38)
sub_50d0h:
push hl ;50d0 e5 .
push de ;50d1 d5 .
ld a,r ;50d2 ed 5f . _
ld d,000h ;50d4 16 00 . .
ld e,a ;50d6 5f _
ld hl,(l50eah) ;50d7 2a ea 50 * . P
add hl,de ;50da 19 .
ld (l50eah),hl ;50db 22 ea 50 " . P
ld a,l ;50de 7d }
rrc a ;50df cb 0f . .
rrc a ;50e1 cb 0f . .
rrc a ;50e3 cb 0f . .
rrc a ;50e5 cb 0f . .
pop de ;50e7 d1 .
pop hl ;50e8 e1 .
ret ;50e9 c9 .
l50eah:
xor l ;50ea ad .
ex af,af' ;50eb 08 .
核心部分だけですが
レジスタRは7ビットの値しか持たない上に、Accからの値を転送しても直後に変わってしまうので、ソフト的には乱数生成に使うくらいしか用途の無いものですので
単純に
LD R,Aをsrand(Areg);
LD A,Rをrand()%128
とかで済ますのが全体への負荷は少ないかもしれません。
push hl ;50d0 e5 .
push de ;50d1 d5 .
ld a,r ;50d2 ed 5f . _
ld d,000h ;50d4 16 00 . .
ld e,a ;50d6 5f _
ld hl,(l50eah) ;50d7 2a ea 50 * . P
add hl,de ;50da 19 .
ld (l50eah),hl ;50db 22 ea 50 " . P
ld a,l ;50de 7d }
rrc a ;50df cb 0f . .
rrc a ;50e1 cb 0f . .
rrc a ;50e3 cb 0f . .
rrc a ;50e5 cb 0f . .
pop de ;50e7 d1 .
pop hl ;50e8 e1 .
ret ;50e9 c9 .
l50eah:
xor l ;50ea ad .
ex af,af' ;50eb 08 .
核心部分だけですが
レジスタRは7ビットの値しか持たない上に、Accからの値を転送しても直後に変わってしまうので、ソフト的には乱数生成に使うくらいしか用途の無いものですので
単純に
LD R,Aをsrand(Areg);
LD A,Rをrand()%128
とかで済ますのが全体への負荷は少ないかもしれません。
Katsumi (2019年3月19日 17:26:47)
大体つかめました、どうも有り難うございます。アセンブリーを見た限り、RのインクリメントのZ80における詳細な仕様は余り関係なさそうなのですね。とりあえず、私で調べて得た情報を元に、Rをインクリメントしてみます。これで、仮にZ80の厳密な仕様と少し異なっていたとしても、乱数生成の用途としては十分だと思います。
kirk0119 (2023年7月19日 02:44:43)
今更ですが、Rレジスタの動作についてお知らせ致します。
これはM1サイクルのカウンタです。つまり、基本的には1つの機械語命令実行に対し1つ加算されます。
但し、以下の例外がございます。
・接頭語付きの拡張命令(LDIRとかIX,IYレジスタ関連命令)の場合は2加算されます。
・CPUリセット直後の最初の$0000からの命令読み取りに限り、加算は行われず$00のままです。(誤動作を恐れての事と推定)
そんなRレジスタの用途は…
・ハード開発時のトラブルシューティング(バス系・メモリ系)
・割り込み未使用状態での簡易的な時間計測。
・乱数処理関係。
こんな処で如何でしょうか?
遅きに失しましたが、情報提供でした。
これはM1サイクルのカウンタです。つまり、基本的には1つの機械語命令実行に対し1つ加算されます。
但し、以下の例外がございます。
・接頭語付きの拡張命令(LDIRとかIX,IYレジスタ関連命令)の場合は2加算されます。
・CPUリセット直後の最初の$0000からの命令読み取りに限り、加算は行われず$00のままです。(誤動作を恐れての事と推定)
そんなRレジスタの用途は…
・ハード開発時のトラブルシューティング(バス系・メモリ系)
・割り込み未使用状態での簡易的な時間計測。
・乱数処理関係。
こんな処で如何でしょうか?
遅きに失しましたが、情報提供でした。
kirk0119 (2023年7月19日 03:48:40)
舌足らずを補足させて頂きます。
接頭語付きの命令は、以下の様に特徴的なコードとなっております。
CB xx
DD xx
ED xx
FD xx
厄介な事に、一部Rレジスタの加算が1になる命令も混入しています。
シャープのマニュアルには全部書かれているのですが…。
手間の割に美味しくない、さりとて省略すると乱数系が混乱…。
厄介ですね。
因みに、DRAMのリフレッシュをM1サイクル(最初の1バイトと接頭語付き命令の2バイト目読み取り)で行っているので、このような仕様になっております。
接頭語付きの命令は、以下の様に特徴的なコードとなっております。
CB xx
DD xx
ED xx
FD xx
厄介な事に、一部Rレジスタの加算が1になる命令も混入しています。
シャープのマニュアルには全部書かれているのですが…。
手間の割に美味しくない、さりとて省略すると乱数系が混乱…。
厄介ですね。
因みに、DRAMのリフレッシュをM1サイクル(最初の1バイトと接頭語付き命令の2バイト目読み取り)で行っているので、このような仕様になっております。
Katsumi (2023年7月28日 22:03:00)
kirk0119さん、お返事遅くなりました。どうも申し訳ありません。
情報提供をどうも有難うございます。Z80のエミュレーターはいくつか作っているので、それぞれで一度、見直してみます。
情報提供をどうも有難うございます。Z80のエミュレーターはいくつか作っているので、それぞれで一度、見直してみます。