プロローグ — なぜ 2026 年に 6502 か
あなたは今日も React Server Component をデバッグしてイライラしたはずだ。どのコードがどのランタイムで走るかを追いかけ、「これはサーバで動く?クライアントか?両方か?Edge か?」という問いにきれいな答えを得られなかったはずだ。あるいは Kubernetes Pod が OOMKilled になり、どのメモリページがどこへ行ったかを正確には言えず、メモリ上限を倍にして帰宅したはずだ。
レトロコンピューティングは、その正反対の世界だ。
- 64KB のアドレス空間。 すべてのバイトの行方が分かる。実際、分からなければいけない。
- 1.79MHz の CPU。 命令ごとに何サイクルかかるかを覚える。サイクルカウンティングがデバッグの基本だ。
- 割り込みは 2 種類のみ。 NMI と IRQ。それで全部だ。非同期はこれだけ。
- グラフィックスメモリは別チップに住む。 PPU(Picture Processing Unit)。通信プロトコルを自分で書く。
- コンパイル 1 秒。 ビルドキャッシュなど不要だ。
これは学習ツールとして、また週末の楽しみとして、2026 年の開発者に最適な趣味だ。理由は単純で、現代の抽象化のあらゆるリークは、結局のところレトロプログラマが毎日相対していた問題に還元される。 メモリアライメント、キャッシュライン、DMA、割り込み優先度、リソース競合。これを 8 ビット機で一度でも直接扱った人と、そうでない人ではデバッグが違う。
そして正直に言って — 楽しい。 ポリゴン 1 枚が画面に出るのに 5 秒かかった時代は終わったが、スプライト 1 枚が正しいスキャンラインで出るように NMI ハンドラを調整するあの感覚は今もここにある。小さな画面、大きな制約、すべてのバイトを自分で決めるという全能感。SaaS の時代に失われた種類の喜びだ。
本稿で扱うもの:
- レトロハードウェア — 6502・Z80・8086 のアーキテクチャと、なぜそれが学習に向いているか
- 現代のレトロツールチェーン — cc65・GBDK・CA65・SDCC・z88dk
- デバッガ — Mesen・bgb・bsnes-plus・FCEUX のタイムトラベルとメモリビュー
- ファンタジーコンソール — PICO-8・TIC-80・LIKO-12。なぜ「ファンタジー」で、なぜルネサンスか
- コミュニティ — NESDev・AtariAge・GBADev・Pouet・デモシーン
- 最初の週末プロジェクト — 「自分の最初の 6502 ROM」実戦 12 時間コース
- 大人の言い訳 — これが仕事に役立つか(そして役に立たなくても良い理由)
1 章 · 8 ビット機の解剖学 — 6502 と Z80 と 8086
まず 1 枚の図から。
┌──────────────────────────────────────────┐
│ 6502 CPU (NES, 1.79 MHz) │
│ │
│ A (8b) X (8b) Y (8b) │
│ PC (16b) SP (8b, 0x0100-0x01FF) │
│ P (8b: NV-BDIZC flags) │
└────────────┬─────────────────────────────┘
│ 16-bit address bus -> 64KB
│
┌────────────┴─────────────────────────────┐
│ 0x0000-0x07FF : 2KB internal RAM │
│ 0x0800-0x1FFF : RAM mirrors │
│ 0x2000-0x2007 : PPU registers │
│ 0x2008-0x3FFF : PPU mirrors │
│ 0x4000-0x4017 : APU & I/O │
│ 0x4020-0x5FFF : cartridge expansion │
│ 0x6000-0x7FFF : cartridge SRAM (opt.) │
│ 0x8000-0xFFFF : 32KB cartridge PRG-ROM │
└──────────────────────────────────────────┘
この 1 枚のメモリマップが NES のすべてだ。これより深い抽象も、これより浅い抽象もない。カートリッジを差せば 0x8000 からゲームコードがマップされる。
6502 — シンプルさの名匠
6502 は 8 ビット CPU だが、その単純さはほとんど詩のレベルにある。
- レジスタ 3 個。 アキュムレータ(A)、インデックス X、インデックス Y。それだけ。
- スタックは 256 バイト。
0x0100から0x01FFまで固定。 - 命令 56 個。 1 日で覚えられる。
- アドレッシングモード 13 種。 zero-page、indirect-indexed、indexed-indirect — この言葉は一生頭に残る。
最小の 6502 プログラム。NES の画面を青で塗りつぶす。
; init.s - 6502 assembly for the NES
; 画面全体を青で塗る最小のプログラム
.segment "HEADER"
.byte "NES", $1A ; iNES マジック
.byte 2 ; PRG ROM 2 * 16KB = 32KB
.byte 1 ; CHR ROM 1 * 8KB
.byte $01, $00 ; マッパー 0、垂直ミラーリング
.byte 0, 0, 0, 0 ; パディング
.byte 0, 0, 0, 0, 0
.segment "STARTUP"
reset:
sei ; 割り込み無効
cld ; 10 進モード解除
ldx #$ff
txs ; スタックポインタ = $FF
; PPU ウォームアップ待ち(2 回)
bit $2002
vblankwait1:
bit $2002
bpl vblankwait1
vblankwait2:
bit $2002
bpl vblankwait2
; 背景パレット: $3F00 = ユニバーサル背景色
lda #$3f
sta $2006
lda #$00
sta $2006 ; PPU アドレス = $3F00
lda #$01 ; 色 $01 = 青
sta $2007 ; PPU に書き込み
; PPU を有効化
lda #%00001000 ; show background
sta $2001
forever:
jmp forever
.segment "VECTORS"
.word 0 ; NMI
.word reset ; Reset
.word 0 ; IRQ
React を書いている日々の中で見たことのないコードだろう。だが見てほしい — この 30 行の中にゲーム機まるごとが入っている。 マップされたメモリアドレスに直接書くことで PPU と通信する。抽象は無い。マニュアルがそのまま API だ。
Z80 — もう少し人間味のある 8 ビット
Z80 は 6502 より少しだけ豪華だ。Game Boy、MSX、ZX Spectrum がすべてこのチップ。
- レジスタが多い。 A、B、C、D、E、H、L。ペアで BC、DE、HL。
- インデックスレジスタが 2 本 IX、IY。
- シャドウレジスタセット。 割り込みハンドラで
EXX1 命令でコンテキストスイッチ。 - 命令 700+。 6502 より覚えることが多い。
Z80 は「アセンブリも人が書けるべきだ」という哲学に寄っている。6502 は「最小限でいい」に寄っている。どちらが良いかは宗教戦争で、両方やると両方が好きになる。
8086 — IBM PC の出発点
8086 は 16 ビットだが、悪名高い セグメントレジスタ を持つ。
- セグメント + オフセット = 物理アドレス。
CS:IP、DS:SI、SS:SP、ES:DI。 - 各セグメント 64KB。 16 ビットレジスタで 1MB のアドレス空間を見る。
- MS-DOS の
INT 21h。 OS 呼び出しが 1 つの割り込みベクタにまとまる。
8086 は 6502 より豊かで、Z80 より整理されているが、セグメントが頭を痛める。現代の x86-64 アセンブリがなぜ今の形なのかを知りたければ、8086 から見るのが最短だ。
なぜこれが学習に良いか
3 つのチップに共通する点 — 機械の全部が頭に入る。
- 全レジスタ、全命令、全メモリ領域を暗記できる。
- 命令ごとのサイクル数が分かる。命令表は 1 ページに収まる。
- 割り込みは多くてもいくつか。非同期モデルが完全に可視化される。
- コンパイラ無しで書く。アセンブラ出力がそのままメモリに乗るバイトだ。
これを 1 度通ると、「機械が本当は何をしているのか」が分かる。 現代の CPU はもっと複雑だが、原理は同じだ — レジスタ・メモリ・割り込み。64KB の中で身につけた直感が、64GB のサーバでもそのまま働く。
2 章 · 現代のレトロツールチェーン — ROM も C で焼ける
レトロだからアセンブリしか書けない時代は終わった。2026 年の NES 開発者は C で書く。 アセンブリは要る(コンパイラ出力を読まなければいけない)が、日常の 90% は C だ。
cc65 — 6502 の C コンパイラ
cc65 は 6502 系のための C コンパイラとアセンブラ群。NES、Atari 2600/8-bit、Commodore 64、Apple II、Atari Lynx を 1 つのツールで扱える。
# cc65 のインストール(macOS)
brew install cc65
# Hello World をコンパイル
cc65 -O -t nes hello.c
ca65 hello.s
ca65 -t nes crt0.s
ld65 -C nes.cfg -o hello.nes crt0.o hello.o nes.lib
# エミュレータで実行
mesen hello.nes
5 行で NES ROM が出来上がる。これが 2026 年だ。
cc65 が生成する C は 現代の C ではない。 関数呼び出しが高価(スタックをソフトウェアで模す)なので、グローバル変数を多用し、インラインを積極的に使う。コンパイラは親切ではない — オプティマイザは単純で、インラインアセンブリ(例えば __asm__("lda #$00"))を頻繁に混ぜる。
そしてそれが良い。C が本当にどのコードに化けるかが見える。 現代の LLVM が出す魔法のような結果ではなく、「この C の 1 行がアセンブリの 5 行になる」というのが目に見える。
CA65 — アセンブラ
純粋にアセンブリで書くなら ca65(cc65 パッケージ同梱)を使う。強力なマクロ、セグメント定義、条件アセンブリ、include — 普通にモダンだ。
; マクロで関数呼び出しっぽくする
.macro CALL routine
jsr routine
.endmacro
; 条件アセンブリ(マッパーごとに別コード)
.if MAPPER = 1
; MMC1
.elseif MAPPER = 4
; MMC3
.endif
GBDK — Game Boy の C コンパイラ
Game Boy は Z80 のいとこ(Sharp LR35902)を使う。GBDK はその上の C ツールチェーンだ。
brew install gbdk
lcc -Wa-l -Wl-m -Wl-j -o hello.gb hello.c
# hello.gb が本物の Game Boy ROM
GBDK はスプライト・タイル・サウンド・入力のヘルパーを備えていて、cc65 より入りやすい。Game Boy の LCD にタイルを置くのが 1 行だ。
// hello_gb.c
#include <gb/gb.h>
#include <stdio.h>
void main() {
printf("Hello, Game Boy!\n");
while (1) {
wait_vbl_done(); // VBlank 待ち = 1 フレーム
}
}
これが本物の Game Boy で動く。16 ビット PC でコンパイルした ROM が、1989 年のハードウェアで実行されるのだ。
SDCC と z88dk — 一般 Z80
SDCC(Small Device C Compiler)は Z80・MCS-51・HC08 などの C コンパイラ。z88dk は ZX Spectrum・MSX・CP/M など Z80 システム全般のツールチェーンだ。
アセンブリ vs C — どこをどちらで?
| 作業 | アセンブリ | C |
|---|---|---|
| ゲームロジック | 可能だが苦痛 | 適 |
| NMI ハンドラ | ほぼ必須 | インライン asm |
| サイクル精度の IRQ 分岐 | アセンブリのみ | 不可 |
| データテーブル | アセンブリマクロ | 配列 |
| サウンドエンジン | 概してアセンブリ | 可能 |
ルールは単純 — タイミング精度が命の箇所はアセンブリ、それ以外は C。 最初は 両方を少しずつ やって、自分に合う方に落ち着けば良い。
3 章 · デバッガ — タイムトラベルとメモリビューの復活
ここからが本番だ。現代のデバッグで失ったものが、レトロデバッガには全部ある。
Mesen — NES デバッグのゴールドスタンダード
Mesen は NES・Famicom・Game Boy・SNES・PC Engine を 1 つで動かせる精密エミュレータ。そしてデバッガが 圧倒的だ。
Mesen が備えるもの:
- タイムトラベルデバッガ(rewind)。 直近数分の実行を巻き戻し、1 サイクル単位で前後に動く。
- メモリビューア。 RAM、PRG-ROM、CHR-ROM、OAM、パレット、ネームテーブルをリアルタイム表示。
- イベントビューア。 1 フレーム分の PPU と CPU のイベントすべてを 1 枚の格子で可視化。どのスキャンラインでどの命令が走るかをピクセル単位で見える。
- トレースロガー。 実行されたすべての命令をディスアセンブリで記録。
- CDL(Code/Data Log)。 ROM のどのバイトがコードでどれがデータかを自動でラベリング。
- Lua スクリプト。 デバッガ内に Lua フックを書く。「この変数が変わったら画面に表示」みたいなのが 5 行で書ける。
このツールが ある意味で 2026 年の Chrome DevTools より強い という事実が、我々が失ったものを物語る。
bgb — Game Boy 最強のデバッガ
Game Boy デバッグの標準は bgb。Windows で最も良く、macOS/Linux では Wine で動く(またはクロスプラットフォームの兄弟 SameBoy)。
- メモリ、レジスタ、スタック、I/O ビュー
- ブレークポイント(アドレス・条件)
- スプライトビューア、タイルビューア
- ディスアセンブリ
bsnes-plus — SNES の精密デバッガ
bsnes-plus は SNES 用精密エミュレータ。byuu の bsnes にデバッガを足したフォーク。メモリ・トレース・ブレークポイント、フル装備。
FCEUX — NES の古典
FCEUX は今も保守されている最古の NES デバッガ。Mesen 登場前は標準だった。今でも軽くて速く、NES の動画フォーマット(fm2)と TAS(Tool-Assisted Speedrun)コミュニティは今もここを中心に動く。
SameBoy — macOS/Linux のネイティブ Game Boy
bgb が Windows 中心なら、SameBoy は macOS と Linux でネイティブに動く。デバッガは Mesen 並みに良く、精度もトップ級。
失われたもの
現代のデバッガにできない、しかしレトロデバッガが毎日やっていること。
- タイムトラベルがデフォルト。 Chrome DevTools の「Time Travel」は今も β だが、Mesen は 10 年前からサイクル単位の巻き戻しをやっている。
- ハードウェアイベントの可視化。 どのスキャンラインでどの IRQ が立ったか?1 フレームでメモリのどの領域に何回触れたか?1 枚の格子で全部分かる。
- すべての状態が見える。 64KB は 1 画面に収まる。Pod の 16GB ヒープを人の目で見る日は永遠に来ない。
レトロデバッガを 1 週末通ると、「デバッガがここまでやれるのか」 が頭に刻まれる。そして現代デバッガの限界が、自然法則ではなく選択に見えてくる。
4 章 · ファンタジーコンソール — PICO-8、TIC-80、LIKO-12
ここからルネサンスの話だ。
ファンタジーコンソール(fantasy console) とは「実在しなかった架空の 8 ビット/16 ビット機」を模した開発環境だ。本物の 6502 ではないが、その精神を継ぐ — 小さな画面、限られたパレット、限られたメモリ、単純な API。
PICO-8 — すべての始まり
Lexaloffle の PICO-8 がこの運動の出発点。スペックを見てみよう。
- 画面: 128 x 128、固定 16 色
- コード: Lua、8192 トークンまで(行数ではなくトークン数)
- スプライト: 128 枚、各 8 x 8 ピクセル
- マップ: 128 x 32 タイル
- サウンド: SFX 64、パターン 64、4 チャネル
- コントローラ: 6 ボタン(上下左右、O、X)
- カートリッジ: 32KB、友人に渡せばその場で編集可能
この制約こそが本質だ。PICO-8 のカートリッジは、1 人が 1 週間で完成できるサイズだ。 それが意図された設計。
PICO-8 の Lua は標準 Lua の部分集合 + ゲーム向け API。
-- pico-8 cart: hello.p8 -- 最小のゲーム
-- 矢印キーで動く点
x=64 y=64
function _update()
if btn(0) then x-=1 end
if btn(1) then x+=1 end
if btn(2) then y-=1 end
if btn(3) then y+=1 end
end
function _draw()
cls()
pset(x,y,11)
print("pico-8!",40,60,7)
end
15 行。15 行にゲームの核心構造が入っている。 入力・更新・描画。あらゆるゲームエンジンは結局その 3 段に還元される。PICO-8 が教えるのはまさにそれだ。
PICO-8 のコンソール自体に BBS(splore)が組み込まれていて、カートリッジを直接検索・ダウンロードできる。毎週、新しいものが数十本上がる。誰でも瞬時にソースが読める — カートリッジがそのままソースだ。
TIC-80 — オープンソースの代替
TIC-80 は PICO-8 のオープンソースのいとこ。
- 画面: 240 x 136、16 色(パレット編集可)
- コード: Lua・Moonscript・JS・Wren・Fennel・Squirrel・Python — 7 言語サポート
- スプライト: 256 枚
- サウンド: 4 チャネル
- 無料、オープンソース、ブラウザでも動く
PICO-8 の有料(USD 15 前後)が引っかかるなら TIC-80 が答え。仕様は PICO-8 より少し寛大、言語の選択肢が広い。コミュニティは PICO-8 より小さいが活発。
LIKO-12 — LOVE2D 上のフレンドリーなファンタジーコンソール
LIKO-12 は LOVE2D 上で動くもう 1 つのファンタジーコンソール。PICO-8 に似た設計だがカートリッジが大きく、制約が緩い。学習用に向く。
その他 — Pixel Vision 8、Pyxel、GB Studio
- Pixel Vision 8 — C# ベース、カートリッジ単位
- Pyxel — Python ベースのファンタジーコンソール。ML エンジニアに親しみやすい
- GB Studio — 本物の Game Boy ROM をビジュアルノードエディタで作る。コード無しで実 ROM が出力される
なぜ「ファンタジー」コンソールか
名前が奇妙だ。実在しなかった機械 を模す意味は?
理由は 2 つ。
- 制約が創造を生む。 PICO-8 の 8192 トークン制限、128 x 128 画面、16 色パレットは恣意的に見えるが、これが人を 完成可能な小さい作品 に押し込む。AAA を始めたインディは 99% 完成しない。PICO-8 カートを始めた人は 1 週間に 1 本仕上げる。
- 著作権のないノスタルジー。 本物の NES や Game Boy 開発も可能だが、任天堂の IP や廃棄された SDK は法的にグレー。ファンタジーコンソールは最初から自分のものなので自由だ。
ファンタジーコンソールは 2026 年に 8 ビット時代の精神を蘇らせたもの だ。韓国・日本・米国・東欧の小さなインディシーンがこれを中心に集まる。
5 章 · コミュニティ — 50 年経っても生きている人たち
レトロコンピューティングは人なしには成り立たない。幸い、人は多い。
NESDev Wiki — NES 開発のバイブル
nesdev.org の wiki はインターネット上で最も整理されたハードウェアドキュメントの 1 つ。すべてのマッパー、すべての PPU ビット、すべての APU チャネルの挙動がサイクル単位で書かれている。新作を作る人々が 30 年かけて積み上げてきた成果だ。
合わせて見るべきもの:
- NESDev BBS — 質問と回答がリアルタイムで飛び交う
- NESDev Discord — 活発なチャット、毎週新しいカートが共有される
- wiki.nesdev.org/w/index.php/Programming_guide — 入門ガイド
AtariAge — Atari のメッカ
Atari 2600・5200・7800・8 ビットコンピュータ・Lynx・Jaguar — 全機種を扱う巨大フォーラム。毎年新作カートが数十本リリースされる。そう、2026 年に新しい Atari 2600 カートが出る。 それが AtariAge だ。
GBADev / Game Boy Dev — Game Boy と GBA
gbadev.org(Game Boy Advance)と gbdev.io(Game Boy classic + Color)が Game Boy 開発者のハブ。GBDK・rgbds などのツールチェーン、マニュアル、デモ、新作ゲームがすべてここに集まる。
6502.org — 6502 全般
NES だけでなく Commodore 64、Apple II、Atari 8 ビット、BBC Micro まで — 6502 ファミリ全体を扱うサイト。30 年分のアセンブリチュートリアルが積まれている。
Pouet — デモシーンの宝庫
pouet.net はデモシーン(demoscene)の中央データベース。デモシーン は 1980 年代欧州で始まったコンピュータアート運動で、制約あるハードウェア上で音楽・グラフィックス・コードを組み合わせた短いプログラム(demo・intro・tracker)を競う文化だ。
- 64K イントロ — 64KB の中に 3D・音楽・エフェクトすべてを詰める
- 4K イントロ — 4KB。0.004 メガバイト。映像作品 1 本が入る
- 256 バイトイントロ — 256 バイト。1980 年代のツイート 1 行サイズの ROM で画面が動く
デモシーンはデジタル時代の最高峰の craft。Revision、Assembly、Demosplash のような年次パーティが今も開かれている。2026 年も 64K イントロのコンペが開かれる。 これが人々が手放さなかった craft だ。
Demozoo、Scene.org
demozoo.org と scene.org はデモ・イントロのアーカイブ。30 年分のすべてのデモをダウンロードして自分の PC で動かせる。タイムカプセルだ。
r/EmulationDev、r/PICO8、r/GameBoyDevelopment
Reddit の小さなサブも活発。PICO-8 サブレディットは毎週カートの共有とコードレビューが行われる。
6 章 · 週末プロジェクト — 最初の 6502 ROM を焼く 12 時間コース
理論は終わりだ。実際に作ろう。
土曜日の午前 — 環境構築(1 時間)
# macOS
brew install cc65 mesen
# または Linux
sudo apt install cc65
# Mesen は .NET 6 必要、github.com/SourMesen/Mesen2 リリースからダウンロード
土曜日の午前 — Hello World ROM(2 時間)
GitHub の bbbradsmith/NES-ca65-example をクローン。これが cc65 ベースの NES 開発の標準的出発点。
git clone https://github.com/bbbradsmith/NES-ca65-example
cd NES-ca65-example
make
mesen example.nes
画面に「Hello World」が出る。最初の NES プログラム だ。Makefile を開いてビルドを追う。.s ファイルを開いてアセンブリを読む。Mesen のデバッガを開く。 F10 で 1 命令ずつ実行する。
土曜日の午後 — コントローラ入力(3 時間)
NES のコントローラは 8 ビットシフトレジスタ。$4016 に 1 を書くと入力をラッチ、0 を書くとシフト開始。あとは $4016 を 8 回読むと A・B・Select・Start・Up・Down・Left・Right が順に出る。
read_controller:
lda #$01
sta $4016 ; ラッチ開始
lda #$00
sta $4016 ; シフト開始
ldx #8
loop:
lda $4016 ; 1 ビットずつ読む
lsr ; ビット -> carry
rol controller ; carry -> controller
dex
bne loop
rts
controller 変数の各ビットが各ボタン。この 8 行が NES の入力システムの全部だ。 Chrome で addEventListener("keydown", ...) を書いてきた人には新鮮なはず — 割り込みなし、ポーリングのみ、8 回読んで終わり。
土曜日の夕方 — スプライトを動かす(4 時間)
NES の OAM(Object Attribute Memory)は 64 スプライトスロット。各スプライトは 4 バイト(Y・タイル・属性・X)。1 フレームに 1 回、$2003 と $2004 で OAM を更新する(または $4014 経由のページ DMA)。
PICO-8 では spr(0, x, y) の 1 行で済んだのが、NES では 12 行の OAM 更新ルーチン。その差が学習だ。
日曜日の午前 — サウンド(2 時間)
NES の APU はチャネル 5 つ — パルス 2 本($4000-$4007)、三角波($4008-$400B)、ノイズ($400C-$400F)、DMC($4010-$4013)。各チャネルのレジスタに直接書くと音が鳴る。
; パルス 1 チャネルで A4 (440Hz) を出す
lda #%10111111 ; duty 50%、無限長、音量 15
sta $4000
lda #%00001000 ; sweep オフ
sta $4001
lda #$fd ; period 下位バイト
sta $4002
lda #$00 ; period 上位バイト
sta $4003
4 つのレジスタに書くと、NES が歌う。サウンドカード抽象なしに合成チップを直接操作する経験だ。
結果 — 12 時間で何が出来上がるか
土日 2 日が終わると、あなたは次のものを持っている。
- 「Hello World」ROM
- コントローラでスプライトが動く ROM
- 当たり判定とスコア表示が入った小さなゲームのプロトタイプ
- 単純な BGM 1 曲
- そしてそれらすべてがどう動くかについての頭の中のモデル
そのモデルが最大の収穫だ。64KB の中で 60Hz の 1 フレームを自分で書いた経験のある人のデバッグは、その後ずっと違う。
7 章 · 大人の言い訳 — 仕事に役立つか
レトロを始めた友人に我々はよく聞く — 「で、それ仕事に役立つの?」答えは 2 つある。
役立つ、本当に
- メモリアライメントとキャッシュライン。 6502 では zero-page(
0x0000-0x00FF)が他より速い。1 サイクル差。現代の CPU も同じだ。 L1・L2・L3・メインメモリ。同じ直感が働く。 - 割り込みレイテンシ。 「NMI は次フレームまでに終わらなければいけない」という制約が、「キューが詰まったらどうなる」という現代分散システムの問いと構造的に同じだ。
- 命令サイクルカウンティング。 「この関数は 200 サイクルか?」を自然に考えるようになる。CPU バウンド分析が直感になる。
- DMA の本質。 NES の OAM DMA は 1 フレームに 1 回、ページ 1 枚を PPU へまるごと送る。これを見ると、PCIe DMA、GPU テクスチャアップロード、NVMe キューの動作が 1 行で理解できる。
- エラーコードのない世界。 関数は carry フラグで成否を伝える。Result/Option 型がなぜ発明されたかが、carry を一度使えば分かる。
役立たなくても良い
そして正直に言って — 役立たなくても良い。 すべての趣味が仕事に直結する必要はない。クラシックギターを弾く人がエレキも上手くなるわけではない。それでも楽しい。
レトロコンピューティング最大の価値は 喜び だ。小さな画面、大きな制約、毎週仕上がるプロジェクト、50 年経っても生きているコミュニティ、デバッガのタイムトラベル、すべてのバイトを自分で決める全能感 — SaaS の時代に失った種類の喜び。
あなたが今週 React で書いたコード 100% は、半年後には消えているかもしれない。今夜書いた PICO-8 カート 1 本は 30 年後も同じように動く。その差が craft だ。
エピローグ — 8KB ROM の中の魂
この長い文章を 1 行に圧縮すると、こうなる。
「64KB の中に宇宙を作れる。そしてその宇宙は 30 年経っても同じように動く。」
スターターチェックリスト
今週末始めるなら:
-
brew install cc65 mesen(または OS 別の同等コマンド) - PICO-8 か TIC-80 をインストール(TIC-80 は無料)
-
bbbradsmith/NES-ca65-exampleをクローン、make - Mesen で ROM を開き、F10 で 1 命令ずつ実行
- NESDev wiki を 30 分読む
- Pouet で 64K イントロを 1 本見る
- 最初のカートを PICO-8 BBS に投稿(または itch.io へ)
アンチパターン
- AAA ゲームを始めない。 1 週間で仕上がるサイズから始める。最初のカートは「ボールが画面をバウンドする」程度が適当。
- アセンブリを先に全部覚えようとしない。 必要な命令をその都度見る。命令表は机の横に置く。
- エミュレータだけで終わらない。 1 度は自作 ROM を実機で動かす。
EverDriveのようなフラッシュカートを使えば実 NES で自分の ROM が走る。 - 1 人でやらない。 NESDev Discord、PICO-8 BBS、AtariAge — 人がいる場所に参加する。
- 未完成のカートを長く持ちすぎない。 80% で 1 年寝かせるより、50% を 1 週間で出す方が良い。
次回予告
次回は 「PICO-8 で 7 日間にゲーム 1 本仕上げる — 8192 トークンの詩」(仮題)で、本稿の 4 章で触れた PICO-8 を本格的に扱う。トークン節約テクニック、ゼロから始めるゲームデザイン、BBS への投稿まで — 週単位スケジュールで整理する。
その次は 「デモシーン、64KB の中の宇宙 — イントロ 1 本がどう作られるか」(仮題)で、デモシーンの歴史と現在、そして最初の 256 バイトイントロを書くガイドを扱う。
「抽象が積まれすぎたら、たまには床まで降りてみる。そうしないと、その上に何が積まれているかが見えない。」
— レトロコンピューティングに戻ってきた、ある週末、終。
参考 / References
- NESDev Wiki
- NESDev BBS
- cc65 — 6502 C コンパイラ
- GBDK — Game Boy Development Kit
- Mesen — NES/SNES/GB マルチプラットフォーム精密エミュレータ
- bgb — Game Boy デバッガ
- SameBoy — macOS/Linux 用 Game Boy エミュレータ
- bsnes-plus — SNES デバッガフォーク
- FCEUX — NES エミュレータ
- 6502.org
- PICO-8 公式
- TIC-80 公式
- LIKO-12 GitHub
- Pyxel — Python ファンタジーコンソール
- GB Studio — Game Boy ビジュアル IDE
- AtariAge — Atari コミュニティ
- GBADev — Game Boy Advance 開発
- gbdev.io — Game Boy classic/Color
- Pouet — デモシーンデータベース
- Demozoo — デモシーンアーカイブ
- Scene.org — デモファイルアーカイブ
- SDCC — Small Device C Compiler
- z88dk — Z80 ツールチェーン
- Easy 6502 — ブラウザで 6502 を学ぶ
- NES-ca65-example — cc65 ベースのスターター
- Famitracker — NES 音楽トラッカー
- EverDrive — 実機用フラッシュカートリッジ
- Revision Demoparty — 年次デモシーンパーティ
현재 단락 (1/324)
あなたは今日も React Server Component をデバッグしてイライラしたはずだ。どのコードがどのランタイムで走るかを追いかけ、「これはサーバで動く?クライアントか?両方か?Edge か...