$30 off During Our Annual Pro Sale. View Details »

ファミコンに思いを馳せる〜エミュレータ自作を添えて〜

Avatar for noharu36 noharu36
December 01, 2025

 ファミコンに思いを馳せる〜エミュレータ自作を添えて〜

Avatar for noharu36

noharu36

December 01, 2025
Tweet

More Decks by noharu36

Other Decks in Programming

Transcript

  1. 自己紹介 • 名前: 能島明希 • ハンドルネーム: harukun • 出身: 広島->岡山->大阪->東京->会津 • 技術: フロント(React+TS),     バックエンド(Rust,

    Go勉強中),     その他(Rust, Haskell勉強中),     Rust(Rust) • 好きなもの: ゲーム、タバコ、炒飯、 Rust、Neovim • 落とした単位数: おそらく同期内1位 • Twitter: https://twitter.com/pieceofharuki • Blog: https://zenn.dev/haru_blog
  2. 基本情報 • 1983年7月15日発売 正式名称ファミリーコンピュータ • 累計出荷台数6000万台 • 当時の家庭用ゲーム機 脅威の80%シェア • 世帯普及率25% 小中学生がいる家庭のほとんど •

    スーパーマリオブラザーズ 世界売上 4000万本 2020年にあつ森に抜かれるまで 30年以上国内売上1位 今でも歴代世界売上本数6位
  3. 技術 • CPU Ricoh 2A03 MOS 6502(Apple Ⅱに搭載)をカスタマイズしたもの 当時よく使われていたz80に比べクロック数は劣るが、チップ面積が1/4でコストを削減できた 当時日本ではほぼ無名でリバースエンジニアリングされづらかった(ナムコは執念で解析した)

    • ROM USBメモリとは違う メモリにアクセスするようにCPUから直接アクセスできて早い(カセットの中身をメモリに展開する必要がない) キャラクターROMとプログラムROMに分かれている • APU(オーディオプロセッシングユニット) CPUに内蔵されている 主にパルス波・三角波・ノイズで構成されている • PPU(ピクチャープロセッシングユニット)  Ricoh 2C02(最初期) Apple Ⅱ
  4. 実装の流れ 1. NES(ファミコンのこと)についておおまかに理解する 2. アセンブラの復習 3. CPUの実装 4. BUSの実装 5.

    テスト、そして圧倒的デバッグ 6. PPUの実装 7. コントローラーの実装 8. (スクロールの実装) 9. APUの実装 //まだ!
  5. ファミコンについて大まかに理解する • アーキテクチャ OSがないのでアプリケーション層が直接ハードウェアと通信する • CPUとPPUは直接カセットに接続できる • カセットを挿入するとCPUがプログラムROMに、PPUがキャラクターROMに接 続される •

    CPUのメモリは2KiB(2048B)しかなかった • CPUの内部にAPUが実装されている • CPUにはWRAMという2KiBのメモリが接続されている • PPUにはVRAMという背景情報・スプライト情報などが格納される 2KiBのメモリ が接続されている • CPUは直接VRAMにアクセスできないが、PPUのレジスタを介してアクセスで きる
  6. PPUの実装 • レジスタ CPUとの接続に使う( CPUアドレス空間の0x2000~0x2007) • 内部メモリとしてスプライトの状態を保持する OAMを持つ(256B) • 描画サイクル

    ◦ PPUは1秒間に262ラインレンダリングする ◦ NESの解像度は320 x 240 ◦ よって262-240=21ラインは画面に映らない ◦ 241ライン目に入ると VBlankというNMI割り込み命令が CPUに送 られる ◦ この間PPUのメモリは変更されないので CPUから自由にアクセス できるため次のフレームのために画面の状態を更新する
  7. スクロール 長くなるのでカット! ファミコンには画面の状態を保持する VRAMと呼ば リがあって、サイズは2 KiB。1画面を表示するのに モリは1KiBなので2画面分を割り当てられる。まず zero hit flagの設定をする。sprite

    zeroを画面の特 置(X, Y)に配置し、sprite zero hit flagが0から1に と、CPUはPPUが[0..Y]スキャンラインのレンダリン しYスキャンライン上でXピクセルのレンダリングが ことを示す。垂直または水平ミラーリングを実装し viewportを動かしていった分を shift_x, shift_yとお 256-shift_x, 240-shift_yを2つ目の画面のサイズ 定しフレーム毎に更新することで、静的な背景を動