This tool is intended to read NES headers (giving a preference to 2.0 headers) and generate an XML file reflecting the syntactic meaning of the headers, as well as to take an XML file in the same format and apply it to a ROM set.
The tool uses the SHA256 hash of a ROM to determine which ROM the file contains, ignoring the existing iNES or NES 2.0 header currently on the ROM (if any; it also works with headerless ROMs for applying headers), as well as any trainer data. Other hashes are calculated and provided in generated XML files for convenience, but they have no significant meaning within this application.
This tool uses its own XML data format to include sufficient data about ROMs for both header application and organization, but also supports the NES 2.0 XML Database format for header application, for which it matches on SHA1 sums.
Although matching against UNIF ROMs for applying headers is supported (which will convert the output ROMs to NES 2.0 or INES ROMs), the amount of work that would be required to add full support for all of the UNIF boards is far too high. So, all that can be done with this tool for UNIF ROMs is to use them as a source ROM set for applying an existing XML file in order to transform them into NES 2.0 or INES ROMs.
Some NES 2.0 header sets assign the value of "2" to byte 13 of the header for some ROMs identified in byte 7 as PlayChoice 10 ROMs (the lower two bits as "2" in byte 7), but zero for this byte in others. The reason for this is unknown, but the specification at https://wiki.nesdev.com/w/index.php/NES_2.0 implies that these ROMs should be assigned a value of "0" in byte 13 when those bits in byte 7 are not 1 or 3, so that's what this tool does in those circumstances. Because of this, this tool is unable to model the entirety of those sets, and will result in differing data for headers for those ROMs (the value of byte 13 on those ROMs will be 0) if read to an XML file and re-applied to the same set.
Occasionally when running this tool to apply headers or organize ROMs, there will be errors on some files saying that the source file was unable to be found, when it does exist on the filesystem. For now, running the tool again with the same options and the same source and output directories seems to resolve this, but I hope to eventually figure out the root cause.
There also doesn't seem to be consensus on how to identify FDS titles aside from checksumming the entire file. Because FDS games can write to their own disks, it seems like there should be a better way. Once I've determined that, the way in which this tool matches FDS titles is likely to change. For now, however, this tool just uses a checksum of the unheadered version of the entire file, as other tools do.
To use this tool, compile it for your favorite OS and then run it with the following options:
-enable-fds
Enable FDS support.
-enable-fds-headers
Enable writing FDS headers for organization.
-enable-ines
Enable iNES header support. iNES headers will always be lower priority for operations than NES 2.0 headers.
-format-transform-destination
Destination file for format transform operations.
-format-transform-type
Format of destination file for transform operations. {default|nes20db|sanni}
-generate-fds-crcs
Generate FDS CRCs for data chunks. Few, if any, emulators use these.
-operation string
Required. Operation to perform on the ROM set. {read|write}
-organization
Read/write relative file location information for automatic organization.
-preserve-trainers
Preserve trainers in read/write process.
-print-checksums
Print checksums as ROMs are loaded or processed.
-rom-output-base-path string
The path to use for writing organized NES and/or FDS ROMs.
-rom-source-path string
Required. The path to a directory with NES and/or FDS ROMs to use for the operation.
-truncate-roms
Truncate PRGROM and CHRROM to the sizes specified in the header.
-xml-file string
The path to an XML file to use for the operation.
-xml-format string
The format of the imported or exported XML file. {default|nes20db} (default "default")
Clone the repository, switch to the directory you checked out, then run:
$ go build