Super Mario source code

Started by
47 comments, last by CrazyCdn 16 years, 8 months ago
Quote:Original post by Vampyre_Dark
I have to wonder why that design decision was made. Was vram too expensive, or a foreign concept in this age? I assume a bit of vram for to hold the frame (not double buffered) would only take a few KB, especially with the restricted pallet.


It has more to do with the simple fact that a 1.79 MHz CPU simply does not have the processing power to render complex scenes at 256x240, at 60 fps. (That works out to about 1/2 clock cycle per pixel.) Using a tile-based PPU meant that NES games could use more of their precious CPU cycles for game logic instead of video rendering. (Compare with the Atari 2600, which basically required that the game code spent most of it's time in rendering.)

The 8 sprite/scanline limit is a timing issue. The PPU can only fetch sprite tiles during the horizontal blanking period, when it is not actively fetching background tiles; the horizontal blanking period is just long enough to fetch 8 tiles.

As an aside, the SNES PPU is very similar to the NES PPU; the main difference is that it's RAM is clocked at 5.37 MHz instead of 2.68 MHz, and has a 16-bit data bus instead of 8-bit, allowing it to load 16 bytes/tile instead of 4.
Advertisement
Quote:Original post by apatriarca
Quote:Original post by Goober King
Quote:Original post by GilliganCoder
I know that Nintendo never released the code officially but it's probably past the copyright restrictions now after 20+ years... The RAM & ROM maps are already on the net so I figured maybe the source would be available somewhere.


Hate to break it to you but its something like 75years After the Death of the creator that a copyright expires. So Mario has a long way to go, and if Micky mouse has anything to say about it, it will take even longer.


In Italy the copyright expires 70 years after the death of the last author. So it’s a lot more than 75 years. I think the law is similar in other countries.


Yeah, it's similar. In Japan, it's 70 years now after the date of publication, and in the US, it's 95 years after the date of publication (because SMB is owned by Nintendo, not Miyamoto).

So assuming, they don't republish it (which they have), nor get any sort of extention, the absolute earliest you're going to be able to do a legal remake is 48 years from now.

As for the leniency of other remakes? Well, those are all illegal, and Nintendo can at any point in time send a cease and desist on the project. While they probably won't for an unknown project, they have the option too, should they choose to change their minds.
Quote:Original post by Vampyre_Dark
I have to wonder why that design decision was made. Was vram too expensive, or a foreign concept in this age? I assume a bit of vram for to hold the frame (not double buffered) would only take a few KB, especially with the restricted pallet.


You have to consider that things like RAM were pretty expensive at the time, the cost of RAM was so much of a concern for Nintendo that they only included 2k of working ram in the NES itself. At 256x240 pixels, with 4 bits (see note) per pixel, and double-buffered you're looking at just under 64k of RAM solely as framebuffer memory. The NES also used SRAMs which were more expensive than DRAMs -- DRAMs require the NES to have refresh circuitry which would have added to the cost and power-consumption of the NES unit.

note: Sprites on the NES use 2bits per pixel, plus another 2 bits in the sprite attribute table to specify one of four 4-color palettes, giving an effective bpp of 4. Its technically a little more complicated since color 0 of each pallete was always transparant/background.

Anthony also makes some good points, though I'm not sure that I'd go as far as saying the the SNES PPU is all that similar. While the idea of tiles is preserved on the SNES, it has far more capabilities: A larger color palette, larger sprites, more sprites, more tile/object planes, 8 different video modes and 4 different resolutions.

throw table_exception("(? ???)? ? ???");

Quote:Original post by ravyne2001
Quote:Original post by Vampyre_Dark
I have to wonder why that design decision was made. Was vram too expensive, or a foreign concept in this age? I assume a bit of vram for to hold the frame (not double buffered) would only take a few KB, especially with the restricted pallet.


You have to consider that things like RAM were pretty expensive at the time, the cost of RAM was so much of a concern for Nintendo that they only included 2k of working ram in the NES itself. At 256x240 pixels, with 4 bits (see note) per pixel, and double-buffered you're looking at just under 64k of RAM solely as framebuffer memory. The NES also used SRAMs which were more expensive than DRAMs -- DRAMs require the NES to have refresh circuitry which would have added to the cost and power-consumption of the NES unit.

note: Sprites on the NES use 2bits per pixel, plus another 2 bits in the sprite attribute table to specify one of four 4-color palettes, giving an effective bpp of 4. Its technically a little more complicated since color 0 of each pallete was always transparant/background.

Anthony also makes some good points, though I'm not sure that I'd go as far as saying the the SNES PPU is all that similar. While the idea of tiles is preserved on the SNES, it has far more capabilities: A larger color palette, larger sprites, more sprites, more tile/object planes, 8 different video modes and 4 different resolutions.
Mario Paint at least demonstrated that it had full 'buffer' access?
Actually, I don't believe so. According to Wikipedia and everything else I've read on the net, the SNES does not have a "proper" bitmapped display mode, all 8 video modes are variations on tile-based modes.

That said, there are some relatively simple ways to emulate a bitmapped mode in a tile-based system. The most obvious is to write a set of tiles into the tile-buffer, and then write into the coresponding tile RAM instead of into a nice, linear frame-buffer. I'm not sure how the tiles are laid out in memory, but I assume its linear, in which case you can imagine a single screen as a collection of 8x8 framebuffer "tiles". Calculating the correct pixel address is obviously somewhat complicated, but as far as I know this is the technique that game's that used the SuperFX and possibly DSP chips used to achieve their appearantly bitmapped displays. Its likely that the cartriges used memory mappers or other hardware to alleviate this pain. Cartriges that did use these add-on chips were essentially a complete system unto themselves -- they had their own Processors (SuperFX/DSP), ROM and RAM -- The SNES unit itself was often little more than an IO conduit in these games.

The SNES, unlike the NES, had its own pool of RAM for storing tile and sprite images; the NES PPU had a dedicated memory bus to CHR ROM on the cartridge (all NES carts contain 2 ROM chips: one for tile/sprite images, the other for the program and other data such as maps, text and music.) making this technique possible out-of-the-box. It would be possible on the NES with the proper hardware built into the cartrige.


Wikipedia has a ton of technical information on the SNES, NES and most other systems. I don't think there was a console with a proper bitmapped mode until the 32bit era.

throw table_exception("(? ???)? ? ???");

Quote:Original post by ravyne2001
Anthony also makes some good points, though I'm not sure that I'd go as far as saying the the SNES PPU is all that similar. While the idea of tiles is preserved on the SNES, it has far more capabilities: A larger color palette, larger sprites, more sprites, more tile/object planes, 8 different video modes and 4 different resolutions.


Just looking at the patents, the two devices are more similar than one would expect. Most of the differences between the two PPUs are matters of scale; the only major architectural differences are:
1) The mode 7 background generation is completely different,
2) Sprites are drawn to a temporary linebuffer, rather than being rendered via shift registers,
3) The SNES PPU generates 2 screen images, the main and sub screens, which can be either horizontally interlaced (for 512-pixel horizontal resolution; note that this resolution change doesn't change the pixel clock) or used as inputs for the color arithmetic circuit,
4) The palette is RGB instead of modified HSV, and therefore the color arithmetic circuit has an entirely different design, and
5) The SNES PPU is capable of generating a interlaced video signal.

On the other hand:
1) They both use the same shift register plus demultiplexer system for rendering the backgrounds (though the SNES has several such units operating in parallel),
2) They both use the same drawing algorithm (latch scroll values - load attribute and tile data for 33 tiles, using priority data to select which plane or sprite to draw every pixel - while drawing the scanline, scan sprite memory to identify which sprites to draw next scanline - during horizontal blanking, load sprite tile data),
3) They both position tile data and tile maps with the same address-space granularity, and
4) They both handle priority in the same manner. (On both devices, lower-ID sprites are drawn over higher-ID sprites regardless of priority; then the priority of the sprite pixel drawn is compared against the background planes' priorities to determine what pixel to output. This means that both systems allow per-pixel sprite masking against a single background using the same method.)

There are a handful of other minor architecture differences, but most of them are based upon similar parts of the NES PPU; for example, the background tile flip circuit is based on the NES's sprite tile flip circuit.

Other tile-based graphics chips are notably different internally from the NES and SNES PPUs; just compare them with, say, the Genesis/Mega Drive VDP.

Quote:but as far as I know this is the technique that game's that used the SuperFX and possibly DSP chips used to achieve their appearantly bitmapped displays. Its likely that the cartriges used memory mappers or other hardware to alleviate this pain. Cartriges that did use these add-on chips were essentially a complete system unto themselves -- they had their own Processors (SuperFX/DSP), ROM and RAM -- The SNES unit itself was often little more than an IO conduit in these games.


The SuperFX was specifically designed to be able to provide images to the SNES CPU in a format that could be directly used as normal background tiles (taking advantage of the SNES's direct-RGB capability, where the tile data is treated as R3G3B2 color data rather than as a palette index); the same is true of devices such as the C4 chip used in certain late Capcom games.

The DSP chip doesn't do any rendering; it's primary use was to provide fast calculation of values to be fed into the mode 7 scale/rotate registers (Although one game, the port of Dungeon Master, used the DSP for image format conversion).

Also, most SuperFX games made rather heavy use of the main CPU as well. StarFox, as I recall, runs most of the game logic on the main CPU, as well as certain portions of the graphics (the UI images, the Nova Bomb effect, the background gradient image, etc).

Quote:The SNES, unlike the NES, had its own pool of RAM for storing tile and sprite images; the NES PPU had a dedicated memory bus to CHR ROM on the cartridge (all NES carts contain 2 ROM chips: one for tile/sprite images, the other for the program and other data such as maps, text and music.) making this technique possible out-of-the-box. It would be possible on the NES with the proper hardware built into the cartrige.


The NES also had a small amount of video RAM (2 KB) internal to the system; due to the way the system was designed, it was the cartridge's responsibility to determine how that RAM was connected to the PPU address bus. Almost all carts mapped it to $2000-$2FFF in the PPU's address space (with either A10 or A11 unconnected), effectively making it tile map space. (Some games left both A10 AND A11 unconnected, effectively using only 1 KB of the internal VRAM; others ignored the internal VRAM altogether and instead used 4KB of RAM on the cartidge, allowing full use of the attribute table space.)

A cartridge could be made, if one so desired, that mapped this RAM to $0000-$1FFF instead (which is the address range for tile image data; 2 address lines would have to be ignored though, so you'd only have a total of 128 tiles to use between background AND sprites).

Beyond that, it was once again entirely up to the cartridge as to what was mapped to the remaining PPU address space ($0000-$1FFF; the $3000-$3FFF range doesn't generate an external memory access, because that entire range is mapped to the PPU-internal 32-byte palette data). By far the most common alternatives were:
1) Connect it to a ROM holding all the tile data, or
2) Connect it to an 8 KB RAM chip, and let the game program write the tile data into it,
depending upon the specific needs of the game. (Many action games used ROM; many RPGs and similar titles used RAM. Note that these are just generalizations; the first and third Mega Man games, for example, used RAM.)

The real difficulty in implementing a pseudo-bitmapped background on the NES was the fact that it only supported 256 unique background tiles (all 8x8, and non-flippable), which is simply insufficient for any image larger than 128x128. Some very complicated memory mappers, such as the MMC5, were able, through ingenious hardware trickery, to get around this 256-tile limitation; and it is theoretically possible for a cartridge to have multiple banks of RAM mapped to that range, and change RAM banks on-the-fly during the frame to achieve this effect.

The SNES, on the other hand, supports 1024 unique background tiles per background, and those tiles can be 8x8 or 16x16. Combined with the SNES's direct-RGB mode, this makes it fairly easy to provide a pseudo-bitmapped 256x240 R3G3B2 image (though that will take up almost the entire VRAM). With creative use of transparency, even pseudo-bitmapped R4G4B4 images are possible (though obviously not fullscreen). Granted it requires some arithmetic to determine exactly which bytes of VRAM need to be changed to write a specific pixel, but that's a fairly trivial problem to solve.
These posts have been very interesting and informative.
Yes, very informative. I'm not terribly familiar with all the internal details of the NES PPU, only from from the outside. The SNES PPU I've never looked into in any detail, just bits I've picked up here and there, but again those are external details rather than internal ones.

Out of curiousity, where did you become so familiar with these chips? Have you studied them, or do you have professional experience with them? Homebrew perhaps?

throw table_exception("(? ???)? ? ???");

I've always had a thing for gaming consoles; so when console emulation started to take off back in the mid-to-late '90s, I gathered up as much information as possible for several different consoles (especially my two big loves, the NES and SNES) in the hope of making homebrew games.

Luckily, I had already had some experience with digital electronics and hardware-level programming, which made it easier to spot flaws and errors in those documents and seek out more correct information to supplement it. Eventually, I got to the point of examining circuit boards, reading patents, and disassembling game code in my quest to understand those consoles.
Very cool.

I don't want to jack this thread much longer, but have you used this knowledge in any formal way? Written any homebrew? Emulators? Written any documentation? It sounds as if you could really contribute to any of those efforts.

I've written a "simulated" tile-based GPU which, of course, worked entirely differently on the inside, but which interacted with the code in a manner similar to the NES PPU (command/data "buses", state-machine-like programming, CHR "ROM") and having some influence from the Master System / Genesis VDPs, but that's as close as I've ever been to writing something like an emulator.

throw table_exception("(? ???)? ? ???");

This topic is closed to new replies.

Advertisement