How to determine if a specific mapper 0 ROM has readonly CHR?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
merehap
Posts: 9
Joined: Mon Jan 17, 2022 8:35 am

How to determine if a specific mapper 0 ROM has readonly CHR?

Post by merehap »

I'm currently treating CHR on NROM as writeable because Blargg's instr_test-v3 test singles require write-ability in order to display results to the screen. Unfortunately this behavior means that I can't emulate the game 1942 accurately since it writes to CHR memory addresses, blanking out various pattern table entries with zeroes. Of course 1942's board has readonly CHR such that these writes have no effect on a real NES.

Do all true NROM/mapper 0 boards have only readonly CHR? If so, then presumably the instr_test-v3 tests won't work on a real NES.

How do I address this in my emulator if I want both the tests and 1942 to render properly? Which of the following options is best?
  1. If certainly NROM boards are write-able, somehow detect what board a given ROM represents and enable writes for those cases.
  2. Set CHR to be readonly for mapper 0 and introduce a hack to make it writeable for test ROMs only.
  3. Use only NES2.0 ROMs such that CHR RAM is made explicit? (An incomplete option since other emulators make do with just iNES.)
  4. Create a database of mapper 0 ROMs that tells my emulator which ROMs have writeable CHR. Or use someone else's existing database.
  5. Something else?
I've verified that well-established emulators run both ROMs in their intended manner, so I'm curious what the best solution is here.

Thoughts? Thanks!
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: How to determine if a specific mapper 0 ROM has readonly CHR?

Post by Fiskbit »

For the original iNES header format, when CHR-ROM size is specified as 0, you should assume 8 KB of CHR-RAM. NES 2.0, on the other hand, makes the sizes of each type explicit (so 0 bytes CHR-ROM does not imply presence of CHR-RAM).

I've downloaded and tested a few of the v3 singles (v5 is the current version; I'm not sure what's different) and I don't see any writes to PPU $0000-1FFF, although I'm testing on an emulator that passes, so I don't know what happens in the failure case. Are you sure these are relying on writes to these regions?


Edit: To elaborate a bit, if a ROM is writing to CHR-ROM expecting the writes to stick and doesn't claim in its header it uses CHR-RAM, then the header should be considered misconfigured. For your own personal copy, you could fix the header, or you can use the NES 2.0 database that NewRisingSun maintains to look up ROM CRC's and get proper header info, since so many ROM headers are wrong or incomplete. In the case of the instr_test ROM singles, they supply 8 KB of CHR-ROM, so if they're then relying on writes to these, that won't work on any normal cartridge hardware. You can certainly use CHR-RAM with NROM, but the game would need to populate it at runtime.
User avatar
merehap
Posts: 9
Joined: Mon Jan 17, 2022 8:35 am

Re: How to determine if a specific mapper 0 ROM has readonly CHR?

Post by merehap »

According to this post viewtopic.php?p=26451 , some ROMs overwrite portions of CHR as a form of copy-protection so that the games won't work properly on a CHR RAM-enabled board. In this case all that happens (that I've noticed) is some letters aren't displayed on the screen, so the game is otherwise playable. Since the writes aren't expected to succeed, I doubt that they would register in an emulator's debugger, assuming that's what you're using.

01-basics.nes of the v3 singles specifies 8KiB of CHR ROM, so that doesn't give any indication that the ROM is in fact RAM. So I can't just rely on CHR ROM = 0KiB in iNES 1.0 in this case :( . That said, I'll at least update my emulator for cases where CHR ROM = 0KiB, so thanks for that! I'm still curious what the general purpose solution is here though.
Fiskbit
Posts: 891
Joined: Sat Nov 18, 2017 9:15 pm

Re: How to determine if a specific mapper 0 ROM has readonly CHR?

Post by Fiskbit »

But that is what you should rely on; if the header claims that it's ROM, it's ROM. Unlike consoles like the SNES, NES emulation relies on the header fully specifying the cartridge hardware (and for iNES, conventions are used where it's underspecified). If the header is wrong, the game should not work. This is why the NES 2.0 database is necessary, because wrong headers make ROMs work incorrectly, so emulators try to get around that with a known-good source for known software. If software isn't in that database, the header is all you have, and it needs to be right.

Games that use ROM and test to see if it's RAM for anti-piracy purposes should have those writes ignored. If the tests you're using are CHR-ROM and are relying on writes not being ignored, then the tests are wrong. It isn't the role of your emulator to make software work that doesn't work on real hardware because that will create inaccuracies that will likely break other software.

Also, I don't see a 01-basics.nes in instr_test-v3, but it does seem to be present in v5. Running that one in emulator, I still don't see any writes to $0000-1FFF on the PPU bus, so I'm confused about what issue you're actually seeing.
User avatar
merehap
Posts: 9
Joined: Mon Jan 17, 2022 8:35 am

Re: How to determine if a specific mapper 0 ROM has readonly CHR?

Post by merehap »

OK, mystery solved. It wasn't 01-basics.nes that was failing when I changed CHR to be readonly, it was actually 1-Branch_Basics.nes. 1-Branch_Basics.nes DOES set CHR-ROM=0, so your earlier suggestion of setting up 8KiB of CHR-RAM in that case will solve that issue. I had a dirty test image directory which made me confuse the two since 01-basics.nes had briefly failed for a different issue.

(And yes, 01-basics is from v5, not v3.)

Thanks a lot for your help, Fiskbit! No need for hacks nor integrating the NES 2.0 database now.
Post Reply