コンソール
二つのチップが一つのクロックに乗り、実 CPU を付けて標準テスト ROM が走る
まず糊。NES-001 基板上で二つのチップ以外にある少数の部品(アドレスデコーダ、PPU のアドレスラッチ、二つの RAM、コントローラポートのバッファとその先のコントローラ、リセット回路)だ。どれも数行のコードで、それぞれ自前のテストでデータシートと照らし合わせ、手で書いたものだと明記してある。ネットリストから来るものは一つもないからだ。二つは最初に書き間違え、テストがそう言った。次にコンソール: 2A03 の高速コアと高速 PPU を一つのマスタハーフステップ計数器に乗せ、CPU は十二ごと、PPU は八ごとに進む。始まりの位相は二つのスイッチレベルチップ自身のクロック分周器から測った(cpu_phase 4、ppu_phase 3。分周器が電源投入で取り得る 24 通りの一つで、どの走行もそれを記録する)。配管の検査はテストカートリッジを 6 フレーム走らせ、ドットあたり八カウントであること、奇数フレームが一ドット短いこと、絵が単体 PPU のものと同じこと、RAM で数えた NMI が一フレーム一回であることを確かめる。一コアで毎秒 125 から 140 フレーム、実時間の 2.1 から 2.3 倍。位相の検査は、このプロジェクト全体の要である二つのチップの出会う場所を、二通りに確かめる。まず、PPU の実 NMI を BRK の周りに一サイクル刻みで 8 通りの位置に落とし、コンソールの CPU を同じエッジで駆動したスイッチレベルの 6502 とハーフサイクルごとに比べる: 960 ハーフサイクルが一致、取ったベクタも、プッシュも、タイミングも。次に、$2002 読み出しの競合をコンソールと同じ読み方でスイッチレベル PPU 上に全ハーフステップで測り、コンソールの読み出しをその表と 24 通りすべての位相で照らし合わせる: フラグのセット周りで 145 回、クリア周りで 185 回、両窓の全ハーフステップに届き、結果はすべてチップのもの。 そして、このプロジェクト全体が目指してきた、本物での検査: blargg のテスト ROM をコンソール全体に通す。これらの高速チップが何百万サイクルも実プログラムを走らせた最初の機会だ。CPU タイミング検査は合格。命令検査は 16 本中 16 本が合格、公式・非公式の全命令。スプライトヒット検査は 11 本中 11 本が合格。縦長の一本は、高速 PPU の縦長スプライト規則をスイッチレベルチップで測ってドット単位で確かめてからの合格だ。vblank と NMI のタイミング検査は 10 本中 5 本が合格。残りは文書化された実機から一、二ドットずれていて、すべて一つの問いに帰する: 実機の NMI は、それぞれ自身の実測タイミングと照らし合わせた二つのチップが許すより約二ドット遅れて CPU に届く。決められるのは実基板に当てるスコープだけだ。音の検査は 8 本中 8 本が合格。うち六本は、不合格をスイッチレベルの 2A03 で測り、そこから修正を書いてからの合格だ: $4017 書き込みの位相ジッタと即時クロック、バスに尋ねた半ステップ後にラッチされるステータス、三サイクル続けて立つ IRQ フラグ、読み出しが着地する所で数えられる DMC のバイト。ROM が見つけたものこそ走らせる意味だ: 高速 CPU は記録済みの全トレースを正確に再生しながら、トレースが覆っていなかった見落としを抱えていた(駆動されないバス線に乗って次の命令へ渡る桁上げ、誤った捕捉から読んだシフトの桁上げ、結果がバスの取り合いでありスイッチモデルが独自に決着させる三命令、割り込み入力を標本化するハーフサイクル(位相の検査が捕まえた)、そしてバスに尋ねるより遅くラッチされるバイト)。高速 PPU にもさらに四つ。それぞれ、スイッチレベルチップと高速版を ROM 上で食い違うまで並べて走らせて見つけ、正しい振る舞いをスイッチレベルのチップで測り、高速版を直し、修正がなければ赤になるテストを加えた。記録はN5 報告。遊びの検査はカートリッジ待ち。
コンソールのフレームがテレビ模型を通り、その捕捉が採点される
絵は ntsc-crt の連鎖(タグ v0.2.18)を通り、コンソールが足すのは二つだけ: フレームの順序と、一つのフレームから次へ持ち越す色副搬送波の位相だ。奇数フレームの短い一行が位相を動かすので、コンソールはドットだけでなく、各フレームが奇数か偶数かを渡す。各フレームは NES と同じやり方で符号化され、三ラインコムフィルタで復号され、私たちが選んだ設定で CRT の各段を通る。検査は二つ。コンソールのフレームをこの連鎖に通したものは、同じテスト場面から単体の高速 PPU が出したフレームを同じ連鎖に通したものと、復号された全標本で一致する(1474560 成分が一致、OddShort フレーム、画面上 768 × 720)。そして 12 フレーム(うち 5 が短い)後の位相は、その列にタイミング格子の算術が与えるもの(位相 8。全フレームを偶数に強制すると違う値になり、検査が赤になる)。実機比較に要るカラーバーのカートリッジは PPU の描画を切って塗るが、それは高速 PPU に誰も訊いたことがなかった: スイッチレベルのチップで測ると、描画を切った絵はアドレスレジスタが指すパレット項目で、行途中の書き込みに対するそのタイミングにはいまそちらに専用のテストがある。 次に捕捉経路、実機が加わる比較の機械側半分。カラーバーのカートリッジをコンソールに通し、そのフレームを ntsc-crt の捕捉カード模型に通して実際の録画とまったく同じ手順で復元し、合成は模型自身のフロントエンドを通して両側が同じ帯域制限を持つようにする。そして平坦な領域すべてを、同一の復号器を通したその合成に対して、縁から 5 ドット内側で採点する。この距離は選んだのではなく復号器の色フィルタから導いた。許容は走らせる前に書いた: 輝度 0.01 以内、色相 1 度以内、彩度 5 パーセント以内。カートリッジは私たち自身のもの。blargg のバーは十六ドット幅で、復号器が落ち着くには五ドット要るからだ: 三十二ドットのセルに十二の色相を一つの輝度行で並べて背景色を加え、行は二秒ごとに進み、行ごとに一走行で採点する。輝度行 1: 13 領域中 13 が三つとも成立(最悪で輝度 0.0007、色相 0.4 度、彩度 0.0011、レートは +0.0 ppm)。輝度行 2: 13 領域中 13 が三つとも成立(最悪で輝度 0.0007、色相 0.4 度、彩度 0.0012、レートは +0.0 ppm)。輝度行 3: 13 領域中 13 が三つとも成立(最悪で輝度 0.0005、色相 0.4 度、彩度 0.0005、レートは +0.0 ppm)。輝度行 0: 13 領域中 13 が三つとも成立(最悪で輝度 0.0006、色相 0.4 度、彩度 0.0008、レートは +0.0 ppm)。往復は閉じる。最初の走行群は、絵について何かを見つける前に、測る道具の不具合を三つ見つけた: ヒストグラム一区画分粗いレベル基準、消去期間と取り違えられた暗い絵、同期エッジと取り違えられた最も暗い色のクロマの谷。それぞれ ntsc-crt 側で直し、新しいタグを付けた。同じカートリッジを実機で録ることがベンチの課題で、そのためのカートリッジはいまある。記録はN6 報告。
コンソールの音が基板の音声段を通り、blargg のミキサー検査で確かめられ、彼の録音と並ぶ
2A03 の五つの出力コードは CPU ハーフサイクルごとにチップを出て、二つの DAC を通る。使うのは最初の音以来の nesdev の表で、測ったものではなく借りたものだと明記してある。その先は NES-001 の回路図にあり、直接読んだ: 各音声ピンは 100 オームで引き下げられ(表自身の「プラス 100」)、二つのピンは 20K と 12K で加算され(表の二つの定数がすでに抱える比)、結合コンデンサを経て、47K の帰還抵抗と並列の 220 pF で線形に保たれた 74HC04 インバータに入る。つまりジャックまでは、時定数 7.50 ms のハイパス、インバータの符号付きの利得 -2.350、10.34 マイクロ秒のローパス、そして厳密な有理時刻での窓付き sinc による 48 kHz への再標本化。段はその算術と照らし合わせてある(ステップは時定数ごとに 0.3679 に減衰し、10 kHz の音は 200 Hz に対して 0.8401 で通り、値が与えるのは 0.8433)。模していないと明記するもの: インバータの有限な開ループ利得とその電源レール、そして表の絶対電圧。後者はスコープの記録が与える一つの倍率だ。 実機に対する検査は blargg のもの: 四つのミキサー ROM で、それぞれ一チャンネルを鳴らしながら DMC がその逆波形を鳴らすので、正しいミキサーは二つの参照ビープの間でほぼ無音に打ち消す。それぞれをコンソール全体に通し、各検査の最悪の 100 ms 窓はビープに対する割合で 5 パーセント未満でなければならない(DMC の一段だけで約二)。ノイズ ROM は設計上ノイズをフェードさせるので、純音成分で判定する。コンソール、次いで同じ ROM を実機で録った blargg の録音を同じコードで測ったもの: square は 2.4 パーセント対 6.1、triangle は 2.7 パーセント対 3.0、noise は 21.1 パーセント対 19.0、dmc は 3.1 パーセント対 5.6。三角波とノイズは実機とコンマ数パーセントで一致する。矩形波と dmc は実機でコンソールの二倍の残差を残し、その残差は純音だ: 実物のパルス DAC と DMC DAC は、表が blargg の逆波形から離れる以上に表の曲線から離れている。これはスコープへの問いなので、テストにはせず記録する。代わりに wiki の線形近似で混ぜると検査は赤になり、ビープの三分の一に達する。記録はN7 報告。実機の音声出力を録ることがベンチの課題。
窓の中のコンソール。GPU 上の絵は CPU 版と一致し、二つ目の居場所はブラウザ
何かを書く前に一フレームが一コアで要する時間を測り、それが仕事の行き先を告げた: コンソールと符号化器は一コアに収まり、コム復号と五段の CRT は CPU のどこにも収まらない。その二つはいま GPU 上の八つの計算パスで、すべての定数は打ち込むのではなく復号器と CRT の設定から送られる。連続する三フレーム(最後は画面の残光が見えるよう黒)の全画素の全成分で、信号経路自身の CPU 版と照らし合わせてある。私たちが選んだ設定では最悪の成分差が 4.8e-7、平均が 1.2e-8。マスクと幾何を入れると 2.8e-5 と 1.9e-7。先に述べた許容は 1e-3 と 1e-5。一フレームは NVIDIA GeForce RTX 3070 で転送込み 0.87 ms。残光を飛ばすと検査が赤になる。 窓は Linux のプログラムだ。音付きのコンソールは自分のスレッドで、信号経路のドリフト方針が壁時計から決める分だけフレーム単位で進み、繰り返しと欠落を数え、時間を引き伸ばすことは決してない。表示は新しいフレームごとに符号化して GPU の絵を走らせ、音は音声デバイスへ、キーボードまたは gilrs 経由のゲームパッドがコントローラ 1。ループは偽の時計で確かめる: ちょうど周期では 60 拍で新フレーム 59、繰り返し 1、欠落 0。半周期では 60 拍のうち 31 が前のフレームをもう一度見せる。二倍では 20 拍で 19 欠落。この機械では仮想ディスプレイで走った。本物の画面、スピーカー、そして手で試すのは机でこれから。 二つ目の居場所はブラウザ: 音付きのコンソールを WebAssembly にし、node で full_palette.nes を測った: 300 フレームを 4.19 秒、毎秒 71.7 フレーム、実時間の 1.19 倍、一フレームあたり 798.7 音声標本。いまはページもある: コンソールはここで走る。自分のディスクのカートリッジで、信号のベンチと同じ信号経路を通り、ドリフトカウンタを生で表示する。記録はN8 報告。
ここの数字は、テストを走らせ直した実測から来ている
下の数字は 2026-09-29 に、記録されたコミットでコンソールのリポジトリ自身のスイートをもう一度走らせて得たもので、このページはその走行が書いたものだけを読む。
コンソール
一枚の基板に載った二つのチップ: 糊、テスト ROM を走らせる機械、そしてその絵、音、遊ぶための窓。
- The mainboard's glue N4 report: The handful of parts on the NES-001 board between the chips, each checked against its datasheet and labelled as written by us.
- Both chips on one clock N5 report: The console running: the two fast chips on one clock, the timing between them checked against the transistor-level chips, and blargg's test ROMs run end to end.
- Planning the console's picture N6 plan: The picture through the signal path, and how a captured frame will be compared, with the tolerances written down first.
- The console's picture N6 report: The picture through the signal path, the screen with rendering off measured on the chip, and a captured frame scored, figures recorded and not fitted.
- Planning the console's sound N7 plan: The sound through the board's audio stage, read off the schematic.
- The console's sound N7 report: The sound through the board's audio stage, blargg's mixer test ROMs cancelling, and his recordings of real hardware beside ours.
- Planning the console's window N8 plan: The window the console plays in, the picture on the GPU, the pacing, and a second target in the browser.
- The console in a window N8 report: The window built and checked without a screen, the GPU picture matching the CPU's, and the browser build measured.