DQ6 Extended(拡張ベースパッチ)作成にあたっての考慮点4

一応しこしこと作業は続けていて、ようやく一番の難関と思われた「アイテムの9bit化」が大体終わりました。これによりアイテムをあと128個定義できるようになります。さすがに作業とエントリの更新を同時にやるのは無理ということがわかったのでエントリの投下はしばらく後回しにしています。また、すでに終わっていると思っていた「モンスターの9bit化」はこの作業の途中で8bitだった部分があったのを見つけたので、アイテムの9bit化についてもまだ完全に終わっているとは思えませんが、見つけ次第順次潰していくことにします。作業の進行度合いとしてはようやく作業がひと通り終わったのでこれからテストプレイをするところです。気になるのは仲間の数を増やすことを視野に入れた変更で、職業熟練度と呪文特技習得状態の情報を一応空いていると思われる場所のメモリを見つけてそこに割り当てたのですがそこが果たして本当に使われていないかどうかが確信が持てないことです。こまめに情報が書き換わっていないかチェックをしながらのテストプレイになりそうです。

さて、アイテム9bit化に際して、ここしばらくやっていたのは以下のような作業でした。

  • SR: $04584C 袋にアイテム追加
04584C CLC c=off
04584D PHP Push P Flag
04584E PHB Push DB
04584F SEI i=on
045850 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
045852 PHA Push A
045853 PHX Push X
045854 PHY Push Y
045855 SEP #$30 m=on(A/M:8b) x=on(X/Y:8b)
045857 LDY #$01 Y=#$01
045859 JSL $C426CB SR: $0426CB 引数をYバイト取得
04585D LDA #$7E A=#$7E
04585F PHA Push A
045860 PLB Pull DB
045861 LDA $4898 A=$4898
045864 JSL $C426E0 SR: $0426E0 引数解釈
045868 CMP #$00 A==#$00? アイテムIDが0なら何もしない
04586A BEQ #$0C if(z==on) goto $045878
04586C TAX X=A
04586D LDA $3F0A,X A=$3F0A+X
045870 CMP #$63 A>=#$63? 袋の中のアイテム数を99個でクリップする
045872 BCS #$09 if(c==on) goto $04587D
045874 INC A++
045875 STA $3F0A,X $3F0A+X=A
045878 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
04587A BRL #$DC2A goto $0434A7
04587D LDA $08,S A=Stack($08)
04587F ORA #$01 Aor=#$01
045881 STA $08,S Stack($08)=A
045883 BRA #$F3 goto $045878

このSRは引数の場所の値(FF:Aレジスタ、FE:Xレジスタ、FD:Yレジスタ、それ以外DP(XX))をアイテムIDとして取得しアイテムID-1の箇所の数値を1増やす(99でクリップ)する、というものです。問題の箇所は$045868~$045875のあたりで、M,XフラグがONになっているために$045868でAレジスタにセットした値、$04586CでXレジスタにセットした値が1バイトでしか扱われないというものです。アイテム数を255以上にするためにはこの部分を2バイト化する必要があります。

  • SR: $04584C 袋にアイテム追加(2バイト化後)
04584C CLC c=off
04584D PHP Push P Flag
04584E PHB Push DB
04584F SEI i=on
045850 REP #$30 m=off(A/M:16b) x=off(X/Y:16b)
045852 PHA Push A
045853 PHX Push X
045854 PHY Push Y
045855 LDY #$0001 Y=#$0001
045858 JSL $C426CB SR: $0426CB 引数をYバイト取得
04585C LDA #$7E7E A=#$7E7E
04585F PHA Push A
045860 PLB Pull DB
045861 PLB Pull DB
045862 LDA $4898 A=$4898 引数解釈
045865 AND #$00FF A&=#$00FF
045868 JSL $C426E0 SR: $0426E0
04586C CMP #$0000 A==#$0000?
04586F BEQ #$05 if(z==on) goto $045876
045871 JSR $FEDC SR: $04FEDC アイテム数を増やす(99個でクリップ)
045874 BCS #$03 if(c==on) goto $045879
045876 JMP $34A7 ($0434A7) goto $0434A7
045879 JMP $FED2 ($04FED2) goto $04FED2
04FED2 LDA $08,S A=Stack($08)
04FED4 ORA #$0001 Aor=#$0001
04FED7 STA $08,S Stack($08)=A
04FED9 JMP $34A7 ($0434A7) goto $0434A7
  • SR: $04FEDC 袋のアイテム数を増やす(99個でクリップ)
04FEDC TAX X=A
04FEDD LDA $2E7F,X A=$2E7F+X 袋のアイテム情報は7E2E80-に移動
04FEE0 AND #$00FF A&=#$00FF
04FEE3 CMP #$0063 A>=#$0063?
04FEE6 BCS #$05 if(c==on) goto $04FEED
04FEE8 INC $2E7F,X $2E7F+X++
04FEEB CLC c=off
04FEEC RTS return
04FEED SEC c=on
04FEEE RTS return

個々の箇所でやることは大したことはないのですが、M,XフラグがOFFになると定数を取るニーモニックのサイズも2バイトから3バイトに変わるため、単純により多くの領域が必要になります。当然ながら周囲は隙間なく他のSRが並べられているため、サイズを増やすことはできません。さらにSR自体が引数をとっているのでPC(プログラムカウンタ)を操作していたりする都合上、安易に別SRを定義して呼ぶのは危険だったりして、やむを得ずJMPを使って別の場所に飛ばして処理を行った後同じSRに戻すというかなり汚い処理をする必要があったりもします。また、オリジナルではLDAなどで得られる結果は1バイトだけだったのが、M,XフラグがOFFになっていると2バイト取ってきてしまうため、ANDで下位1バイトだけマスクしたりする作業も必要になってきます(主に引数の値の取得など)。全部が全部2バイト化する必要がなかったりするので、個々のSRについて2バイト化の必要があるかを検討する必要があり、さらにそのSRが何をやっているのかを理解しないといけないということで結構しんどい作業だったことは確かです。袋のアイテム操作は比較的簡単でしたが各キャラクターのアイテム操作はさらに複雑でコードも領域の都合上かなりグチャグチャになっているので、ここで解説する気にはなりません。正直この作業中何度も「何やってるんだろ」と思ったりもしましたが、一応ひと通りテストも終わったのでバグがなければいいなあというのが希望的観測です。まじめに言えばテストプレイの時には一部のアイテムをID#$100以上に配置して問題なく使えるかを確認するべきなんでしょうが、他の箇所も相当変えているのでとりあえずオリジナルと差異なくプレイできるかを確認しようと思います。