Creating a NES emulator in C++11 (PART 1/2)

Loading...

Sign in or sign up now!
Alert icon
Upgrade to the latest Flash Player for improved playback performance. Upgrade now or more info.
24,632
Loading...
Alert icon
Sign in or sign up now!
Alert icon

Uploaded by on Dec 4, 2011

In this tool-assisted education video I create a NES emulator with C++0x. You see me type every line.
The emulator is very accurate, and sort-of portable; it compiles on any architecture that support libSDL, but it outputs audio through an external program and reads joypad input from a file.
This video is part 1/2.
-- Part 1 ( http://youtu.be/y71lli8MS8s ): Creating the emulator.
-- Part 2 ( http://youtu.be/XZWw745wPXY ): Compiling and running.

The source code is about 940 lines in total.
Download & resources: http://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/
FAQ: http://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/FAQ.txt

Approximate count of lines of code per topic, in the source code:

- 20 lines, CPU: Declarations (registers, flags and internal memory)
- 100 lines, CPU: Interpreting and executing CPU opcodes & signals
- 100 lines, CPU&GamePak: Memory mapping (iNES mappers 0,1,2,3,7 are supported)
- 40 lines, PPU: Declarations (registers and emulator-specific status variables)
- 50 lines, PPU: Memory mapping and I/O
- 180 lines, PPU: Rendering and timing control
- 30 lines, PPU & IO: Joypad updating (PPU provides the timing for input-file access)
- 40 lines, PPU & IO: Color NTSC emulation (converting NES colors into RGB through NTSC modem)
- 15 lines, IO: libSDL initialization and rendering
- 35 lines, main&IO: ROM loading from file, initialization and emulation loop
- 200 lines, APU: Sound emulation (of which 40 lines are because of DMC/DPCM support)
- 130 lines, (other, such as comments, and inaccuracies in the above numbers)

Background music: Jinguji detective series. It was difficult to choose. I wanted good NES music, but I did not want it to too recognizable. I intended to convert something, but I had already spent months on this video... It was getting late.

Because of the 15 minute limit that YouTube still imposes on my account (I have no idea why; none of the restrictions mentioned on their help pages should apply to my account, and I have even sms-validated it); I had to develop many techniques to shorten the code dramatically. I also had to type it very quickly... And I had to split the actual demonstration into a second video.

I use C++11 exclusive techniques extensively in the code. I am particularly proud of the CPU emulator. It is cycle and memory access accurate, and feature-complete. It is not very slow, either. It is only 100 lines long, thanks to a number of clever ideas. I thank byuu for a particular idea that helped make it horizontally shorter. Each if() in ins() is completely parsed and evaluated at compile-time. Effectively the compiler synthesizes 259 distinct ins() functions, each performing only the particular opcode's worth of work.

I architected all the components in as close conformance as I could to whatever documentation I found on nesdev.org regarding how they work. There may be a few minor shortcuts that I took in order to avoid the trap of investing 90 % of source code to fix a problem that affects 10 % of games.

In design, my primary guiding principle was the assumption, that the _hardware_ was always designed for simplicity (with regards to chipspace consumption). Most compact design that gets the work done. This means, that whenever there is a behavior that seems to require extra-ordinary amount of work (code-lengthwise) from emulator authors to replicate accurately, I would take the extra effort to try and see the big picture and figure out how to generalize it. If the hardware does unproductive work at time, it is because they reused some component and did not needlessly create a special case to disable the component for those times where its function does not produce benefit. I would, rather than adding a special case to replicate that unproductive work, also find a way to reuse a productive part, so that the unproductive work comes automatically as a side effect, just like on the hardware.
I always tried to replicate that simplicity in my emulator. I think I managed quite well in that regard. It is not perfect though: It does not pass _all_ tests by Blargg, and some games that should run, outright crash at start. But the compatibility according to my tests is still very high, and interestingly, many TASes made with FCEUX run also on my emulator.

Note that creating an emulator is perfectly legal. I wrote all the code from scratch; it comes from my mind, and is therefore entirely my copyright; it is not anyone else's copyright. I believe that programming is art, and my code is my means of expressing myself. There exists no legislation that prohibits anyone from e.g. printing this source code on a t-shirt (assuming that *I* gave permission to that). I am also not selling this as a product, i.e. even in the dystopian event that I should happen to be using algorithmic methods that someone else has previously patented against every notion of conscience and wisdom, I am still not infringing on any patents. Or so I believe.

Link to this comment:

Share to:

Uploader Comments (Bisqwit)

  • Seriously though, are you like a pro at programming?

  • @MrAlexanderHoff I do it professionally, though not at this level. It is more a hobby to me. Once you gain experience, you too can do this. Do not forget that I spent a few months designing and refining this program thoroughly, before I finally made the video. Details are explained in the FAQ.

Top Comments

  • I have no idea what's going on.

  • @Tialah The most important skill a programmer, or a designer in general, must learn, is to subdivide a problem. It's easier to build a house if you realize that it's made of things like walls, ceilings and floors. Then you research how to build walls. Then you discover that you need electricity and insulation, so you realize you need to design your walls differently. Sorry for using a metaphor full of holes. But that's what it's like, designing; determine the parts, and the parts of those parts.

see all

All Comments (111)

Sign In or Sign Up now to post a comment!
  • Now seriously i have an IQ of 120 and i love programming since i went to school i was very bad at maths, my logic is very good but becouse of my poor mathematic skills i think im not very good at problem solving, now im in 9th grade im very good at maths but still have some "problems" with problem solving, what advice could u give me ? im really doomed i want to become an engineer and without problem solving mind i will never succeed in engineering becouse it's all about problem solving ! HELP !

  • For god sakes this program is just an emulator no big deal, no big deal if i was Bisqwit xD

    Nice job bro, one day i'll be 1/3 as good as u are !

  • @FeYoshiParty So basically I should ignore criticism that I disagree with? Sorry man, that is not how world works. My video, my comments page, my right to contribute to discussions and/or respond to criticism regarding my creations. If you are calling your opinion an advice, what do you advise I should have done, instead of that which is shown in the video? An advice without suggestions is not an advice; it is criticism.

  • @Bisqwit

    Grow up, you act like a child. If you think your code is fine ignore my comment, otherwise see it as an advice not an offense.

  • Its rarely i get impressed by anything.

    But this i don't even know what to start credit you with?!

  • I just got my Bachelors in Software Engineering (Fall 2011) and this video made me come to the realization that I absolutely suck.

    BTW, I love the douche bags critiquing this video with generalizations like, "this is bad code" or otherwise alluding that they could do it "better". As if anyone of those people actually know what "good" code is. (Quotation marks because 'good' is an extremely relative description in software development.)

  • @FeYoshiParty I challenge you to create a version of this program, written in what you think is "good" C++ programming style, and present the source code in 15 minutes so that one can read and follow it as it's being typed. I do compromises for entertainment and presentation purposes. I also do not believe that there is wisdom in religiously following certain rules, such as in avoiding "goto" at any cost. Though maybe I am not one, a wise person knows why rules exist and _then_ breaks them.

  • @nw0n

    yes I have to aggree with you. I've read through his source and it's not very good...

    It's not even real c++ code as he calls it... It's a mix of C and C++ and this is something that you should definately avoid!

Loading...

Alert icon
0 / 00Unsaved Playlist Return to active list
    1. Your queue is empty. Add videos to your queue using this button:
      or sign in to load a different list.
    Loading...Loading...Saving...
    • Clear all videos from this list
    • Learn more