NES Elite - NES向けEliteのドキュメント化されたソースコード
(github.com/markmoxon)- Ian BellとDavid BrabenによるNES向けEliteのソースコードで、すべての行にドキュメントが付いており、大半に説明があり、元のゲームバイナリの逆アセンブルから手作業で再構築されている
- 最新のコンピュータ上でソースから完全に動作するゲームをビルドし、実機のNESまたはエミュレータで読み込めるiNES ROM imageを生成できる
- 対応するバリアントはImagineerのPAL variantとIan Bellの個人ウェブサイトにあるNTSC variantで、デフォルトビルドはPAL variant
- ソースの閲覧方法は、elite.bbcelite.comで人間が読みやすい形で見るか、IDEで注釈付きソースを開く方法で、ウェブサイトとソースファイルの内容は同一
- ビルド要件はBeebAsm、Python、Mac/Linuxの
makeで、Pythonビルドは3.xでのみテストされており、Windowsにはmake.exeが含まれる- Windowsでは
make.bat、Mac/Linuxではmakeでビルドし、デフォルト出力は5-compiled-rom-imagesフォルダ内のelite-pal.NES variant=ntscでelite-ntsc.NESを生成可能
- Windowsでは
- ビルドオプションでは、バリアント選択、最大値に近いテスト用commanderの使用、元バイナリとの一致確認の省略、crc32検証の無効化などを制御できる
- 代表的な例は
make variant=ntsc commander=max match=no verify=no crc32.pyは生成ファイルと、元ソースから抽出した基準ファイルのチェックサムおよびファイルサイズを並べて比較する
- 代表的な例は
- PALとNTSCのバリアントは、NMI handlerのサイクル数、Start screenのImagineer/Nintendo heading、combat demo auto-playの待機時間、save slot checksumアルゴリズム、内部バージョン番号、隠されたcopyright message、scroll text、y-coordinate定数などに違いがある
- NTSC variantは実際のNTSC実機では動作せず、一部エミュレータのNTSC modeに合わせてNMI timingが変更されたNTSCエミュレーション
- ライセンスファイルはなく、デフォルトの著作権法が適用されるため、閲覧とforkのみが許可され、複製・配布・派生著作物の作成は認められていない
1件のコメント
Hacker News のコメント
ずっと前に Frontier で働いていたとき、David Braben から NES Elite に関する面白い逸話を聞いた。最初は NES のハードウェアタイマーで実時間を追跡し、フレームレートが違っても物理演算が一定に進むようにしていた、と記憶している
Nintendo の発売前チェックで、初期の NES の一部ではそのタイマーが正しく動作しないとして使用不可と判定されたため、Bell/Braben は各関数がそのフレームで何クロックサイクルを使ったかの独自推定値を保持し、フレーム終端で合算して経過時間を推定するようにした、と聞いた
ただ、GitHub のソースを見ると、自分の記憶違いか、Braben の話をきちんと理解していなかったようだ。
elite-source-bank-7.asmには「NES がサポートしていないハードウェアタイマーの代わりに使える NMI タイマーを更新する」というコメントがあり、マスク不能割り込みを数えて疑似的なリアルタイムクロックを実装していたように見える初期の NES CPU ダイには、バグがあり無効化されたプログラマブルインターバルタイマーの名残があった: https://www.nesdev.org/wiki/RP2A03_Programmable_Interval_Tim...
後のリビジョンでは完全に削除されており、開発キットのようなものだけで有効になっていた可能性はある。消費者向け機器で動かない機能に依存していたなら、Nintendo のテストで拒否されるのは当然だったはず
仮に発売されたコンソールにプログラマブルインターバルタイマーがあったとしても、精密なラスタ効果のようなサブフレーム測定にしか役立たなかっただろう。実時間の測定には NMI カウントのほうがずっと妥当だ。NMI は各ビデオフレームの開始時に発生し、60.0988Hz で非常に安定しており、ゲームエンジンが遅くなってフレームレートが変わっても、CPU 側の処理はビデオ信号のタイミングに影響を与えられない
ちなみに、オーディオハードウェアもタイマー割り込みを作れるし、多くの拡張チップにはレンダリング同期用のスキャンラインカウンターがある。NES で時間を測る方法には事欠かない
あるゲームを Nintendo に承認してもらおうとしたとき、米国版 NES の特定の 1 バージョンで動作しない、あるいはシステムの過熱を引き起こした、と聞いた。発売スケジュールが厳しく、Nintendo 本社まで飛んで解決しなければならず、その特定バージョンの流通量は 100 台未満だったと記憶している
後で未刊行本のメモを見つけたところ、実際には少し違っていた。ゲームテストはゲームプレイだけに限られず、動作し得るすべての NES コンソールのバリエーションでテストしなければならなかった。Beam Software の Andrew Davie は、「The Three Stooges」がワシントンの Nintendo オフィスにあるテスト用 NES で問題を起こしたため、自分で出向いたと回想していた
彼によると、ゲームが合格するにはチップメーカーの組み合わせ違いなど「マシンのバリエーションが 23 種類ほど」あり、公式ドキュメント不足のせいで、彼はスプライトデータを公式推奨のように RAM に書くのではなく、2 秒ごとに直接書き込むようにしてしまい、NES が過度に熱くなり、ゲーム全体でスプライトのちらつきが発生したという。修正後に発売承認を受け、問題の NES の組み合わせは米国全体で約 5 台しかないとして、Nintendo のテストラインアップから外されたと聞いた
最近、続編である Elite: Dangerous を始めた。問題がないわけではないが、かなり驚く体験だ
1984 年版から続くゲーム要素を見るのは、不思議と感動的だった。当時最新だった 16K メモリマップ画面のベクターグラフィックスで見ていた船、特に Coriolis ステーションが、4K/60fps の完全な 3D レンダリングに変わったのを見ると、思った以上に感情を揺さぶられた
広告板、植物、ドッキング設備まで備えた詳細な Coriolis の内部をついに見られたのは、正直、少し目頭が熱くなるほどだった。現在いろいろ難しさがあっても、このゲームは大切な遺産であり、何らかの形で残り続けてほしい
Blue Danube を聴きながら宇宙船を手動ドッキングするのは、いつも心地よい体験だった
宇宙シミュレーターや宇宙ゲームは、なぜいつもこんなに問題を抱えることになるのか不思議だ。Elite Dangerous はどこにも進めていないように見えるし、Star Citizen は永遠のベータのようで、KSP2 も期待外れだった
9 年前に書いた考え: https://hypertexthero.com/elite-dangerous-education/
Odyssey 拡張パックも面白いし、いつか船外活動の宇宙遊泳や無重力ミッションが追加されるといいと思う
原作にかなり忠実なC版である Elite - The New Kind もある: https://github.com/fesh0r/newkind
Christian Pinderが作ったもの: https://www.christianpinder.com/games/
Ian BellのEliteホームページも見る価値があり、オリジナル版がいくつもある: http://www.ianbellelite.com/
1991年のNES版の核心、つまり128K ROMのおよそ30%は、本質的には1986年のBBC Master版であり、それ自体が1984年の元祖BBC Micro版の発展形である。Commodore 64版とApple II版も同じ系譜で、開発もBBC Micro上で行われた
バンク0、1、2のコードの大部分は元のBBC版から直接持ってきたもので、バンク7にもさらに一部がある。前段に新しいグラフィック、サウンド、コントローラールーチンが付けられているが、鼓動している心臓部はいまも Beeb版 だ
Eliteの作者であるIan Bellは、NES版を自分が最も好きな 8ビットElite版 だと言っていた
全体としては32ビットArchimedes移植版がいちばん好きだったという
インタビュー全文は http://www.elitehomepage.org/archive/b5081501.htm にある
これは、彼が最も好きなバージョンは BBC Microカセット版 で、最も好きな移植版はNES版、という意味だと解釈している。ただし、BBCのファンボーイなので希望的に解釈しているだけかもしれない
各バンクの先頭にこういう バンク切り替えshim が入っているのが気に入っている
SEI/INC $C006/JMP BEGIN省スペースのためにこうしているという説明が詳しく出てくるが、私の目には、
JMPが必要な唯一の理由は命令パイプラインのためで、NOPだけでもフラッシュできそうに見えるなので私の2バイト最適化はこうだ:
SEI/INC $FFFD ; 命令ベクタ内のC0を代わりに使う/NOPJMPが必要な唯一の理由は命令パイプラインのため」というのも正しいが、人間にとっても意味は通る。実行は バンク7 から始まるので、バンク7へジャンプするということだ余談だがGame Boyではエントリーポイントが固定バンクであるROM0にあるため、少なくとも一般的なMBCではそもそもこうした問題はない
比較対象として、Objective-Cで書かれたオープンソースのEliteクローン Oolite のソースコードがある: https://github.com/OoliteProject/oolite
https://oolite.space
https://news.ycombinator.com/item?id=7894145
8歳のときにC64でこれをプレイした。30年経った今でもこのコードは理解できない
バンク0だけでアセンブリ18,305行だなんて、これをどうやって頭の中に維持していたのか見当もつかない
最高レベルのツールがあったとしても、コードを追跡するには途方もない組織力と規律が必要だったはずだ。80年代初期の Hitachi 6303[0]/Motorola 6800[1] 向けアセンブラを調べたが、こうしたツール上の制約の中で人々が成し遂げたことには驚かされる
たとえば下の2つのアセンブラでは、ラベルは6文字までしか使えず、サブルーチン内部専用のローカルラベルもなかった。自分の作業では説明性のためにラベルを40文字に制限していたが、それでもそう感じた
ただ、こうしたアーキテクチャの相対的な単純さは、現代のシステム組み込み作業と比べると本当に新鮮だ。システム全体の状態をおおよそ頭に入れられるというのは、間違いなく利点がある
0: http://www.bitsavers.org/components/hitachi/_dataBooks/U24_H...
1: http://www.bitsavers.org/components/motorola/6800/exorciser/...
全体として、アセンブリプログラミングも高水準言語と大きくは違わない。コードを関数やブロックなどに整理する。ジャンプが絡み合った超長大なコードの壁を1つ書くのは、深刻な問題を自ら招く行為だ
自由ソフトウェアではないのが残念だ。自分が Elite の作者だったなら、すべてのゲーム移植版を自由ライセンスで公開していただろう
いずれにせよ、今では安価なネットブックで Oolite をプレイできるし、膨大なアドオン一覧のおかげで同じか、それ以上に楽しめる
Braben 側は Elite 4/Elite: Dangerous を作っていたので、著作権を弱めたくなかったのだと思う
すべてのソースコードはこの程度には文書化されるべきだ