Wanted Dead or Alive

June 22nd, 2008

Apologies for the long delay since my last blog post, I’m quite swamped with work at, well, work.  I guess that’s why they call it work.

As some of you may have heard and some of you may’ve not, the “Next Big Thing” as far as MAME is concerned is “decapping”.

What is “decapping”?  “Decapping” is short for “decapsulation”, which involves removing the plastic packaging surrounding the silicon chip that comprises a microchip.  Decapping is important, because depending on the skill of the decapper and the type of chip, it is possible to optically read out the contents of ROM on otherwise read-protected microcontrollers, zap security bits and electronically read out the contents of ROM on otherwise read-protected microcontrollers, determine the type of microcontroller used in a chip that has otherwise had its serial numbers filed off vis-a-vis custom fabrication by a third party (such as the CIC present in N64 cartridges), and more.

The Guru, of MAME dumping fame, is currently preparing a very large shipment of chips to be sent off for decapping.  He’s agreed to send off any N64-related chips that need decapping, as long as I can get them to him in a timely manner.

I don’t want to sacrifice my single N64, nor do I want to sacrifice the single copies of some of my N64 games.  I don’t have an eBay account, and I have no idea where I could locally find a large stash of used N64 games in the Albany, NY area.  This is where you guys come in.

If anyone reading this blog post can spare one or all of the following to ship to me to in turn ship to Guru, I can offer my eternal gratitude:

  • Nintendo 64 (doesn’t have to be working, I just need the motherboard)
  • An example of a game using the 6101 CIC from this list
  • An example of a game using the 6102 CIC from this list
  • An example of a game using the 6103 CIC from this list
  • An example of a game using the 6105 CIC from this list
  • An example of a game using the 6106 CIC from this list
  • Jet Force Gemini
  • Donkey Kong 64

Thanks in advance.

Promenade

June 2nd, 2008

Tonight I fixed up the Controller Pak code to contain a valid initial image and fixed EEPROM support.

With the former, I can now browse a blank Controller Pak in various games’ Pak browsers.  I could probably do more if I made MESS actually save the Controller Pak image:

With the latter, a number of games boot up for the first time, including Chameleon Twist:

Donald Duck: Goin’ Quackers:

Pilotwings 64:

Mario Party 2:

Tomorrow I’ll try to abstract Controller Paks as devices so that it’s possible to specify a Controller Pak from an external file.

Pak Your Bags

June 1st, 2008

I’ve got a grab bag of assorted updates tonight!

First is a feature that I implemented several weeks ago but never got around to posting - proper frame sizing based on VI registers. As the driver was written, it relied entirely on the FB_WIDTH and VI_CONTROL registers to determine the frame size, which was incorrect. Games only use those two registers to determine the gross sizing of the framebuffer, but the actual video timing signals are generated based on an entirely different set of VI registers. The end result was that in the previous implementation, a lot of games displayed garbage in the surrounding frame that was supposed to be resized out of the frame based on the VI register settings.

A quick fix later and the driver goes from this (click for big):

To this (click for big):

Incidentally, this also fixes a number of issues wherein garbage would be displayed during transitions, when the games would set up the VI registers to display an effective height or width of 0, which would obviously display nothing on a real TV.

Next up, apparently Ville forgot to plug in the appropriate CIC response code for 6102-chipped games, resulting in Star Fox (among others) not booting. A quick fix there, as well, nets us this:

It boots, but man is it slow.

Last but not least, some fixes to PIF comms handling have caused a few things to spring to life. Hooray!

First, tweaking the controller status parameters that were being sent back by the Read Pad command now satisfies Command & Conquer:

For some reason or other, Armorines was displeased with PIF comms as well, and my fixes seem to have placated it, though it has rather severe texture issues in the UI (throw another game onto the growing list of RDP issues):

Lastly, I have Controller Paks almost working. Games will at least detect that a Controller Pak is inserted, but it detects the Pak as being irreparably damaged - all repair attempts fail. I think this is because the Controller Pak needs to have a few pages pre-initialized with some data that games are unable to re-write in the event of corruption, but I’ll have to verify this on real hardware if I can find someone selling Controller Paks that are New Old Stock (yeah, good luck).

With those tweaks in place, games start to light up, but as I said, are displeased with the corruption (click for big):

That’s about it for tonight, stay tuned for work on the PIN64 Viewer sometime in the next week!

Mission Statement

June 1st, 2008

Rumor has it that sometime next week some good folks from NOA are going to be reading this blog in order to give a final yay / nay on whether or not I’ll be able to submit all of my improvements to MESS.

With that in mind, I looked over my blog myself, and I realized that at no point have I really laid out any kind of mission statement as to just what I’m doing and what I plan to do. With that in mind:

The Story

In the mid to late 90’s, emulator authors in pursuit of kudos from people looking for wholesale piracy while the N64 was still alive and kicking were attempting to write N64 emulators using the traditional method at the time: Have a C or C++ implementation of each opcode of each CPU in the relevant system, and simulate the display processor through software rasterization. By late 1998, the best emulators of their ilk were able to display the opening 2D legal screens of a handful of games, including Waverace 64 and Mortal Kombat Trilogy.

Depending on one’s perspective, January 28th, 1999 marked the point at which everything came up roses (if you’re in it for free games, you pirate) or went straight to hell (if you’re a company that cares about your IP), which was when a brand new emulator hit the scene: UltraHLE.

UltraHLE introduced two concepts of emulation that were relatively unknown at the time: Dynamic Recompilation (DRC) and library black-boxing, dubbed “High-Level Emulation” or “HLE”.

The former is a straightforward method of speeding up the emulation of high-speed processors in order to achieve more efficiency on commodity hardware. Unlike a standard “interpreter” core that requires the overhead with a function call for every emulated opcode, a DRC core will convert blocks of opcodes into sequences of assembly code that can be executed in one go, often caching off heavily-used translated blocks in order to mitigate the overhead of block conversion.

The latter is also straightforward in principle, but is a bit of a square peg trying to be forced into a round hole when applied to the N64. When applied to systems that have a coprocessor with a fixed program, the principle involves figuring out what the program is doing, and then simply simulating the effects of the commands that are sent to it rather than attempting to simulate the coprocessor itself. This is applicable to the N64 as well, with one rather humongous caveat: There are a number (around 10) of different microcode programs that games uploaded to the RSP (the N64’s vector coprocessor), and not all of them are fully understood. The end result is emulators with many per-game hacks in order to make them work properly.

HLE, in fact, is most likely what Nintendo is using for Virtual Console - this is mostly obvious by the fact that all games appear to be running at a full 640×480 resolution, there is no visible dithering in alpha blending, the Invisible Cap Mario in Super Mario 64 is drawn as completely translucent rather than using a noise dither pattern, and the same issue occurs when Mario’s model fades in and out during teleportation. The latter two issues are kind of sad, actually, as I can think of at least one method that could accomplish the effect on the GX.

Unfortunately, the nature of people wanting free games without supporting their publisher being what it is, the end result of HLE was that popular games were made to run fine, whereas lesser-known games or games that push the RSP in unusual ways run in either a glitchy manner or not at all. I actually suspect that this is the primary reason why certain popular games may be delayed or be completely absent from Virtual Console entirely - Blast Corps relies on the processing speed of the RSP and the drawing speed of the RDP to slow things down rather than run out of control, Goldeneye (licensing notwithstanding) uses a bizarre method for drawing the skybox, and Animal Crossing has many graphical issues on most all HLE-based emulators.

The Plan

I’ve always been an accuracy-minded fellow, and it always pained me that low-level emulation of the N64 went by the wayside in favor of haphazard grabs at popularity and kudos from people interested in little other than piracy. Redemption came in the form of MAME, around two and a half years ago. MAME emulates arcade machines, but there were a number of arcade machines made for the Seta Aleck64 hardware, which is little other than a Nintendo 64 on a custom arcade board and custom per-game inputs. Emulator author Ville Linde wrote a first-pass implementation of the Nintendo 64’s hardware, which ran well enough that Magical Tetris Challenge ran, as it used almost entirely 2D commands.

Over the coming six months during the first half of 2006, Ville put together a Nintendo 64 driver for MESS, the sister project to MAME; whereas MAME concentrates on arcade machines, MESS concentrates on computers and game consoles. A number of games booted, but the majority of them had issues ranging from crashing MESS to major graphical glitches.

In early 2007 I came to the decision that I would start contributing to MESS’s implementation of the Nintendo 64, as Ville went Missing In Action to the siren song of World of Warcraft. Someone was kind enough to donate a Nintendo 64 cartridge copier, and another friend of mine helped me get a cross-compiling version of GCC running that could compile code for the Nintendo 64. The project is located here, uses no official Nintendo development tools or libraries, and as such is completely legal.

Once the groundwork was put down I began to write a test suite for the Nintendo 64 that could run RSP code in parallel with MESS’s implementation, verifying register contents after each opcode was executed. For good measure I threw in a memory viewer, an input tester, and a couple other bits and bobs. Thus was born NUTS: Nintendo Ultra64 Test Suite.

Until late 2007, all of my work was done to produce an initial version of NUTS. However, once NUTS was mostly done, I became interested in tackling the RDP as well, since Ville was well and truly engrossed in World of Warcraft and nobody else was stepping up to the plate. In the past six months I’ve begun working on a new tool, PIN64: Polygon Inspector for Nintendo 64. The end goal is to be able to capture a frame’s worth of RDP commands from MESS, then play back that frame in a separate program, being able to view the individual commands and the RDP’s state while the frame is being built. In addition, a user should be able to then play back that frame on a real Nintendo 64 as well, in order to compare how the RDP commands would behave on real hardware versus the current emulation state. You can see the current state of PIN64 in previous blog posts.

The Rules

The rules are simple: Do everything legally, accurately, and non-competetively.

From a legal standpoint, my intention is for everything to be on the up-and-up. This means that I will not use any confidential Nintendo documents, tools or hardware.

From an accuracy standpoint, I want to make MESS good enough that anything that will run on real hardware will run on MESS with no modifications and no degradation in graphical or aural quality. This means fully emulating every aspect of the RDP including coverage.

From a competition standpoint, unlike the folks who wrote HLE-based emulators, I am not in this for kudos, and I am not in it for free games. My goal is expressly for MESS not to draw attention away from Nintendo’s Virtual Console service. My accuracy goal will probably do this for me, as accuracy will in turn affect the overall emulation speed; the current inaccurate RDP implementation and interpreter RSP implementation causes games to run at an average of 10% of full speed on my average-spec laptop. Things will likely only grow slower as I make the RDP implementation more accurate.

This is not to say that I will reject any patches from other developers that increase the speed of MESS’s Nintendo 64 implementation without affecting accuracy, but I myself will not go out of my way to seek out kludgey optimizations.

In short, my entire goal can be summarized as follows: Do not upset and do no harm to Nintendo.

So far everything is on the up-and-up; now we can only hope that NoA agrees.

Primitive Rituals

May 27th, 2008

Tonight I discovered something that was fairly non-obvious in its nature: Textured Rectangle commands can affect the Z buffer, but only if the Z Update and Z Source Select bits were set in the most recent Set Other Modes command.

It makes sense in that it can allow a game to both clear the Z buffer and draw useful pixels by setting the Primitive Z value to an appropriate clear value and then drawing a full-screen textured rectangle.

The only game that I’ve seen use this mode thus far is Brunswick Circuit Pro Bowling, which draws a bowling-scorecard texture backdrop for its main menus before drawing 3D items over top of it. With the fix implemented, we get…

Before:

After:

Hooray!

Cover Charge

May 3rd, 2008

One of the few(?) remaining issues with MESS’s RDP implementation, at least in my local source tree, is a lack of coverage emulation. Tonight I made the first of several steps to supporting it by adding a partial implementation to the PIN64 Viewer. The downside is that if I ever submit this to MESS (and by association, MAME), the Aleck 64 games in MAME and the N64 driver in MESS will easily become the slowest drivers in their respective emulators.

The problem with proper coverage emulation is that in its current implementation the worst case is that video rendering is approximately 32 times slower than without coverage, the best case is approximately 16 times slower. The reason for this is that in order to calculate coverage, the N64 driver has to render internally at 4 times the original X resolution and 4 times the original Y resolution. Coverage is calculated by applying a 4×4 50% dither mask over the sub-pixels comprising a single pixel like so:

If one of the gray pixels in the above mask is occupied by the primitive that is being drawn, it adds 1 to the current coverage value, for an effective range of 1 to 8 (though it is stored as 0 to 7 in order to fit into three bits). The coverage functionality can additionally be modified by the Set Other Modes RDP command, which has four modes:

  1. Clamp coverage to 8
  2. Wrap coverage value with each successive primitive overdraw
  3. Force coverage value to 8 for each partially-covered pixel
  4. Don’t modify coverage at all

As such, MESS needs to render with quarter-pixel accuracy, first of all. Second of all, it is possible for the Blender to use the pixel’s coverage as the alpha value when blending the pixel. I cannot think of a decent alternative means of accomplishing this other than by rendering each pixel twice, first to accumulate the coverage value, then to actually blend the pixels themselves.

Now for the metric you readers are interested in: Frame rate.

While I haven’t hooked this into MESS itself yet, I can tell you that it is SLOW. Rendering a scene from Super Mario 64 with Mario standing outside Princess Peach’s castle now takes between two and three seconds in the PIN64 Viewer. For the sake of being able to debug the rest of the N64 driver, if and when I submit this to MESS I’m probably going to make it a compile-time switch so that it’s possible to turn on the less accurate, non-coverage implementation.

Yikes.

Green Grass & High Tides

April 28th, 2008

ZZT32 seems to be doing… something… with homebrew as of late, and he sent a test case my way. Sure enough, it uncovered an issue with MESS’s implementation of 32-bit framebuffer mode.

Here’s what I first saw when plugging in the test case:

Thanks to a kindly-provided screenshot off of real hardware, it was easy to figure out that it’s actually supposed to look like this:

As it turns out, the now-WoW-addicted fellow who contributed the original N64 driver didn’t know that the N64 stores its 32-bit pixels in RGBA format, not ARGB format. A quick tweak to the VIDEO_UPDATE, BLENDER1_32, BLENDER2_32 and texture_rectangle_32bit functions, and everything’s fine!

Thanks again to ZZT32 for the helpful test case.

Going Mad(den)

April 26th, 2008

One issue that’s bugged me for a while now has been the fact that the majority of in-game graphics in Madden 64 are broken, displaying entirely in white.

As it turns out, Tiburon were saved from a broken game by the Nintendo 64 managing to do some modicum of error correction on the texture information that is uploaded to it. Madden 64 specifies most of its player and stadium textures as being in a format of either 4-bit RGBA or 8-bit RGBA. This is an invalid mode; RGBA textures must be either 16-bit or 32-bit.

After some digging, I found that the N64 silently treats such textures as 4-bit Color Indexed (palettized) or 8-bit Color Indexed. In addition, the current RDP implementation in MESS fails to emulate the fact that a 4-bit CI texture can select which of 16 different palettes to use; it’s hard-coded to index 0. After fixing this functionality, the game went from this:

To this:

I’m not sure what’s causing the purple corruption on the field, it looks fine in the PIN64 Viewer.

In addition, it fixes the field in Madden 2001 as well:

Simple fixes, big results.

Bicycle

April 20th, 2008

Two-cycle texture lookups are completely wrong in MESS. Big shock, right?

The whole principle behind two-cycle texturing is that you can look up texels from independent textures in order to do clever things like masking, or not having to upload textures quite as often (upload two textures one time, then just change the combiner mode to switch textures). With the current implementation, we just copy the value of texel0 into texel1. Yeah, that’s kind of wrong. I fixed it.

This gets us from the current jumbled mish-mash for menu backgrounds in Paper Mario (see my previous blog post) to this:

The menu backgrounds aren’t supposed to be black, certainly, but it’s a start.

I’m stumped as to exactly why the menu backgrounds are black. More accurately, I know why they’re black, but I don’t yet know how to fix them. The problem is that the blender set-up never directly carries in the result from the color combiner, it uses the C_BLEND input. As best I can tell, that input is supposed to be what’s set by the Set Blend Color command. In this case, it’s set to black.

The only thing I can come up with is that the “Force Blend” bit in the Set Other Modes command has some sort of effect on the Blend Color register’s contents. It’s something I’ll have to verify on real hardware.

Edit 8:17PM -

Oh, hey, my theory paid off. Apparently Force Blend forces the Blend Color register to carry in the Color Combiner output. I’m not really quite sure why, but it seems to fix Paper Mario without horrendously breaking anything else:

Mirror, Mirror on the Wall

April 20th, 2008

Just a quick fix this morning for texture masking and mirroring. Fixes some shadows and some other miscellaneous stuff. The fix this time around is that if the bit specified by the S or T mask value plus one is 1 and mirroring is enabled for S or T, then that bit and all lower bits are inverted.

In plain English, with an S mask bit of 3, the following sequence of texture coordinates:

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

…would become:

0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0

Simple! Among other things, I’m sure, this fixes things like shadows (depending on how a game rendered its shadows), some visual effects, some car textures, and such. Before:

Castlevania - Legacy of Darkness VFX (click for big)

Paper Mario - Curtains

California Speed - Car Textures

Army Men - Sarge’s Heroes 2 - Shadow tiling

Aaaaand after:

Good stuff! My next goal is to fix the rest of Paper Mario’s menu system.