ここまでで、船の数を増やしたり、魚雷にやられても減らなくしたりすることができましたが、
そもそも魚雷にやられない(無敵モード)を作ることを考えてみます。
t88toolだけでは無理なので、X88000の「実行ログ記録」機能を使います。
(改造版ではうまく動かなかったので、本家X88000を使って下さい)
X88000で、submarine.d88を起動し、下記のように操作します。
操作は全て、「デバッグ」メニューの中にあります。
1.X88000フォルダにDebug.logができていたら、削除する(重要!)
2.「メインCPUデバッグ」をオンにした後、「デバッグ実行」でゲームを再開する。
3.「実行ログ記録」をオンにする(ログ取り開始)
4.やられないように遊ぶ(やられてしまったらDebug.logを削除して最初からやり直し)
5.「実行ログ記録」をオフにする(ログ取り停止)
6.「Debug.log」のファイル名を「Safe.log」にリネーム(名前の変更)する
7.「実行ログ記録」をオンにする(2個目のログ取り開始)
8.今度はわざとやられる(できるだけやられた瞬間だけを記録するようにする)
9.「実行ログ記録」をオフにする(ログ取り停止)
10.「Debug.log」のファイル名を「Crash.log」にリネーム(名前の変更)する
(X88000で実行ログ記録中の状態)

・巨大なログファイルができますので、ログ取得時間はできるだけ短くして下さい。
・改造ポイントを絞りこむために、4のログはいろいろなパターンを含んでいる必要があります。
・8のログは、やられた一瞬だけのログにすることで、改造ポイントを絞り込めます。
X88000フォルダ内の「Safe.log」と「Crash.log」をt88toolのある場所にコピーして下さい。
このログをt88toolで解析します。n80ファイルも1つだけ指定して下さい。
t88tool -Bd submarine.n80 Safe.log Crash.log
ちなみに、logファイルのファイル名は「.log」で終われば、何でも構いません。
最初のログファイルをやられないログ、2番目のログファイルをやられた時のログとして扱います。
画面に、無敵改造の候補が表示されます。
[Safe.log (1) 1038] 1038
[Crush.log (1) 594] 594
<Binary Diff Mode>
?(-P B6C1=18) B6C1(90,88) JR
NZ,0B6FAH ;B6C1 : 20 37
B6C3(0,1)
* LD A,(0B707H)
;B6C3 : 3A 07 B7
B6C6(0,1) * DEC A
;B6C6 : 3D
B6C7(0,1) * LD (0B707H),A
;B6C7 : 32 07 B7
かっこ内の表示は、アドレス(Safe.logの回数,Crash.logの回数)です。
直前のB6C1までは何回も来ているのに、B6C3以降は、魚雷にやられてからの1回しか来ていないことがわかります。
しかも、B6C1は、条件ジャンプ命令です(JR NZ,0B6FAH:20,37)。
ということで、この命令を無条件ジャンプ(JR
0B6FAH:18.37)に変えて、絶対に、B6C3に来ないようにすることで、 無敵化ができる可能性があります。
左上の表示「?(-P B6C1=18)」が、パッチコマンドです。-Bコマンドと一緒に使って下さい。
t88tool submarine.n80 -B 無敵.n80 -P B6C1=18
上記のバイナリパッチで、B6C3に絶対来ないようにした所、予想通り、絶対にやられないようになりました(無敵モード完成)。
(無敵.n80を実行。魚雷が当たっても爆発しません)

改造ポイントとパッチコマンドは、下記のような考え方で候補を表示しています。
1.やられ処理の1行前の条件付き分岐命令は、無条件に分岐させて、処理からそれるようにする。
JP ??:条件ジャンプ(C2, CA, D2, DA, E2, EA, F2, FA)
→無条件ジャンプ(C3)
JR ??:条件相対ジャンプ(20, 28, 30, 38)
→無条件相対ジャンプ(18)
RET ??:条件リターン(C0, C8, D0, D8, E0, E8, F0, F8)
→無条件リターン(C9)
2.やられ処理に飛んでくる条件付き分岐命令は、NOPに変えて飛んでこなくさせる。
JP ??:条件ジャンプ(C2, CA, D2, DA, E2, EA, F2, FA)
→NOP×3(00,00,00)
JR ??:条件相対ジャンプ(20, 28, 30, 38)
→NOP×2(00,00)
CALL ??:条件コール(C4, CC, D4, DC, E4, EC, F4, FC)
→NOP×3(00,00,00)
3.やられ処理の先頭をRET(C9)にする。(topキーワードを指定した時のみ)
通常は、候補が複数表示されます。この場合は、出力されるpatch.patファイルを使って、無敵になるポイントを探し出して下さい。
また、この例では、たまたま、うまく行きましたが、B6C3に来ないようにしただけだと、他の場所に流れてゲームの動作がおかしくなってしまう場合もあります。
その場合に、B6C3にジャンプした上で、処理の先頭でリターンするとうまく動くゲームがあります(何も考えずにリターンするので、動く確率は低いです)。
「top」キーワードを追加することで、このようなパッチコマンド(-P
B6C3=C9)も表示されるようになりますので、試してみて下さい。B6C3には来るようにした上ですぐリターンします。
t88tool -Bd submarine.n80 Safe.log Crash.log top
???(-P B6C3=C9) B6C3(0,1) * LD
A,(0B707H)
;B6C3 : 3A 07 B7
候補がたくさん出すぎている時には候補の絞り込みが必要です
表示されている候補は、Crash.logの命令からSafe.logの命令を引いたものです。
1.Safe.logに魚雷にやられる前の全ての命令が含まれるようにする
2.Crash.logを魚雷にやられた瞬間だけの命令が含まれるようにする
ことで表示される候補を減らすことができます。
後から、取得したDebug.logもどんどん追加していって構いません。
Safe.logについては「+」で追加していって下さい。すべてのログを結合したものになります。
Crash.logについては「*」で追加していって下さい。すべてのログに共通する処理に絞り込みます。
t88tool -Bd submarine.n80 Safe1.log+Safe2.log+Safe3.log
Crash1.log*Crash2.log
「+」「*」もついていない時には、最後のファイルのみをCrashファイルとして扱い、
それ以外をSafeファイルとして扱います。
t88tool -Bd submarine.n80 Safe1.log Safe2.log Safe3.log
Crash.log = t88tool -Bd
submarine.n80+Safe1.log+Safe2.log+Safe3.log Crash.log
ちなみに、記号は下記からつけました。 「+」:和集合ということで。AまたはB、A∪B
「*」:積集合ということで。AかつB、A∩B
それでも複数の候補が残る時には、各ブロックの先頭(B6C3など。B6C1ではないので注意)をX88000の「デバッグ」「ブレークポイント」に全部設定して動かすと絞りこむことができます。
魚雷にやられていないのにブレークするポイントは、対象外です。
ブレークポイントから削除してから、「デバッグ実行」でゲームを再開して下さい。
魚雷にやられた時に一番最初にブレークするポイントが改造すべきポイントの候補になります。
いろいろやっても、改造ポイントが見つからない場合には、下記の命令でCrash.logで実行した命令を逆アセンブル表示しますので、
テキストファイルに落として、マシン語の解析をして下さい。
やられた時にどこを取っているかが回数でわかるので、通常のマシン語解析より、はるかに楽です。
t88tool -Bd submarine.n80 Safe.log Crash.log disasm
> result1.txt
…Crash.logの新規命令のみ逆アセンブル表示
t88tool -Bd submarine.n80 Crash.log disasm > result2.txt
…Crash.logの全命令を逆アセンブル表示
t88tool -Bd submarine.n80 Safe.log Crash.log B6B0-B6FF
> result3.txt
…B6B0〜B6FF番地の逆アセンブル表示を追加
|