6502tinymachines

2A03 から出た最初の音

A3 の報告。作業の後に書かれた。

走行スタンプ: 2026-09-03、rustc 1.97.1、halfphi v0.1.3。REQUIRE_NETLIST=1 REQUIRE_GOLDEN=1 を付けた cargo test --release --workspace: 5 テストが緑 (A0 の三つと A3 の二つ)。MUTATE=1 は A3 の二つの検査 (ゲート) をどちらも赤にし、それぞれ自分の声で鳴る: ゴールデンの再生は半ステップ 43 で分岐する。改竄されたバイトが初めてデータバスを渡る瞬間だ。そしてプラトーの測定は 160 半ステップと読む。これは妨害されたタイマー自身の算術 (2 x 2 x (9+1) x 4) が、正直なプログラムの 144 と食い違っているということだ。

閉じたもの

  • メモリのハーネス (src/harness.rs): CPU バスの世話をリファレンスの macros.js から一文ずつ写した (halfStep は clk0 が反転するまでマスタクロックを回す。読み出しはデータバスのプルを反転させ、八本すべてを種として一度だけ落ち着かせることで駆動する。書き込みは立ち上がりの半ステップで捕捉する。書かれていないメモリはゼロを読む)。妨害のフックは一つのアドレスをマスクと XOR して差し出す。2C02 の P1 から来た CHR バイトの模様だ。
  • A3 のゴールデン: リファレンスのシミュレータ自身が、書き下ろしの矩形波の音のプログラムをメモリ付きで走らせたもの (gen-a3.js)。全ノードにわたる 2,001 状態を CPU 半ステップの粒度で持ち、ハーネスを通して例外一覧なしのビット厳密で再生された: 6502 コア、APU 全体、バスの糊が一つの比較の下に入る。
  • プログラムは一度だけ書かれる (tools/golden-trace/program-a3.json)。JS の生成器と Rust のテストが同じファイルから読む: 矩形 0 を有効化、デューティ 50 パーセント、定音量 15、長さは停止、タイマー 8、あとは回るだけ。
  • 音は実測であり、仮定ではない: sq0_out の 4 ビットを半ステップごとに標本化すると、ちょうど 0 から 15 まで振れ、プラトーはちょうど 144 半ステップで、それを十個実測した。144 はプログラム自身のタイマーバイトから導かれる (シーケンサは 2 x (t+1) CPU サイクルごとに進み、このデューティでは八歩のうち四歩が高い)。ネットリストが提案し、測定が決定した。両者は半ステップまで一致する。
  • 値としての最初の音: 走行を書き下ろしの nesdev の表 (当時は src/mixer.rs、N7 以降は v2a03-dac を再エクスポート) に通して混ぜ、nes-bus の AudioSamples に入れた。CPU 半ステップごとに 1 標本、厳密な有理レートで。AD1 は二値で、無音と ad1(15, 0)。AD2 は無音のままだ。

書き下ろしであり、そう札が付いている

ミキサーの定数は nesdev wiki の APU Mixer ページ (2026-09-03 に読んだ) のもので、N0 の検査より前の nes-bus のピン表と同じ出自の水準だ: 日付の付いた主張であって、このリポジトリからの測定ではない。実物の AD1/AD2 ピンを表に照らして測ることは、コンソールのスケッチの捕捉一覧にすでに載っているベンチの作業であり、2C02 の映像 DAC の書き写したレベルが、その測定が着地したときにどう見えるかの先例になる。

先送りしたもの

  • 歌ったチャンネルは一つだ。三角波、ノイズ、DMC にはプログラムが一度も触らなかったレジスタがあり、ゴールデンが電源投入状態で押さえてはいるが、一度も運動させていない。もっと豊かな刺激 (と、フレームカウンタの四つのモード) は、最初の音ではなくピン・ロックステップの節目のテスト群のものだ。
  • プラトーの算術はシーケンサの周期を押さえる。デューティの模様の位相 (八歩のうちどの四歩が高いか) は、ノードのゴールデンによって暗黙にしか覆われていない。デューティの掃引 (四設定すべて) は、何かが波形を消費するようになったときの自然な A3 の続きだ。

ビルド時に 2a03/docs/a3-report.md から取り込まれる。写しはリポジトリの一つだけだ。報告は独自の作業用の言葉をいくつか使う: 報告書で使われる言葉。