SNES プログラム改造のテクニック

テクニックというほどでもないですが、どうやら定番らしいので書いておきます。プログラムの改造をするにあたって、存在しているコードの一部を変更することになるわけですが、コードを追加する場合は後ろに十分な空きがないと追加できません。ところが、大抵はすきまなくプログラムが並べられているのでまず難しいです。こういう場合は、新しくSR(サブルーチン)を余裕がある場所に定義して処理をいったんそこに飛ばしてしまうのがいいです。

例)Lv40以上の賢者の場合は消費MPを3/4にする。

変更前

  • SR: $02B44A 消費MP計算
02B4A4 JSR $B4C1 $02B4C1 不思議なぼうし装備時の消費MP計算
02B4A7 JSR $B4DD $02B4DD 不思議なボレロ装備時の消費MP計算

変更後

  • SR: $02B44A 消費MP計算
02B4A4 JSR $D347 $02D347 条件によるMP調整
02B4A7 NOP つめないでEAで埋める
02B4A8 NOP つめないでEAで埋める
02B4A9 NOP つめないでEAで埋める
  • SR: $02D347 条件によるMP調整(新SR)
02D347 JSR $D351 $02D351 賢者がLv40以上の消費MP計算
02D34A JSR $B4C1 $02B4C1 不思議なぼうし装備時の消費MP計算
02D34D JSR $B4DD $02B4DD 不思議なボレロ装備時の消費MP計算
02D350 RTS Return
  • SR: $02D351 賢者がLv40以上の消費MP計算(新SR)
02D351 JSR $C46951
02D358 CMP #$0007
02D35B

※この部分の実装はこれでは未完です。

このようにすることで、容量を気にせずコードが書けます。もともとの場所に$EA(=NOP)を入れて埋めていますが、これはコードサイズを変えないようにするためです。65816の分岐命令は「その地点から前後XXバイトに飛べ」というものなので、空いているからといってつめてしまうとこれらの分岐命令のジャンプが正しくできなくなってバグの元になります。それも書き換えれば埋めてもいいですが、余計な手間ですよね。いまのところこの方法で問題なく動いてるみたいです。

※コード部分の見やすい書き方を模索中です。アドバイスあればお願いします。