さて久々の解析のお題はスターラスター。 このゲームの裏技に 「ピンチの時にアステロイドでコントローラ2のABを押しながらマイクに叫ぶとスターノイドが出てきて回復してくれる」 というのがあるんだけど、この裏技当然マイクのないニューファミコンでは使えないわけで。 そこで強引にマイク入力を不要にしてしまおうというのが今回の計画。 で、ゼロページのメモリを見れば、コントローラ1が0x18、コントローラ2が0x19番地に割り当てられているのはすぐわかるんだけど、 肝心のマイク信号がどこにも見あたらない。 仕方がないので強引に割り出すことにする。 手順としては、 ・まずアステロイドに行き0x19番地にon readでブレイクポイントを仕掛け、ブレイクした箇所を書き留める。 ・スターノイド出現の条件を満たしてから同様にブレイクポイントを仕掛け、さっきはブレイクしていなかった場所を探し、そこからプログラムを追いかける。 こんな感じ。 でヒットしたのが ADEA bit $19 <ここでブレイク ADEC bpl $AE0B ADEE bvc $AE0B ADF0 lda $4016 ADF3 pha ADF4 eor $B4 ADF6 and #$04 ADF8 adc #$FE ADFA pla ADFB sta $B4 ADFD bcc $AE0B ADFF lda #$3C AE01 sta $B5 AE03 inc $b6 AE05 lda $B6 AE07 cmp #$20 AE09 bcs $AE15 AE0B lda $B5 AE0D bne $AE12 AE0F sta $B6 AE11 rts AE12 dec $B5 AE14 rts ここで一瞬最初の三行が意味不明だったんだけど、 bit命令はネガティブフラグにbit7を、オーバーフローフラグにbit6を代入するという働きがあるので、 ABボタンを押していた場合の値"0xC0"のときは、両方のフラグが真になるので、 下二行の分岐命令では分岐しないということになる(上手いプログラムだなぁ)。 ということで、このルーチンがスターノイドの呼び出し条件である可能性は極めて高い。 問題はその次。0x4016番地なんてアドレスは聞いたことがない。 メインメモリは0x0000~0x07FF、拡張メモリは0x6000~なのでどっちにも当てはまらない。 とここでもしやと思い、マイク入力の有無でプログラムの動作を比較してみると、 ・マイクon→0xADFD番地の分岐をスルー ・マイクoff→0xADFD番地で分岐 と見事にヒット。どうも0x4016番地というのはマイクのI/Oアドレスのようだ(他のゲームでも確認してみたが共通していた)。 というわけで、0xADFD番地の分岐をスルーするために、0xADF6番地を"and #$04"(29 04)を"lda #$04"(A9 04)に書き換える。 この状態でエネルギーを減らしてコントローラ2のABを押してみると、見事スターノイドが出現。目的達成となりました。 プロアクションロッキー用コード スターノイド呼び出しにマイク不要 A6ABE522