裏CHUNSOFT > ゲーム解析入門 > 1.読み込みと書き込み

1.読み込みと書き込み

まずは簡単なプログラムから見ていきましょう。 現在のフロアを取得して、$00にその値を入れるというだけのルーチンです。

062771  08           PHP                ; "P"をスタックにプッシュ
062772  E2 20        SEP #$20           ; "A"のサイズを1バイトにする
062774  AF F2 D5 7E  LDA $7ED5F2        ; "A"={7ED5F2}(現在のフロア)
062778  85 00        STA $00            ; {7E0000}="A"
06277A  28           PLP                ; "P"にスタックからプル
06277B  6B           RTL                ; 元の命令へ(JSLに対して)

PHPとPLPは、元のルーチンからこのルーチンにジャンプした時点でのフラグの内容を待避させておくということで、殆どのサブルーチンで、先頭と元のルーチンに戻る直前に決まり文句のように使われます。 このルーチンでは"A"のサイズを1バイトにしていますが、元のルーチンでは1バイトなのか2バイトなのか分からないので、それをスタックにプッシュしておき、元のルーチンに戻る直前にプルして戻すようになっているのです。

SEP #$20は命令一覧に書いた通り、"A"のサイズを1バイトにするということです。 $7ED5F2はメモリリストにある通り、現在のフロア数を示します。 LDAはメモリの値を"A"に読み込む、STAはメモリに"A"の値を書き込むということです。

$00は詳しく言うと、基礎知識に書いた通り、引数が1バイトなので上位1バイトは00、下位2バイトは基点"D"の値0000に00を加えて0000、従って$000000、すなわち$7E0000に書き込むということです。 しかし、"D"は0000以外になっているのを私は見たことがありません。 また、$000000〜$001FFFは$7E0000〜$7E1FFFと同じなので、普通は$XXとあるとそれは$7E00XXと考えて差し支えありません。

RTLは3バイト指定してジャンプするJSL命令に対して、元のルーチンに戻る命令です。 つまり、このルーチンはどこからでも呼び出せる、JSL命令で呼び出さなければならない命令ということです。

続いて2バイト読み込むプログラムを見てみましょう。 $00,$01に町における初期X座標、Y座標を入れるルーチンです。

0627B2  08           PHP                ; "P"をスタックにプッシュ
0627B3  C2 20        REP #$20           ; "A"のサイズを2バイトにする
0627B5  AF F0 D5 7E  LDA $7ED5F0        ; "A"={7ED5F0}
0627B9  85 00        STA $00            ; {7E0000}="A"
0627BB  28           PLP                ; "P"にスタックからプル
0627BC  6B           RTL                ; 元の命令へ(JSLに対して)

$7ED5F0は町における初期X座標、$7ED5F1は町における初期Y座標です。 なので、3行目で"A"の下位バイトにX座標が、上位バイトにY座標が入ることになります。 書き込みもやはり2バイトなので、4行目で$00={7E0000}に"A"の下位バイトすなわちX座標が、$01={7E0001}に"A"の上位バイトすなわちY座標が入ります。

既にお気付きだと思いますが、高級言語では普通はX座標とY座標の変数は別々に定義しますが、アセンブリではこのように、連続する1バイトのデータ2つを2バイトのデータ1つとして読み書きすることもできます。 その2つのデータが無関係でも構いません。 このルーチンもRTLで終わっているので、どこからでも呼び出せる、JSL命令で呼び出さなければならない命令です。

今度は配列の例を見てみましょう。 $00番目のイベント進行状況を取得して、$00にその値を入れるというルーチンです。

060512  08           PHP                ; "P"をスタックにプッシュ
060513  E2 30        SEP #$30           ; "A","X","Y"のサイズを1バイトにする
060515  A6 00        LDX $00            ; "X"={7E0000}
060517  BF 94 D2 7E  LDA $7ED294+"X"    ; "A"={7ED294+"X"}
06051B  85 00        STA $00            ; {7E0000}="A"
06051D  28           PLP                ; "P"にスタックからプル
06051E  6B           RTL                ; 元の命令へ(JSLに対して)

$7ED294以降にはイベント進行状況のデータが入っています。 $7ED294=(到達度)、$7ED295=(不明)、$7ED296=(不明)、$7ED297=(お竜イベント)、$7ED298=(ガイバライベント)、$7ED299=(座頭ケチイベント)、……といった具合です。 このルーチンでは7ED294に"X"の値を加えて、そのアドレスの値を読み込んでいます。

なので、例えばお竜イベントの進行状況を取得したい時は、LDA #$03,STA $00,JSL $C60512とすれば良いのです。 $7ED297から直接取得しても良いような気もしますが、任天堂公式のプログラム開発環境が非公開なのでよく分かりませんが、イベント進行状況の領域は後で決めたとか、何か事情があったのでしょう。 このルーチンもRTLで終わっているので、どこからでも呼び出せる、JSL命令で呼び出さなければならない命令です。

2010年3月28日更新

裏CHUNSOFT > ゲーム解析入門 > 1.読み込みと書き込み