烈火なんだが、バグ面を引きずり出すには当然スタート面の格納場所を調べなくてはいけない。 幸いこのゲームにはステージセレクトが裏技で用意されているので、これを使って調べる。 いつものようにゼロページを眺めてみても見つからなかったので、検索をしてみると0x01B5番地に格納されていることがわかった。ってここスタックエリアじゃねーか。 気を取り直して0x01B5番地にon Writeでブレイクポイントをセットしステージを変更してみる 855A lda $20 855C and #$D0 855E cmp #$D0 8560 bne $8571 8562 lda $1F 8564 and #$20 8566 beq $8571 8568 ldx $01B5 856B lda $85B2,x [$????] 856E sta $01B5 <<ここでブレイク 8571 rts え?incじゃないの??っていうか何だこの処理は。 ということで0x85B2番地以降を見てみると、「00 01 02 03 ……」と数が並んでいる。 どうもこれはステージセレクト用の数値テーブルらしい。さて困った。 「incを使っているだろうから上限値をつぶせばオッケー」とか思っていたのに。 ……まてよ。これよく見たらそもそも上限判定がないぞ。 ということは、0x856E番地のストア命令"sta $01B5"(8D B5 01)を"inc $01B5"(EE B5 01)に書き換えるだけで256面セレクトできるんじゃないか? 試してみたところあっさり成功。ちなみに100以降の表記は十の位が順に「A,B,C,D,E,F,G,H,I,K,L,M,N,P,R,S」と変化する(なぜか0xFFのときは"00"になるけど)。 ステージセレクトリミッタ解除 915CAFFA ところでこのステージセレクト、操作方法が「サウンドテスト画面でA+B+スタートを押しながらセレクト」というかなり面倒なもので、一度スタートボタンから指を離してしまうと、一旦サウンドテストを抜けなくてはならなくなってしまうため、非常に勝手が悪い。 とここでさっきのルーチンの少し上を見てみると、0xD0という数値が見える。 これはちょうどA+B+スタートを同時に押したときの値なので、次の分岐を"bne $8571"(D0 0F)から"bne $8562"(D0 00)に書き換えてつぶしてみると、サウンドテスト画面でセレクトを押すだけでステージセレクトができたので採用。 A+B+スタートを押さなくてもステージセレクト可能 FC76BE00 -----以下 26/04/69 追記----- スレで依頼があったので、無敵コードをさがしてみる。 無敵時間を表しているのは 0x01A6 番地なので、ここに on read でブレイクポイントをしかける。 //無敵時間処理ルーチンここから F3AF:AD A6 01 LDA $01A6 //無敵時間を a レジスタに読み込み // ↑ここでブレイク F3B2:F0 18 BEQ $F3CC //無敵時間が0ならば次のルーチンに分岐 F3B4:CE A6 01 DEC $01A6 //無敵時間をデクリメント F3B7:F0 0D BEQ $F3C6 //デクリメントの結果が0ならば分岐 //デクリメントの結果が0以外だった場合 F3B9:29 03 AND #$03 //デクリメント後の無敵時間の下位2ビットを取得 F3BB:D0 0F BNE $F3CC //デクリメント後の無敵時間の下位2ビットが0ならば次のルーチンに分岐 F3BD:A5 98 LDA $0098 //自機状態を a レジスタに読み込み F3BF:49 01 EOR #$01 //点滅ビットを反転 F3C1:85 98 STA $0098 //自機状態を a レジスタから書き込み F3C3:4C CC F3 JMP $F3CC //次のルーチンへ移動 //デクリメントの結果が0だった場合 F3C6:A5 98 LDA $0098 //自機状態を a レジスタに読み込み F3C8:29 BE AND #$BE //無敵ビット・点滅ビットをOFF F3CA:85 98 STA $0098 //自機状態を a レジスタから書き込み //無敵時間処理ルーチンここまで F3CC:AD 9E 01 LDA $019E //以下省略 このルーチンから 0x98 番地が自機の状態を表しており、 無敵時間が0になるときに無敵フラグがクリアされていることがわかる。 これを以下のように書き換える。 //無敵時間処理ルーチンここから F3AF:AD A6 01 LDA $01A6 //無敵時間を a レジスタに読み込み // ↑ここでブレイク F3B2:F0 12 BEQ $F3C6 //無敵時間が0ならば「デクリメントの結果が0だった場合」に分岐 F3B4:CE A6 01 DEC $01A6 //無敵時間をデクリメント F3B7:F0 0D BEQ $F3C6 //デクリメントの結果が0ならば分岐 //デクリメントの結果が0以外だった場合 F3B9:29 03 AND #$03 //デクリメント後の無敵時間の下位2ビットを取得 F3BB:D0 0F BNE $F3CC //デクリメント後の無敵時間の下位2ビットが0ならば次のルーチンに分岐 F3BD:A5 98 LDA $0098 //自機状態を a レジスタに読み込み F3BF:49 01 EOR #$01 //点滅ビットを反転 F3C1:85 98 STA $0098 //自機状態を a レジスタから書き込み F3C3:4C CC F3 JMP $F3CC //次のルーチンへ移動 //デクリメントの結果が0だった場合 F3C6:A5 98 LDA $0098 //自機状態を a レジスタに読み込み F3C8:09 40 ORA #$40 //無敵ビットをON F3CA:85 98 STA $0098 //自機状態を a レジスタから書き込み //無敵時間処理ルーチンここまで F3CC:AD 9E 01 LDA $019E //以下省略 プロアクションロッキー用コードは以下 無敵 539D885A A53B85EC D2368D12