ツインビーいきます。 ブートケーブルでROMイメージを読み出して、VBAに放り込んで0x02000000から0x20000バイトを切り出してNESヘッダを追加。 virtuaNESで動作確認。タイトルロゴが見えないが、別に問題ないからいいや。 GNESを起動して、例によってキャラクタステータスの見極め。 ゼロページを眺めてみると、どうやら84番地がそうらしい。 手動で死んだときの数値0x03を書き込むと死亡したので確定。 "on write"でブレイクポイントを仕掛けてゲームスタート。 敵に体当たりすると即座にヒット。 EAA0 lda #$03 EAA2 sta $84,x げげっ、またインデックスレジスタ使ってる…と思ったが、 よくよく考えたら二人同時プレイがあるので当然だわな。 面倒なので"lda #$03"を"lda #$02"に書き換えて、敵に体当たり。 見事にスルー。やったね! …と思いきや、分身をつけた状態で敵に当たると、分身が地縛霊化。 やっぱり分岐をつぶさないとダメだね、ということでプログラムをさかのぼる。 EA4D bcc $EA7E ここを通過して分岐してくれれば無効化できるんだけど、残念ながらスルーされているので、さらにさかのぼる。 EA39 bne $EA8C ここで分岐して死亡ルーチンに行っているようなので、上で出た分岐先を参考に、 "bne $EA8C"(D0 51)を"bne $EA7E"(D0 43)に書き換えてみる。 今度こそ大丈夫。ちゃんと分身もついてくる…と思ったら、弾に当たると腕が取れるのを忘れていた。 また管理アドレスが別のようなので、ゼロページを眺めて88番地にあたりをつける。 0x03で腕あり、0x00で腕なしなので、ここと断定。"on write"でブレイクポイントを仕掛ける。 敵弾に当たると…これまた即座にヒット。 EA6B lda #$00 EA6D sta $88,x さっきと同じ形式ですな。とりあえずダメだとは思うが"lda #$00"を"lda #$03"に書き換えて、敵に体当たり。 救急車が出てきて、自機が化けました。やっぱり分岐つぶさないとダメですか… プログラムをさかのぼると、 EA45 beq $EA52 ここで分岐しているようなので、体当たりとと同じくEA7E番地に飛ぶよう "beq $EA52"(F0 0B)を"beq $EA7E"(F0 37)に書き換えて… 今度こそオッケー。 ROMアドレスはExxx=6xxxなのでX-TAコード化すると 32006A3A0043 32006A460037 になる。 さて、ほかにネタもないので、とっととマスターコードを探しましょうか。 ADVTermの候補は10001564だが、あてにならないので無視。 1周クリアしても止まらなかったのでこれに決定。 100015680007 0000FE05000A 例によってGBA-PARコード マスターコード 9E765F97 96F8C394 5D847438 6E33BAA4 無敵 1AD75626 17DC5558 敵本体 F5FDBECD 0BFD2789 弾 プロアクションロッキーコード(未検証) 無敵 C0361866 敵本体 5CCA88A8 弾 以上終了。 --以下6月1日追加-- …と思っていたのだが、なんと体当たりの方のコードのみ使用すると、 救急車を取れないことが発覚。 急遽88番地(腕の状態)に"on write"でブレイクポイントを仕掛けて調査再開。 結果 EA8C cmp #$80 EA8E beq $EABF この分岐が救急車の取得のようである。 なので、その後をたどってみる。 EA90 ldx $EB EA92 lda $0509,x EA95 beq $EA9A EA97 jmp $E9F3 このEA95番地の分岐の後死亡ルーチンに移動しているため、 "beq $EA9A"(F0 03)を"beq $EA97"(F0 00)に書き換える。 見事救急車と合体可能になりました。 せっかくなので、弾が当たると吸収していたのを、すり抜けるようにしてみる。 前回潰した分岐からさらにプログラムをさかのぼっていくと、 EAF3 cmp #$0D EAf5 bcs $EAFA という分岐があり、スルーすると当たり判定に進むので、 "cmp #$0D"(C9 0D)を"cmp #$00"(C9 00)に変えて、キャリーフラグを立たないようにさせ、 強制的に分岐させる。 結果は成功。 というわけで、修正版無敵コード。 ついでに、検証中に止まりまくったのでマスターコードも変更(前回はうまくいったのに…) X-TA マスターコード 100015600007 0000FE05000A 無敵 32006A960000 敵本体 32006AF40000 弾 GBA-PAR用 マスターコード 89D45E24 ED28E0FF 5D847438 6E33BAA4 無敵 19D5678A AAA858F9 敵本体 01F8D103 CA296E95 弾 プロアクションロッキー用 無敵 FCCF2C34 敵本体 FC586066 弾 なお、FCのロムを手に入れたので、ロッキー用コードの動作は確認できました。 ☆おまけ 折角なので、自機のX座標、0305番地を使って遊んでみる EA90 ldx $EB EA92 lda $0509,x EA95 beq $EA9A EA97 jmp $E9F3 この部分を EA90 lda $0305,x EA93 eor #$20 EA96 sta $0305,x EA98 bne $EA7E に書き換え、ついでに敵弾の当たり判定のジャンプを、 EAF7 jmp $EA3E から EAF7 jmp $EA90 に書き換える。 すると、攻撃を食らうと横方向に分身して避ける。 さすがに行数が多すぎてFC実機では無理だが、コード化すると X-TA 32006AF80090 52006A900005 BD050349089D 0503D0E40000 GBA-PAR 6EC463F7 EA45977C CEBAA4EA F9826D67 36AE0ED7 2B87E5D8 9BEEC00D 4A6D998C 本当はeorの値を大きくすれば派手に避けてくれるのだけれども、 GBAの画面だと、すぐ画面外に出ちゃうんだよね。 --以下6月3日追加-- 検証していて、連射するのが面倒になったので、オート連射を探す。 例によって適当に弾を撃ちながらゼロページを眺めてみると、 弾を撃った瞬間83番地に数値が加算されている。 その後徐々に減算されていることから、おそらく次のショットが撃てる間でのフレーム数だと思われるので、 "on write"ではなく"on read"でブレイクポイントを仕掛ける。 すると、何もしていないのにヒット。 B6EE lda $83 B6F0 bne $B719 B6F2 lda $05 B6F4 and #$40 B6F6 beq $B71B 40hはBボタン押下時の数値であるため、可能性は非常に高い。 B6F2番地でロードされている05番地は、ブレイクがかかってはじめて気づいたのだが、 どうもコントローラのボタンが押されたフレームのみ数値が書き込まれる(押しっぱなしでは変化しない)アドレスのようだ。 逆に、近くの07番地はボタンが押されている間中数値が変化するアドレスのため、 ロード命令を"lda $05"(A5 05)から"lda $07"(A5 07)に変更し、参照アドレスをずらしてみる。 結果、Bボタンを押しっぱなしで連射できるようになった。 ついでなので2Pも同様の手順で、A3番地にブレイクポイントをセットして、 B8B2番地の"lda $06"(A5 06)を"lda $08"(A5 08)に書き換えることで実現。 連射コード化 X-TA 320036F30007 1P 320038B30008 2P GBA-PAR 34BB556A F641A3A3 1P A149FEA2 6A551FA0 2P プロアクションロッキー E51DF532 1P A0334784 2P あと、分身避け、やっぱり地味なので移動量を増やす。 時々画面外に出るが、気にしない。 X-TA 32006AF80090 52006A900005 BD050349209D 0503D0E40000 GBA-PAR 6EC463F7 EA45977C E49C88CD 62B71EF5 36AE0ED7 2B87E5D8 9BEEC00D 4A6D998C --以下6月24日追加-- アクションリプレイ誌が届いたのだが、連射コードの説明に -なお、分身すると効果が無くなります ……マジで? 試しに使ってみると…あ、ホントだ。 というわけで急いで分身時のコードを探します。 要は分身を取ってから83番地にブレイクを仕掛ければいいわけで。 BF00 lda $83 BF02 bne $BF22 BF04 lda $05 BF06 and #$40 BF08 beq $BF24 わはは。全く一緒だ。"lda $05"(A5 05)から"lda $07"(A5 07)に変更 というわけで、次の行を追加 X-TA 32003F050007 1P分身時 GBA-PAR 61CF8A83 AF9AAD11 1P分身時 プロアクションロッキー E51D08DE 1P分身時 なお、2P時はそもそも分身自体が出ないので、これでFIX完了。