I was waiting awhile before I brought this up, but I had an idea for a slightly modified .NES header format myself.
I have gone through over 4000 ROMs, doing various testing on my FPGA NES console now, and I believe I'm in a fairly good position to recommend some changes.
The goals of my changes are thus:
1) retain absolute backwards compatibility (for existing ROMs)
2) this format must be "future proof"
3) the changes I make must be carefully documented and must make sense.
4) The changes must make "sense" from both a hardware and software standpoint.
This thread has kind of made me post my ideas early before I've had a chance to fully revise and pull together exactly what I want to do, but you should be able to get a good idea for what I wanted to do.
So, without further ado...
As mentioned before, the format will be retained as it is. For a recap, here is the existing format:
byte 0-3: 'NES<eof>'
byte 4: # of PRG pages
byte 5: # of CHR pages
byte 6: flags byte 0
byte 7: flags byte 1
byte 8-15: not used
There are two free bits on flags byte 1.
I propose the following:
D3 set and D2 clear of flags byte 1 will indicate that this is an extended header. DiskDude! in the header will have D2 set and D3 clear, so this will prevent interference with those old dirty ROMs. (thanks to Q for this suggestion)
If D3/D2 are not set and clear respectively, this is not a "Version 2" header. This should be a pretty definitive way to prevent confusion. Again, if the emulator does not support the extended header, the game loads like normal and the emulator is none the wiser.
Now that we know this is an extended ROM, the following things were concidered as problem areas for .NES
1) Vs. Unisystem.
The Vs. Unisystem has no less than 11 different PPUs and various protection schemes on some of the Namco/Atari games (such as RBI baseball). Some way has to be found to accomodate this.
2) PRG ROM in excess of 2Mbytes, CHR ROM in excess of 1Mbyte.
This has already occured, and has been causing trouble for some
ROMs. So far, the hack has been to set PRG ROM to 00h to indicate 4Mbytes of ROM (since FFh is 16K short of 4Mbytes), and in the case of
exceeding the 2Mbyte-8K CHR barrier, ROMs have been allocating the CHR in the PRG space, and the emulator has to sort this out. Very messy.
3) "sub mappers".
Some of the allocated mappers are actually multiple mappers with 1
number. The only way to sort this mess is to use CRC checks in the emulator. This of course is messy, since when a new ROM comes along that isn't in the CRC table, things break.
4) mapper numbers.
Face it, we're running out of mapper numbers. 256 was alot at the start (heck, 16 even was alot to begin with!) but we're filling the space up.
5) WRAM.
Not all carts that support WRAM support 8K of it. Some support less, some support more, and some even have EEPROM!
So, after testing nearly every ROM in goodNES, those are the trouble areas I have found.
The proposed solution is thus:
Code:
byte8:
7 0
---------
SSSS xxxM
S: sub-mapper number
This specifies the sub-mapper for this ROM. If the ROM has no
sub-mappers, this field shall be 0000b.
M: mapper bits 8.
This specifies 1 more mapper number bit, which extend the total
number of possible mappers to 512. The other three bits are
earmarked for more mappers- up to 4096 total if needed- but I wish to stress that we should NOT just willy-nilly allocate mapper numbers greater than 0ffh until it is absolutely required. See below for more on this. The "x" bits shall thusly be clear at all times.
byte9:
7 0
---------
CCCC PPPP
C: 4 more CHR ROM size bits
P: 4 more PRG ROM size bits
These combine with the existing 8 bits of each to form 12 bits total for the number of PRG and CHR banks... this is enough for 64Mbytes-16K of PRG data and 32Mbytes-8K of CHR data.
byte10:
7 0
---------
CCCC PPPP
C: quantity of CHR RAM present which is not battery backed
P: quantity of WRAM present which is not battery backed
each nybble:
0 - no RAM of this type is present.
1 - 128 bytes of RAM
2 - 256 bytes of RAM
3 - 512 bytes of RAM
4 - 1K of RAM
5 - 2K of RAM
6 - 4K of RAM
7 - 8K of RAM
8 - 16K of RAM
9 - 32K of RAM
10 - 64K of RAM
11 - 128K of RAM
12 - 256K of RAM
13 - 512K of RAM
14 - 1M of RAM
15 - reserved, do not use
byte11:
7 0
---------
CCCC PPPP
C: amount of battery backed CHR RAM (yes, carts exist with this!!!)
P: amount of battery backed WRAM or EEPROM.
Certain Famicom cartridges use an EEPROM for storing their game data, instead of a static RAM.
Like above, these values follow the size table listed.
byte12:
7 0
---------
xxxx xxBP
P: this is a PAL ROM. when set, indicates PAL mode.
B: when set, indicates this ROM works on both PAL and NTSC machines (some of the Codemasters games actually will adjust the game depending on if it detects you running on a PAL or NTSC machine. It adjusts the timing of the game, and fixes the music).
Not many games would have this B flag set.
x: this bit is not used yet. They shall be maintained clear.
byte13:
7 0
---------
UUUU PPPP
This byte is reserved for the Vs. Unisystem only. If this is not a Vs. Unisystem ROM, then this byte shall be all 0's.
P: PPU type. This specifies the type of PPU used for this game. I have a list of this, but I have not processed it yet. There's around 11 different PPU's that exist.
U: various Unisystem flag bits. Again, I am working hard on this stuff so it's not fully complete.
I am working on buying 1 of every Unisystem game so I can study the hardware and come up with a coherent methodology. If anyone has any Unisystem games that I don't have, I could REALLY use them.
So far, for the Unisystem flags I can come up with, there's a special copy protection chip or chips that exist on games such as RBI Baseball. I totally RE'd RBI baseball's chip, but I know at least 2 other namco/atari games use similar but different chips... since running those games with my clone of the chip doesn't work.
Well, that in a nutshell is my proposal. It has been extensively thought out, future proofed, and carefully designed to fit in with existing emulators and ROMs. In fact, these additions would probably only affect around 5% of the existing ROMs, but they would banish CRC and mapper hacks forever.
I propose making a "fixup" program for existing ROMs which need it, and CAREFULLY documenting all the updates needed in 1 central location so that the existing mapper issues cannot occur again.
Also on the mappers issue, I have made an absolutely comprehensive mapper guide vs. mapper number which I will be posting to my page at some point. It lists every single implemented mapper number, where it can be found, and what it is composed of. Everything on it has been tested and revised, since it was produced when I made the FPGA NES.
And as such, the extra mapper bits should NOT be used until we run out of existing mapper numbers to prevent confusion and needless trouble.