UNIF: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(Create page, since I've linked to it enough times.)
 
(category, tidy up)
 
(22 intermediate revisions by 10 users not shown)
Line 1: Line 1:
[[UNIF]] (Universal NES Image Format) is a differently constrained and more descriptive format for holding NES and Famicom ROM images. It has not really caught on due to network effects. Nonetheless, certain games can only be stored as UNIF.
'''UNIF''' (Universal NES Image Format) is an alternative format for holding NES and Famicom ROM images.


Since the standard has not been updated since 2000, this has not been updated to reflect more recent findings.
Its motivation was to offer more description of the mapper board than the popular [[iNES|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 [[UNIF_to_NES_2.0_Mapping#So-far_unassigned_UNIF_board_names|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 [http://web.archive.org/web/20080827175203/http://www.parodius.com/~veilleux/ website deleted].
 
Since 2011 the UNIF standard has been maintained as part of the [http://github.com/eteran/libunif libunif project], a library for loading and creating UNIF files.
 
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==
==Format==
The suggested file extension for UNIF is <tt>.unf</tt> or <tt>.unif</tt>.
("LE16" and "LE32" below denote little-endian 16/32-bit integers.)


UNIF images start with a 32-byte header:
UNIF images start with a 32-byte header:
  offset  length(bytes) value
{| class="tabular"
      0       4         "UNIF"
! Offset || Length (bytes) || Value
      4       4         le32, minimum version number required to parse all chunks in file
|-
      8     28        all nuls
| 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:
The header is followed by any number of Type+Length+Value blocks:
  offset  length(bytes) value
 
      0       4         Type, varies, defined below
{| class="tabular"
      4       4         le32, length
! Offset || Length (bytes) || Value
      8     length     content encoding varies by type
|-
| 0 ||  4 || Type, varies, defined below
|-
| 4 ||  4 || LE32, length
|-
| 8 ||length|| content encoding varies by type
|}


===Types===
===Types===
Line 22: Line 46:
{| class="wikitable sortable"
{| class="wikitable sortable"
|-
|-
! Type !! Length !! Minimum version required !! encoding !! content meaning
! Type !! Length !! Minimum version required !! Encoding !! Content meaning
|-
|-
| MAPR || variable || 1 || null-terminated ASCII || 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
| 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
|-
|-
| PRG''n'' || variable, should be power of two || 4 || raw || the contents of the ''n''th PRG ROM; at least PRG0 is required; ''n'' is in hexadecimal
| PRG''n'' || variable, usually power of two || 4 || raw || the contents of the ''n''th PRG ROM; at least PRG0 is required; ''n'' is in hexadecimal
|-
|-
| CHR''n'' || variable, should be power of two || 4 || raw || the contents of the ''n''th CHR ROM
| CHR''n'' || variable, usually power of two || 4 || raw || the contents of the ''n''th CHR ROM
|-
|-
| PCK''n'' || 4 || 5 || le32 || the CRC-32 of the ''n''th PRG ROM
| PCK''n'' || 4 || 5 || LE32 || the CRC-32 of the ''n''th PRG ROM
|-
|-
| CCK''n'' || 4 || 5 || le32 || the CRC-32 of the ''n''th CHR ROM
| CCK''n'' || 4 || 5 || LE32 || the CRC-32 of the ''n''th CHR ROM
|-
|-
| NAME || variable || 1 || null-terminated ASCII || the name of the game
| NAME || variable || 1 || null-terminated UTF-8 || the name of the game
|-  
|-  
| WRTR || variable || unknown || null-terminated ASCII || unofficial? the name of the dumping software. Should be in the DINF Type instead
| 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 ASCII || comments about the game, especially licensing information for homebrew
| READ || variable || 1 || null-terminated UTF-8 || comments about the game, especially licensing information for homebrew
|-
|-
| DINF || 204 || 2 || special || Dumping information-
| DINF || 204 || 2 || special || Dumping information
  offset  length(bytes) value
{| class="tabular"
      0           100 ASCIIZ dumper name
! Offset || Length (bytes) || Value
    100             1 day-of-month of dump
|-
    101             1 month-of-year of dump
| align=right |  0 || align=right | 100 || null-terminated UTF-8 dumper name
    102             2 year of dump
|-
    104           100 ASCIIZ the name of the dumping software or mechanism
| align=right | 100 || align=right |  1 || day-of-month of dump
|-
| align=right | 101 || align=right |  1 || month-of-year of dump
|-
| align=right | 102 || align=right |  2 || LE16, year of dump
|-
| align=right | 104 || align=right | 100 || null-terminated UTF-8 the name of the dumping software or mechanism
|}
|-
|-
| TVCI || 1 || 6 || byte || TV standard compatibility information-
| TVCI || 1 || 6 || byte || TV standard compatibility information-
Line 59: Line 90:
| CTRL || 1 || 7 || byte || Controllers usable by this game (bitmask)
| CTRL || 1 || 7 || byte || Controllers usable by this game (bitmask)
{|
{|
| align=right |  1.||Joypad
| align=right |  1.||[[Standard controller]]
|-
|-
| align=right |  2.||Zapper
| align=right |  2.||[[Zapper]]
|-
|-
| align=right |  4.||R.O.B.
| align=right |  4.||R.O.B.
|-
|-
| align=right |  8.||Arkanoid
| align=right |  8.||[[Arkanoid controller]]
|-
|-
| align=right | 16.||Power Pad
| align=right | 16.||[[Power Pad]]
|-
|-
| align=right | 32.||Fourscore
| align=right | 32.||[[Four Score]]
|-
|-
| align=right | 64.|| expansion (leave cleared)
| align=right | 64.|| expansion (leave cleared)
Line 78: Line 109:
| BATR || 1 || 5 || byte || Boolean specifying whether the RAM is battery-backed.
| BATR || 1 || 5 || byte || Boolean specifying whether the RAM is battery-backed.
|-
|-
| VROR || 1 || 5 || byte || Boolean specifying whether CHR''n'' should be ignored and replaced with RAM
| 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:
| MIRR || 1 || 5 || byte || [[Mirroring|What CIRAM A10 is connected to]]:
{|
{|
| align=right | 0.||PPU A11 (horizontal mirroring)
| align=right | 0.||PPU A11 (horizontal mirroring)
Line 90: Line 121:
| align=right | 3.||Vcc (one-screen B)
| align=right | 3.||Vcc (one-screen B)
|-
|-
| align=right | 4.||Extra memory has been added (four-screen "mirroring")
| align=right | 4.||Extra memory has been added (four-screen)
|-
|-
| align=right | 5.||Mapper controlled
| align=right | 5.||Mapper-controlled
|}
|}
|}
|}


==Shortcomings==
==Shortcomings==
MAPR chunks are nominally supposed to use the text on the PCB. However, the [[UxROM|same PCB]] can have [[iNES Mapper 180|different incompatible behavior]], depending on how or what things are populated or jumpered. The workaround has been to add extra text the MAPR chunk (in this case, [http://bootgod.dyndns.org:7777/profile.php?id=3869 "HVC-UNROM+74HC08"]). Some games have no identifying text on the PCB at all. Other games have only symbols in [http://bootgod.dyndns.org:7777/profile.php?id=1762 Japanese] or Chinese.
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, [http://forums.nesdev.org/viewtopic.php?f=3&t=9883 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 [http://bootgod.dyndns.org:7777/profile.php?id=1762 Japanese] or Chinese. Sometimes the [[UxROM|same PCB]] can have [[iNES Mapper 180|different incompatible behavior]], depending on how things are populated or what things are jumpered. The workaround has been to add extra text in the MAPR chunk (in the ''Crazy Climber'' case, [http://bootgod.dyndns.org:7777/profile.php?id=3869 "HVC-UNROM+74HC08"]).
 
There is no ability to specify PRG RAM outside of the MAPR chunk. Two games using VRC4 ([http://bootgod.dyndns.org:7777/profile.php?id=1565 Gradius II] and [http://bootgod.dyndns.org:7777/profile.php?id=3988 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.
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.


CTRL chunks do not specify which controller should be plugged into which port nor Famicom-only controllers.
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 CHR''n'' 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.


BATR chunks do not disambiguate which RAM is battery-backed, if more than one is present.
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 [[Standard controller|12-key controller]] or the [[mouse]]).


There is no ability to specify PRG-RAM or CHR-RAM outside of the MAPR chunk. [http://bootgod.dyndns.org:7777/profile.php?id=3988 Two] VRC4 [http://bootgod.dyndns.org:7777/profile.php?id=1565 using] games use the exact same PCB, but one has 2KB PRG-RAM and the other doesn't.
There is no way to fully describe PlayChoice 10 or [[Vs. System]] games.


==References==
==References==
Last published version of the standard: http://libunif.googlecode.com/files/UNIF_current.txt
* [http://github.com/eteran/libunif libunif project on Github]
* [http://raw.githubusercontent.com/eteran/libunif/master/UNIF_current.txt Last published version of the standard]
 
==See also==
* [[UNIF to NES 2.0 Mapping]]
 
[[Category:File formats]]

Latest revision as of 22:49, 28 January 2023

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, a library for loading and creating UNIF files.

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.

("LE16" and "LE32" below denote little-endian 16/32-bit integers.)

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

The header is 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
Offset Length (bytes) Value
0 100 null-terminated UTF-8 dumper name
100 1 day-of-month of dump
101 1 month-of-year of dump
102 2 LE16, year of dump
104 100 null-terminated UTF-8 the name of the dumping software or mechanism
TVCI 1 6 byte TV standard compatibility information-
0. NTSC only
1. PAL only
2. compatible with both
CTRL 1 7 byte Controllers usable by this game (bitmask)
1. Standard controller
2. Zapper
4. R.O.B.
8. Arkanoid controller
16. Power Pad
32. Four Score
64. expansion (leave cleared)
128. expansion (leave cleared)
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:
0. PPU A11 (horizontal mirroring)
1. PPU A10 (vertical mirroring)
2. Ground (one-screen A)
3. Vcc (one-screen B)
4. Extra memory has been added (four-screen)
5. Mapper-controlled

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 in 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).

There is no way to fully describe PlayChoice 10 or Vs. System games.

References

See also