nsfplay icon indicating copy to clipboard operation
nsfplay copied to clipboard

S5B register ranges?

Open BleuBleu opened this issue 7 months ago • 6 comments

Hi Brad!

Is it possible that NSFPlay doesn't accepts the full range of registers for S5B? According to the doc we should be able to use C000-DFFF for address and E000-FFFF for data.

Image

Looking at the code, it seems we just accept exactly C000 and E000. This also matches my quick testing, I get no audio if I write to E001 for example.

Image

The reason why we would want the full range is to give us more options to work around conflicts with VRC7 and N163. I may be looking at the wrong code, let me know if there is something we can do.

-Mat

BleuBleu avatar May 24 '25 08:05 BleuBleu

I think the prevailing consensus was that wwell-formed NSFs should use the canonical register addresses rather than mirrors. Many other NSF player programs don't accept writes at any of the mirrors.

For that code, I don't know if selecting only the single address was a conscious decision, or if it's a hold-over from the older implementation, but there hasn't yet been an NSF case presented where this was an issue.

In NSFPlay 3, the intention was to support mirrors, except when multi-chip is used in which case only the canonical addresses will be accepted to prevent conflicts.

So, if you think it's important to have this feature in NSFPlay 2, I'd accept a patch that does so, but I think it should have a case for multi-chip that limits it only to the two canonical addresses... and because of that I'm not sure it fits the use case you described, since you seem to want to use non-canonical addresses for multi-chip instead?

Ignoring all mirrors is the prevailing way that multi-chip NSF conflicts are currently resolved by many NSF players, so I am not sure what solution you have in mind involving mirrors, but it might go against the existing body of NSFs?

If this is meant as a feature to enable all mirrors but also have multi-chip, I think this would have to be a separate advanced user option that can be enabled or something, because it would break many existing multi-chip NSFs to enable such a thing.

bbbradsmith avatar Jun 04 '25 06:06 bbbradsmith

Hi.

Thanks for the reply.

The case I would like to resolve is N163 + VRC7 + S5B:

  • On VRC7 E000 resets the audio
  • On N163 E000-E7FF is the sound enable register
  • On S5B E000-FFFF is the main internal register write address.

As you can see, it is getting pretty crowded around E000. Unless I am mistaken, the spec does not provide a solution for this conflict.

Being able to use the full range would mostly resolve this issue. It would create conflicts with other things, but these other conflicts would be "solvable", this one does not appear to be.

I can think of a few ways of fixing this:

  • As you mentioned, adding an advanced option to enable a wider register range for writes would be a good idea. But i am not sure if we would want to limit this to these specific problematic ranges, or open the full register ranges for all chips. I dont have a good enough grasp of the side-effects that could come from this.
  • Another way would be for the player to take a more active part in the process and enable specific additional ranges when certain combinations of chips are detected, but this seems even more of a hack.

I totally understand the NSF standard says we should only accept writes to the canonical registers. But when it comes to multi-expansion, I consider the whole things to be a bit of a fantasy and i'm not sure we should be too strict about what is correct or not.

I am fairly sure there are less than 3 guys in the entire world who ever played these kind of crazy expansion combinations on actual hardware (not to mention you would need to own a copy of Gimmick! too).

-Mat

BleuBleu avatar Jun 04 '25 07:06 BleuBleu

Well, in my perspective, the main goal is that NSFPlay should play the existing body of NSFs as expected as much as is possible.

The conflict you just described seems like this would be more about whether any existing NSFs actually write the enable or reset registers, and whether any NSF players actually implement them. (I don't remember offhand if NSFPlay implements them, I'm guessing not.) So similarly I suppose the suggestion would be, if implemented, to just ignore those two for multichip that include more than 1 of those 3, and in such cases only 5B responds to $E000.

The goal is with NSFPlay 3 to have as much of that rarely-implemented stuff (mirrors, reset registers, etc.) available as is practical in single-expansion mode, and then selectively remove them to avoid conflicts in multichip mode. For NSFPlay 2, I don't want to pre-emptively work on that myself, but if there's something that you think demonstrates a need I'm willing to look at patch.

bbbradsmith avatar Jun 04 '25 08:06 bbbradsmith

I think your suggestion of ignoring those toggle registers makes more sense than my ideas.

I see that in NSFPlay (the current version), N163 does handle the E000 register, but not VRC7. So simply disabling the N163 E000 when S5B is also active would probably fix my problem.

https://github.com/bbbradsmith/nsfplay/blob/6af5406e3325b5507bea1ae1a57c77d5efe5c7f3/xgm/devices/Sound/nes_n106.cpp#L245

Would we need to make this an option, or you think its safe to just comment out that code?

Looking forward to NSFPlay 3 btw.

-Mat

BleuBleu avatar Jun 04 '25 13:06 BleuBleu

So, theoretically when that was added (12 years ago?), a conflict was created with 5B+N163 multichip, though nobody has reported it has a problem since, to my memory.

I think the solution I'd suggest is a case that skips that condition if 5B or VRC7 is present, but otherwise I think it should be kept functional for single-expansion N163.

bbbradsmith avatar Jun 04 '25 22:06 bbbradsmith

That sounds like an excellent compromise.

I will first try it locally when I have some spare time and see if it fixes my problem. I'll report back soon.

-Mat

BleuBleu avatar Jun 05 '25 03:06 BleuBleu