So-net無料ブログ作成
  PC-98x1(補完計画) ブログトップ
前の10件 | -

Neko Project21/W [  PC-98x1(補完計画)]

記事を3つ書いたが、消してしまった。その理由は、私がクリーンインストールをしなかったせいで、デバイスドライバのインストールが不確実になり、複数回試したら成功したり失敗したりしたから。たまたま最初に成功して自信満々に記事を書いたが、後から失敗することもあるとわかり、記事が出せなくなった。きっとWindows95をクリーンインストールすれば問題は起きないに違いない。

現在、とにかくNeko Project21/WでWindows95は動いている。T98NEXT用に作ったNHD(Windows95入り)を流用したのでディスプレイドライバとCD-ROMドライバを手作業で入れた。その代償として、もしも問題が起きた時に、その問題がWindows95またはNeko Project21/Wに起因するものなのか、それとも私がドライバを手作業で入れた際に不備があったのかを、特定できなくなってしまった。

そして問題は、起きてしまった。私は4つのゲームソフトA、C、M、Oをインストールしようとした。Aは問題なくインストールできて、ゲームの初期画面まで確認した。CとOはInstallShieldが起動してファイルの展開を始めたが、やがてInstallShieldのウィンドウが消え、その後何のウィンドウも現れない。スタートメニューにもゲームが登録されず、それ以前の段階で問題が起きている。それ以後シャットダウンまでの間、Windows95の動作がおかしくなる。アイコンの選択やウィンドウを閉じるのが、ものすごく遅い。でもフリーズではなく、気長に待っていればそのうちにアイコンが選択されたりウィンドウが閉じたりする。それにたいしてInstallShieldのウィンドウが消えた後現れるはずのゲーム画面は、1時間待っても現れない。

残るゲームソフトMは、そもそもCD-ROMの中身が認識されずに「0個のオブジェクト」となる。Mのディスクイメージを直接Neko Project21/Wに読み込んでも、MのディスクイメージをまずDaemon Tools Liteでホスト(Windows10)の仮想DVDドライブにマウントし、それをNeko Project21/Wに読み込んでも、結果は同じ。ちなみに、MのディスクイメージをDaemon Tools Liteで仮想DVDドライブにマウントすると、Windows10からはCD-ROMの中身が見える。

考察。ゲームソフトAがインストールできるということは、どのアプリケーションソフトも動かないのではなく、動くソフトもある。では動かなかったCやOは、動いたAと何が違うか。CもOも、インストール用ウィンドウにInstallShieldとはっきり書いてある。そのファイル展開の途中か直後に問題が起きる。Aのソフトハウスはプログラマーが強者(つわもの)で、インストールソフトもゲーム用ドライバーも全部自前で作っていた。InstallShieldを使うことで問題が起きている可能性は高い。ただし前述のように私がWindows95をクリーンインストールしなかったから、他の可能性(私のせいという可能性)まで考慮しなければならなくなった。

ゲームソフトMについても、私がドライバを手作業で入れた際に不備があった可能性も考慮しなければならない。






元気がないので元気を出したい [  PC-98x1(補完計画)]

ジョジョにスイッチングウィンバックというのが出てきた。私にそんなすごい技は使えない。私はちょっと元気が出たと思ったら何かの出来事にまた潰される。それはわかっている。が、だからといって、解決策を何も講じずに酒に溺れるとか、首を吊るとかいうのは正しくない。たとえ潰れても、じたばたするのが生き物としてまともだ。そういえばアバンという勇者も漫画の中で「じたばたしましょう」と言っていた気がする。だからじたばたするけれども、私にとっての困った点は、現実世界の何らかの要素によって私がウィンバックの手段を奪われた状態だということだ。ウィンバックの手段は人それぞれに違う。はるか昔、若者の頃の私は、好きな女の子のために何かをするのが人生のすべてだった。そこに太陽があったから、苦しみは乗り越えられた。さて、この歳で同じことをするかと言えば、それはもうない。まずひとつめの私のウィンバック手段は年齢が私から奪い去った。ふたつめ。同じく若いころ、何をやってもうまく行かなかった私はパソコンに出会い、コンピュータープログラミングに出会った。私は初めて、何かをやって成功するという体験をした。それ以来、プログラミングだけは壁に突き当たっても乗り越えられた。時間はかかるが、いつか必ず壁は越えられた。さて、今の私に同じことが出来るかというと、腰痛でPCの前に長時間座ることを禁じられ、出来なくなった。プログラミングにはたくさんの時間が要るが、デバッグにはさらにたくさんの時間が要る。PCの前に何十時間座るかわからない。私の腰は、もうそれに耐えられない。ふたつめの私のウィンバック手段は健康状態が私から奪い去った。私はさらに続けて、私が今でも出来るウィンバック手段を探し続けた。おそらく腰痛から来ると思われる歩行困難で、旅行やウォーキングをウィンバック手段には出来ない。DAWが機を逸したのは少し前の記事に書いた通り。たまたま、あるものを見つけた。Neko Projectをご自分で改造してWindows95を動かした方がいらっしゃる。私は以前にT98NEXTでWindows95を動かそうとしたが、画面解像度がうまく行かなかった。VirtualBoxだったか、他の何かも試したが、問題があった。何年も前のことだから詳細は忘れてしまった。最終的に私がしたかったのは、自分が持っているMYSTというゲームとOBSIDIANというゲームを動かすことだ。でも、Windows95が何とか動いても、その上でゲームソフトが完動するのは難しかった。とくに音関係が。私は以前に複数回チャレンジして完動しなかったから、今回はもう期待していない。そもそも私自身に元気とやる気がなくなってしまった。それでも、ちょっと試してみようと思う。それで1日でも元気が出れば、良い1日が得られたと言えるだろう。

そういうわけで、Neko Project 21/Wを使わせていただいてWindows95を動かし、無理を承知でMYSTとOBSIDIANを動かしてみる。失敗しちゃったら記事にもならないかもしれない。途中まででも何かの成果が出たら、記事にするかもしれない。人生の中で何かの出来事にまた潰されたら、ブログが沈黙するかもしれない。未来は霧の中。今回は、ここまで。







最後のブラウン管テレビ [  PC-98x1(補完計画)]

最後のブラウン管テレビ
(=パナソニック製品と格闘中(9))

前回の記事の後、私は仕事で使う動画をチェックしようと、新しく買ったテレビに映した。すると、動きが大きい部分だけ被写体がボヤーっと見える気がした。それを見た私の脳裏にまた後悔が蘇った。

その後悔とは、新しく買うテレビやディスプレイが、買うたびに満足度が上がるのでなく、買うたびに満足度が下がるという後悔だ。発端は昔、古い4:3ブラウン管テレビをイヤホンジャックが壊れたというだけで新しい16:9平面ブラウン管テレビに買い替えた時に後悔は始まった。その買い替えたテレビが初期状態では陰影が薄く人の顔が平面的に映るテレビだった。でも私は苦労して裏のつまみを調整し、ギリギリ「暗すぎて黒く潰れることなく、明るすぎて白飛びすることもない、人の髪の毛が一本一本認識できる状態」にすることができた。だからこのテレビは調整の結果、満足できる絵になった。唯一の不満は「物が発光する時に光っているというより白いという映り方をする」ことだが、他は満足し、私は末永くこのブラウン管テレビを使うつもりだった。ところが新しく買ったBDレコーダーにはアナログ出力がなく、せっかく満足していたブラウン管テレビを手放さなければならなくなった。新しく買った液晶テレビは、ダイナミックというプリセット画質だと明るすぎるほどで、陰影は薄く、私に平面ブラウン管テレビの初期状態の映り方を思い出させた。でもきっと、コントラストの調整で私の好みに調整できるだろう。これでうまく行ったと思ったが、最後にテストした画面下のテロップが右から左へ動くシーンで文字がボヤーっとして読みにくい。人間の目はそんなものかなと思いつつ試しにブラウン管テレビに映してみたら、なんだ見えるじゃん。そして、どこも壊れておらずそれどころか映り方に満足しているブラウン管テレビを捨てなければならない自分が辛くなった。

どうやら私の頭は疲れてきたようだ。もはや、複数の画面を比較して冷静に違いを認識しようという精神状態ではなくなった。テレビ画面を見るたびに動く物がボヤーっと見え、それを普通だと脳が誤認する事への嫌悪。このままブラウン管テレビを捨てる事への嫌悪。でも自分の部屋を見回すに、この大きなブラウン管テレビ(ブラウン管というのは液晶と違って奥行きがあるので大きい)を置いておく場所はない。今は、夜布団を敷く時にはそのスペースを確保するために、重いブラウン管テレビを載せたテーブルを押し遣る。そして翌朝布団を上げ、雨戸を開ける時にはそのままではテレビが邪魔で雨戸に近づけないので、またテーブルを引っ張って元の場所へ戻す。これを毎日繰り返している。もう少しわかりやすく書くと、自室の真ん中にブラウン管テレビを載せたテーブルが居座っている。このままでいいわけがない。でもブラウン管と永遠に別れて、動く物が永遠にボヤーっと見えるのは嫌だ。このテレビを捨ててしまったら、もうブラウン管はない・・・

いや、違う。ブラウン管はまだある。PC-9821のモニター。幸いにも私にとって大事なのは今どきの動画ではない。大昔のVHSビデオテープ時代のテレビ番組こそ私は大事で、それはPCのハードディスクに入っている。それがPC-9821で鑑賞できれば、ブラウン管テレビで鑑賞できることになる。

私が現在PCで使っている動画プレーヤーはGOM Playerだ。このプレーヤーについてはネット上で批判も見るが、ひとまず便利だという所までは事実だ。でも私のPC-9821に入っているOSはWindows98。古すぎてGOM Playerがサポートしていないのではないか。私はネット検索した。Windows98 Second Editionからサポートしているという。果たして私のPCに入っているのはSecond Editionだろうか。いや、そもそもそれでは駄目だ。たとえSecond Editionでも、当時のPCのスペックでは滑らかな動画再生はできない。それなら、ディスプレイだけ使えばいい。動画再生は現在使っているWindows10マシンで行い、その画面出力をPC-9821のディスプレイにつなぐ。これなら、PC-9821マシンのスペックに関係なく、Windows10マシンで再生できる動画は表示できる。以前に「PCの画面出力を今どきの液晶テレビにつなぐことはできるか」と調べた時に、Windows10マシンにアナログ出力端子がひとつあるのを確認していた。

私はPC-9821を出してきた。

pc98disp1.jpg
うーん、PCのディスプレイだからテレビと比べるとずいぶん小さい。でも上に書いた通り、今の私は複数の画面を比較して冷静に違いを認識しようという精神状態ではない。捨てたくないブラウン管を捨てなければならない。その理不尽さに、なんとか自分が納得できる理由を探している。

pc98disp2.jpg
私はPC-9821マシンから画面出力のコードを抜いた。このコードを抜いた事は、今までの人生でなかったと思う。これを買って、最初にコードをつないで、今に至っていたはずだ。こんな端子だった。

この端子が、Windows10マシンのアナログ出力端子と同じだと良いが。いや、たとえ端子が同じで接続できても、Window95時代(上にWindows98と書いたが、マシンにプリインストールされていたのはWindows95)のディスプレイが映るだろうか。今どきのディスプレイとは解像度がすごく違うと思うが。

pc98disp3.jpg
端子は接続できた。次は、映るかどうかだ。Windows10のデスクトップ画面を右クリックしてディスプレイ設定を選択。

pc98disp4.jpg
ディスプレイ「1」の隣にディスプレイ「2」があった。認識されている。

pc98disp5.jpg
表示するディスプレイを変更。おお、うまく行きそうだ。

この時点で私が興奮したからなのか、Windows10でGOM Playerを使って動画を再生した画面はデジカメ撮影がピンボケになってしまったのでUPできない。ひとつ上の画像でWindows10の画面設定が表示されているのだから、当然動画も表示されるというのはわかってもらえるはずだ。

実用的かどうかは別として、私は自分が所持する最後のブラウン管を使って動画を視聴できることがわかった。人生というのは100%成功する事がまずないものだ。その中で、これだけの成果を出せたのは、最高の出来といえる。

実は私はここ数カ月、PC-9821実機の処分を悩んでいた。今の家に永遠にいられるのなら、そんな悩みは不要なのだが。PC-98関係ではすでに優秀なエミュレータが複数あるからソフトはWindows10上で起動できる。キャノワードミニのフロッピーからデータを読み出すという使命も無事に終えた。これで、PC-9821で出来ることはすべて終わったのかもしれないと私は思っていた。ところが、ものすごい使命がPC-9821に与えられた。私にとって最後のブラウン管であるこのディスプレイに、必要とあらばいつでも動画を映し出すという使命が。

孤独へ向って突っ走れ (50) [  PC-98x1(補完計画)]

「テニス・テニス2」をT98NEXTでプレイしている方へ

はじめに
私が実験に使ったT98NEXTは "V1.00 build May 25 2010(17:39:40)" というものです。Windows上で普通にPC-9801用ソフトを動かすT98NEXTのバージョンとしては、この記事を書いている時点では最新のはずです。でも将来的にバージョンアップの結果、この記事の内容が当てはまらなくなることはありえます。




前回の記事で私は、「ゲーム内で2けたの半角数字を表示すると10の位の値のかわりに1の位の値が表示されるという問題は、エミュレータを変えなければ解決せず、エミュレータを変えれば解決する」と書きました。それが通常の結論だと思います。今日は、通常でない、あまり良くない方法を見つけたのでそれを報告します。

以下に記す方法を使うと、T98NEXTで「テニス・テニス2」をプレイしても文字化けがありません。ただし、大きな問題があります。一度この方法で「テニス・テニス2」のゲームを書き換えてしまうと、他のエミュレータや実機でそのデータを使った時に文字が変になります。
(もともとゲームソフトのほうに問題がなく、T98NEXTのほうに小さな問題があるのを、ゲームソフトのほうを改変することで修正するので、そういう良くないことになるのです。)

その他にも、そもそも他人が作ったソフトを勝手に改変するというのは、たとえそのソフトがすでに売られていない昔の物でも本当は良くありません。

そのへんをよく考えて、自己責任でご判断ください。




では始めます。
次のものを用意します。

「テニス・テニス2」のディスクイメージ。T98NEXTを使っているのが大前提なので、当然ありますね。おそらくはnfd。

そのディスクイメージからファイルを取り出してWindows上のフォルダにコピーできるソフト(Windows上で動くもの)。フリーソフトで存在します。私はDiskExplorerを使っています。DiskExplorerで直接nfdファイルは読み込めませんが、これは問題ありません。私は次のようにしています。T98NEXTに起動可能なハードディスクイメージをセットし、それを起ち上げ、その後でゲームのディスクを入れて、そこから必要なファイルをハードディスクへコピーし、T98NEXTを終了し、DiskExplorerを起動してハードディスクイメージを読み込んでファイルをWindows上へコピーします。

バイナリエディタ(Windows上で動くもの)。フリーソフトで存在します。私はたまたまBZというソフトを見つけて愛用していますが、バイナリエディタはきっとたくさん存在すると思います。大事なのはビューアではなくエディタだということです。見るだけでなく書き込みが必要です。

当たり前すぎて書くのを忘れていましたが、T98NEXTの起動に使っているWindowsマシン。当たり前ですね。

用意するものは、以上です。用意したものを使いこなす知識は必要ですが、プログラミングやデータ解析の知識は必要ありません。

作業を開始します。

ゲームのディスクイメージからT.EXEをWindows上のフォルダ内にコピーします。

後で元に戻せるように、書き換えるファイルとは別にT.EXEのバックアップを作成しておきます。

バイナリエディタにT.EXEを読み込み、ファイル先頭からオフセット196D0Hの場所を表示します。
tt78.png

ここでデータを確認します。196D0Hの場所(上の画像では左端の赤アンダーライン)が"17"になっていますか?そして1バイト前の場所(上の画像では右端の赤アンダーライン)が"74"になっていますか?もしもそうでなければ、この先へは絶対に進んではいけません。

バイナリエディタでオフセット196D0Hの値(上の画像では左端の赤アンダーライン)を"6F"に変更します。ここは慎重に、絶対に間違えないように。

バイナリエディタでT.EXEを上書き保存します。

この、Windows上にある改変したT.EXEをディスクイメージ内のT.EXEに上書きします。方法はわかりますね。先ほどディスクイメージ内のT.EXEをWindows上にコピーしたのと逆の手順です。

そのディスクイメージをT98NEXTにセットし、ゲームを開始してみてください。今までT98NEXTで "00月00日" と表示されていた所が "10月10日" になっています。バンザーイ!
tt79.png

でもこのディスクイメージはデータが改変されたので、T98NEXT以外(他のエミュや実機)では使えません。




++++ ++++ ++++ ++++ ++++
以下は、上に書いた記事が出来るまでの解析の記録です。どうして「T98NEXTのほうに小さな問題がある」なんてことが書けるのか、証拠があるのか、という時にだけ必要なものです。「テニス・テニス2」のゲームプレーヤーの方はお読みにならなくて良いです。
++++ ++++ ++++ ++++ ++++





追っかけ8-2
どうしてT98NEXTではキャラクタジェネレータからユーザー定義文字のフォントを読み出す命令を実行すると文字化けするのか。どのような文字化けかを思い返すに、2桁の半角文字を表すフォントが、10の位も1の位の値になった。これは、フォントの左半分も右半分のデータになったということだ。それにつけて思い出すことがある。PC-9801のキャラクタジェネレータでは、CGウィンドウを使ってフォントを読み出す時、2バイト文字のうち第1バイトが76H以上の文字のフォントはCGウィンドウの奇数アドレスからしか読み出せない。つまり全角文字の右半分と左半分を別々に読み出さなければならない。そしてユーザー定義文字の文字コードは第1バイトが76H以上だ。だから、テニス・テニス2のプログラムでは文字の右半分と左半分を別々に指定し、どちらもCGウィンドウの奇数アドレスから読み出している。上記のことを踏まえて考えると、T98NEXTがフォントの左半分も右半分のデータにしてしまうような、もっともありがちなミスとは何だろう。それは、2バイト文字のうち第1バイトが76H以上の文字のフォントはCGウィンドウの奇数アドレスからしか読み出せないというキャラクタジェネレータ(CGウィンドウ)の制約を考慮せずに、フォントの左半分が指定されても右半分が指定されてもCGウィンドウの偶数および奇数アドレスにフォントの全体を反映させてしまった場合ではないだろうか。私はそういう仮説を立てた。

この仮説が正しいかどうかは実験の結果で確認する。では、どういう実験をしようか。

T98NEXTの中身はブラックボックスであり、いじれない。T98NEXT上で実行するほうのプログラムを変更して実験するしかない。テニス・テニス2のプログラムのCS:9B71以降に、CGウィンドウから文字フォントを読み出すルーチンがある。その中に、文字コードの第1バイトが76Hならばフォントを左右半分ずつ読み出すルーチンへと行く条件分岐がある:
2C70:9B8C 80FC76 CMP AH,76
2C70:9B8F 7417 JZ 9BA8
いっぽう、第1バイトが76Hを含む特定の値でないならば、フォントを一度に全部読み出すルーチンへ行く:
2C70:9BA5 EB59 JMP Short 9C00
そこで、上記のJZ 9BA8をJZ 9C00に変えれば、プログラムはユーザー定義文字のフォントをCGウィンドウから読み出そうとする時に左右とも奇数アドレスから読まずに偶数と奇数のアドレスから読む。もしもその結果ゲームの2桁の半角数字が正しく表示されれば、上述の私の仮説は正しいことになる。

ジャンプ命令はアドレスを絶対アドレスではなく相対アドレスで指定するので、注意しなければならない。次のように考えた:

(このブロックに書かれている数値はすべて16進数)
jz 9ba8をjz 9c00に変えたい
jzは飛び先を1バイトの相対アドレスで指定する(short jump)
命令jz 9ba8の次のアドレスはcs:9b91
9ba8-9b91=17
このやり方で合っているかどうか確かめる
jz 9ba8のコードは7417
この計算でok
このjzの飛び先を9c00に変える
9c00-9b91=6f
従って、jz 9ba8をjz 9c00に変えるには
cs:9b90の値を17から6fに変更する

ここまでわかれば、後はT.EXEをバイナリエディタに読み込み、ロードモジュール内のCS:9B90に相当する1バイトを書き換えるだけだ。ではその1バイトはT.EXE全体の中のどこか。EXEファイルの構造を調べ直した。

MS-DOS時代のEXEファイルは、ヘッダとそれに後続するロードモジュールから成る。ヘッダ内のオフセット08Hからの2バイトにヘッダのサイズが入っている。これは同時にヘッダの直後から始まるロードモジュールの開始点でもある。ただし単位はバイトではなく16バイトのパラグラフ単位で入っているので、バイトに直すために10H倍してから計算する。ヘッダ内のオフセット16Hからの2バイトに、コードセグメントにロードする情報の先頭位置が、ロードモジュール内のオフセットとして入っている。ただしこれも、16バイトのパラグラフ単位で入っている。

T.EXEの場合、ファイル先頭からのオフセット08Hから2バイトの値は00C0H。これを10H倍してC00H。ファイル先頭からのオフセット16Hから2バイトの値は0EF4H。これを10倍してEF40H。C00HにEF40Hを足してFB40H。書き換えるのはCS:9B90だから、さらに9B90Hを足して196D0H。

実験開始。ゲームのディスクイメージからT.EXEをWindows上のフォルダ内にコピーする。後で元に戻せるように、書き換えるファイルとは別にT.EXEのバックアップを作成。バイナリエディタにT.EXEを読み込み、ファイル先頭からオフセット196D0Hの場所を表示する。その1バイト前からの値は74H,17H。上記JZ 9BA8のコードと一致する。間違いなし。
tt78.png
バイナリエディタでオフセット196D0Hの値を6FHに変更。上書き保存。このT.EXEをディスクイメージ内のT.EXEに上書きする。そのディスクイメージをT98NEXTにセットし、ゲームを開始する。2桁の半角数字は、T98NEXTでも正しく表示された(下図)。私の仮説は正しかった。

ただし、本当はこれは行うべきデータ改変ではない。なぜならゲームのプログラムは間違っていないからだ。それを改変する(あえて間違ったコードにする)のはプログラムの作者に失礼だし、ゲームがT98NEXT専用になってしまう。他のエミュレータや実機では表示が変になるはずだ。

とはいえ、ここまで出来れば私の大昔の劣等感は払拭された。若いころの私にはゲームのプロテクト外しもパラメータ変更もできなかった。でも今は、時間と努力を費やせばできる。私には認識力も知識も不足しているが、時間をかけて自分の間違いを見つけ出し、何度でも技術情報を調べれば、PC-98関係は何だってできる。もうPC-9801用ゲームを実際に解析することはないだろう。でもやろうと思えばできるという自信がついた。それで十分だ。

tt79.png
tt80.png
コメント(0) 

孤独へ向って突っ走れ (49) [  PC-98x1(補完計画)]

この記事は一度公開してから間違いに気づき、非公開とし、1日かけて間違いを直して公開したら、また間違っていた。だから記事が出て、消えて、また出て、しばらくしたら中身が書き換わったというとんでもない記事だ。やる気はまだまだあるんだが、脳ミソが疲れてバカになっているらしい。ちょうど「テニス・テニス2」の解析が終わったので、私はしばらくの間別の作業をして脳ミソをリフレッシュしたほうがいいのかもしれない。

この記事には、自分用の記録をそのまま出すことになった。その関係で、環境依存文字が使われている。ご勘弁いただきたい。



追っかけ8-1
「テニス・テニス2」の全PICファイルにパレットを適用してGIFファイルとして書き出す作業を終えた私は、「テニス・テニス2」と別れる前にもうひとつだけやっておきたいことがあった。
ゲーム内で2けたの半角数字を表示すると、10の位の値のかわりに1の位の値が表示されてしまう。たとえば下の画面の左上の場合、
tt66.png
この55日とは、実際には15日か25日のどちらかだ。ここだけでなく、ゲーム内で2けたの半角数字を表示する時はすべて同様の現象が起きる。この現象を直せないだろうか。

私はまず、画面に文字を表示するルーチンを見た。データセグメントにはゲームで使われる文字列がShiftJIS文字コードで格納されている。それを画面に表示するルーチンとして、追っかけ2-3aで、ShiftJIS文字コードをJIS文字コードに変換するルーチンと、キャラクタジェネレータからCGウィンドウ経由で文字フォントを取得するルーチンが解析済みだ。私は、この辺りに問題があるに違いないと考えた。追っかけ2-3aの文字フォント取得ルーチン(サブルーチン9B6EHの一部)が、2バイト文字にしか対応していないことを発見した。ここに問題があるのかもしれない。

次に私は、読み込む文字列のほうはどうなっているかと調べた。いったい2けたの半角数字部分はどういうデータになっているのか。普通の1バイトのASCII文字コードが2つ続いているのか、そうではないのか。Windowsの「メモ帳」にT.EXEを読み込んで中を見ると、ゲーム内のカレンダーをあらわす文字列がある。それをPrintScreenしたものが、下の画像だ。4月1日の大会開始セレモニーから10月10日の決勝戦までが見える。この部分の文字列では、1日をあらわすデータの最初に月(2バイトの全角数字)、続いて日(2バイトの全角数字)、続いて曜日(2バイトの全角文字)があることがわかる。ただし日は、1けたの数字ならば良いが、2けたの数字だと'・'になっている(緑下線と赤下線は、後の図と対応している):
tt67.png
tt68.png
この結果を出すには注意しなければならなかった。私ははじめ、T.EXEを直接バイナリエディタで開くと2バイト文字が表示されずこの部分を見つけるのが大変なので、「メモ帳」に読み込んでこの部分以外を削除し保存してからバイナリエディタで開いた。すると、上の'・'はどれも81H,45H、つまり中点の'・'の文字コードだった。私はこれのせいで遠回りをしてしまったが、どうやら「メモ帳」で保存するさいにコードが変わってしまったらしい。T.EXEをバイナリエディタで直接開いて同じ部分を見つけると、上の図のとおりに場所により'・'の文字コードは異なっていた。試行錯誤の途中で調査した他の場所の結果も出そう:
tt69.png
tt70.png
tt71.png

tt72.png
tt73.png

大会開始セレモニーのアナウンスの中に"10月10日"があり、これがゲームの表示では"00月00日"になる。そこはどうか。T.EXEをバイナリエディタに読み込み、他になさそうな文字として直前の'集'を検索することでたどり着いた:
tt74.png

これらの調査からわかるのは、
"10"がEBH,A8H
"11"がEBH,A9H
"12"がEBH,AAH
"13"がEBH,ABH
"14"がEBH,ACH
"15"がEBH,ADH
"28"がEBH,BAH
"29"がEBH,BBH
規則性があることはわかった。私が思いつく範囲で可能性を列挙し考えた。
①ShiftJIS文字コード表のこの場所に2けたの数字が登録されている可能性→そんなものは登録されていなかった。
②ShiftJIS文字コードをJIS文字コードに変換した時のこの場所に2けたの数字が登録されている可能性→JIS文字コード表にも、(○つき数字を除いて)2けたの数字というものはなかった。
③PC-9801のキャラクタジェネレータが、上記のコードに対応して2けたの数字フォントを出力する仕様になっている可能性→昔のワープロソフトがJIS文字コード表で空いている場所に独自のフォントを設定していたことから類推するに、その可能性はある。
④このソフトがユーザー定義文字として、この文字コードに2けた数字のフォントを登録した可能性→PC-9801のユーザー定義文字の文字コードは76H,20H以降。(テクニカルデータブックでは7620Hと書かれているが、これだとリトルエンディアンである8086系プロセッサでは20H,76Hの順と思われてしまう。でも実際には第1バイト76H,第2バイト20Hだから、私は7620Hというまぎらわしい記述をしたくない。)この76H,20HはJIS文字コードであり、これをShiftJIS文字コードに変換するとEBH,9EH。この可能性が正解らしい。
⑤このゲームの文字列表示ルーチンがEBHを見つけると、2バイト文字表示とは別処理に分岐して2けたの数字を表示する→上の④が正解とわかるまでは、この⑤も本気で考え、今までの解析結果を見直した。もちろん、文字列表示ルーチンを調べてもそのような分岐は見当たらなかった。

こうして、④、つまりユーザー定義文字の表示に問題があることがわかった。ではその問題点は、ゲームソフトの側にあるのか、それともエミュレータの側にあるのか。実はこの記述にたどり着くまでに色々と回り道をして調査したので、結論はもう出ている。

私は今まで、フロッピーディスクから作ったディスクイメージをT98NEXTで運用しゲームを起ち上げていた。これをNeko Project IIに変更してみた。すると2けたの数字が正しく表示されるではないか:
tt75.png
tt76.png
とはいえ、Neko Project II独自の問題点も見つかった。ストーリーモードの冒頭にあるスクロールが表示されない。
tt77.png

これではっきりしたことがある。2けたの数がおかしく表示されるのは、ゲームソフトの問題点ではなかった。エミュレータT98NEXTの問題だ。

このゲーム「テニス・テニス2」にかんしては、T98NEXTはユーザー定義文字の表示がうまく行かず、Neko Project IIはスクロールがうまく行かない。私は2つのエミュレータの動作の違いを見て、エミュレータはとても良く出来ているが実機とまったく同じではなくそれぞれに個性があるという現実を改めて思い出した。

これで、ゲーム内で2けたの半角数字を表示すると10の位の値のかわりに1の位の値が表示されるという問題は、エミュレータを変えなければ解決せず、エミュレータを変えれば解決するという(あまり喜ばしくない)結論に至った。ここから先は余談だが、私はNeko Project IIでスクロールが表示されない件がどうにかならないかと考えた。私が使っているNeko Project IIはver. 0.83で、以前に私がエミュレータについて色々調べた時にはこれが最新バージョンだった。しかし今ネット検索したら、現在の最新バージョンはver. 0.86と書いてある。ver. 0.86で試してみたが、結果は同じだった。実機から作ったBIOS.ROMをNeko Project IIの実行可能ファイルと同じ場所に置くと使用されるそうなので試してみた。メニューの[Other]-[About]でbios.romを確認。しかし結果は同じだった。これで、Neko Project IIでは「テニス・テニス2」のスクロールは表示できないという(これも喜ばしくない)結論に至った。

コメント(1) 

孤独へ向って突っ走れ (48) [  PC-98x1(補完計画)]

「テニス・テニス2」の全PICファイルにパレットを適用してGIFファイルとして書き出す作業は、きょう最大の難関を突破した。

テキストで書くよりも見てもらったほうが私以外の人にはわかりやすいので、例の小さなアイコンの形で見てほしい。(以前の記事を見てない方のために説明すると、パレットを適用して正しい色合いになった絵を全部出す時は、自分で努力してゲームを制覇したい人の意欲を削がないように、とても小さく縮小して出すことにしている。)
tt64.jpg
tt65.jpg

赤い絵が2つだけある。赤い絵は、まだそれ用のパレットファイルが指定されていない絵だ。そのうちのひとつTITLE3は、調べたところPICファイルはフロッピーにあるが、ゲーム内でそれが使われていない。だからそれのためのパレットは存在しない。「使われないファイルがフロッピー内にあるなんて、本当かなぁ」と思う方は、「テニス・テニス2」をお持ちの方ならば、次の方法で確認できる。このゲームのEXEファイルには、読み込むファイルごとに「ファイル読み込み用データ」が入っている。そのデータの中にファイルのパスも記されている。そこで、Aディスクの中にあるT.EXEをWindows上にコピーし、それをWindowsの「メモ帳」で開く。メニューの「編集」をクリックし、「検索」をクリックする。"TITLE3"を検索する。すると、EXEファイル内に"TITLE3"はひとつもない。他のPICファイルの名前を検索すると、それは出てくる。そういうわけで、TITLE3は赤い絵のままでいい。

残るはただひとつ。CCC.PICという絵だ。この絵は、スケジュール画面にキャラクターが表示されない時のための「透明データ」で、全面がパレット番号0で埋め尽くされている。だから適当にそのへんのパレットを適用しても結果は同じなのだが、そういういい加減なことはしたくないので、私は実際にCCC.PICに適用されるパレットを調べるつもりだ。これが、最後に残った作業だ。ここまで来たらチェックメイトと宣言しても良いかもしれない。

これで今日のご報告は終わりだ。この作業も残りわずかなので、記念に今日の解析記録を出しておきたい。でも、このゲームや解析に興味のない方にとってはただのチンプンカンプンな言葉の羅列だから、お読みになる必要はない。私が勝手に出したいと思っているだけなので。





追っかけ7-4
残っている解析は:
CCC.PIC
A07.PIC, B02.PIC, C12.PIC, T02.PIC

CCC.PICはキャラクターがいない時のための透明データなので全面パレット番号0で、適用するパレットはどれでも同じようなものだが、ここまで来たらしっかり解析したい。

A07.PIC, B02.PICは初日の大会セレモニーで表示され、その時のキャラクター絵がC12.PICであり、パットが話しかけてくるのがT02.PICなので、これらは初日のパレットがわかれば一気に全部解決するだろう。

初日のパレットを知るには、初日の分岐条件を知ることだ。初日はスケジュールが決まっていてゲームプレーヤーが変更できないから、データセグメントの初期状態で値が入っている可能性が高い。
分岐条件はDS:77B6から2バイトに入っている値をベースアドレスとして、それにDS:12DCから2バイトに入っている値を4倍してオフセットとして加算する。そのアドレスに入っている1バイトが分岐条件だ。
word ptr DS:[77B6]はA71CH。今回は初日を調べたいので、ゲーム内の日付をあらわすword ptr DS:[12DC]は0とする。byte ptr DS:[A71C]はFDH。
ちなみに、それ以後の4バイトごとの値はたいていFFH。ごくたまにFEHがある。FFHが"日程がありませんので今日は休みにします"だということは調査済み。つまりこれはゲームプレーヤーが選手のスケジュールを決める前の状態だ。FEHが初めて出るのは、初日を0として27、つまり28番目の日。ゲームを起動してカレンダーを28番目の日までスクロールすると、「藤井絵麻☆ 夏木 の試合」。つまりFEHは自分が試合の日だ。
FDHが分岐条件の時にサブルーチンBF96H(スケジュール画面右半分のキャラクター絵を読み込み、描画するサブルーチン)が読み込むファイルを調べてみよう。それが大会セレモニーの時の絵C12.PICならばすべて順調ということになる。追っかけ5-1cのサブルーチンBF96Hを見る。解析の
①ALがFDHならば、AXを10Hに変更。
が当てはまる。この条件分岐の先は
⑭ここに来るのは上記条件分岐のうち①②③④⑩⑪⑫⑬。これらの場合、ALはまだ最終的なものでない。DS:47CCからデータ配列がある。ALはその添え字として使い、そこから1バイトを読み出す。これをAXの値とする。
データ配列の内容は、追っかけ7-1にある。byte ptr DS:[47CC+10]は0BH。その先の処理は
⑮AXに1FHを掛け、それに31C2Hを足す。これが最終的なSI。
SI=3317H。DS:3317が「ファイル読み込み用データ」の先頭アドレス。調べてみると読み込むファイルはb:\tennis\pic4\c12.pic。すべて順調。
ここまで理解が深まればひとまず十分だろう。パレットファイル読み込み用サブルーチンBD57Hで、分岐条件がFDHの時にどのパレットを読み込むか調べよう。追っかけ5-1cのサブルーチンBD57Hを見る。解析の
①ALがFDHならば、AXは11Hに変更。
が当てはまる。この条件分岐の先はもう単純で
読み込むファイルのデータはAXを18H倍してそれに2049Hを足したアドレスにある。
パレットファイルはa:\pal\pa18.pal。

コメント(0) 

孤独へ向って突っ走れ (47) [  PC-98x1(補完計画)]

最近の記事で、本命と思われる巨大なサブルーチンに突き当たったと書いた。今日はそれの全体像がわかっただけでなく、私の固い頭を柔らかくしてくれる発想が出てきた。

解析を続けてさらにわかったことがある。現在解析中のものはサブルーチンではなかった。サブルーチンならばcallで呼び出され、retで呼び出し元に処理が戻るはずだ。ところがこのルーチンの先頭アドレスへ処理が移る時は、jmpで飛んでくる。サブルーチンとは呼べないからメインルーチンの一部というべきなのだろうが、アドレス的にはまるでサブルーチンのように、プログラム開始点から続くメインルーチンのアドレスとは離れている。これは特殊な事例だと思う。普通はこういうものをサブルーチンで実現する。一般には、サブルーチンへ処理を移したらいずれ呼び出し元に戻らなければならない。しかしこれはPC-98ゲームだ。当時のゲームは終了後にDOSに戻らないものが多かった。だからゲーム終了時には適当な場所で無限ループを作ってそこまでとできる。呼び出し元に戻る必要がない。戻る必要がないのだからcallする(IPの値をスタックに退避する)必要もない。retもない。私は今まで、コード内のretを目安にサブルーチンの始まりと終わりを探してきた。サブルーチン内に複数のretがある場合もあるが、それでもとにかくサブルーチンの終わりにはretがあり、始まりのひとつ前の命令は別のサブルーチンのretかiretだろう。しかし今回のルーチンはサブルーチンではないので終わりにretがなく、私はその後のアドレスに続く別のサブルーチンをこのルーチンの一部と思いretを探し続けた。さらに運が悪いことに、ルーチンの始まりのほうも同様の事情だった。つまり、アドレス的にひとつ前のルーチンが、これもまた同様にサブルーチンではなく終わりにretがなかったから、私はアドレスを遡ってルーチンの始まりを調べるさいも別のルーチンをこのルーチンの一部と思いさらに遡って調べた。その結果、このルーチンはたしかに巨大だが、それ以上に巨大に見えてしまった。私が誤りに気づくことができたのは、このルーチンのひとつ前のルーチンが「ゲームオーバー表示と無限ループ」だったからだ。無限ループまで来たらそのルーチンの処理は終わっているはず。でもretがない。よくよく考えてみたら処理を呼び出し元に戻さないのだからretはいらない。それで、これがサブルーチンではないと気づいた。
コメント(0) 

孤独へ向って突っ走れ (46) [  PC-98x1(補完計画)]

きのう、何の因果かマタンゴを思い出した。きのこのおばけが出てくるシーンは恐いが、それ以外の部分がやたらと長かったと記憶している。で、マタンゴを思い出した私は、今日になって「マ単語」を思い出した。たしかそんな言葉だったと思う。日高総帥のどれかの著書に出てきた。マだからマシン語の著書のうちのどれかだ。ネット検索してみたけど、だれも「マ単語」については書いていなかった。

マシン語は面白い。サッカーが面白いという人は多いし、野球が面白いという人も多い。ところがマシン語を面白いと言うと、たぶん99パーセントの人の反応は私の期待とは違う。「へえ、すごいですね。」すごい?たしかに世の中にはすごいマシン語使いがいらっしゃる。でも私は初心者だ。たいしたことはできない。でも面白いんだ。ところが、サッカーが面白いと言って人は理解してくれるが、マシン語が面白いと言ってもなかなか理解してくれない。たとえ「すごい」という言葉は返ってきても、「そうですね面白いですね」という言葉はまず返ってこない。サッカー好きの人が話の合う友達を作るのは比較的簡単だが、マシン語好きの人が話の合う友達を見つけるのは難しい。私はある意味不幸を感じる。

さて、例の巨大なルーチン。いずれはコードを遡ったり先へ辿ったりしてサブルーチンの全容を明らかにしなければならないが、手を広げすぎると自滅する恐れがあるから、私はすでに逆アセンブル済みの部分、Word文書にして30ページ分をとにかく解析することにした。今日は有難いことに、その30ページ分が大体わかった。データセグメントの特定の場所の意味が、少しずつわかり始めている。word ptr DS:[134C]の値を100倍すると所持金(円)になる。word ptr DS:[12DC]はゲーム内の日付を意味する。

でも、誤解しないでほしい。こうやってブラックボックスだったものの一部が自分の努力によって明らかになるのは私にとってたしかに楽しいが、でもこれは私の目的ではない。私の目的は全部のPICファイル(PC-9801用に作られたビットマップデータ)に対応するパレットファイルを知ることだ。所持金もゲーム内の日付も、そこに近づくための一歩にすぎない。このゲームでは特定のイベントに関係するパレットファイルはそれを読み込むためのデータのアドレスが即値で指定されているから簡単に解析できて、もうイベント関係のパレットはわかっている。問題は、イベントでも何でもない部分だ。それと、イベントでもたったひとつ、データのアドレスが即値で指定されないものがある。これらは、このプログラムの仕組みを根気強く解析しないと正しいパレットがわからない。

このへんで話を変えよう。この記事を読んでくださる方がどのような方かはわからないが、アセンブラ関係ではなく、解析中の「テニス・テニス2」が知りたくて読んでくださる方もいらっしゃるだろう。だからこの後は、ちょっと前にゲームをプレイした時のことを書こう。

私は病気見舞いのイベントを出して、パレットの判定が正しいかどうかを目で見て再確認したかった。でもこれは、私にとって辛いことだった。たかがゲーム内のこととはいえ、自分が育てている選手をわざと疲れさせ、病気にさせる。私はそんなとんでもないコーチに自分がなるのは嫌だ。この作業は嫌だった。でもしなければならない。

ちょっと選手が疲れると、「アホ顔」の絵になる。でもアホ顔程度では意外と影響が出ない。このゲームをテストプレイしてゲームバランスを調整した方々は、難しくしないようにと頑張って調整したらしい。相当体力を落とすと、この下の絵になる。
tt61.png

こうやって選手をわざと病気にしようという辛いゲームプレーの間にも、容赦なくテニスの大会は進行してゆく。つまり他選手との試合がやってくる。ああ、負けるのか?体力を落とした私の教え子は負けるのか?負けて嬉しいゲームプレーヤーがどこにいる!

ところが、試合の結果が予想外のことになった。選手を病気にさせるためにわざと体力を落とさせても3試合連続で勝ってしまったのだ!下の画像がその証拠。藤井絵麻が3試合連続で○になっている。
tt62.png

このゲームでは、最初のほうの対戦相手は各パラメータを低くして難易度を易しくしているのかもしれない。でもひょっとすると、休ませずに練習ばかりさせたから藤井絵麻の腕力が100になったせいだろうか?
tt63.png

コメント(0) 

孤独へ向って突っ走れ (45)  [  PC-98x1(補完計画)]

どこまでも続く巨大なルーチンに突き当たった。これが本命のラスボスかもしれない。

特定のコードを検索して出くわした場所から先へ行っても戻っても、どっちの方向にどこまで行ってもretがない。とてつもなく巨大なサブルーチンだ。シナリオモードで1日1回実行されるループだと思う。その中にいくつもの条件判定があり、メッセージ表示やイベント絵表示につながっている。現在、解析を記したドキュメントはWord文書で30ページ。これはまだ部分であり、ページ数はさらに増える。あまりにも巨大なので、まだサブルーチンの全体像が掴めない。何日もかけて解析するしかない。

コメント(0) 

孤独へ向って突っ走れ (44) [  PC-98x1(補完計画)]

貞子を見損ねた一件とシェーンの放送があった一件で、ちょっと逆アセンブラ結果の解析は滞ったが、それでも少しずつ進めている。

今やっているのは、純粋なコード解析とは少し違う。パレットファイルが判明しても、それを適用するpicファイルのほうが判定できない場合がある。ファイルを読み込む時点でのデータセグメントの特定の場所の値がわかれば判定できるが、それを知るためにはその場所に値を書き込むコードを探して長い長い解析をしなければならない。いずれはそれもする必要があるが、その「難物」は最後に回そうと思う。それ以外の楽に判定できるものを先に片付けて、いわば囲碁のように「難物」の周りを固め、それから攻略すれば、解析の上でも精神的にも苦労を軽減できるという考えだ。で、本来ならばそのpicファイルは判定できないのだが、それでも判定できる場合がある。なにもコード解析が唯一の方法ではない。ゲームをプレイするという方法を忘れてはいけない。

つまり、こうだ。コードを遡って見てゆくと、判定できないはずのpicファイルを表示する直前に別の絵を表示している。その絵はイベントの絵だ。そこで私はゲームをプレイした時のことを思い出した。このゲームではショッピング、レストラン、アルバイトなどのイベントは1枚の絵で表現される。
tt53.jpg

そしてそのイベントが終わるとスケジュール画面に戻るが、次の日へ移行するまではイベント絵と同様の絵が画面右半分に表示されたままになる。この画面の一部として表示されている絵のうち、先に表示されたイベント1枚絵と明らかに同種の内容を示すものが、判定すべきpicファイルだ。
tt54.jpg

つまりそれはtt55.jpgtt56.jpgtt57.jpgの3つだ。

こうして、判定できないはずのpicファイルは、ゲームをプレイした人間にとっては、コード解析としてでなく、ゲームの進行から判定できる。

でも、今日私はそれを書きたくて出てきたのではない。妙なものを見つけてしまったから、それを報告するために出てきた。

まずは、これを見てほしい。何か気づかれるだろうか。縮小するとわかりにくくなるので、わざと縮小しないで出した。マウスでクリックすると大きくなる。
tt58.jpg
きっとあなたは気づいただろう。ついに日本のカレンダーには、4月00日が出現したらしい。

tt59.jpg
4月44日だってある。私はプログラム解析の途中で何かやらかしてしまったかなと心配したが、ネット上のゲーム写真にも4月44日があったので、どうやらどのディスクを使ってプレイしてもこうなるようだ。

他にも、こういうのが見つかった。縮小したからわかりにくいが、この記事の同様の絵と比べるとひょっとしたらわかるかもしれない。画面左半分だ。
tt60.jpg
上のほうにトレーニングジムの建物が小さく表示されているが、地盤沈下を起こして下へ少し沈んでいる。つまり、画像領域の上辺が黒くなっているが、本来はここに建物を描いた絵の上辺が来なければいけない。でもこれは描画位置のバグではなく、そもそもpicファイルの内容がこういう絵として記録されているという間違いだ。

・・・あっと、睡眠薬が効いてきた。ちょうど書きたかったことは書けたので、今日はここまでにしたい。これからも記事の頻度は減ると思うが、それでも少しずつ解析を進めようと思っている。

コメント(0) 
前の10件 | -   PC-98x1(補完計画) ブログトップ