Building an NES Emulator
An anonymous reader writes: Programmer Michael Fogleman recently built his own emulator for the original Nintendo Entertainment System. He's now put up a post sharing many technical insights he learned along the way. For example: "The NES used the MOS 6502 (at 1.79 MHz) as its CPU. The 6502 is an 8-bit microprocessor that was designed in 1975. ... The 6502 had no multiply or divide instructions. And, of course, no floating point. There was a BCD (Binary Coded Decimal) mode but this was disabled in the NES version of the chip—possibly due to patent concerns. The 6502 had a 256-byte stack with no overflow detection. The 6502 had 151 opcodes (of a possible 256). The remaining 105 values are illegal / undocumented opcodes. Many of them crash the processor. But some of them perform possibly useful results by coincidence. As such, many of these have been given names based on what they do." It's an interesting look at how software and hardware interacted back then, and what it takes to emulate that in modern times. Fogleman released the source code on GitHub.
There are better ones. Why do we care about this project, as opposed to the dozens of other (better) NES emulators?
Those who advocate genocide deserve every protection afforded by law, and none afforded by common human decency.
In a previous lifetime I repaired coin-op arcade games, and the Nintendo VS system was certainly one of them. At some point after Nintendo utterly abandoned the coin-op industry (leaving countless operators flapping in the wind with no new games for their VS system cabinets) I discovered, in the schematics of the VS system motherboard, proof that Nintendo was using the coin-op industry as a test-bed for a home system: the control panel inputs, which in an arcade game are all discrete inputs per switch (4 for a joystick, for instance) didn't go to a parallel buffer or parallel-input register IC, they went to a parallel-input shift register, the serial output of which was routed to a serial-to-parallel shift register, which was then connected to the data bus! If you have or can get a schematic for this PCB, look for it for all the player inputs. There is no reason to have this over-complicated arrangement in an arcade game -- but it just so happens that this is the exact arrangement that the NES used to connect player controls, via a skinny cable with as few connections as possible. So don't go getting so misty-eyed about Nintendo, they're utter bastards who care only about profits, and not who they screw over in the process.
Are YOU using the TOOL, or is the TOOL using YOU? Think about it!
BCD (Binary-Coded Decimal) mode was cool because it changed the way adding and subtracting worked. If you added 0x01 to 0x29, you'd get 0x30 instead of 0x2A. This was possible because there were actually two carry flags on the 6502 — one (named C) which was set upon overflow of values greater than 255, and the other (named D) which was set upon overflow of the low nybble (e.g., the low 4 bits).
6502.org Tutorials: Decimal Mode
The 6502 had relatively few registers (A, X & Y) and they were special-purpose registers. However, its instructions had several addressing modes including a “zero page” mode that could reference the first 256 words ($0000—$00FF) in memory. These opcodes required fewer bytes in program memory and fewer CPU cycles during execution. One way of looking at this is that a developer can treat these 256 slots like “registers.”
That's called "accumulator architecture", because all calculations involve the accumulator (A) register. X and Y are "index registers". No, the zero page can not be treated like registers. All calculations go through the accumulator.
The 6502 had no multiply or divide instructions.
Uphill both ways I tell you.
Ah - the 6502! That takes me back. The Commodore PET, VIC-20, and C-64 all used it and in the C64 in particular, the "illegal" opcodes were documented in "Compute!" magazine, a well-known and invaluable resource at the time (I still have them over two decades later!) In fact, after a bit of hacking at least one of the C64 cartridge games, it appears they were used in those too. Would be fun to see how faithful an emulator would be to them - though I suspect they would likely all fail.
I for one, am very thankful for the money I saved having an NES and not having to pump endless quarters into my local arcade, and I am most especially thankful that I never had to wait in line for my favorite game. It is not Nintendo's responsibility (or mine as a consumer) to protect someone else's outdated business model. Arcades lost, and consumers won.
I read the summary and thought : why the fuck does it tell those common facts about the 6502. I mean who doesn't know this? And then there was this awkward moment when I thought to myself : am I that old?
I wouldn't have minded seeing an example of one of those illegal opcodes and how what it did was useful.
Brooks called such things "curios". Side-effects of invalid operations that people had started to use, and that had to be considered part of the specification.
My policy (seconded by my boss) is that I do not document such things. If a hack is documented people start to use it, then we have to support and maintain it.
...laura
I started serious programming (at around age 14) on the Pet. First in BASIC, but once I found out you could break into a machine language monitor by wiring up a NMI button (we called it the two-button salute), there began my machine coding. In HEX, directly. Didn't even have a relocator at the beginning. It was a year before I could buy the expansion rom to add disassembly and relocation features to the machine language monitor.
Ultimately I wrote an assmbler too. I don't think I have any of that code any more, it's been lost in time. Kinda makes me sad.
The PETs 8-bit IEEE-488 bus was pretty awesome. The PET had a 1 MHz 6502. The external floppy drive also had a 1 MHz 6502 in it, and you could reprogram it. So one of my many projects was to speed up the data transfer between the two by synchronizing the processors with a series of handshakes and then pushing or pulling the sector data without any further handshakes (using processor timing).
My friend did the same thing for the C64's serial interface (which didn't even have a uart) and sold a product called '1514 Flash!' that sped up the serial interface. Basically a little messing around at the beginning of each transfer to get the two sides synchronized within 1 clock cycle of each other and then pushing/pulling bits as fast as the little cpus would go without any further handshaking. The clocks would stay synchronized long enough to copy a whole sector.
Other projects on the PET... it had a character generator rom which I replaced with a static ram. so when I powered it up I had to load a copy of the original rom into the ram blindly (because the display was total garbage due to it being an uninitialized ram).
The PET had built-in CRT screen but the key was that the data input for the screen was actually a TTL input! So I could pop the wire off the connector and use it like a digital oscilloscope to probe various TTL-based projects (as well as the PET's motherboard itself).
Another project...the character generator rom had something called quarter-block graphics. Basically 16 characters that had all 16 combinations of four quarter-blocks (2x2), so you could (I think) 320x200 graphics on it. I spent many hours optimizing the machine code to generate a pixel pusher.
I got so good at writing editors from scratch, once when I went to computer camp and forgot to bring the tape I rewrote the text editor in machine code in less than an hour.
Met Richard Garriott at that camp too, we were both on staff. He was working on (I think) Ultima II at the time (on an Apple II I think) and had an awesome ram disk for storing code temporarily while he was working on it. Once his computer stopped responding and after unsuccessfully trying to resurrect it he finally gave up and power cycled it, losing his work in the ram disk. It turned out he had accidentally disconnected the keyboard and the computer was actually fine. Oh well! Richard taught a class at that camp on human-interface parsing... basically had people write a dungeon game where you typed in what you wanted to do in English. Primitive of course, but the kids had a blast.
I wrote a centipede game in machine code, incredibly fast and awesome (the last level the centipede was invisible and only blinked into existence for a second or two every few seconds), and submitted it to Cursor magazine. They rejected it because they thought I had stolen it from someone :-(. The only thing I ever tried to get published, rejected because the code was *too* good!
The 6502 had two awesome indirect EA modes. (TABLE,X) and (ADDR),Y, along with the standard modes.
Decimal mode wasn't as interesting, I wound up not using it for display conversion at all.
The 6522 I/O chip was an incredibly powerful chip for its time, with multiple timers and timer-driven events. It had a few bugs, too.
I remember all the unsupported machine codes the 6502 had. It was a hardwired cpu so all instruction codes did *something* (even if it was mostly to just crash the cpu). LDAX was my favorite. Mostly, though, the hidden codes were not very useful.
The list goes on. Twas an awesome time, a time before PCs took over the world.
-Matt
Didn't this just happen a few days ago. You are not allowed to say NES.
Are you suggesting that the Famicom was based on a system that wasn't released until two years after its own release (1983 for the Famicom, 1985 for the VS. System)?
Or are you suggesting that Nintendo abandoned the home market after making the VS. System, despite having released not one but three arcade systems after it, (the Playchoice-10, the Super System, and the Triforce board)?
That's not even factually correct. It doesn't have a 6502. The NES had a Ricoh 2A03, which was a modified 6502 which REMOVED the BCD so they could put IO hardware registers in its place for controllers, sound, and DMA. The SNES did the exact same thing with the Ricoh 5A22, which is derived from the WDC 65C816--the same CPU as the Apple IIGS, which is why the development kid for SNES was an Apple IIGS.
How are we supposed to learn something from this submission if they can't even be bothered to check Wikipedia first? Fun-fact: If your information isn't better than what Wikipedia already has, it's useless.
I never owned a NES, but even I know just about everything in that article, just from downloading an emulator once (anyone remember Nesticle?).
Where's the "technical" information? The fact that memory mappers exist for the platform, or that it was sprite/palette based graphics is hardly some massive insight to anyone starting down the route of writing an emulator for something of that era.
I never heard about the original Nintendo game system. Had to Google NES. I use the Nintendo WII and 3DS XL.
Especially the undocumented opcodes -- https://www.youtube.com/watch?v=K5miMbqYB4E
Not knocking this, but there have been tons of open-source NES emulators for decades now.
But I'll take a legit technical story like this one over Soulskill's pro-drug drivel any day.
Only hardcore users of an NES will know what "Nintendo Finger" is.
I wrote a NES emulator too. But I didn't have the foresight to write about it. Especially now that parodius.com has shut down, I'm lucky my old posts are mirrored because that is really the only record I have left of my decision making and thought process through my little hobby project.
These days I mostly write NES and SNES toys rather than the emulators, the emu was more of a learning experience to get better at writing ROMs. (I'm serious enough to have a few modified NESes and carts and EPROM burner and UV eraser)
Of course there's an agenda. Those in power want the plebs fighting amongst each other so that they don't realize that the true villains are the ones that are running the countries, the banks, and the large corporations. While people are distracted with non-issues and cheap entertainment, their rights are pulled out from underneath them, and they're looted to the bone. By the time they figure out what's happened, it's too late.
I know he says a "NES version of the chip" later, but saying 6502 then variant later is confusing.. (Just like the 2600 doesn't use a 6502, it uses IIRC a 6509.)
The NES uses:
http://en.wikipedia.org/wiki/R...
... here is what I want, Xbox and PS emulators.
The PS1 has some pretty good emulators but the PS2 doesn't really... and I think the PS3 doesn't have them at all.
As to the xbox, I've yet to see even one xbox emulator that was worth a damn.
Not even the first xbox. Which makes me sad because I want to be able to play Halo 3 and 4 but I refuse to buy an xbox just for those games. I'm a PC gamer. MS released Halo 1 and 2 for the PC. Cool. And I don't mind waiting a couple years. That's fine too. But release them EVENTUALLY for the PC. Don't tell me the porting process isn't easy. We all know it is. So just do it and make me happy.
That or I'm going to be one of those people skulking around looking for xbox emulators and cruising torrent sites for the game files.
I will BUY your game for the PC. If you don't let me do that... then I'm sawing off my leg, wearing a eye patch, adopting a parrot, and developing an annoying love of the sound "ARRRRR".
you have been warned.
I've decided to stop wasting my time responding to AC trolls/sockpuppets... so if you want a response from me... login.
There are about 30,000 cycles in each NES frame. Converting an 8-bit number from binary ($00-$FF) to three decimal digits (000-255) finishes within 84 cycles on a 6502. Converting a 16-bit number to five decimal digits takes a little longer (about 700 cycles using my routine). But you don't have to convert all the time; you can use a "dirty" system to convert when the score changes.
Where's the "technical" information?
There's plenty on NESdev Wiki.
Top of the technology emulation technology from the 90s. What's next?