Slashdot Mirror


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.

7 of 140 comments (clear)

  1. Nice Project, But... by Tenebrousedge · · Score: 1, Informative

    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.
    1. Re:Nice Project, But... by aardvarkjoe · · Score: 5, Informative

      The story isn't that somebody made an NES emulator. Those have been around forever, and this is going to be uninteresting if all you want to do is play Mario. The story is that somebody wrote an article about it for anyone who is curious about some of the details.

      The article does focus mostly on the NES hardware, though, and I was expecting some insight on interesting or difficult points of writing the emulator itself.

      --

      How can we continue to believe in a just universe and freedom to eat crackers if we have no ale?
  2. Re:Little-known fact by tuffy · · Score: 4, Informative

    Nintendo VS system was an adaptation of their home hardware for arcade use, not the other way around. The Famicom predates it by years, remember.

    --

    Ita erat quando hic adveni.

  3. Re:BCD mode by Anonymous Coward · · Score: 4, Informative

    To those of you wondering why BCD instructions would be useful, it has a lot to do with doing math with character-based input.

    Today, we're accustomed to parsing strings of digits to turn them into numeric types. However, this is actually quite costly, and it turns out that there's a much cheaper way to accomplish the same goals if you're only doing simple arithmetic with these values.

    Let's say you want to compute "2" + "3". "2" is 0x32 in ASCII or 0xF2 in EBCDIC, while "3" is 0x33 in ASCII or 0xF3 in EBCDIC. It is no coincidence that the low 4 bits of a digit's character encoding (in either of the two most popular encodings) correspond to that digit itself; it is specifically to support BCD math.

    I'll focus on ASCII for the remainder of this post, though this all applies equally to EBCDIC. All you need to do is mask things correctly (0x32 & 0x0F is 0x02, and 0x33 & 0x0F is 0x03) to "parse" character-encoded digits. Then you can just add them together (0x02 + 0x03 = 0x05) and OR the appropriate high 4 bits (0x30 for ASCII) to get back to character encoding land: 0x05 | 0x30 is 0x35, or ASCII "5". Much cheaper than contemporary number parsing and string building algorithms.

    Of course, if we had values that summed to 10 or more, we'd need to use the BCD-overflow flag to handle results properly (as 0x05 + 0x05 would yield 0x0A, which when transformed back to ASCII is ":", not "10") . This gets us into packed-BCD territory, which is beyond the scope of this post (but which can be summed up as packing two BCD values into a single byte ((a4) | b), which means we'd want 0x05 + 0x05 to give us 0x10, the packed-BCD value that represents the decimal number 10), as that's how BCD values with more than a single digit tend to be stored.

    BCD was a clever hack that enabled crappy computers to do a lot of work despite their slow speeds. Today, we just parse numbers in software, because it's no longer cost-effective to squeeze this level of efficiency out of our hardware. They don't make 'em like they used to.

  4. Re:Little-known fact by Anonymous Coward · · Score: 1, Informative

    No, sorry, I just looked at the schematics and I'm pretty sure you're mistaken about the electronic design. On all four '165s, pin 9, the serial output, is connected to a tristate buffer (the 74LS240s). Those are interface ICs so the outputs on a shared data bus can all be connected together, so that's a very normal thing to place between the CPU and the peripheral electronics. The way I read it the CPU would output a specific signal to trigger the button state capture, then read from the same address 8 consecutive times to shift the serial data out directly.

    The complement to the '165 (which would convert serial back to parallel) is the '164. I don't see any 74LS164s on the board. So while it's a little weird to me that the buttons go through serial shift registers and the DIP switches don't, what you're describing is not what I see. For all that it feels slightly untidy, I'm pretty sure this design just results from minimizing the number of ICs on the board.

    In the general sense that Nintendo engineers would have gained experience from this project which they would have carried over to the NES, sure, but I don't see anything here that looks like specific intentional experimentation, just design decisions relating to the specific problems of manufacturing this arcade machine.

  5. Re:Little-known fact by MightyYar · · Score: 4, Informative

    The VS system didn't come out until after the NES (well, the Famikon version from Japan). You have the timeline backwards.

    Many of the cabinets on VS machines are older because they were converted Donkey Kong or Mario Bros cabinets.

    --
    W..w..W - Willy Waterloo washes Warren Wiggins who is washing Waldo Woo.
  6. What the hell? by ckatko · · Score: 2, Informative

    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.