NSF format extension for PCM, IRQ, etc.

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NSF format extension for PCM, IRQ, etc.
by on (#34474)
The NSF format has some limitations that prevent some music from being ripped. Most notable is music that plays PCM samples manually by hogging the CPU and writing to $4011 (Battletoads, Skate or Die 2 are two). My DMC saw wave technique which uses an IRQ is also not possible. There are several ways the format could be extended to handle these, and others that make use of currently unsupported NES features. These extensions would NOT be used by all current rips which work fine already, only by the small number of soundtracks which current NSF doesn't support.

Minimal change to allow PCM: A flag in the header tells a player to allow the init return to never return, and interrupt it periodically to call the play routine. A couple of years ago there was discussion about adding support for PCM, with several minor variations on this approach.

NSF version 2: Setting the version to 2 in the header enables a "real NES" mode where the NMI and IRQ are emulated as on a NES, and the play routine is ignored. The player would call the init routine normally, but it would never return. Instead, it would enable NMI or IRQ at some point, and set up its own NMI or IRQ handler.

iNES derivitive: Music is in an iNES ROM that is run as any other iNES ROM, except that there is some way to tell it which track to play, perhaps by setting a few bytes in memory before starting execution. This would allow a NES emulator to be packaged into a library that acts just like an NSF player, where you load an iNES music file, then start a track and get samples out. It wouldn't generate any graphics, just sound. This format would allow the music to do ANYTHING possible on a NES, including for example use of the PPU for timing or something (perhaps reading $2007 repeatedly and waiting for two $FF reads that signal hblank or something).

The minimal change is nice because it's trivial to implement in most NSF players, and solves the main problem of allowing PCM soundtracks. NSF 2 is taking the opportunity to go further, and make rips simpler to play on hardware since they do more of the work. The iNES derivitive goes the whole way, and would be trivial to implement as well.

One suggestion was that the NSF format be unforgiving of problems with rips, rather than hiding them by being tolerant of erroneous behavior, like a non-returning init routine. I think the best way to ensure quality rips is to develop a separate lint-like validation tool for NSF files, that flags any suspicious behavior or outright problems.
Re: NSF format extension for PCM, IRQ, etc.
by on (#34475)
blargg wrote:
The NSF format has some limitations that prevent some music from being ripped. Most notable is music that plays PCM samples manually by hogging the CPU and writing to $4011 (Battletoads, Skate or Die 2 are two). My DMC saw wave technique which uses an IRQ is also not possible. There are several ways the format could be extended to handle these, and others that make use of currently unsupported NES features. These extensions would NOT be used by all current rips which work fine already, only by the small number of soundtracks which current NSF doesn't support.

Minimal change to allow PCM: A flag in the header tells a player to allow the init return to never return, and interrupt it periodically to call the play routine. A couple of years ago there was discussion about adding support for PCM, with several minor variations on this approach.

NSF version 2: Setting the version to 2 in the header enables a "real NES" mode where the NMI and IRQ are emulated as on a NES, and the play routine is ignored. The player would call the init routine normally, but it would never return. Instead, it would enable NMI or IRQ at some point, and set up its own NMI or IRQ handler.

iNES derivitive: Music is in an iNES ROM that is run as any other iNES ROM, except that there is some way to tell it which track to play, perhaps by setting a few bytes in memory before starting execution. This would allow a NES emulator to be packaged into a library that acts just like an NSF player, where you load an iNES music file, then start a track and get samples out. It wouldn't generate any graphics, just sound. This format would allow the music to do ANYTHING possible on a NES, including for example use of the PPU for timing or something (perhaps reading $2007 repeatedly and waiting for two $FF reads that signal hblank or something).

The minimal change is nice because it's trivial to implement in most NSF players, and solves the main problem of allowing PCM soundtracks. NSF 2 is taking the opportunity to go further, and make rips simpler to play on hardware since they do more of the work. The iNES derivitive goes the whole way, and would be trivial to implement as well.

One suggestion was that the NSF format be unforgiving of problems with rips, rather than hiding them by being tolerant of erroneous behavior, like a non-returning init routine. I think the best way to ensure quality rips is to develop a separate lint-like validation tool for NSF files, that flags any suspicious behavior or outright problems.


We were talking about this the last time that you had visited #nesdev along with a few other people, including Kevin Horton. I've also been experimenting a bit in converting NSF rips into ROMs that use the interrupts as normal and expected. The test went well and I might add was a bit more challenging than I thought. While some rips could work with a good deal graphical display. It should be encouraged of blocking several registers, memory address ranges from being executed by the programmer of the player. And that if the Play address is anything other than 0000h, then it won't play. Only writing 80h to $2000 should be allowed for the graphical display registers.

I did bring up the idea of creating a flag in the header to state if the init address call would return or not. From what I was told by Kevin Horton is that this feature would be hard to implement. I can also see the point of balancing out this format between hardware and software. I have seen the basic draft of the format. I think that if we can agree on things, that we can move forward with the format in supporting PCM and sound code called from the IRQ, which I have ran into a few lately that have proven extremely hard to rip.

As far as reading $2007, I have heard of a NSF that actually done that. I can't remember the name of the game right off hand.

As far as validating rips, I check all of mine as much as I can to make sure that they return within 4 frames and that most if not all addresses are written to with the proper value before the play code is called, because you will have a lot of reading without writing in the play code.

I think it's a great idea for the most part, except the possibility of bad rips which I think can be moderated to some extent to keep the quality of rips as good as possible. Not saying that my rips are perfect, because they are not. I do try my best. I do think that making a tool to check NSF 2 rips would also be a good idea.

The thing is that I do not do any type of windows programming, so I cannot help with that part of it. I have been running a lot of tests and ripping experiments for the past week or so.