While testing the PCE version of MDFourier, Tianfeng brought an issue to my attention. The game Ninja Spirit is plagued by a terrible noise when the game is supposed to be silent. This is most easily heard when the game is paused.
The issue in not PC engine or everdrive related and exhibits the same behavior when using an original Hu card. R-type, for example, is completely silent when the game is paused. Several theories were put forward, but since I was working on writing to the sound registers for the PC Engine version of MDFourier I checked the values with Mednafen’s debugger.
It turns out that the game was not telling the system to reduce the volume to zero during silent scenes. Instead, it changes the register that controls the stereo panning, located at address is $0805.
I thought a bug could cause this, since the register numbers are sequential, so I checked out what R-Type, a game that we know to be silent, did during the pause screen. R-type treats silence differently and zeroes a close by register $0804. My theory is that the programmer believed that turning the Left volume and Right Volume to zero should silence the sound completely, but that the system has a slight crossover–not unlike headphone amplifiers–so that even if the sound is completely muted on one side, it still has a small presence.
This led me to patch the ROM so that it changes register $0804 instead of $0805 and it worked, Ninja Spirit no longer has a terrible noise resignation though out the silent sections and on the pause screen.
Tianfeng also discovered this happens in Chase HQ, and applying the same patch cures the issue when paused... but not during the title screen. This is because the sound engine manages that part of the sound and is not a special case, and that would require someone who knows more then I do about the pc engine game code.
There are two interesting issues here though. Most emulators are not emulating the L/R panning correctly, since this is not audible in them, I imagine they assume that volume should be completely silenced, but tests in several hardware revisions show that is not the case.
Currently, we do not know how many games are inflicted with this issue. I have not yet tested this, but I think a simple program can be made to check any set of ROMs for routines that zero out register $0805 and label the results as candidates for patching.
Anyway, here is the patch to fix Ninja Spirit. It can be applied to either the original Japanese (Saigo no Nindou) or US version of the game.
Download the patch
Audio file showing the difference (Coregrafx-I)
Audio file showing the difference (SGFX, lower noise floor)
Using the MAME disassembler, I got to this point while pausing:
Register $0800 is selected, since that address is used to tell the sound hardware which channel will be worked with, here the value is taken from Y which was set previously. Then the opcode stz is used, in order to zero out register $0804.
I searched fo the opcode values and got that stz is 9C, so I did a binary search for:
This got me to the four places where this was set, and I blindly replaced them for:
And it worked. I know a more conscious process must be followed in general in order not to break things, but I believe someone way more knowledgeable, like Chris Covell, could look in into this much further and come up with a good workable solution.