UNIF
UNIF (Universal NES Image Format) is an alternative format for holding NES and Famicom ROM images.
Its motivation was to offer more description of the mapper board than the popular iNES 1.0 format, but it suffered from other limiting constraints and a lack of popularity. The format is considered deprecated, replaced by the NES 2.0 revision of the iNES format, which better addresses the issues it had hoped to solve.
There are a small number of game rips that currently only exist as UNIF.
History
The originator of the UNIF format, Tennessee Carmel-Veilleux, publically abandoned the format in December of 2008, and had its website deleted.
Since 2011 the UNIF standard has been maintained as part of the libunif project. See: http://github.com/eteran/libunif
UNIF is currently considered a deprecated standard. Further updates to UNIF are unlikely, and it is recommended that new games or rips requiring special mapper specifications use the NES 2.0 format instead of attempting to extend UNIF.
Format
The suggested file extension for UNIF is .unf or .unif.
UNIF images start with a 32-byte header:
Offset | Length (bytes) | Value |
---|---|---|
0 | 4 | "UNIF" |
4 | 4 | le32, minimum version number required to parse all chunks in file |
8 | 24 | all nulls |
Followed by any number of Type+Length+Value blocks:
Offset | Length (bytes) | Value |
---|---|---|
0 | 4 | Type, varies, defined below |
4 | 4 | le32, length |
8 | length | content encoding varies by type |
Types
The following Types are known:
Type | Length | Minimum version required | Encoding | Content meaning | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MAPR | variable | 1 | null-terminated UTF-8 | A unique human-readable identifier specifying the exact hardware used; not an iNES mapper number, and not a full text description of the mapper; required | ||||||||||||||||||
PRGn | variable, usually power of two | 4 | raw | the contents of the nth PRG ROM; at least PRG0 is required; n is in hexadecimal | ||||||||||||||||||
CHRn | variable, usually power of two | 4 | raw | the contents of the nth CHR ROM | ||||||||||||||||||
PCKn | 4 | 5 | le32 | the CRC-32 of the nth PRG ROM | ||||||||||||||||||
CCKn | 4 | 5 | le32 | the CRC-32 of the nth CHR ROM | ||||||||||||||||||
NAME | variable | 1 | null-terminated UTF-8 | the name of the game | ||||||||||||||||||
WRTR | variable | unknown | null-terminated UTF-8 | unofficial, invalid. The name of the dumping software. Should be in a DINF chunk instead | ||||||||||||||||||
READ | variable | 1 | null-terminated UTF-8 | comments about the game, especially licensing information for homebrew | ||||||||||||||||||
DINF | 204 | 2 | special | Dumping information
| ||||||||||||||||||
TVCI | 1 | 6 | byte | TV standard compatibility information-
| ||||||||||||||||||
CTRL | 1 | 7 | byte | Controllers usable by this game (bitmask)
| ||||||||||||||||||
BATR | 1 | 5 | byte | Boolean specifying whether the RAM is battery-backed. | ||||||||||||||||||
VROR | 1 | 5 | byte | "If this chunk is present, then the CHR-ROM area will be considered as RAM even if ROM is present." | ||||||||||||||||||
MIRR | 1 | 5 | byte | What CIRAM A10 is connected to:
|
Shortcomings
Prior to 2013, no encoding was specified for any of the fields; 7-bit-clean ASCII was assumed, making NAME inadequate for the vast majority of non-US games. In the first quarter of 2013, UTF-8 became the encoding.
Chunks can come in any order, so conventional patching tools cannot work without going through an "unpacked" intermediary stage.
MAPR chunks are nominally supposed to use the text on the PCB, such as "NES-SNROM". However, some games have no identifying text on the PCB at all. Other games have only symbols in Japanese or Chinese. Sometimes the same PCB can have different incompatible behavior, depending on how things are populated or what things are jumpered. The workaround has been to add extra text the MAPR chunk (in the Crazy Climber case, "HVC-UNROM+74HC08").
There is no ability to specify PRG RAM outside of the MAPR chunk. Two games using VRC4 (Gradius II and Bio Miracle Bokutte Upa) use the exact same PCB, but the former adds 2KiB PRG RAM and the latter adds none.
For greater emulator compatibility, people sometimes use already-known-supported MAPR chunks to get something that's "close enough", rather than specifying a new MAPR for not-necessarily-identical behavior.
BATR chunks do not disambiguate which RAM is battery-backed, if more than one is present.
It's not clear exactly what VROR is supposed to mean—"Do not throw an error if this MAPR normally has CHR ROM but there are no CHRn chunks, just give me 8KiB of CHR RAM"? "All the data I gave you for CHR-ROM, that was actually RAM, make it writeable"? As such, Nestopia, Nintendulator, and FCEUX just ignore it.
CTRL chunks do not specify which controller should be plugged into which port, nor Famicom-only controllers, nor Super NES controllers plugged into a Famiclone or through an adapter (such as the 12-key controller or the mouse).
No way to fully describe PlayChoice 10 or Vs. System games.
References
- libunif project on github: http://github.com/eteran/libunif
- Last published version of the standard: http://raw.githubusercontent.com/eteran/libunif/master/UNIF_current.txt