PowerPak NSF compatibility issue (ZENSF)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
PowerPak NSF compatibility issue (ZENSF)
by on (#224186)
Yesterday I released an open source NSF compilation tool called ZENSF, which seems to be working fine for the .NES export, but it also can build .NSF/.NSFe compilations too.

The generated NSF works fine in emulators I've tried, but strangely it fails on the PowerPak whenever I switch tracks? (Just hangs, no sound.)

I've attached the NSF built by the current code, which as far as I can tell doesn't violate any rules. Doesn't try to use banks from outside the NSF's data, doesn't write to the stack, doesn't touch WRAM either. I can't figure out what causes this incompatibility with the PowerPak!

(I've tried breakpoints on RW $100-1E0, RW $800-3FFF, RW $4020-5FF7, RW $6000-7FFF, W $8000-FFFF, R $4000-4020, W $4016. None of these seem to hit in an emulator.)

Would appreciate any ideas. I tried looking at the PowerPak NSF player source but so far couldn't spot a conflict.
Re: PowerPak NSF compatibility issue (ZENSF)
by on (#224238)
After thinking about it some more, one other unusual thing this NSF did was point PLAY directly at RAM. Relocating it into one of the ROM banks appears to make it compatible with the PowerPak. (NSF attached, for any who are curious.)

PLAY that goes to RAM should be a valid idiom, though, and this seems to indicate a defect in the PowerPak player.

It would be easy to come up with theoretical flaws if the PowerPak used NMI to drive PLAY; thread synchronization bugs would explain it... but it's based on a polling loop, so I don't have any theory on what could happen when switching tracks that would fail for this.
Re: PowerPak NSF compatibility issue (ZENSF)
by on (#224239)
Checking the PowerPak NSF player source linked above (nsf.asm) I think the problem was not PLAY pointing at RAM, but that the banks are not restored for every INIT.

nsf.asm has a routine called bank_init that gets called during reset (just after load of NSF) but does not appear get called again when switching tracks. I believe this is the problem. Writing this post as a reminder to test it later.


Also, I notice there's a hack (see: jmp foo) that skips clearing RAM at $6000-7FFF, which could also cause incompatibility. The FDS banks at $6000/$7000 seem to always get initialized with the same bank as $E000/$F000, which I think might be part of the reason why. The expansion byte gets written to a special register at $5FF3 that probably swaps those out for dedicated RAM banks if not using FDS, but I want to make sure, so this is another thing for my test list:

  • 1. Test NSF that switches the bank containing INIT to indicate pass/fail if after switching tracks it plays the correct INIT.
  • 2. Test if writes to $6000-7FFF are mirrored to $E000-FFFF for non-FDS tracks.
  • 3. Test contents of $6000-7FFF on INIT (and also between tracks) to verify that they aren't cleared.
Re: PowerPak NSF compatibility issue (ZENSF)
by on (#232629)
I made some fixes, zensf.nsf works ok now. Banks are initialized before every INIT. 6000-7FFF is cleared (except when FDS is enabled). And some other stuff (found a bug in the NSF mapper causing playback issues).

rainwarrior wrote:
The expansion byte gets written to a special register at $5FF3 that probably swaps those out for dedicated RAM banks if not using FDS

Yes, that's what it does.
Re: PowerPak NSF compatibility issue (ZENSF)
by on (#232632)
Ah, that's great!