ロットロット (FC) 攻略/解析

RAM

概要

アドレス内容
$00u8PPU_CTRL ($2000) 管理用。
$01u8PPU_MASK ($2001) 管理用。
通常は常に 0x1E で、レンダリングを有効化する際に PPU_MASK へ書き込まれる。
$02u8現在レンダリングが有効かどうか (0:false, 非0:true)。
メインスレッド専用。
$03-$0D(雑用)
$0Eu8NMI スレッド完了フラグ (NMI ハンドラ内で 1 が書き込まれる)。
$0F(雑用: NMI スレッド専用)
$10u8PPU データ転送キュー書き込みオフセット: 現在書き込んでいる要素の開始位置。
$11u8PPU データ転送キュー書き込みオフセット: 現在のバイトの書き込み位置。
$12u8PPU データ転送キュー読み取りオフセット。
$13u8(雑用: NMI スレッドの PPU データ転送キュー消費処理用)
$14u8[2]1P/2P 生入力 (ABSTUDLR)。
$16u8[2]1P/2P エッジ入力 (ABSTUDLR)。
$18u8ポーズフラグ。
NMI ハンドラ終了時に1Pエッジ入力 T があるとき真になる。
$19u8スプライトバッファ選択 (0:スプライトバッファ 1, 1:スプライトバッファ 2)。
OAM DMA を行うたびにトグルされる。
$1A-$21(雑用)
$22-$23(未使用)
$24-$28(雑用: NMI スレッド専用)
$29-$2B(雑用)
$2Cu8ゲームプレイ中かどうか (0:false, 1:true)。
$2Du16be自機の座標x (1/256 px 単位)。
$2Fu16be相方の座標x (1/256 px 単位)。
$31u16be自機の座標y (1/256 px 単位)。
$33u16be相方の座標y (1/256 px 単位)。
$35u8自機の姿勢 (0..=7)。
$36u8相方の姿勢 (0..=7)。
$37u8自機の指している部屋インデックス。
$38u8相方の指している部屋インデックス。
$39u8swap 操作中の自機/相方の姿勢回転カウンタ (0..=16)。
$3Au8swap 操作開始フラグ (0:false, 1:true)。
$3Bu8自機移動履歴読み取りオフセット (0..=161)。
$3Cu8自機移動履歴書き込みオフセット (0..=161)。
$3Du8盤面の行 3..=17 に玉が存在するかどうか (0:false, 非0:true)。
$3Eu8生成待ちの赤玉の個数。
$3Fu8(write-only: 赤玉を盤面外に落とした際にインクリメントされる)
$40u8(write-only: 赤玉を盤面外に落とした際に移動元のマスが書き込まれる)
$41(未使用)
$42u8カニの座標y (px)。
$43u8カニの状態。
0..=1: まだ紐に到達していない (値はアニメーション制御用)
2: 紐を切る直前
3: 紐を既に切った
$44u8カニが上昇中かどうか (0:false, 1:true)。
$45u8カニの状態遷移用カウンタ。
$46u82Pモードかどうか (0:false, 1:true)。
$47u8[7]1Pスコア (10 単位、7 桁 unpacked BCD, 上位桁が先)。
$4Eu8[7]2Pスコア (10 単位、7 桁 unpacked BCD, 上位桁が先)。
$55u8[7]ハイスコア (形式はスコアと同じ)。
$5Cu8[2]1P/2P スコア再描画フラグ (0:false, 1:true)。
$5Eu8ハイスコア再描画フラグ (0:false, 1:true)。
$5Fu8現在のプレイヤーID (0:1P, 1:2P)。
$60u8[2]1P/2P 現在の面 (面イントロでの表示 (ROUND n) と一致する)。
$62u8[2]1P/2P 残機 (プレイ中の自機を含む)。表示値と一致する。
$64u8[2]1P/2P 再開時の 2 * (wave テーブル内インデックス)。初期値は 0。
$66u8[7]現在の面の目標スコア (形式はスコアと同じ)。
$6Du16le乱数生成器の内部状態。下位バイトが乱数として使われる。
$6F-$73(雑用)
$74u8ターン管理用短周期カウンタ。毎ターンインクリメントされる。
初期値は -1 で、その後は mod 8 で扱われる。
$75u8ターン管理用長周期カウンタ。毎ターンインクリメントされる。
初期値は -1 で、その後は mod 113 で扱われる。
$76u8wave 内時間。
$77u82 * (現在の wave テーブル内インデックス)
$78ptr現在の wave データの先頭を指すポインタ。
$7A-$91u8[24]盤面外の通常玉たちの座標x (px)。
$92-$95u8[4]赤玉たちのスプライト座標x (px)。
$96-$ADu8[24]盤面外の通常玉たちの座標y (px)。
値が 240 ならばその通常玉は存在しない。
$AE-$B1u8[4]赤玉たちのスプライト座標y (px)。
値が 240 ならばその赤玉は存在しない。
$B2u8ミス状態管理用カウンタ。
0 ならばミスしていないとみなされる。
$B3u8現在の面の目標スコア達成フラグ (0:false, 0xFF:true)。
$B4u8目標スコア達成後のボーナス残り時間。毎ターンデクリメントされる。
デクリメント結果が 0 になった時点でボーナス終了。
$B5u8面クリア処理用カウンタ。
$B6u8面クリア処理用カウンタ。
$B7u8オーディオ: 現在再生中の効果音ID (0xFF:None)。
$B8ptrオーディオ: 効果音バイトコード用プログラムカウンタ。
値は NES 側の CPU 論理アドレスそのまま。
$BAu8オーディオ: 効果音バイトコード用スタックポインタ。
値は $07B0 からのオフセットで、「現在スタックトップにある値」を指す。
スタックが空の場合 16 (これが初期値)。
$BBu8オーディオ: 効果音ウェイトカウンタ。
効果音を再生中でない場合 0。
$BCu8オーディオ: 現在再生中の効果音の nice 値。
値が小さい方が優先度が高い。同点の場合、後から再生された方が優先される。
効果音を再生中でない場合 0xFF。
$BDu8オーディオ: 現在再生中の効果音で使用する APU チャンネルのマスク (bit0:矩形波A, bit1:矩形波B, bit2:三角波, bit3:ノイズ)。
NOTE: 初期値は 0xFF で、この状態では音楽が再生されない。
$BEu8オーディオ: 現在再生中の音楽ID (0xFF:None)。
$BFptrオーディオ: 音楽バイトコード用プログラムカウンタ。
値は NES 側の CPU 論理アドレスそのまま。
$C1u8オーディオ: 音楽バイトコード用スタックポインタ。
値は $07C0 からのオフセットで、「現在スタックトップにある値」を指す。
スタックが空の場合 16 (これが初期値)。
$C2u8オーディオ: 音楽ウェイトカウンタ。
音楽を再生中でない場合 0。
$C3(write-only)
$C4u8NMI カウンタ。NMI ハンドラが呼ばれるたびにインクリメントされる。
$C5-$FF(未使用)
$0100u8[52]各壁のタイマー値
$0134u8[52]各壁の状態カウンタ
$0168u8[52]各壁の穴パターン
$019C-$01CF(雑用)
$01D0-$01FF(スタック領域)
$0200-$02FFSprite[64]スプライトバッファ 1。
スプライトバッファ 2 と交互に OAM へ DMA 転送される。
$0300-$03FFSprite[64]スプライトバッファ 2。
スプライトバッファ 1 と交互に OAM へ DMA 転送される。
$0400-$04FFu8[0x100]PPU データ転送キュー
$0500-$06EDu8[26*19]盤面 (26 列 19 行)。
$06EE-$078Fu8[162]自機移動履歴
$0790-$079Fu8[0x10]オーディオ: APU レジスタ値キャッシュ。大まかには $4000-$400F に「直前に書いた」値を保持すると考えられる。
NOTE: 必ずしも愚直に書いた値を保持するわけではなく、恣意的な値に設定される場合もある。
また、オーディオドライバ(再)初期化時に 0xFF で埋められる。
$07A0-$07AFu8[0x10]オーディオ: 音楽側の APU レジスタ値バッファ (APU レジスタ $4000-$400F に書こうとしている値)。
NOTE: 必ずしも実際に APU レジスタに書かれるとは限らない (効果音との調停や APU レジスタ値キャッシュの内容に依存する)。
また、一切の初期化処理が行われない
$07B0-$07BFオーディオ: 効果音バイトコード用スタック (16 バイト)。上位から下位へ伸びる。
$07C0-$07CFオーディオ: 音楽バイトコード用スタック (16 バイト)。上位から下位へ伸びる。
$07D0-$07FF(未使用)

詳細

$0400-$04FF: PPU データ転送キュー

PPU へデータを非同期転送するための機構。メインスレッドによって転送データが書き込まれ、NMI スレッドがそれを読み取って PPU への転送を行う。

実装はリングバッファで、書き込みオフセットは $10-$11, 読み取りオフセットは $12 で管理される。

キュー内の要素は以下の構造体:

内容
u16be転送先 PPU アドレスおよび転送方向。
bit0-14: 転送先 PPU アドレス
bit15: 転送方向 (0:横, 1:縦)
u8転送バイト長。
u8[]転送データ。

$06FF-$078F: 自機移動履歴

自機の移動方向の履歴 (長さ 162)。相方はこれを参照して動く。自機が移動可能であるとき NMI ハンドラ内で書き込み/参照される。

実装はリングバッファで、書き込みオフセットは $3C, 読み取りオフセットは $3B で管理される。

面開始時、書き込みオフセットは 161, 読み取りオフセットは 0 で初期化される。つまり、相方は自機から 161 フレーム遅れて動くことになる。

値の意味:

履歴は面開始時にゼロクリアされる。よって、相方は面開始後 161 フレームの間 U 方向へ動こうとするが、これは座標制限に掛かるので実質移動しないのと同じになる。