スーパーファミコン用カートリッジの内部分析
(fabiensanglard.net)- Super Nintendoのカートリッジは単なる記憶媒体ではなく、CICコピー防止、SRAM、補助プロセッサを搭載し、コンソールの機能を拡張するハードウェアだった
- ROM容量は当時ビット単位で宣伝されており、調査対象の3,378本のタイトルのうち、Star OceanとTales of Phantasiaは48Mb、Super Mario Worldは4Mbだった
- セーブ機能はバッテリーで保持されるSRAMに依存しており、Zelda IIIのPCBのように、ROM/RAMアクセスを調整するMAD-1アドレスデコーダが併載された例もある
- 合計13種類の補助チップが72本のゲームで使われ、CPU高速化、スプライト処理、圧縮解除、数学演算、ポリゴンラスタライズといった処理をカートリッジ側で担っていた
- こうしたチップは当時のゲーム表現力を大きく広げた一方で、S-DD1の内部構造が不明だったためグラフィックパックが必要だった例のように、エミュレータ実装には長期にわたるリバースエンジニアリングの負担を残した
カートリッジの基本構成: CIC、ROM、SRAM
- Super NintendoのカートリッジにはROMチップ上の命令やアセットだけでなく、CICコピー防止チップ、SRAM、補助プロセッサまで搭載できた
- CICは、コンソール側チップとカートリッジ側チップがlockstepで通信する方式で動作する
- コンソール側のCICが異常状態を検知すると、すべてのプロセッサをリセットする
- すべてのSNESカートリッジにCICがあるわけではなく、非公式ゲームのSuper 3D Noah's ArkにはCICがない
- Super 3D Noah's Arkでは、まずゲームをコンソールに挿し、その上に公式カートリッジを挿す必要があり、Noah's側が公式ゲームのCICを使ってバスラインを中継する
- ROM容量は当時、バイトではなくビット単位で表記されていた
- Zelda IIIは1,048,576バイトではなく、8Mb ROMとして宣伝されていた
- 調査リストにはUSA/Japan/Europe基準で3,378本のタイトルが含まれる
- Star OceanとTales of Phantasiaは48Mb、すなわち6,291,456バイトで、最大級に属する
- Super Mario Worldは4Mb、すなわち524,288バイトのROMを使用している
- セーブ機能を持つ一部タイトルは、バッテリーで電力を維持するSRAMを使用する
- コンソールの電源が切れると、SRAMは消費電力を抑えるため低電力モードに入る
- Zelda IIIのPCBには、U4のCIC(D413A)、U1の0x80000 ROM(524,288バイト)、U2のLH5268AF-10TLL 64Kbit SRAM(8KiB)、U3のMAD-1メモリアドレスデコーダがある
補助チップの広がりとSA-1
- 最も有名な補助プロセッサは1993年のStar Foxで使われたSuper FXだが、それ以前にもECチップは使われていた
- 全体として13種類のECが72本のゲームで使われた
- 全一覧はwikipediaとsnescentral.comにまとめられている
- SA-1、すなわちSuper Accelerator 1は、34本のカートリッジに搭載された代表的な補助チップである
- SNES本体CPUと同じ65C816 CPUだが、4倍速い10.74MHzで動作する
- 2KiB SRAMと統合CICを含む
- Super Mario RPGのPCBには個別のCICはなく、U3にSA-1があり、U1にはROM、U2には統合デコーダ付きのSRAMがある
- SA-1は個別のオシレータなしでカートリッジポートのSystem Master clockを受け取り、内部で2分周して21.4772700MHz / 2 = 10.74MHzで動作する
- SA-1は起動時にstop状態にあり、SNES CPUがReset Vectorを作成してSA-1を再開する
- SA-1の初期Instruction Pointerは専用のReset Vectorから取得される
- 動作モードはAccelerator、Parallel Processing、Mixed Processingの3種類
- 最も強力な構成では、SA-1 CPUとSuper NES CPUが同時に動作し、Super Accelerator Systemの性能は従来のSuper NES比で5倍になる
- 向上した処理性能は、PPUが提供する128個のスプライト全体のアニメーションや衝突判定、スプライトのリアルタイム回転・スケーリング変換後のPPU VRAM書き込みに使われた
- Nintendo SA-1デモカートリッジがこれらの改善を示している
- レトロゲームコミュニティは、Eliminating slowdown in Super Mario World、Gradius III slowdown removal、Contra III slowdown removalのようなプロジェクトで既存ゲームのslowdownを減らしてきた
- タイトルをSA-1化するにはRAM/ROMアクセスの再マッピングが特に必要で、かなり複雑に見え、SA-1文書に「SNESとSA-1は同じメモリマッピングを使う」とある点と合わせて疑問が残る
- 2019年にはSA-1 Collection Projectを通じて、より多くのSNESゲームを自動で再マッピングしてSA-1化しようとする作業が進められていた
グラフィックス・圧縮・数学向け補助チップ
- CX4はCapcom製チップで、Mega Man X2とMega Man X3を動かす
- 3Dワイヤーフレームレンダリング、各種数学演算、スプライトのスケーリング・回転後のVRAM書き込みを処理できる
- MMX2のイントロとボス戦で例を見られる
- CX4はワイヤーフレームだけでなく、sprite functions、propulsion、vector、triangle、trigonometric functions、result tables、coordinate transform functionsを提供し、MMX2とMMX3ではすべてのスプライトを処理する
- Mega Man X2のPCBには、U4のCIC、U1の8M ROM、U2の追加ROM、U3のCX4、X1の20MHzオシレータがある
- S-DD1はスプライト圧縮解除チップで、PPU VRAMに直接データを供給できる
- Star OceanとStreet Fighter Alpha 2の2作品で使われている
- Street Fighter Alpha 2でラウンド開始前にblankが入るのはS-DD1のせいだという噂があったが、Modern Vintage Gamerの説明によれば、実際の問題はサウンドサンプルをDSP RAMへ転送することにあった
- Street Fighter Alpha 2のPCBには、U1の4MiB ROMと、アセットをその場で圧縮解除するS-DD1があり、CICはS-DD1に統合されているため個別チップはない
- DSP-1はDSP系19本の対応タイトルのうち16本を占め、Super Mario KartとPilotwingsで使われた
- 名称のDSPはDigital Signal Processorを意味するが、一般的なDSPのように連続信号を処理しないため、名前としては不適切だと評価されている
- 開発者マニュアルによれば、DSP-1はblocking modeで動作し、DSPがデータを処理している間はSuper NES CPUが待たされる
- 高速な16ビット乗算、逆数、sin/cos projection、vector size、rotationといった命令を提供し、HDMAプログラミングやMode 7の3Dビュー更新に重要だった
- Super Mario KartのPCBには、外部CIC、ROM、保存用SRAM、MAD-1アドレスデコーダ、バッテリー、8MHz動作用のオシレータがある
- DSP-1、DSP-1a、DSP-1bの3バージョンはバグ修正と製造工程改善を導入したが、動作がわずかに異なり、Pilotwingsのデモで飛行機が地面に衝突する結果が生じた
- そのほかの小規模チップも特定ゲームに限定して使われた
- DSP-2はDungeon Masterの1作品だけで使われ、Atari STルーチンの変換に用いられ、主にスプライトスケーリングを補助する目的だったとみられる
- DSP-3はSD Gundam GXの1作品で使われる
- DSP-4はTop Gear 3000とThe Planet's Champ TG 3000の2作品で使われる
- OBC-1はMetal Combat: Falcon's Revengeの1作品で使われ、スプライト操作用という噂があったが、nesdev.orgでは議論がある
- S-RTCはDaikaijuu Monogatari IIの1タイトルでリアルタイムクロックを追跡するチップで、Hudson Softの開発者がなぜリアルタイム追跡を必要としたのかは不明である
- EpsonのSPC7110はTengai Makyou Zero、Momotaro Dentetsu Happy、Super Power League 4で使われたデータ圧縮解除チップで、Super Power League 4にはリアルタイムクロック機能もある
- SETA CorporationのST系はゲームAI改善を目的としていたとされ、ST-010はExhaust Heat 2、ST-011はHayazashi Nidan: Morita Shougi、ST-018はHayazashi Nidan Morita Shougi 2でのみ使われた
- ST-018は内部ROMに命令を持つARM CPUのように見える
Super FX系とコミュニティ改造
- GSU-1はStar Fox、Stunt Race FX、Vortex、Dirt Racer、Dirt Trax FXの5作品で使われた
- 補助チップの中でも文書化が最も進んでいる部類で、ウィキ、チュートリアル、Super Nintendo Developer Manual Book IIの資料がある
- 10.74MHzで動作し、21.47MHzのmaster clockを内部で2分周する
- 内部512バイトのinstruction cacheのおかげで、SNES CPUを飢えさせずに動作できる
- 処理が終わると、コンソールCPUであるC-CPUに割り込みをかけられる
- SNESのPPU1/PPU2がtilemapとsprite指向なのに対し、Super FXはピクセルレンダリングとポリゴンラスタライズに強い
- 通常はカートリッジ上のフレームバッファにレンダリングする
- フレームバッファの内容はVSYNC中にVRAMへ転送される
- Star FoxのPCBには、U3のGSU-1、U5のCIC、U4の74LS139、U1のROMがあり、U2にはバッテリーなしの32KiB SRAMがある
- このSRAMはセーブデータではなく、Super FXのフレームバッファ保存のために一部使われる
- SNESコミュニティはSA-1と同様にGSU-1にも時間を投じており、Project Super FXのようなプロジェクトで過去タイトルを可能な限り改善しようとしている
- GSU-2は21.47MHzのフルスピードで動作するGSU-1で、Super Mario World 2: Yoshi's Island、DOOM、Winter Goldの3作品で使われた
- Star FoxカートリッジのGSU-1をGSU-2に置き換えて性能向上を示したコミュニティ実験がある
- SNES版DOOMのRandy Lindenは、GSUチップの文書もDOOMのソースコードもない状態ですべてをリバースエンジニアリングした
- SNES版DOOMはPCレベルを使用できる唯一のコンソール移植版で、ほかのコンソールではジオメトリを単純化する必要があった
- Yoshi's IslandはGSU-2を主にスプライトのスケーリングとストレッチに使い、加工したスプライトをPPU VRAMへ書き戻す
- Yoshi's IslandのPCBにはバッテリーがあり、SRAMがフレームバッファとセーブ状態の両方に使われる
- DOOMは32MHzにオーバークロックされ、フレームレートが10〜11fpsから14〜15fpsへ向上した
- MSU-1は実際に発売されたカートリッジに搭載されたチップではない
- Nearが、SNESでCD品質オーディオのストリーミング、FMV再生、最大4GB RAMアクセスを可能にするため設計した
- 対象はゲーム改造コミュニティであり、Enhanced Zelda III: A link to the pastとEnhanced Another Worldでその成果を見られる
エミュレータ実装に残した負担
- 補助チップはプレイヤー体験を大きく改善し、パブリッシャーのコストも削減したが、その後はエミュレータ開発者にとって厄介な課題となった
- 特異なECに依存した一部ゲームは、2012年になってようやく正しくエミュレーションされた
- 初期にはS-DD1の内部構造が分からなかったため、Street Fighter Alpha 2のようなゲームは、事前に圧縮解除されたスプライトgraphic packを要求する形で「エミュレーション」されていた
- チップ実装には相当なリバースエンジニアリングが必要だった
- 一部チップは機能がハードコードされており、de-cappingが必要だった
- ARMベースのチップのように内部ROMへ命令を保存したチップでは、エミュレータ側がBIOSファイルの提供を受ける必要がある
- 2020年時点でも、最も希少なチップの一部ではエミュレーションがまだ完了していない
1件のコメント
Hacker Newsのコメント
昔のコンソールのカートリッジが、PCのPCI拡張カードとほぼ同じだったという点が本当に良い
バスに直接つながっていて、実質的に何でもできたのだが、残念ながらこうした慣行はGameBoy Advance以降に終わり、Nintendo DSからは純粋なデータストレージに近くなった
そのため最近では、レイトレーシングチップhttps://www.youtube.com/watch?v=2jee4tlakqoのような奇妙な現代的拡張も可能だし、実物の物理チップとしては存在せず、ソフトウェアエミュレータにだけあるように見えるMSU1拡張チップも可能になっている
理論上は製造可能なので、Road Blasterの実物SNESカートリッジhttps://www.youtube.com/watch?v=BvIXUOr4yxUも作れるはず
記事本文では一覧で「Street Fighter Zero 2」がUSA ROMになっているが、Street Fighter Zeroは日本でStreet Fighter Alphaを指していた名称なので、Zero 2はAlpha 2の日本版であるべき
ここではカートリッジを現代のコンピュータで置き換えると、おかしなことが起きる。例えばNESでユーモアについての実質的なPowerPointプレゼンをする、といった具合
https://www.youtube.com/watch?v=ar9WRwCiSr0
なので機能を追加する限定的な能力はあったし、追加CPUほど面白くはなくても、GBAでもそこまでとんでもないことをした例が多かったわけではない
特定のユースケースのために計画されていたのか、それとも限定的なカートリッジ拡張部品向けの別チャネルがあったのか知りたい
ここで抜けているもう一つの細部は、拡張チップのないカートリッジでも性能等級が違っていたこと
SNES CPUは公称3.58MHzで動作したが、実際にその速度で動かすには「FastROM」カートリッジが挿さっている必要があった。Nintendoはパブリッシャーにより安価な「SlowROM」形式も提供しており、その場合CPUは2.68MHzまで低下した
SlowROMゲームをFastROMゲームに変えて遅延を減らすパッチを開発しているモッダーコミュニティもある。一部のSlowROMゲームは、もともとFastROM向けに開発されていたが、パブリッシャーのコスト削減要求によって土壇場でSlowROMに変わったように見える、という記事を読んだことがある
記憶が正しければ、その場合SlowROMを使うとカートリッジ1本あたりなんと50セント節約できると主張していた
競合機のTurboGrafx-16は通常7MHzで動作し、似たようなメモリタイミングを必要とする6502系CPUを使っていたのに、なぜSNESが速度にそこまで渋かったのか、いつも不思議だった
それでもTurboGrafxは西側市場で失敗し、SNESは世界的に成功したのだから、何か正しいことをしていたというわけだ
結局、すべてのSNESカートリッジにはマスクROMが載っていた
開発者たちには、こういう細部をYouTubeのVlogにするより、文章形式でブログに書き続けてほしい
数KBの中に多くの細部を詰め込める
「Super Mario World」は今なお最高の名作ゲーム。驚くべきキャラクター、スプライト、ステージをわずか360KBに収めていた
ZIP形式で圧縮して初めて約360KB程度になる
素晴らしい音楽、正確な操作感、魅力的なグラフィックまで、プラットフォームゲームのあらゆる面をきちんとやり切っていた
Terranigmaもほぼ同じレベルで、自分の基準ではSuper Mario Worldはおそらく3位くらい
テキストはスクレイピングされ、数語だけ変えられてSEO広告サイトに再利用できる
カートリッジに「拡張チップ」を入れられる能力を現代技術で活用したら、何ができるのか気になる
SuperFXには独自のフレームバッファがあり、その全体をVRAMへコピーすると書かれている
だとすると技術的には、とんでもなく強力なSoCをカートリッジに入れて、それでSNES解像度の現代的なグラフィックをレンダリングし、結果のフレームをSNESのVRAMへコピーすることも可能なのか?
限界がどこにあるのか気になる
「SNES版DOOMの作者であるRandy Lindenは、GSUチップのドキュメントにもDOOMのソースコードにもアクセスできなかった。すべてリバースエンジニアリングした」という部分は技術的に印象的だが、なぜそうする必要があったのか気になる
移植版の唯一のプログラマーだったRandy Lindenはゲームに魅了され、最初は独力でSuper NES向けのDoom移植に着手した。
当時Doomのソースコードはまだ公開されていなかったため、Lindenはゲームのlump構造を詳しく理解するためにUnofficial Doom Specsを参照した。リソースはIWADから抽出したが、技術的制約のため一部は使われなかった。
インタビューによると、Super FX向けの開発システムが不足していたため、Lindenは本格的な移植開発の前に、自分のAmiga上でACCESSというアセンブラ、リンカ、デバッガのツールセットを自作した。
ハードウェアキットとしては、ハックしたStar Foxカートリッジと改造したSuper NESコントローラー2個をコンソールに挿し、Amigaのパラレルポートに接続し、さらに2つのデバイスを接続するためにシリアルプロトコルを使った。
完全なプロトタイプを作った後、雇用主であるSculptured Softwareに見せ、会社が開発完了を支援した。Lindenは、削られたレベルを入れられればよかったが、ゲームはすでにSuper FX 2ゲームの最大サイズである16メガビット、約2MBに達しており、空き容量はおよそ16バイトしかなかったと語っている。
また、Super Scopeライトガン、Super NESマウス、マルチプレイ用XBANDモデムのサポートも追加した。同僚プログラマーのJohn CoffeyはDoomシリーズのファンとしてレベルを修正したが、その一部はid Softwareに却下された。
こういうものの周辺にはいつも素晴らしい歴史があり、関連する内容をここにも少し書いてある: https://eludevisibility.org/super-noahs-ark-3d-source-code
記憶が正しければ、Crash BandicootチームもSDKがなかったため独自コードで進めていて、メモリーカード保存に関するハードウェアバグを発見した。
複数のゲームのバイト数はどこから出てきたのか気になる。
ゲームはROMチップに入っており、ROMチップらしくサイズは2の累乗だった。たとえばSuper Mario Worldは512kb ROMで発売されたが、346,330バイトという数字はどこから来たのか?圧縮後のサイズなのか?
各ZIPを展開し、ファイル末尾のゼロバイトのパディングを数えるプログラムを書くべきだろう。
今日は遅すぎるので、明日書いて記事を更新するつもりだ。
ほかにも問題がある。記事ではSFA2の停止がオーディオデータの読み込みによるものだという事実をMVGが発見したかのように書いているが、その動画よりずっと前から知られていた: https://forums.nesdev.org/viewtopic.php?p=70474#p70474
RTCについてもかなり混乱しているように見える。コンソールの電源が切れていてカートリッジが抜かれていても時計を動かし続けるためのものだというのは、GBC/GBAのPokemonゲームのように明白なのに、NTSCクロックのドリフトのためかもしれない、というような言い方をしている。いったい何を言っているのか分からない。
「Super Mario Worldもこうした処理を受けた。スローになるのは覚えていないが、その時私はまだ12歳だった」という部分に関連して、Yoshi’s Island 4は特定条件でスローになる。
Yoshiに乗った状態でStarmanを取り、P-Switchを押すとそうなるし、正確には思い出せない別のレベルでもあった。Monty Moleたちが一斉にたくさん飛び出してくる場所で、Chocolate Islandだったと思う。
画面にSumo Bros.が2体とAmazing Flying Hammer Bro.が同時に出る3つ目のケースもあった気がする。
エミュレーター用ROMをカートリッジからどうやってダンプするのか、いつも理解できなかった。
命令とアセットをダンプし、エミュレーターが解釈できるデータファイルにまとめるのは分かる。だがエミュレーターは、カートリッジ内のすべての拡張チップハードウェアをどうモデル化するのか?それは元のカートリッジからどうやってダンプされるのか?
個人的には、SNESの前身であるNESのほうが状況は少し悪かったと思う。
NESにはマッパーと呼ばれる拡張チップがかなり多かった。一般的な機能は追加プロセッサや能力を加えることではなく、NESのメモリ空間を拡張することで、NESはこれらがないとPRG ROM 32KBとCHRグラフィックROM 4KBまたは8KBに制限されるため、ほとんどのゲームに搭載されていた。
NES発売後のほとんどのゲームはこうしたチップを使っていた。
これらもコンソール本体とともにすべてリバースエンジニアリングする必要があった。幸い、追加CPUやアクセラレータをリバースエンジニアリングするよりはずっと単純だった。
MMC1、MMC3のように多くのゲームで使われた一般的なチップもあれば、MMC2のように事実上Punch-Out専用のチップもある。
拡張チップの種類はそれほど多くないので、手に負えないほどではない。
SNESのコピー防止方式は、消費者の立場では簡単に回避できた。ただし、ゲーム開発会社やパブリッシャーにとってはそうではなかったかもしれない。
当時はみんなSNES用の「バックアップ装置」を持っていた。SNESに差し込み、フロッピードライブが付いた装置で、とても安い3.5インチフロッピーにゲームを「バックアップ」していた。
システムの動作に必要なのは元のカートリッジ1本だけで、それをコピー機に差し込むと、装置がそのカートリッジのCICチップを再利用していた。
https://en.wikipedia.org/wiki/Game_backup_device
「DSP-1にはDSP-1、DSP-1a、DSP-1bの3つのバージョンがあった。バグ修正とプロセス改善が入るにつれてチップの動作が少し変わり、その結果Pilot Wingsデモの飛行機が地面に墜落した」という部分を見ると、誰かにどうしてそんなに下手なのかと聞かれたら、その言い訳を使うべきだな。