基礎知識
戦闘関係
このページには、1ページにまとめるほどではない小ネタ、本編に関係ない没データのネタ、調査中のネタ、または調査してみたが筆者の力不足である程度までしかわからなかったことを掲載しておく。
随時変更予定。
最終編で最初に飛ばされる真っ暗な異次元空間について。
ここは真っ暗で、どちらに進んでも行き止まりがない。
最終編のカウンターのアドレス$00:11F0には、異空間での歩数の値が入る。
初期値は$00で、$32(10進数50)以上だと背景(各シナリオの一部分)が表示されるようになり、$64(10進数100)まで増加すると階段が出現する。
各マップは左上隅を座標(X,Y) = ($00,$00)として、味方キャラ1人目(主人公)のいる座標が(X,Y)=($00:0A21,$00:0A29)に入るが、異次元空間に飛ばされた時点での座標は、(X,Y)=($09,$1A)【※10進数(9,26)】である。
座標からもわかるのだが、この空間はX方向が0~31、Yが0~63まであり、Xが31の時に更に右に移動すると0に戻るし、Yが63の時に更に下に移動すると0に戻るため、
「横32マス、縦64マスのマップが上下左右に無限ループ」
している空間である。
このため、上下左右がうまく繋がるよう、50マス以上移動時の背景画像が作られている。
100マス移動すると階段が出現するが、階段出現位置は100マス移動した時の主人公の座標で決まるので、マップ上で固定ではないことになる。
ヘッドプラッカーが出現する時の異次元空間だが、ヘッドプラッカーの座標は(X,Y) = ($00:13CC, $00:13CE)である。
このアドレスはヘッドプラッカーで固定ではなく、$00:1300~あたりにはマップ上のキャラクター(敵シンボルも、普通の街の人なども含む)の座標などが入っていて、異次元空間ではヘッドプラッカーの座標が入るアドレスである。
初期位置は($00:13CC, $00:13CE) = ($00,$00)である。
つまりヘッドプラッカー初期位置は、異次元空間マップの原点位置になる。
図で示すと以下の通りになる。
ヘッドプラッカーは主人公たちの座標へ向けて移動していく。
移動速度はおそらく味方キャラの歩行速度の1/2である。
つまり、ヘッドプラッカーが1マス移動する間に、味方は歩行だと2マス、ダッシュだと4マス、おぼろ丸のダッシュだと8マス移動できる。
おぼろ丸の場合は上にひたすら上へダッシュ移動でも、100マス移動時にヘッドプラッカーに接触せず階段が出現して脱出できるが、他キャラの場合はただ上ダッシュしているだけだと100マス移動前にヘッドプラッカーに遭遇する。
というのは、異次元空間に入ってからすぐ上にダッシュ移動し続けた場合、下図のようになってしまうのである。
味方キャラのダッシュ速度だと、ちょうど異次元空間を1周+10~16マス(75~80マス移動)くらいのあたりで、原点位置から移動してきたヘッドプラッカーに接触してしまうのである。
(ヘッドプラッカーの移動は上図とは必ずしも一致しない。右移動と下移動を繰り返してだいたい上くらいの位置で味方キャラに接触する)
ちなみに階段出現後は、階段を障害物とすることでヘッドプラッカーの移動を阻止することも可能。
世界の合言葉は森部様の「その他メモ」の最後の方に、以下のように書かれている。
敵には戦闘開始時の行動異常や状態異常が設定できるようになっているけど、
実質誰も設定されていません。王様は設定の片鱗があるけど。
これは敵データ27~28のことである。
敵データは、1体につき0~31の32バイト分の容量があるのだが、敵データ27~28の2バイトはゲームでは実際に使われていないし、値もほとんどが$00で埋まっている。
ただし、中世編にてルクレチア城で出現する偽魔王にだけ、敵データ27に「$20」という値が入っている。
戦闘開始時、敵データ28の読み込みは行われるのだが、「敵データ28と$F0で論理積をとってゼロフラグが立つ時のみ$C1/FCD4分岐」という処理があり、敵データ28がどの敵も必ず$00なので、$C1/FCD4に分岐することは絶対にない。
その、飛ばないはずの処理$C1/FCD4~を見てみると、敵データ27を状態異常にセットするサブルーチンになっているようである。敵データ28は状態異常継続時間を計算するための値になっている。
つまり$C1/FCD4~が戦闘開始時の状態異常発生処理なのだが、どの敵も「発生する状態異常継続時間 = 敵データ28 = 0」だから処理されない。
ゲーム本編では実質、没設定ということになる。
では、偽魔王に設定されている、敵データ27の$20は何の状態異常なのか。
状態異常は8種類あるが(隠し設定の首かため含む)、8種類の状態異常のON・OFFを、2進数8桁の1・0で表している。
2進数8桁を16進数2桁に変換した値が、敵データ27に入っているのである。
16進数$20は、2進数だと%0010 0000である。
2進数表記の時、各桁は以下のように各状態異常に対応している。
| 2進法の位 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |
|---|---|---|---|---|---|---|---|---|
| 状態異常 | 石化 | 酔い | 眠り | マヒ | 毒 | 腕かため | 足かため | 首かため |
「$20(%0010 0000)」だと、眠り状態にのみフラグが立っていることになる。
つまり偽魔王との戦闘開始時、偽魔王を眠り状態にするつもりがあったらしいのだが、実際のゲームでは採用されずに終わった、ということのようだ。
※偽魔王はルクレチア王が姿を変えられたというのが一般的な解釈だが、小学館のSFC版攻略本には偽魔王について「王を殺した犯人で、オルステッドを罠にはめるための影武者」と解説しており、ルクレチア王ではない、という解釈である。もしゲームでも眠り状態で戦闘開始になっていたら、「ルクレチア王は魔王の姿に変えられた上で玉座で眠っていた(眠らされていた?)」という解釈の方が自然であっただろう。
装備品による開戦時行動異常(特定の装備品を装備していると、戦闘開始時に特定種族の敵に一定確率で行動異常を発生させる)は実際にゲームでも発生するが、これも戦闘開始時の行動異常や状態異常のネタのひとつとして考案されていたものかもしれない。
余談ではあるが、没になったサブルーチンの処理をざっと追いかけてみた。
;X:1B00 Y:1A00とする(敵種類1、敵番号0) ; $C1/FCC7 LDA $003C,y[$00:1A3C] ;Aに[$00:1A3C](敵データ28)をロード $C1/FCCA BIT #$F0 ;Aと$F0で論理積(ステータスフラグのみ変更) $C1/FCCC BNE $06 [$FCD4] ;ゼロフラグが立っていないとき[$FCD4]分岐 ; ;どの敵も敵データ28は$00なので、この先の処理がゲームで行われることはない $C1/FCD4 ORA #$0F ;A(敵データ28)と$0Fで論理和 $C1/FCD6 STA $10 [$00:0310] ;Aを[$00:0310]に書き込み $C1/FCD8 LDA $003B,y[$00:1A3B] ;Aに[$00:1A3B](敵データ27)をロード $C1/FCDB STA $7E8F07,x[$7E:AA07] ;Aを[$7E:AA07](敵番号0 状態異常)に書き込み $C1/FCDF STA $12 [$00:0312] ;Aを[$00:0312]に書き込み $C1/FCE1 LDA $003C,y[$00:1A3C] ;Aに[$00:1A3C](敵データ28)をロード $C1/FCE4 AND #$0F ;Aと$0Fで論理積 $C1/FCE6 BEQ $09 [$FCF1] ;ゼロフラグが立っているとき[$FCF1]分岐 $C1/FCE8 ASL A ;Aを算術左シフト *2 $C1/FCE9 ASL A ;Aを算術左シフト *2 $C1/FCEA ASL A ;Aを算術左シフト *2 $C1/FCEB ASL A ;Aを算術左シフト *2 $C1/FCEC STA $11 [$00:0311] ;Aを[$00:0311]に書き込み = 敵データ28 & $0F * $10 $C1/FCEE JSR $35C4 [$C1:35C4] ;[$C1:35C4]へジャンプ ; $C1/35C4 PHX ;Xレジスタをスタックへプッシュ $C1/35C5 LDA #$08 ;Aに$08をロード $C1/35C7 STA $09 [$00:0309] ;Aを[$00:0309]に書き込み(ループ回数$08を[$00:0309]にセット) ; ;ループ処理ここから $C1/35C7 STA $09 [$00:0309] ;[$00:0312]を論理右シフト(/2) $C1/35C9 LSR $12 [$00:0312] ;キャリーフラグが立っていないとき[$35E3]分岐 $C1/35CB BCC $16 [$35E3] ;(CフラグONの処理)[$C1:6150]へジャンプ ;([$C1:6150]~[$C1/61A4] 戦闘乱数生成サブルーチン処理、乱数がAと[$00:033B]に入る) $C1/35D0 CMP $10 [$00:0310] ;A(乱数$00~$FF)と[$00:0310](敵データ28 & $0F)を減算比較(ステータスフラグ変更のみ) $C1/35D2 BCS $0F [$35E3] ;キャリーフラグが立っているとき[$35E3]分岐 $C1/35D4 LDA $11 [$00:0311] ;(CフラグONの処理)Aに[$00:0311](敵データ28 & $0F * $10)をロード $C1/35D6 CLC ;キャリーフラグクリア $C1/35D7 ADC $7E8F08,x[$7E:AA08] ;A + [$7E8F08,x]([$7E:AA08]~[$7E:$AA0F]、首/足/腕/毒/マヒ/眠/酔/石 継続時間) $C1/35DB BCC $02 [$35DF] ;キャリーフラグが立っていないとき[$35DF]分岐 $C1/35DD LDA #$FF ;Aに$FFをロード $C1/35DF STA $7E8F08,x[$7E:AA08] ;Aを[$7E8F08,x]([$7E:AA08]~[$7E:$AA0F])に書き込み $C1/35E3 INX ;($C1/35CBと$C1/35D2のCフラグOFFの飛び先)Xをインクリメント +1 $C1/35E4 DEC $09 [$00:0309] ;[$00:0309](ループ回数)をデクリメント -1 $C1/35E6 BNE $E1 [$35C9] ;ゼロフラグが立っていないとき[$35C9]分岐 ;ループ処理ここまで ; $C1/35E8 PLX ;Xレジスタに値をプル $C1/35E9 RTS ;サブルーチン戻り
長々と書いたが、
$C1/FCD8 LDA $003B,y[$00:1A3B] ;Aに[$00:1A3B](敵データ27)をロード $C1/FCDB STA $7E8F07,x[$7E:AA07] ;Aを[$7E:AA07](敵番号0 状態異常)に書き込み
結論はここである。
敵データ27がそのまま敵の状態異常がセットされるアドレスに書き込まれている。
ただ、$C1/FCD8は、$C1/FCD4以降の処理なので、実際のゲームでは読み込まれないことになる。
敵データ28から、状態異常継続時間を設定するサブルーチンもきちんと組まれている。
$C1/FCE1~が該当し、敵データ28の上1桁が状態異常発生判定用の数値、下1桁で状態異常発生時間を計算するようだ。
状態異常が格納された敵データ27を、8ビットで下の位から順に8回分、ループ処理で値が入っているか判定し、もし値が入っているのなら、戦闘乱数$00~$FFを生成して、乱数 - (敵データ28 & $0F)(※&は論理積)を計算する。
敵データ28 & $0Fは、$01~$0Fのいずれかの数のはずである。
このため、戦闘乱数$00~$FFから$01~$0Fを減算することになる。乱数が$0F以上なら、敵データ28の値に関係なく、減算結果が必ず0以上になる。
この分岐を見る限り、かなりの高確率で状態異常が発生する処理のようだ。
上の戦闘開始時状態異常もそうだが、本作のプログラムを見ると、設定はしたが本編では没になったデータや処理があるようだ。デバッグ用と思しきテキストもある。
没アイテムなどはSFC版攻略本にまで掲載されているし、最終編でサモに与えるアイテムの中に「満腹度が減るアイテム」があるが実際のゲームでは没になったことまでSFC版攻略本には書かれている。
とはいえ、それら没ネタは、本作にきちんと関係したもので、諸事情で採用されずに終わったのだろうということが察せられる。
システム関連のテキストデータは、$D6:AC00~$D6:CFFFの領域に入っており、本作の文字データの法則に則りデコード(復元)できる。
(文字データを参照)
技名、敵の名前、アイテム名、メニュー画面用のテキストなどは、没ネタも含めてだいたいこの領域に入っている。
例外として現代編のセリフもだいたいここに入っている。
没ネタにしても本作に無関係のものは(ほぼ)ない。
ところが最後の方のデータを見てみると……?
1D C5 1E D5 1E 77 B0 CE B3 CC C2 C4 BB BE D9
67 91 68 00 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F
3F 3F 3F 00 20 20 20 20 20 4B 49 4C 4C 20 59 4F
55 3D 3D 00 70 6A ED DE C5 B2
↓デコード(00で改行)
古代神をほうふつとさせるキック
???????????????
KILL YOU‥‥
タコじゃない
順に、
であるが、最後は明らかに没テキストの上、本作で登場する場面があったとは思えない謎テキストである。
テスト用の何かなのか、お遊びで入れたのか、はたまた没になったタコっぽいキャラでもいたのか、謎のままである。
「タコじゃない」といえば「ライブ・ア・ライブ」と同時期に発売の「ファイナルファンタジー6」に登場した敵「オルトロス」が、タコっぽい見た目のためにゲーム内外でネタにされるが、こちらからのネタという可能性も一応はある。
上の「タコじゃない」はゲームとは関係なさそうな没テキストだが、他にも幾つか、面白そうなテキストがあるので紹介しておく。
中世編シナリオテキスト後あたりにデバッグ用らしきテキストがある。
おそらくデバッグ用テキストを呼び出して、指定すると実行できたのだろう。
それらサブルーチンが残っているのかや、実機で呼び出せるのかまでは筆者にはわからない。通常は実機では呼び出せないように処理されているはずである。
上はおそらく、原始編で特定の場所へ移動するためのデバッグコマンドだろう。
内部では各地域が「荒野」「狩猟場」という名称で設定されていたことがわかる。「敵部落」はざきたちクー族の集落のことだろう。
他にも「エンカウント オフ?」などのテキストも見られ、ランダムエンカウントのオンオフもデバッグで行えたようだ。
「功夫の伝承者は?」でユン・レイ・サモを選べるらしきテキストもあり、功夫編や最終編のデバッグに使用したものと思われる。
7A 40 8A 40 C9 1E E6 5B B2 C2 B6 D7 F1 3F 02 20
17 E7 20 71 8D A7 87 C9 01 20
1E 3F 1E E2 C6 C5 D8 BB E7 E1 C0 C9 CA 07
↓デコード(00で改行)
ハーレーの男「いつからだ?
$17が チンピラの
集団になりさがったのは‥‥
近未来編冒頭のクルセイダーズ襲撃時、無法松がやってきた時にクルセイダーの「誰だッ?」というセリフの直後に上のテキストが入っている。
上のデコード前テキスト2行目の「17 E7 20」が「$17が 」の部分なのだが、$17は戦闘中なら数字の「7」で、これでは意味が通じない。
本作では、セリフで多用される単語(キャラ名など)は容量節約のために定型テキストとして登録されており、フィールドにおけるテキストでは「$17」は「クルセイダーズ」になる。
ということで、上テキストは、
ハーレーの男「いつからだ?
クルセイダーズが チンピラの
集団になりさがったのは‥‥
である。
SFC版ではこの無法松のセリフは未使用となったが、リメイク版では使われている。
(リメイク版だと、「いつからだ? クルセイダーズが チンピラ集団に成り下がったのは…?」と、細部が異なるがほぼ同じである)
SFC版でなぜ未使用となったのか、どうしてリメイク版で復活させたのか、そのあたりはわからない。
上のセリフが冒頭で使われると、無法松とクルセイダーズは現在は敵対しているが、何かしら繋がりがある(あった)ことが察せられることになる。
近未来編開始早々に情報過多にならないように削ったのか、それとも先の展開をあまり匂わせすぎないようにしたか……といったところなのだろうか。
ちなみにフィールドにおける定型テキストは以下の通り。どこで使われるものかは本作をプレイしていればだいたいわかるだろう。
名前の後にカッコがついているものがあるが、セリフの冒頭用と思われる。
| ID | 定型テキスト |
|---|---|
| $02 | 兵士「 |
| $03 | アリシア |
| $04 | レイチェル |
| $05 | コンピュータ |
| $06 | 伍長 |
| $07 | カトゥー |
| $08 | ヒューイ |
| $09 | 船長 |
| $0A | 老師様 |
| $0B | お師匠 |
| $0C | 少年「 |
| $0D | ならず者「 |
| $0E | ビリー「 |
| $0F | マスター「 |
| $10 | アニー「 |
| $11 | ・キッド |
| $12 | 保安官 |
| $13 | 液体人間 |
| $14 | 妙子 |
| $15 | 無法松 |
| $16 | 藤兵衛 |
| $17 | クルセイダーズ |
没になったテキストはいくつかあるが、ここでは最終編のダンジョン関係のテキストを紹介する。
最終編、知のダンジョンにおける「キューブの知」のセリフの後に、各ダンジョン用のテキストがある。
以下、力のダンジョン入口のアポフィスフィオのセリフ以外は没テキストになっている。
わかりやすいようにダンジョン毎に区切って以下に掲載する。
ここは「本能」のダンジョン‥‥
強い野性を持つものだけが
この入り口を通り抜けられる‥‥
ここは「技」ダンジョン‥‥
優れた技を持つ者は
より早く 優れた力を
手に入れられるだろう。
ここは「時」のダンジョン‥‥
時の流れの中では すべてが
限りあるものだ‥‥
この先は「力」のダンジョン‥‥
最強の力きわめたくば
腕ずくで道をひらいてみろ!
($16)の心に
誰かが かたりかけてくる‥‥
「心」のダンジョンへ よく
来てくれました‥‥
あなたをここへ いざなったのは
私達です‥‥
ここは「鍵」のダンジョン‥‥
奥へすすむには 多くの小さい鍵と
4つの大きな鍵が必要だ‥‥
『ここは「技」ダンジョン』の部分は、「の」が抜けているようだ。
元は
07 BA BA CA 5B 1D 77 5C A1 8D 9D 90 8D
で、「の」にあたる「C9」がない。
文字数オーバーで入らなかったということはなさそうだから、脱字と思われる。
ゲーム内では採用されなかったので問題にはならなかったが。
『($16)の心に』の部分だが「16 C9 1E 72 C6」であり、ここで最初の「16」に入るのは近未来編主人公の名前になる(プレイヤーがつけた名前)。
「アキラ」なら「アキラの心に」となる。
以上のテキストから、開発中は各ダンジョンについてそれなりに説明するつもりがあったのではないか、ということがわかる。
技のダンジョンだったら、比較的高レベルに配置されている「老狐の舞」で最後の岩を破壊できることが、「優れた技を持つ者はより早く 優れた力を手に入れられるだろう。」につながっているのかもしれない。
鍵のダンジョンのヒントは、ぜひ欲しかったところである。探索すればどうにかなるダンジョンではあるが……。
心のダンジョンのセリフはアリシアによるものという想定だろうか。
心のダンジョン内ではゲームでもアリシアの心の声「お願いです‥‥止めてください‥‥オルステッドを‥‥」が聞けるが、合わせて考えると、アリシアはアキラを通して主人公たちに呼びかけ、オルステッドを止めて欲しいと頼みたかった、ということになるのだろうか。
バンク$C1(バンク$41のミラーリング)は、$C1:0000~$C1:FDA5と、アドレスの大半に戦闘中のサブルーチンが入っている。
残りの$C1:FDA6~$C1:FFFFの$0259バイト(601バイト)に、戦闘中のテキストが格納されている。
戦闘で頻繁に使うテキストを戦闘用プログラムのサブルーチン近くに置いて、呼び出しにかかる時間や負担を減らしたのかもしれない。
内容は戦闘コマンドや画面上部表示用テキストだが、中にはデバッグ用と思われるエラー表示用テキストも残されている。
以下、「n」は任意の文字列。
| 内容 | 表示 |
|---|---|
| 戦闘コマンド(1) | 戦う パス アイテムを使う 逃げる |
| 戦闘コマンド(2) | 戦う パス アイテムを使う やめる |
| 戦闘コマンド(3) | 戦う パス アイテムを使う テレポート |
| 戦闘コマンド(4) | 戦う パス アイテムを使う ハルマゲドン |
| 戦闘コマンド用メッセージ | 今は使えません 反撃技です 使えないアイテムです 指定可能マスがありません 1回だけ使えます |
| 勝利時表示 | はレベルnになった nを覚えた nを入手 勝利ッ! 敗北‥‥ 逃亡‥‥ |
| 毒の状態異常ダメージ | 毒のダメージ |
| フィールドダメージ発動 | 水フィールドのダメージ 毒フィールドのダメージ 火炎フィールドのダメージ 電撃フィールドのダメージ |
| 功夫編修行戦闘終了時セリフ | 老師『これまでじゃ! 老師『不覚をとったわ! |
| 功夫編戦闘終了時 | nを修得 修業により素早さが5UP 修業により力が5UP 修業により体力が5UP |
| BREAKDOWNで勝利時 | BREAK DOWN |
| ハルマゲドンコマンド | ハルマゲドン |
| 反撃技発動時 | n:反撃 |
| 最終編オルステッド主人公 技説明 | ???????????????? |
| デバッグコマンド系? | BGナンバーエラー 裏表 サイズ 数 NO 逆転 アニメ LRで抜け |
功夫編で、修行が「修業」表記になっているのはこの戦闘終了時表記だけである。
リメイク版では「修業」で統一された。
デバッグらしきメッセージだが、どんな意味か、だいたい察しはつく。
BGナンバーエラーは「バックグラウンドナンバーエラー」、つまり戦闘背景のエラーだろう。
「裏表」は敵か味方の表示を裏側にする(上向き)とか、「サイズ」は敵サイズ、「数」は敵の数(か、敵味方トータルの数)、「NO」は何かしらのナンバリング、「逆転」は敵味方逆転の戦闘などの意味、「アニメ」は味方の動きのアニメーションか、技のアニメーションといったあたりだろう。おそらく。
そういったデバッグ用表示か、エラー表示の画面から抜ける(終了させる)ためのコマンドが、LボタンとRボタン同時押しであり、「LRで抜け」であろうと推測できる。
余談だが、テキスト直前、つまり最後の戦闘用サブルーチンは$C1/FD81~$C1/FDA5で、戦闘開始時に必ず処理が入る。
$C1/FD81 LDA $0A00 [$00:0A00] ;Aに[$00:0A00](シナリオID)をロード $C1/FD84 CMP #$08 ;Aと$08を減算比較(ステータスレジスタ変更のみ) $C1/FD86 BNE $17 [$FD9F] ;ゼロフラグが立っていないとき[$FD9F]分岐 ;ゼロフラグON 最終編 $C1/FD88 LDA $0A10 [$00:0A10] ;Aに[$00:0A10](最終編主人公)をロード $C1/FD8B BEQ $12 [$FD9F] ;ゼロフラグが立っているとき[$FD9F]分岐 ;ゼロフラグOFF 最終編オルステッド主人公以外 $C1/FD8D LDA $12FC [$00:12FC] ;Aに[$00:12FC](フラグ判定 ラスト7連戦)をロード $C1/FD90 BEQ $0D [$FD9F] ;ゼロフラグが立っているとき[$FD9F]分岐 ;ゼロフラグOFF ラスト7連戦 $C1/FD92 LDA $11F1 [$00:11F1] ;Aに[$00:11F1](異空間での歩数)をロード $C1/FD95 BNE $04 [$FD9B] ;ゼロフラグが立っていないとき[$FD9B]分岐 ;ゼロフラグON 異空間での歩数0 $C1/FD97 LDA #$FF ;Aに$FFをロード $C1/FD99 BRA $06 [$FDA1] ;フラグにかかわりなく常に分岐[$FDA1] ;ゼロフラグOFF 異空間での歩数1以上 $C1/FD9B LDA #$01 ;Aに$01をロード $C1/FD9D BRA $02 [$FDA1] ;フラグにかかわりなく常に分岐[$FDA1] ;最終編ラスト7連戦以外 $C1/FD9F LDA #$00 ;Aに$00をロード ;処理合流 $C1/FDA1 STA $7EFEFB[$7E:FEFB] ;Aを[$7E:FEFB]に書き込み $C1/FDA5 RTS ;サブルーチン戻り
処理を追っていくと、戦闘開始時に[$7E:FEFB]に値をセットするためのサブルーチンであることがわかる。
判定を見ると、最終編のオルステッド主人公時以外で、ピュアオディオ撃破後の7体の石像の部屋における7連戦のみ、[$7E:FEFB]に$01を書き込み、それ以外の戦闘では$00を書き込む、という処理になる。
問題は$C1/FD95のゼロフラグ分岐で、ここまでの判定でラスト7連戦フラグが立っているのに、[$00:11F1]、つまり最終編冒頭の異空間での歩数のゼロフラグ判定をしている。
通常、ラスト7連戦時には、異空間で100マス以上歩いて階段を登っているから、[$00:11F1]には必ず$64が入っているはずだ。
ということで、おそらくだが、[$7E:FEFB]に$00または$01をセットするためのサブルーチン、ということになると思われるが、$C1/FD97に辿り着くケースがあるかどうかは筆者にはわからない。
ちなみに[$7E:FEFB]の値は、最終的に、7連戦終了時の処理を行うための分岐に利用されるようである。
$C1/6DCC LDA $7EFEFB[$7E:FEFB] ;Aに[$7E:FEFB]をロード $C1/6DD0 BEQ $40 [$6E12] ;ゼロフラグが立っているとき[$6E12]分岐 ;ゼロフラグOFF 7連戦中 $C1/6DD2 LDA $0012FF[$00:12FF] ;Aに[$00:12FF]をロード $C1/6DD6 BEQ $3A [$6E12] ;ゼロフラグが立っているとき[$6E12]分岐 ;ゼロフラグON 7連戦中 $C1/6DD8 JSR $6150 [$C1:6150] ;[$C1:6150]へジャンプ ;乱数生成 $C1/6DDB AND #$07 ;Aと$07で論理積 $C1/6DDD STA $28 [$00:0328] ;A(乱数 & $07)を[$00:0328]に書き込み $C1/6DDF STA $210E [$00:210E] ;Aを[$00:210E](BG1Yスクロール)に書き込み $C1/6DE2 STZ $210E [$00:210E] ;[$00:210E]に$00を書き込み $C1/6DE5 STA $2110 [$00:2110] ;Aを[$00:2110](BG2Yスクロール)に書き込み $C1/6DE8 STZ $2110 [$00:2110] ;[$00:2110]に$00を書き込み $C1/6DEB STA $2112 [$00:2112] ;Aを[$00:2112]に書き込み $C1/6DEE STZ $2112 [$00:2112] ;[$00:2112](BG3Yスクロール)に$00を書き込み $C1/6DF1 LDA #$07 ;Aに$07をロード $C1/6DF3 SEC ;キャリーフラグON $C1/6DF4 SBC $28 [$00:0328] ;A($07) - [$00:0328](乱数 & $07) $C1/6DF6 STA $28 [$00:0328] ;Aを[$00:0328]に書き込み $C1/6DF8 LDX #$0700 ;Xに$0700をロード ;ループ処理ここから $C1/6DFB LDA $0001,x ;Aに[$00:0701+x]をロード $C1/6DFE AND #$F8 ;Aと$F8で論理積 $C1/6E00 ORA $28 [$00:0328] ;Aと[$00:0328]で論理和 $C1/6E02 STA $0001,x ;Aを[$00:0701+x]に書き込み $C1/6E05 INX ;Xをインクリメント +1 $C1/6E06 INX ;Xをインクリメント +1 $C1/6E07 INX ;Xをインクリメント +1 $C1/6E08 INX ;Xをインクリメント +1 $C1/6E09 CPX #$0718 ;Xと$0718を減算比較(ステータスレジスタ変更のみ) $C1/6E0C BNE $ED [$6DFB] ;ゼロフラグが立っていないとき[$6DFB]分岐 ;ループ処理ここまで $C1/6E0E LDA #$FF ;Aに$FFをロード $C1/6E10 STA $FD [$00:03FD] ;Aを[$00:03FD]に書き込み ;処理合流 $C1/6E12 RTS ;サブルーチン戻り
snes-docs-ja/video/bg/scroll.md スクロール
乱数から背景のスクロール値を決めているが、おそらく画面上のドットがランダムに消えていく時の計算であろう。
ループ処理で、敵ドットが全て消えるまで処理していると思われる。
カートリッジヘッダ snes-docs-ja/cartridge/header.md
ROM領域の$00:FFC0~$00:FFDFはカートリッジヘッダ、ゲームそのものの識別データ部分のようなものが収められている。
上サイト様によればタイトルやROMのサイズなど各種データが収められている。
ライブ・ア・ライブについて、重要そうなところだけ紹介しておく。
$00:FFC0~$00:FFD421バイト分、カートリッジのタイトルが入る。
ライブ・ア・ライブの場合、
4C 49 56 45 20 41 20 4C 49 56 45 20 20 20 20 20 20 20 20 20 20
という21バイトのデータが入っており、本作の文字コード表(Google スプレッドシート)でそのままデコードができる(ASCII文字コード)。
デコードしてみると、
と、英字タイトルそのままである。
$00:FFD5動作速度、マッピングモード
ライブ・ア・ライブの場合は$21(%0010 0001)。
上3ビットがメモリマッピングの仕様であり、%001はHiROM。
$00:FFD6チップセット(カートリッジの基盤構成)。
ライブ・ア・ライブの場合は$02で、構成は「ROM + RAM + Battery」を意味する。
Batteryはバッテリーバックアップ、セーブデータの保存機能のこと。
$00:FFD7%0000 0001を$00:FFD7に格納されている値分、ビットシフトした値がROMサイズ(単位はKB, キロバイト)。
つまり2進数で見た時に桁を左に動かしていく。
1のビットシフトだと、実質2の累乗計算と考えても良い。
n << mで、数値nをm回ビットシフトしたことを表すとすると(<< : 左シフト演算子)、
1 << ($00:FFD7の値)
ライブ・ア・ライブの場合は$0Bなので、
1 << $0B
= $800
= 2048
(211でも計算結果は同じ)
ROM容量は2048KBということになる。
$00:FFD8%0000 0001を$00:FFD8に格納されている値分、ビットシフトした値がRAMサイズ(単位はKB)。
ライブ・ア・ライブの場合は$03なので、
1 << $03
= $8
RAM容量は8KBということになる。
ここでいうRAMというのはカセット内部のSRAM、セーブデータ保存用RAMの領域の意味である。
ただ、実際にはセーブ・ロードの通り、セーブデータには2KB分の領域しか使っていないようである。他にも何かしらに使っているかどうかは筆者にはわからない。
スーパーファミコンのサウンドは、スーパーファミコン自体のCPUから、スーパーファミコンのサウンド用CPU(SPU700、APU)へ、4種類のポート(I/Oレジスタ)を通してデータのやりとりをする。
CPUのメモリアドレスだと$00:2140~$00:2143の4種のアドレスが、APUとのI/Oレジスタにあたる。
($00:2144~$00:217Fは$00:2140~$00:2143をミラーリング)
このAPUを初期化するためのゲーム開始直後の処理が以下。
スーパーファミコンの仕様に従った処理なので、どのゲームでも似たような処理は行っていると思われる。
この処理の後、実際のサウンドデータ転送を行うことになる。
$C3/0000 JMP $0034 [$C3:0034] ;[$C3:0034]へジャンプ(レジスタをスタックに積まない) ;サウンド転送初期化 $C3/0034 PHB ;DBレジスタをスタックにプッシュ $C3/0035 PHD ;Dレジスタの値をスタックに積み $C3/0036 PHP ;ステータスレジスタをスタックへプッシュ $C3/0037 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C3/0039 REP #$10 ;X/Yレジスタを16bit幅に変更、Xフラグをクリア $C3/003B PHA ;Aをスタックにプッシュ $C3/003C PHX ;Xをスタックにプッシュ $C3/003D PHY ;Yをスタックへプッシュ $C3/003E SEP #$20 ;MフラグON Aレジスタは8bit幅 $C3/0040 LDA #$00 ;Aに$00をロード $C3/0042 PHA ;Aをスタックにプッシュ $C3/0043 PLB ;DBレジスタに値をプル $C3/0044 LDX #$1D00 ;Xに$1D00をロード $C3/0047 PHX ;Xをスタックにプッシュ $C3/0048 PLD ;Dレジスタにスタックからプル $C3/0049 LDX #$BBAA ;Xに$BBAAをロード $C3/004C LDY #$F0FF ;Yに$F0FFをロード $C3/004F STY $2140 [$00:2140] ;Y($F0FF)を[$00:2140]に書き込み $C3/0052 CPX $2140 [$00:2140] ;X($BBAA)と[$00:2140]を減算比較(ステータスレジスタ変更のみ) $C3/0055 BNE $F8 [$004F] ;ゼロフラグが立っていないとき[$004F]分岐 ;ゼロフラグON [$00:2141][$00:2140]=$BBAA, プログラム初期化完了 $C3/0057 LDX #$0000 ;Xに$0000をロード ;転送先アドレス書き込み[$C3:001C][$C3:001D]→[$00:2142][$00:2143] $C3/005A LDA $C3001C[$C3:001C] ;Aに[$C3:001C]をロード $C3/005E STA $2142 [$00:2142] ;A($00)を[$00:2142]に書き込み $C3/0061 LDA $C3001D[$C3:001D] ;Aに[$C3:001D]をロード $C3/0065 STA $2143 [$00:2143] ;A($02)を[$00:2143]に書き込み ;[$00:2141]に$CCを書き込み(0以外の任意の値書き込み) $C3/0068 LDA #$CC ;Aに$CCをロード $C3/006A STA $2141 [$00:2141] ;A($CC)を[$00:2141]に書き込み ;[$00:2140]に$CCを書き込み $C3/006D STA $2140 [$00:2140] ;Aを[$00:2140]に書き込み ;ループ処理 [$00:2140]が$CCになるまで待機 $C3/0070 CMP $2140 [$00:2140] ;Aと[$00:2140]を減算比較(ステータスレジスタ変更のみ) $C3/0073 BNE $FB [$0070] ;ゼロフラグが立っていないとき[$0070]分岐 ;ループ処理ここまで ;サウンド転送初期化完了