SourMesen / Mesen

Mesen is a cross-platform (Windows & Linux) NES/Famicom emulator built in C++ and C#
https://www.mesen.ca
GNU General Public License v3.0
1.25k stars 317 forks source link

NSF player track selection issue + Playback issues with Layla: The Iris Missions NSF #793

Closed TakuikaNinja closed 4 years ago

TakuikaNinja commented 4 years ago

With NSF/e files that have a large number of tracks (which is common as most NSF rips include sound effects), the track selection drop-down menu does not work very well when a track is playing. The scroll bar on the side just jumps back to the currently playing track. I am aware that using the scroll wheel without clicking on the drop-down menu, or pausing the current track before using the menu will work fine, but I doubt many users would notice that.

My other issue revolves around a specific ROM hack, Layla: The Iris Missions. Mesen currently seems to skip the first few notes for the majority of the tracks of this game's NSF rip, which does not happen on other emulators. MrNorbert1994 kindly re-ripped the NSF recently to remove unnecessary game code, but the issue still persists.

I have attached the new NSF rip for convenience, as it highlights both issues mentioned here: Layla: The Iris missions NSF

SourMesen commented 4 years ago

Thanks for the report. The dropdown issue I wasn't even aware of (I personally haven't really used the NSF player all that much over the years), should be easy to fix, though.

As for the missing notes, it seems like that behavior is shared with Nintendulator, as far as I can tell? Mesen is very similar to Nintendulator's code for the NSF implementation, so that might be a hint. After the first call to INIT, memory is identical to FCEUX, but it looks like after the first call to PLAY, the values in memory don't match up.

After some trace log comparisons, it looks like the PLAY routine puts data in memory at $01EC/$01ED, which get overwritten by the stack via a JSR instruction. FCEUX has the stack pointer set to $FD when PLAY starts, whereas Mesen has it set to $F7 (due to the way Mesen/Nintedulator handle NSF files), so it sounds like the NSF file is assuming $1EC/D is safe to write to, but it gets overwritten in this case.

Since the NSF spec says The precise position of the stack on INIT or PLAY is not guaranteed, as the NSF player may need to use the top area of the stack for its own internal purpose. Make sure the tune does not attempt to modify $01F0-01FF directly. (Armed Dragon Villigust did, and was relocated to 2xx for its NSF.), I'd be tempted to consider this to be a bug with the NSF file itself? 1F0-1FF is reserved for the NSF player's implementation, which means that the PLAY routine's JSR/RTS calls may end up writing to addresses below $1F0 if the player uses up more stack than other players.

TakuikaNinja commented 4 years ago

Thanks, I'll let MrNorbert1994 know so he can fix the NSF. Edit: He has fixed the NSF rip, and it works perfectly now. Thanks for the help!

SourMesen commented 4 years ago

Thanks for the confirmation!

The track dropdown issue during playback should also be fixed as of the latest commit.