さて、アイテム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以上に配置して問題なく使えるかを確認するべきなんでしょうが、他の箇所も相当変えているのでとりあえずオリジナルと差異なくプレイできるかを確認しようと思います。
コメント