Development of NES (Famicon) emulator from scratch is fun, and tough

Mitsunori Komatsu
5 min readDec 30, 2020

--

Why I started developing game emulator?

After the development of https://medium.com/@komamitsu/what-i-learned-from-implementing-raft-consensus-algorithm-in-ocaml-17c71b1b412f, I was seeking something to develop for my spare time. I noticed I had never developed OS-ish lower layer thing from scratch. BTW, I have a son who loves game programing with Scratch. I thought developing game console emulator was better than simple OS so that I cloud proudly show off the game emulator to him.

This is my hobby NES emulator project. I believe Super Mario Bros also runs with it.

https://github.com/vblank182/falling-nes
http://hp.vector.co.jp/authors/VA042397/nes/sample.html

Which emulator to develop?

There are some kinds of game emulators: Atari, Amiga, Nintendo Entertainment System (NES, or Famicon), Super Nintendo Entertainment System (SNES, or Super Famicon), Game boy family, and so on. I thought Atari was a bit too old. I’m familiar with NES, GB and SNES. The development of SNES seems too hard for newbies according to some comments on http://forums.nesdev.com/ and . So the candidates were NES and GB (not Advance or later.) The difficulties and complexities of the both developments looked similar and I chose NES.

How I started the development of NES emulator?

Yeah, I didn’t have any knowledge about NES emulator development and needed to get good documents easy to read for a newbie like me. https://wiki.nesdev.com/ is a great site to get many detailed information, but I needed to grab kind of abstract overall idea what NES emulator development was. I found this slide (https://speakerdeck.com/bokuweb/huamikonemiyuretafalsechuang-rifang) written in Japanese and I understood the whole picture. Of course I needed to read https://wiki.nesdev.com/ and some detailed contents later, though.

Technical stack

I chose Kotlin and TornadoFX for this project.

  1. Kotlin

The reasons for using Kotlin was that it’s easy to use Java libraries and enough convenient and productive with its ecosystem although it’s not so interesting as OCaml ;)

2. TornadoFX

I tried to simply use JavaFX at first, but it sounded TornadoFX was a better choice in Kotlin. Actually I didn’t throughly evaluate both JavaFX and TornadeFX with Kotlin, though. One thing I struggled with TornadeFX was how to use Campus-like component in TornadeFX. I finally solved the question as follows:

Implementations

I think NES emulators are supposed to consist of these components:

  • ROM loader: parser of iNES header
  • CPU: opcode, operand, addressing mode, register
  • PPU (Graphical module): background tile, sprite, scroll, palette, register
  • Keypad

I started with ROM loader and then just rendered nametable data that is kind of bitmap image data on screen to motivate me. I recommend this first step.

Next step was to implement CPU opcodes and PPU. The NES’s CPU is a Ricoh 2A03 which is based on MOS Technology 6502, so I needed to implement all the opcodes of 6502. But it was not so exciting since I didn’t have any UI in Konessem other than just printing CPU instructions, registers and stack to stdout. I fortunately got very simple “Hello, world” ROM at http://hp.vector.co.jp/authors/VA042397/nes/sample.html which requires only several basic opcodes in CPU and background rendering w/o sprite rendering in PPU. I implemented the minimum requirements of the ROM in CPU and PPU. When I saw the ROM showed white “Hello, world” string on black screen, it excited and motivated me.

Test ROMs

Many NES emulator developer created many test ROMs. I found https://github.com/christopherpow/nes-test-roms that has collected many test ROMs. I recommend to try some in the following order:

  1. https://github.com/christopherpow/nes-test-roms/tree/master/tutor : This requires the implementation of sprite rendering in PPU and some other basic opcodes
  2. https://github.com/christopherpow/nes-test-roms/tree/master/instr_test-v3 : This requires all official opcodes implementation
  3. https://github.com/christopherpow/nes-test-roms/tree/master/instr_misc : This tests some corner cases to be finally fixed
  4. https://github.com/christopherpow/nes-test-roms/blob/master/other/nestest.nes : I think this is one of the most popular NES test ROMs

CPU

I read the following contents for reference:

6502 instructions have ADC (Add with Carry) and SBC (Subtract with Carry.) Especially around overflow flag, I introduced many bugs in them. I fortunately found http://www.righto.com/2012/12/the-6502-overflow-flag-explained.html and it’s very helpful for me.

Also, some addressing modes (Indexed Indirect and Indirect Indexed) in 6502 are bit complicated and I also introduced some bugs in them…

PPU

The implementation of rendering background tiles and sprites are basically not so difficult. But I needed to take care of other features (scroll, 8x16 sprite, nametable mirroring, sprite 0 hit, sprite overlap, etc.) and I struggled with them for a while. I recommend to read PPU-related contents in https://wiki.nesdev.com/ when you notice you’ve spent a lot of time in investigation of unexpected PPU behavior.

Pitfalls in implementation

I think there are some pitfalls in NES emulator development. It took long time for me to notice them…

How do I like NES emulator development?

Yeah, it was basically exciting experience since this was the first time of creating OS-ish lower layer thing from scratch by myself. When I ran some Famicon games with the emulator and showed it to my son, I felt so happy since he seemed to look up to me (just my misconception? 😉)

On the other hand, the development of low layer component from scratch is tough because I need to debug it with no useful information. What I can do is only dump all instruction, stack and registers logs and guess what’s happening. And the PPU spec seems a bit tricky and complicated to me although I guess it’s for reducing memory usage. But, even NES emulator development contains some tough parts, it’s a great chance to enjoy lower layer component development and I bet running NES game on your own emulator is very exciting experience.

--

--