ROM loader: header zeroing heuristic breaks NES 2.0 ROMs
- Dominant language
- JavaScript
- Stars
- 6.4k
- Forks
- 857
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
If any byte from 8-15 in the iNES header is non-zero, the code masks the mapper number to 4 bits (0-15 only), ignoring the high nibble from byte 7. This was a reasonable heuristic for early iNES dumps with garbage in the unused header bytes (like "DiskDude!"), but it breaks NES 2.0 ROMs which legitimately use bytes 8-15.
## Current behavior
```javascript
// rom.js:61-70
let foundError = false;
for (i = 8; i < 16; i++) {
if (this.header[i] !== 0) { foundError = true; break; }
}
if (foundError) {
this.mapperType &= 0xf; // Ignore byte 7
}
```
NES 2.0 ROMs use bytes 8-15 for:
- Submapper numbers (critical for distinguishing MMC3 variants, bus-conflict boards)
- Extended mapper numbers (>255)
- PRG-RAM/CHR-RAM size
- NTSC/PAL timing mode
## Expected behavior
Detect NES 2.0 first and only apply the heuristic for iNES 1.0:
```javascript
if ((this.header[7] & 0x0C) === 0x08) {
// NES 2.0: parse extended fields, don't apply zeroing heuristic
} else {
// iNES 1.0: apply the header zeroing heuristic
}
```
## References
- [NES 2.0 format](https://www.nesdev.org/wiki/NES_2.0)
- [NES 2.0 submappers](https://www.nesdev.org/wiki/NES_2.0_submappers)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.