2024年9月21日土曜日

Meta Fight

Xで見かけたので、パソピア7版のメタファイターを紹介。

月刊ログイン1983年11月号に掲載

Phase 1 ATTACKゾーン
4と6キーで左右に移動し、スペースバーで弾を発射
全ての敵を倒すと、次のレベルにワープ
レベル4はチャレンジステージで、敵は弾を撃ってこない。
全ての敵を倒すまでの時間で、ボーナスが決まる

Phase 2 INVATION(?)ゾーン
XキーとCキーで、発射の向きを45度ずつ変えられる

Phase 3 CAPTUREゾーン
敵は上下にいて、弾も上下から飛んでくる

Phase 4 CHAOSゾーン
8と2キーで上下にも移動できるが、敵の弾も上下左右から飛んでくる

自分が行けたのはここまで。
つたない腕ですが、動画でどうぞ

CHAOSゾーンはクリアできる気がしない。

2024年7月28日日曜日

88mk2/80SR用ゲームコントローラー

せっかくなので、ゲームコントローラーの対応も考えてみる。

PicoのUSB Hostサンプルを参考にしてBuffaloやElecomのUSB Joypadを試してみたが、パッドによってリターンデータの格納場所がバラバラで、汎用的なロジックが難しい。。

どれか1つだけ、と考えるとPicoのサンプルにあったDS4が良いのかな、と思う
こちらもPC-8001mk2SRに接続すると本体側のModifierキーが無効になるので、困った時に備えてL1(GRAPH)/L2(カナ)/R1(SHIFT)/R2(CTRL)にしておく。

USBハブでキーボードとDS4をつなげて動作確認。
同時接続しても、どちらからでも入力できることを確認。
ただ80SRの5V、電力的に大丈夫かは不明。
DUALSHOCK4は充電もするから、外部給電できるUSBハブとかの方が安全かも。

88mk2キーボードへのマッピングは以下の通り。
CAPSとカナキーは、SHIFTと同時押しでロックするようにした。
CAPSロック中はキーボード右上のCapsLock LEDが点灯、カナはScrollLock LEDが点灯。

88mk2実機が無かったので手間取ったが、なんとか動く(だろう)ものができたと思う。


余談。DS4の横にチラッと映っているやつのUSBキーボードアダプタも考えたことがあったが、キーボードから音が鳴るとか曲者なので見送っている...

2024年7月25日木曜日

PC-8801mk2用USBキーボードアダプタ

88mk2のUSBキーボードアダプタの問い合わせが来たので、少し調べてみた。

PC-8801mk2シリーズ(PC-8801mk2/SR/TR/FR/MR)のキーボードコネクタはDIN 13pinで、雄コネクタを覗き込んだ場合、左上が1pinで右下が12pin、真ん中下が13pinの並び。

13pinが5Vで外周がGND、88mk2本体から9~12pinでスキャンラインを指定し、押されたキーを1~8pinを読み取る様子。キーマトリックスは素直でシンプル。
88mk2シリーズの場合、スキャンラインは0~11まで。
キーが押されるとビットはLow(0)になり、何も押されていない場合は全ビットがHigh(1)になりFFhが返答される。

入力と出力のピンが独立してるので、余計な回路も必要なくPicoで行けそう。

ほぼDIN13コネクタとPicoを接続するのみだが、テスト基板を作成

うちには88mk2が無いので、PC-8001mk2SRで試してみる。
80SRの背面には汎用入力インターフェイスがあって、DIN 13pinのコネクタがある

基本動作はパソピア700用USBキーボードアダプタと同じ。8個のPIOで8個のリターンピンで独立して処理することで、PC本体の読み取りタイミングに間に合うように押されたキーを応答する。
少し違うのは、パソピア700はキーのスキャンタイミングがわかるピンがあるので、その1つのピンを監視していればよかったのだが、88の場合はタイミングの信号線がないので、9~12pinのどれかがLow(0)になるまでボーリングするようにした。
実際にUSBキーボードとシリアルを接続して動作確認。
結果は以下の波形。
下の4つが88mk2本体から送られてくるスキャンライン9~12pinだが、LowになってからHighになるまでの間隔が590nsくらい。
今回はポーリング処理が入っているためタイミングによるばらつきがあるが、それでもスキャン信号が届いてから200nsちょっとで返答できている。

USBキーボードでキーを押すと、ちゃんとキー入力されている。

1つ気になる点は、PC-8001mk2SR本体側のModifierキーが無効になる。
今回作成したアダプタを本体に接続すると、CTRL/SHIFT/GRAPH/カナキーがUSBキーボード側のみ有効になり、本体側のModifierキーが無効になってしまう。
仕様かもしれないが、本物の88キーボードを持っていないので確認できず。。

あと、今回88mk2版を試すにあたりPicoのUSBライブラリを最新にしたが、安定性がかなり上がった印象。USBキーボードの抜き差しをしてもハングしにくくなったし、今まで動かなかったHub付きキーボードも動くようになった。

88mk2シリーズでも動きそうだが、本体で検証できていないので...

2024年6月17日月曜日

UOOTOY Pasopia7移植

PiO 1986年5月号 119~131ページに掲載されているMZ用のUOOTOYをパソピア7に移植。
PC-6001mkIIにも移植されている方がいて、参考にさせてもらいました。助かりました。

PiO 1986年5月号は国立国会図書館に所蔵されており、遠隔複写サービスもできるようです
札幌近郊の方は、北海道立図書館の館内でコピーすることもできます(持ち出し不可)

PiO 1986年6月号 42ページにバグ情報があり、以下のように修正するようです。
・4B97hから: 00 40 E5 E7 03 40 E7 E7 07
・5C89hから: 00 10 00 10

あと、マッチが袋小路に行った際にハングする問題も対応しました。

どれだけニーズがあるかわかりませんが、ここにパソピア7用パッチのソースとRAM PACイメージを置きます。

PiO 1986年6月号に掲載されているMZ版のダンプ2000h~5FFFhを、Pasopia7で打ち込み保存します。パソピア7は0000h~7FFFhまでBASIC ROM領域のため、別の領域に一旦打ち込みます。
例えばA000hから打ち込んだ場合、以下のように保存。
BSAVE"UTDATA",&HA000,&H4000

続いて6000h~8CFFhを打ち込んで保存します。A000hから打ち込んだ場合は以下の通り。
BSAVE"UTMAIN",&HA000,&H2D00

雑誌ダンプリストの入力は、bugfireさんがダンプリスト入力用のツール(DumpListEditor)を公開してくれているので、便利でお勧めです。
バイナリを直接RAM PACイメージに上書きする場合は、以下の領域です。
・2000h~5FFFhは、RAM PACイメージの0504h~4503h
・6000h~8CFFhは、RAM PACイメージの4604h~7303h

BASICは以下の通り
10 CLEAR,&HB8FF
20 PRINT"LOADING..."
30 BLOAD"UTDATA",&H2000
40 BLOAD"UTMAIN",&HB900
50 BLOAD"PATCH7",&HE600
60 SCREEN 2:WIDTH 80:CLS:A=&HE600:CALL A
RUN"UOOTOY"で起動
(STOP)キーでBASICに戻った場合、アトリビュート領域が壊れている可能性があるので、CLSで画面クリアして下さい。再起動する場合は、"RUN 60"でOKです。

武田氏のエミュレータでも動作します。
エミュレータの場合、DCSGの高音部が出力されない音があったので、それらの効果音は音程をすこし変更しています。

パソピア7実機での動画をどうぞ。

2024年6月14日金曜日

キーボードとジョイスティック

以前、パソピアのキーの信号に関する書き込みで紹介したキーマトリックス

どのキーが押されたか判断する場合、
スキャンする行(nKS 0~B)から、スキャンデータ(KSL)とキーブロック(KB)を決めて
KSL 0KSL 1KSL 2KSL 3
KB_AnKS 0nKS 1nKS 2nKS 3
KB_BnKS 4nKS 5nKS 6nKS 7
KB_CnKS 8nKS 9nKS AnKS B

KBインターフェイススキャンデータ(Port 30h)で出力

続いてKBインターフェイスリターンデータ(Port 31h)を読み込む
キーが押された場合、その列のbitが0になる。押されていない場合は1。
全て押されてない場合は、FFhが返ってくる


ジョイスティックの押されたキーを取得する場合は、ジョイスティックアダプタ入力ポート ( ポートA 19h, ポートB 1Ah)の値を読み込む
ボタンが押された場合、その列のbitが0になる。押されていない場合は1
全て押されてない場合は、FFhが返ってくる

スピタル産業のジョイスティックには、SELECTとRUNボタンが付いており、
・SELECTボタン:↑+↓
・RUNボタン:←+→
が割り当てられている

-----
UOOTOYのキー操作について
基本はMZ-2000と同じキーを使うが、いくつかキーを追加しジョイスティックをサポート。
BASICに戻るキーも追加。

パスワード入力画面
MZ-2000Pasopia7 KeyboardPasopia7 Joystick動作
A~ZA~Zパスワード入力
SPACESPACE, INS/DEL一文字戻る
CRRETURNSELECT, Aボタン, Bボタンパスワード確定
カナカナ, HOME/CLS, PF8ROOM選択画面に進む

ROOM選択画面
MZ-2000Pasopia7 KeyboardPasopia7 Joystick動作
←, 4(テンキー)←(十字キー)ROOM数デクリメント
→, 6(テンキー)→(十字キー)ROOM数インクリメント
CRRETURNSELECT, Aボタン, Bボタンゲームスタート
F2~7同時押しPF2~7同時押し隠しメッセージ
(STOP)RUNボタンBASICに戻る

ゲーム中画面
MZ-2000Pasopia7 KeyboardPasopia7 Joystick動作
4(テンキー)←, 4(テンキー)←(十字キー)左に移動
6(テンキー)→, 6(テンキー)→(十字キー)右に移動
5, 8(テンキー)↓/↑キー, 5, 8(テンキー)↑(十字キー)ジャンプ
1(!)1(!), ZBボタンブロックを積む
2(")2("), XAボタンブロックを消す
Break(STOP)RUNボタン一時停止/解除
NNSELECTボタン次の面に進む
(クリア済みの面まで)

MZ版は、PiO 1986年6月号 42ページにあるパッチを当てると、ブロックを積む(カナ→1キー)、消す(1→2キー)に変更される。MZ-2500もそうだがパソピア7もカナキーが右側にあるので、1キーと2キーの方が操作しやすい。ただ上の列は間違って別のキーを押しそうなので、ZキーとXキーも割り当てておく。

パスワード入力のA~Zのキー入力はBIOSからの取得も考えたが、カナモードの制御ができず、アルファベットを入力しているつもりがカナが返ってくる可能性もあったので、I/Oポートで直接キーを読み込むロジックを作った。

あと、ゲーム中にキー入力のポチポチ音が気になったので、キーの割り込み処理を無効化
; キーボードリターン用の割り込みベクタを何もしないアドレスに変更
LD HL, (0FEF8h)
LD (0FEFAh), HL
元のアドレスは事前に保存しておき、BASICに戻る際に戻す。

2024年6月7日金曜日

メモリマップ

Pasopia7のメモリについて

ポート3Chでメモリモードの切り替え
・bit0=0, bit1=0:0000h-7FFFhがBASIC ROM
・bit0=1:4000h-7FFFhがBIOS
・bit1=1:0000h-7FFFhがRAM
・bit2=1:8000h-BFFFhがV-RAM
・bit3=1:(I/O Memory Mode) RAM(64KB)をI/O空間としてアクセス。次のI/Oアクセスのみ有効で、I/Oアクセス後に解除される。BIOSからのRAMアクセスで利用される

メモリ構成の優先順位
BASICを使わない場合、ROMの裏にあるRAM領域(いわゆる裏RAM)を利用できる。

メモリーのステータスは、ポート22hで読み込むことができる
マシン語処理が呼ばれた後にbit0とbit1の値を保持しておき、元の処理に戻る際は保存しておいたメモリモードに戻しておく。

V-RAMのプレーンは、ポート0Chで切り替える
bit7-4:各bit=1のとき、対応プレーンのV-RAMへのCPUアクセスが可能
bit3-0:各bit=1のとき、対応プレーンのV-RAMデータバスとCPUデータバス間のデータ交換が可能
以下の値をセットしてV-RAMプレーンを切り替える。
・11h:ブルー
・22h:レッド
・44h:テキスト/グリーン
複数プレーンの同時設定も可能
・77h:ブルー, レッド, テキスト/グリーン全てのプレーンにデータを書き込む
→画面の消去などで利用できる

-----
UOOTOYのメモリマップについて

MZ-2000版は2000h-8CFFhにロードした後、表示用データとメインプログラムを別の領域にコピーしている。
2色文字データは、Pasopia7のV-RAM領域(8000h-BFFFh)と重なるため、コピー先を変更
・MZ-2000版:7C90h-810Fh
・Pasopia7版:0B80h-0FFFh
コピー前コピー後内容
-0900h-09FFhビット反転テーブル
-0A00h-0AFFhV-RAMプレーン変換テーブル
-1000h-1FFFhV-RAM変換テーブル
2000h-28BFh2000h-28BFhプログラム、文字列データ、仮想画面など
2C00h-3FFFh2C00h-3FFFh面データ
4000h-4094h556Ch-5600h表示用データ:7色の棒データ
405Ch-408Bh55C8h-55F7hV-RAMコピーのロジック(Pasopia7では使用しない)
4100h-47BFh6000h-66BFh表示用データ:題字データ
4800h-4EBFh6A00h-70BFh表示用データ:32x16ドットキャラクデータ
4EC0h-57FFh70C0h-79FFh表示用データ:16x8ドットキャラクデータ
5800h-5A8Fh7A00h-7C8Fh表示用データ:1色文字データ
5A90h-5F0Fh0B80h-0FFFh表示用データ:2色文字データ
6000h-8CFFhB900h-E5FFhメインプログラム
-E600h-EB86hPasopia7用追加ロジック
-EB87h-ED94hPasopia7用Patch書き込み処理

ビット反転テーブル、V-RAMプレーン変換テーブル、V-RAM変換テーブルは、Pasopia7用追加ロジックの中で作成する

Pasopia7はF0FBh以降がスタック領域のため、この領域は使えない。
MZ版でF2xxhとF3xxhがデータ保存領域として使われていたがEExxhとEFxxhに移動する。
Pasopia7用Patch書き込み処理の中で、これらのコンバート処理も行う。

50面分の面データの後ろに使っていないエリアがある。
将来的に100面分のデータを対応することも考えていたのかもしれない。

2024年6月5日水曜日

V-RAM変換

MZ-2000からPasopia7のV-RAMアドレス変換について考えてみる

MZ-2000のV-RAMグラフィックは、アドレスC000h-FFFFhに割り当てられていて
80char(1char=8bitで640ドット)ごとに1行ずつ配置されている。
右のアドレスは+1で、1行下は+80(50h)という普通(?)の配列。

Pasopia7のV-RAMアドレスは以前も紹介したが、かなり独特。
アドレス8000h-BFFFhに割り当てられていて、キャラクタ(8バイト)単位で配置。
右のアドレスは+8、1行下は+1だがキャラクタの最終行だった場合は+633(0279h)加算される

MZ-2000のV-RAMアドレスからPasopia7のアドレスへの変換を考えてみる。
V-RAMバンク領域は16Kバイトでアドレスは2バイトなので、32Kバイトの変換テーブルを作るのが速度的には理想だが、今回は厳しいので4Kバイトの変換テーブルで考える。

変換テーブルは16char単位で作成する。1行80char÷16=5charぶんのアドレスを格納。
1画面200行なので、1000char分の変換テーブルになる。

1char分のデータは、Pasopia7のV-RAMアドレス2バイト+Y行数(0-199)1バイト+X列数(0-79)1バイトの合計4バイト

MZ-2000のV-RAMアドレスを16で割って、変換テーブルのインデックスにする。
変換テーブルから取得したアドレスに、16で割った余り×8を加算するとPasopia7のV-RAMアドレスになる。

それでも割り算などの処理が入るので、1回の変換に250clock程かかってしまう。
もっといい方法もあるかもしれないが、一旦はこれで変換ロジックは完成。
最初のV-RAMアドレスだけテーブル変換し、その後は差分の加算で対処する。

V-RAMアドレスの左右アドレスを取得する場合は、単純に±8バイト。
上下アドレスは少し面倒で、変換テーブルからY行数を取得し、bit2-0=000(0)なら上のアドレスは-633、bit2-0=111(7h or Fh)なら下のアドレスは+633、それ以外は±1で上下アドレスは取得できる。
変換テーブルにX列のデータも格納しておいたが、今回は使っていない。

あと1charデータのビット並びが逆になっているのも注意。
MZ-2000の場合はbit0が左に表示される。例えば■□□□ ■■□■の並びでデータを表示する場合、V-RAMへセットするデータはB1h(1011 0001)。
Pasopia7の場合はbit0が右。V-RAMへセットするデータは8Dh(1000 1101)。

ビット反転は、ここのサイトを参考にさせてもらいました。助かりました。
少しでも速度を確保したいので、起動時にキャラクタのデータが格納されている領域を一括してビット反転。
が、ここに悲劇がありました。
データの隙間に、ロジックを埋め込んではいけない。。