DQ3 K.Mix アイテムID9ビット拡張作業3

袋の中身にアクセスするSRを自作します。基本的にはオリジナルで存在しているSR: $090717などとやっていることは同じなのですが、用途を限定化し袋の中身のアクセス専用にすることで不要な処理を飛ばし高速化するというのが主目的です。今回のケースでは扱う対象のデータが最長でも9bitであるため、3バイトに渡ってデータを操作する必要がないというのがかなり大きいです。

  • SR:$0406DA 指定位置のインデックスの袋のアイテムIDを取得する(X:インデックス)(新SR)
$0406DA PHX Push X
$0406DB PHY Push Y
$0406DC TXA A=X
$0406DD ASL A< <1
$0406DE ASL A< <1
$0406DF TAX X=A
$0406E0 LDA $D6F640,X A=$16F640+X
$0406E4 TAY Y=A
$0406E5 LDA $3725,Y A=$3725+Y
$0406E8 PHA Push A
$0406E9 LDA $D6F642,X A=$16F642+X
$0406ED TAY Y=A
$0406EE PLA Pull A
$0406EF CPY #$0000 Y==#$0000?
$0406F2 BEQ #$04 if(z==on) goto $0406F8
$0406F4 LSR A>>1
$0406F5 DEY Y–
$0406F6 BRA #$F7 goto $0406EF
$0406F8 AND #$01FF A&=#$01FF
$0406FB PLY Pull Y
$0406FC PLX Pull X
$0406FD RTS return
  • SR:$0406FE 指定位置のインデックスの袋のアイテム個数を取得する(特殊以外 X:インデックス A:アイテムID)(新SR)
$0406FE PHX Push X
$0406FF PHY Push Y
$040700 TXA A=X
$040701 ASL A< <1
$040702 ASL A< <1
$040703 TAX X=A
$040704 LDA $D6FAF0,X A=$16FAF0+X
$040708 TAY Y=A
$040709 LDA $3725,Y A=$3725+Y
$04070C PHA Push A
$04070D LDA $D6FAF2,X A=$16FAF2+X
$040711 TAY Y=A
$040712 PLA Pull A
$040713 CPY #$0000 Y==#$0000?
$040716 BEQ #$04 if(z==on) goto $04071C
$040718 LSR A>>1
$040719 DEY Y–
$04071A BRA #$F7 goto $040713
$04071C AND #$000F A&=#$000F
$04071F PLY Pull Y
$040720 PLX Pull X
$040721 RTS return

前提として袋の中身のデータの場所のオフセット(バイト、ビット)をインデックスとして別の場所に定義しておき、それを使うことで処理速度を一定にしています。変わるのはビットシフトの位置(最大7回)くらいです。値の変更は周辺のビットをXORして取って置かないといけないのでその分複雑になりますが、SR: $90717を使うよりはざっと半分くらいの長さになっているっぽいので多少マシと言う程度です。

DQ3では基本的に袋に複数のアイテムを一度に入れる経路は殆どありませんが、例外としてPCの所持アイテムを「どうぐせいり」で袋に入れる場合があります。12個x4人で最大48種類のアイテムが1回の操作で袋に追加される可能性があるわけですが、自分で実装した袋の自動整理機能がONになっていると笑っちゃうくらい時間がかかります(3-4秒?)。これは1個アイテムを入れるたびに袋の整理をする処理が実行されてしまうからなので、処理の前にいったん自動整理機能をOFFにしておき、袋に入れ終わった後で1回だけ自動整理をするというようにすることで回避します。

  • SR:$040919 道具整理(1人分) + 袋の中の整理を最後に行う(新SR)
$040919 PHA Push A
$04091A PHX Push X
$04091B PHY Push Y
$04091C PEA #$35BE Push #$35BE
$04091F PEA #$000C Push #$000C
$040922 PEA #$7E00 Push #$7E00
$040925 JSL $C9029E SR: $09029E RAM上情報取得 現在の袋自動整理状態を取得して保存しておく
$040929 PHA Push A
$04092A LDA #$0000 A=#$0000 袋自動整理しないにいったんセットする
$04092D PEA #$35BE Push #$35BE
$040930 PEA #$000C Push #$000C
$040933 PEA #$7E00 Push #$7E00
$040936 JSL $C902E9 SR: $0902E9 RAM上情報変更
$04093A JSL $C3BD17 SR: $03BD17 道具整理(一人分)
$04093E LDA $01,S A=Stack($01)
$040940 CMP #$0000 A==#$0000? キープしていた袋自動整理設定値を見る
$040943 BEQ #$0F if(z==on) goto $040954
$040945 CMP #$0001 A==#$0001?
$040948 BNE #$06 if(z==off) goto $040950
$04094A JSL $C4012F SR: $04012F 袋のアイテムを種類順にソート(2バイト化対応)
$04094E BRA #$04 goto $040954
$040950 JSL $C40193 SR: $040193 袋のアイテムをあいうえお順にソート(2バイト化対応)
$040954 PLA Pull A
$040955 PEA #$35BE Push #$35BE
$040958 PEA #$000C Push #$000C
$04095B PEA #$7E00 Push #$7E00
$04095E JSL $C902E9 SR: $0902E9 RAM上情報変更 設定値をリストア
$040962 PLY Pull Y
$040963 PLX Pull X
$040964 PLA Pull A
$040965 RTL return
  • SR:$040969 道具整理(全員分) + 袋の中の整理を最後に行う(新SR)
$040969 PHA Push A
$04096A PHX Push X
$04096B PHY Push Y
$04096C PEA #$35BE Push #$35BE
$04096F PEA #$000C Push #$000C
$040972 PEA #$7E00 Push #$7E00
$040975 JSL $C9029E SR: $09029E
$040979 PHA Push A
$04097A LDA #$0000 A=#$0000
$04097D PEA #$35BE Push #$35BE
$040980 PEA #$000C Push #$000C
$040983 PEA #$7E00 Push #$7E00
$040986 JSL $C902E9 SR: $0902E9
$04098A JSL $C5DF7D SR: $05DF7D
$04098E DEC A–
$04098F BMI #$0C if(n==on) goto $04099D
$040991 PHA Push A
$040992 JSL $C5E0D9 SR: $05E0D9
$040996 JSL $C3BD17 SR: $03BD17
$04099A PLA Pull A
$04099B BRA #$F1 goto $04098E
$04099D LDA $01,S A=Stack($01)
$04099F CMP #$0000 A==#$0000?
$0409A2 BEQ #$0F if(z==on) goto $0409B3
$0409A4 CMP #$0001 A==#$0001?
$0409A7 BNE #$06 if(z==off) goto $0409AF
$0409A9 JSL $C4012F SR: $04012F
$0409AD BRA #$04 goto $0409B3
$0409AF JSL $C40193 SR: $040193
$0409B3 PLA Pull A
$0409B4 PEA #$35BE Push #$35BE
$0409B7 PEA #$000C Push #$000C
$0409BA PEA #$7E00 Push #$7E00
$0409BD JSL $C902E9 SR: $0902E9
$0409C1 PLY Pull Y
$0409C2 PLX Pull X
$0409C3 PLA Pull A
$0409C4 RTL return

これで極力余計な処理をしないことで速度の低下を防ぐことができます。