How much effort making a NES emulator takes (info)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
How much effort making a NES emulator takes (info)
by on (#107970)
This is just information, and the text is targeted to less involved audience, so sorry for telling obvious things. I don't know yet which future this project will have, will be it a public release or something else. For now it remain a personal, private project.


I know that many programmers, who are interested in retro gaming, starting to think about creating their own emulator at some point. So there are people who are curious how difficult it is and how much effort could it take, but I barely can remember anyone who shared any real numbers on this regard. Today I have a chance to share my own experience.

Project outline: a basic NES emulator, minimalistic approach - no GUI or configs whatsoever, NROM only, just as complete as required for my own games to run. It has pretty complete scanline based PPU emulation, though, most of classic games runs flawlessly (sans sound). A twist, it is in Java, a language that I used like 10 years ago last time. Did quite some JS and AS3 programming since, though, so it didn't take too long to catch up. Take in account that this wasn't my first emulator, I can't even really count which one it is - seventh, probably.

Total time to get it done, except refreshing Java knowledge, is 27 hours. 3 hours spent for framework that displays generated raster, plays sound, handles input, loads game data. 3 hours for complete CPU core, all addressing modes, official opcodes, interrupts handling. Complete PPU emulation took 6 hours. 5 hours for limited APU emulation, it lacks envelopes and length counters. Remaining time, 10 hours, spent for extensive bug hunting through code overview, running various games and tests (Kevin Horton's and NEStress were most helpful), tracing. First game that ran properly was Battle City, one of easiest to emulate. Super Mario Bros and especially Galaxian were the most tricky. Two most difficult things were debugging the CPU core, very easy to make a mistake there, and proper PPU scrolling/addressing emulation - many games do actually require complete emulation of the internal registers and their logic, as explained by skinny in 1999.

Another interesting number is how much of code it is. 1560 lines for the whole emulator - CPU, PPU, APU. 200 extra lines for platform dependent framework. About 40K of source code total. So, where is the good 2 megabytes of source code with many thousands of lines in emulators like FCEUX are coming from? Mostly from GUI, service features, and support for all mappers. So that is what you could cut if you just want to make a working emulator without spending many months.
Re: How much effort making a NES emulator takes (info)
by on (#107971)
Can you elaborate on the order you wrote things, what testing you did along the way? Also, from the sound of it, you've had plenty of experience programming things (just noting this because some people making an emulator are just learning the programming language too).
Re: How much effort making a NES emulator takes (info)
by on (#107972)
Memory arrays, ROM loading, read and write handlers were first. Then I filled VRAM with random values, and did a crude scanline based background rendering without attributes (had to replace it altogether later). Added sprites rendering. It does a crude trick - background is rendered line by line, but sprites are rendered all at once at the end of the frame. Sprite 0 check is done per-scanline, by reading rendered scanline data. Then I added CPU emulation, PPU registers emulation. Improved background and sprite rendering, attributes, priority, etc. Caught many CPU bugs, added input handling. Lan Master got into the menu at this point. After tons of CPU core debugging, adding 8x16 sprites, no scrolling yet, Battle City started to work more or less. Even more debug, using most of tests linked from NesDev wiki, scrolling emulation - it seemingly worked, Battle City and Ice Climber worked well. However, SMB didn't work - hanged after scrolling a screen forward, so I realized that PPU needs to be rewritten in the proper way, with the temp and current pointers and stuff. Galaxian was showing garbage instead of the enemies formation - spent quite some time to get IRQ/BRK working properly. Added sound emulation, all channels, in a crude way - all is done at sample rate rather than at CPU clock rate, DPCM does not take CPU time and works asyncroniously. Sounds not quite good, but more or less acceptable. Rewrote PPU emulation and rendering, so SMB and Galaxian started to work properly. One game that still have visible glitches is F-1 Race, few random road lines are off by a tile horizontally. Checked all timings, no success - don't know what is wrong yet, but it isn't too important, as screen splits in my games working properly.

Yes, I have quite some programming experience. This project had a number of reasons - it was like a test of my NES knowledge (learned some things), an opportunity to remember Java, and a way to have copyright free code that I can use for anything I want. Debug purposes considered too, as I know my own code much better than code in existing emulators, I can add pretty much anything whenever I'll need it - a new custom mapper, some kind of tracing, etc.
Re: How much effort making a NES emulator takes (info)
by on (#107996)
Thanks for sharing the details, it's interesting to see the different approaches - personally I started with CPU, running non-graphical test ROMs against known good logs, then memory handling, ROM loading and finally the PPU. I haven't touched the APU yet, I'd be interested in seeing your code if possible - an insight into even a crude implementation would be very useful to me.

Total time spent so far - probably about 50 hours, although I'm not that experienced a coder and struggled early on with attribute tables and scrolling.
Re: How much effort making a NES emulator takes (info)
by on (#107999)
Shiru wrote:
Take in account that this wasn't my first emulator, I can't even really count which one it is - seventh, probably.

First NES emulator or first emulator in general?
Re: How much effort making a NES emulator takes (info)
by on (#108001)
Problem with showing the sound code is that it all scattered around the source, mixed with memory handlers - I was too lazy to structure the code in a proper way. I think I'll do some improvements and un-tie the sound code a bit later, so I'll be able to show it easily.

Not first in general, but first NES emulator. Other systems were all 8-bit, mostly obscure, and I think only one of my emulators has been ever released to the public.
Re: How much effort making a NES emulator takes (info)
by on (#108005)
27 hours is pretty good, I think. If I had to hazard a guess (it's been 10 years since I started :shock:), I think it probably took me twice that long to get from nothing to being able to play some games (no sound, NROM and a couple of the easy mappers).
Re: How much effort making a NES emulator takes (info)
by on (#108041)
Twenty seven hours is pretty remarkable, at least in my eyes. It took Mr. Snazz and I way longer with VeNES (I would say multiple weeks worth of actual man hours); the effort Mike Perry and I put into qNES would have been slightly less.
Re: How much effort making a NES emulator takes (info)
by on (#108075)
I'm so slow that I doubt I could finish even the header parser in 27 hours!

Sometimes I feel tempted to write an emulator, but I know that when I reach the advanced stages of handling the minute timing details I would get bored as hell and would just give up. Since I wouldn't want end up with an inaccurate emulator, I usually decide I'm not even gonna try.
Re: How much effort making a NES emulator takes (info)
by on (#108126)
tokumaru wrote:
I'm so slow that I doubt I could finish even the header parser in 27 hours!

Sometimes I feel tempted to write an emulator, but I know that when I reach the advanced stages of handling the minute timing details I would get bored as hell and would just give up. Since I wouldn't want end up with an inaccurate emulator, I usually decide I'm not even gonna try.


Even if your emulator isn't perfect it's still fun to write one of your own. I know the ones I've made certainly aren't better than the best emulators for those systems but they work pretty well and it's nice to know that you made it. One of these days I'll try to tackle APU/sound emulation for the NES. I've always used blargg's awesome APU library. I considered trying to write a SNES emulator of my own since he has a nice SPC library for it too.