さて改造実践編。
ポーズをかけるのが目的なんだけど、初めての改造なのでとりあえずわかりそうなことからやってみます。
……無限ボンバーとか試してみますか。
「mame -debug raiden」みたいな感じでMAMEをデバッグモードで起動します。
今回逆アセンブルして初めて知ったんですが、雷電ってCPUがV30だったんですね……68000だとばかり思ってましたw
MAMEのソースやデバッガで出力した逆アセンブルのソースを見てワークエリアっぽいところにあたりをつけておきます。
今回はMAMEドライバのソースにA0000HからプログラムROMを読み込むって書いてあるので、逆アセンブル結果はそれを確かめる程度でOK。
デバッガで起動するとプログラムは止まった状態です。
F5キーを押して目的の場面(ゲームが始まってボンバーの数が3個にセットされたであろう頃合い)までゲームを進行させた後、デバッガのコマンドでメモリの中から「3個」を記録してある場所を探します。
「find 00000,9FFFF,3」で、メモリの先頭からプログラムの手前まで探します。
プログラムの後方にワークエリアが取ってあったら、それはそれでまた考えましょう。
ボンバーを1個ずつ消費しながら、findコマンドで「2個」「1個」「0個」と探りながら該当しそうなアドレスに目星をつけます。
今回はどうやら00BE3Hがボンバーの数に連動しているように見えます。これがすぐに発見できるといいんですけどね……
今度はデバッガのメモリウィンドウを表示させて、00BE3Hを眺めつつプレイしてみましょう。
このメモリウィンドウ、アドレスごとにワード単位で内容が表示されます。
8086系はリトルエンディアンで上位バイトと下位バイトが入れ替わってる(ように見える)ので見る場所に気をつけて。
※追記:何バイト単位で表示するか指定できました
で、ただメモリの様子を眺めていても仕方ないので、同時にウォッチポイントを設定して、00BE3Hのメモリにデータが書き込まれたらプログラムを停止するように設定します。
コマンドは「wp 00BE3,1,w」です。
アドレス00BE3Hから1バイトを見張り、データが書き込まれたら(w)プログラムを停止します。
プログラムを走らせると頻繁に00BE3Hへの書き込みが起こってプログラムが停止しますが、ゲームが始まる前準備の段階は関係ないので停止→F5→停止→F5の繰り返しでゲームが始まるまで進めましょう。
ゲームが始まったらボンバーボタンを押します。
この瞬間に00BE3Hに保存されているボンバーの個数を減らすように書き込みが発生してプログラムが止まります。
省略しますが、何回かボンバーを発射するとこんな感じ。
メモリの内容が見事に「3個」→「2個」→「1個」→「0個」と減ってます。
メモリウィンドウの数値もリアルタイムで減っていきます。
上の画面からするとPC(プログラムカウンタ)がF6B37Hで止まっているので、その直前の命令が00BE3Hに保存されている数値を減算しているに違いありません。
該当箇所を上の逆アセンブルウィンドウで見ると、
dec word ptr [iy + 10h]
となっています。
もう間違いないですね。8086系弱い私でもわかります。
念の為に左側のレジスタも確認するとIYレジスタは0BD3Hとなっているので、これに10Hを足せばさっきの00BE3Hになりますね。
さて、ボンバーの数を書き込んでいる場所がわかったので、ここを直せば無限ボンバーができそうです。
実際にプログラムを書き換えるために、プログラムROMのバイナリを読み込んで該当箇所を探し出します。使用したのは
Stirlingというバイナリエディタです。
http://ja.wikipedia.org/wiki/Stirling
さっきのボンバー数減算命令の部分をコードで入力して検索します……あ、あれ?
MAMEのソースを読むとどれがプログラムのROMかわかるので、それを頼りに全部読み込んで検索してましたが同じコードが見つかりません……どういうことなの?
ちょっとROMの中身と、MAMEからのぞいたメモリ上のプログラムを見比べてみます。
上の2つのウィンドウがROMの中身、一番下のウィンドウがMAME上の雷電のメモリの中身です。
全然違いますね。
……?
……あれ?
これって、rai1.binのROMとrai2.binのROMを1バイトずつ交互に取り出すと、下のメモリの中身と一致するんじゃないの……?w
rai1.bin 00 00 12 24 36 48 5A …… rai2.bin 00 02 02 02 02 02 02 …… メモリ内容 0000 0200 0212 0224 0236 0248 025A ……
まあ、冒頭は02ばかり並んでいるんで、念の為に先の方も確認したところどうやら2つのROMのバイナリがメモリ上に交互に読み込まれているようです。
すぐ思いついたように書いてありますが、ここで結構悩みましたw
それなら1バイトおきに値を取り出して検索してみましょうか……
おお!ありました!
結局、rai3.binとrai4.binの後半らしき2つのROMから該当箇所のコードを見つけることができました。
アドレスも一致してるようです。
さて、ここがdec命令の場所です。
イージーにこれをNOPで潰しましょうw
こんな感じかな……8086のNOPは90Hらしいです。
初めて知りましたw
キター!
できました!
動画録ればいいのですが、面倒なのでスクリーンショットで。
開幕ボンバーで残数3なので減っていません。
こんな感じで無限ボンバーはうまく行ったようです。
この後、同じ要領で自機の数が格納してあるアドレスが0BD5Hと判明しました。
被弾したときにその数を減じているF0F5AHの命令も潰して無限残機もできたようです。
まとめ
無限ボム F6B34 rai3.bin 1B59A FF 10 → 90 90 rai4.bin 1B59A 4D → 90
無限自機 F0F5A rai3.bin 187AD FF D5 → 90 90 rai4.bin 187AD 8C 0B → 90 90
まあ、どちらも別に楽しくない改造なんですけどね……w
改造の練習ということで最初の一歩です。
他にも色々やってみたのですが、この続きはまた!
あ、MAMEデバッガのコマンドはこちら。
http://mess.redump.net/debugger