I built a Game Boy emulator in F#

· web hardware design · Source ↗

TLDR

  • Engineer built Fame Boy, a working Game Boy emulator in F# with sound, running on desktop and web, after hundreds of hours and prior CHIP-8 and Nand-to-Tetris groundwork.

Key Takeaways

  • Core interface is minimal: a 160x144 framebuffer, a 32768 Hz ring audio buffer, stepEmulator(), and a joypad callback, enabling both desktop and web frontends.
  • F# discriminated unions compressed 512 raw opcodes into 58 typed instructions using From/To types, with illegal states ruled out at compile time.
  • A 16-line Flags module using inline pure functions replaced a DU-based setFlags array approach, improving FPS by ~10% with zero heap allocation.
  • Single-threaded stepper function sequences CPU, timers, serial, APU, and PPU steps in the correct T-cycle ratios to simulate parallel hardware.
  • AI was used only to generate CPU unit test cases from the spec, not to write emulator logic, enabling true TDD while preserving learning.

Hacker News Comment Review

  • Commenters with F# experience noted that [<Struct>] discriminated unions in Instructions.fs could reduce allocations further, and flagged redundant byte-masking in register setters.
  • Consensus praised the use of genuine human effort and functional-language domain modelling for hardware emulation, a pairing most consider harder than imperative approaches.
  • A side thread asked about cycle-accurate emulators with visual CPU step panels (NES/SNES era), unresolved but distinct from this project’s goals.

Notable Comments

  • @debugnik: Suggests [<Struct>] on DUs in Instructions.fs and notes a &&& 0xFFuy is a no-op on byte registers.
  • @cermicelli: “Finally someone putting in actual human effort to learn something” – sharp contrast to LLM-built project posts.

Original | Discuss on HN