We were sent a Nintendo 64 test cartridge ROM that was dumped anonymously. Zoinkity wrote up a nice readme explaining the details which is included in the 7ZIP file we’ve uploaded to the Internet Archive for safekeeping. Download it by clicking here.
Below is the text from the included readme file with details.
.: Nintendo 64 Test Cart version 1.? :.
Finally, a public release of both complete ROMs from a Nintendo 64 test cart!
Test carts were designed to be reprogrammed–in full or in part–through the jtag port or via gangwriter. When there’s any kind of electrical delay whatsoever it seems to map the “testcart_reflash” ROM, allowing you to pipe a new “testcart_runtime” to it. (Check the “reflash interface.txt” doc for more info on how that works.)
That’s rather been the problem up to this point, but it turns out if you stick a bit of polyimide tape over the cart’s CIC pins you can boot to a 64DD while it still maps the main runtime (assuming yours has a CIC+IPL or you programmed your own). Having the code you want exposed means you can just DMA everything instead of trying to read from the exposed flash addresses; there’s a bit of a trick to doing that with 16bit hardware.
This dump was taken via a 64DD dev unit while the runtime was accessible. It was checked against a second dump taken via IO access (doubled-reads, similar to the writing method), and both were compared against an earlier partial dump to verify known good contents. You could also read the individual flash units themselves if your IC programmer supports the chipset / has the right adapter.
Please note that the runtime is not supposed to be some perfect multiple of a chip size. If you have ever had the “privilege” of using jtag you’d understand why. The reflasher is aligned to the start of the last unit (each unit being 0x200000 large) and retains its padding (in other words, the unwritten bytes erased to 0xFF at the end). That file has a maximum size in other words, so that feels like an important thing to preserve.
.: Why version 1.? :.
The specific build is up for debate. It is clearly *not* version 1.0. It’s suspected to be at least a version 1.1–likely final–based on the audio test.
There are two existing blobs of source code for the Go/No Go tool (GnG, used for factory quality control): one from the OMAN archive and another distributed with libultra OS2.0E. Both predate this release (built against OS2.0H). The most noticeable–arguably only–difference from 2.0E is that the left/right audio test stopped using beeps and midi sequences, replacing them with a voice saying “This is your * channel.” It also doesn’t use the “subway” sequence. It’s not clear what version was first used for these standalone cartridges.
(So yes, there’s at least one other version that needs to be tracked down and dumped.)
For those in the know, a partial dump of the main runtime was taken by marshallh back on Jun 29, 2016. That was done by sniffing the address lines and was largely complete, lacking only data that wasn’t accessed (as opposed to used). It’s been available to emulator devs since then, awaiting a complete dump before public release. It’s the same build as this one or very, very close.
It was missing:
*) The tail end of all audio samples. They’re clipped by the player before running to completion so the ends weren’t loaded. (Samples are only loaded on-demand in blocks.) One did have a short non-matching segment, could be a smidgen of corruption or maybe it was leveling or something applied to a single spot.
*) Sequences for noteLeft, noteRight, and subway (plays G, then E). LR were replaced by more explicit “This is your * channel.” messages from version 1.1 onward, but the original beeps & sequences are still compiled in.
*) The number sequence used for the PI test. This is only run (or relevant) when a zaru test rig is attached, not when booted standalone (unless you run it manually via command line).
.: About Zaru :.
Also provided is a short, hopefully accurate, document on how the zaru rig should operate. You could theoretically build one and stick it in a controller slot (like a mempak) to pointlessly check all your grounds. Many of the tests only run with a zaru or run alternate code when one is found.
.: Does It Emulate? :.
If it doesn’t, complain to your emulator’s devs.
There isn’t much point to emulating it other than to confirm accuracy or complaining about the lack of it. The central focus is usually on passing the RCP tests, but you’d be surprised how few emulators support the Recenter button (the Start in L+R+Start toggles 0080, not 1000) or how many neglect the VI entirely, directly outputting the framebuffer (the wiggly triangle video test uses VI settings to clip a window out of the framebuffer and scale it, otherwise you’ll see a triangle bouncing inside a box). Or how many aren’t unicode-aware. (Did they just copy some old PJ64 source or something? Is it that hard to use strncpy(20) and decode instead of hoping a raw bytes “filename” doesn’t throw an error?)
It works fine on flashcarts, but then the test cartridge *is* a flashcart so that’s no surprise. Might be useful if you did a console mod and need to know how bad your solder job really was.
Note it’s *supposed* to display garbage for ~15 seconds, then differently colored garbage about as long before ultimately loading the interface. There’s an initial bootloader in the 80200000 range that first runs some very basic tests–like confirming RDRAM is available & works by running through its setup and some r/w tests–before loading the actual interface code to the 80000000 range, faking a reset (except with zaru where the reset is quite real), then going through the entire initialization routine again and finally setting up some video. Don’t be surprised that it has two sets of basic lib functions. You can sidestep that–and need to if you’re using an iQue–but you’re also avoiding some of the lowest level tests.
It runs some tests a bit differently if 4MB, 6MB, or 8MB of RDRAM are detected. If you don’t think 6MB was ever a thing, try asking around about 64DD support in Ocarina of Time ;*)
The reflasher is relatively pointless to run without a real unit. It was incredibly helpful to learn how to talk to the flash properly and understand the IO limitations; the dumper(s) wouldn’t have been possible without it.
.: Checksums :.
internal 318B3640 72EC843F
internal BDFEF553 94A42EF9
.: Thanks :.
Many thanks to the anonymous donor that lent one of these! Praise be to Anon!
Thanks again to all contributors!