The S-CPU boots the S-SMP by sending a sound driver program to audio RAM, using a protocol over ports $2140-$2143 defined by the S-SMP's IPL, and then sending a jump command. I have this working in NO$SNS and on my SNES PowerPak thanks to a host library and SPC700 macro pack for ca65, both written by blargg. After that, the CPUs continue communicating using a separate protocol defined by the sound driver until system reset or power cycle, after which the IPL takes control again.

But now I want to write a program that loads music in some format (not necessarily .spc) and switches among tracks. The problem with .spc and .sp2 formats is that the S-CPU can't reset the S-SMP back to the IPL. This means that unless the program on the S-SMP exposes some defined protocol to the S-CPU, the user has to get up and press the Reset button in order to switch songs. In order to make it possible to write a "sound test" style front-end for playing homebrew SPC700 music, or even just to include music in a game, we first need to define a baseline protocol that can be used by homebrew sound drivers. Is there a common protocol used by official games' sound drivers to do all these?

The problem with .spc and .sp2 formats is that the S-CPU can't reset the S-SMP back to the IPL

Can't you simply write a second version of the IPL ROM, but instead of jumping to the "reset" vector it simply continues to run the sound engine like normal ? That's what I'd do, but you can also write your own communication protocol, in order to make things simpler for common messages such as simply pause and resume the music, instead of tweaking the sound engine state manually you just give an order to the SPC program, this makes sense.

Some sound drivers do reset back to the IPL just to load new audio data (or they support a command that can perform this). However, you'd need a comprehensive list of what command performs this particular action for the corresponding sound driver, and not all sound drivers actually do this (so, if possible, you'd probably have to use the sound driver's own load function to overwrite with code to reset back to IPL).

Really what I'm looking for more than anything is creating a standard for homebrew sound drivers going forward. I thought it'd be easier to follow an existing standard if one existed, such as the protocol of Nintendo's driver.

It's pretty easy to play around with vspcplay and find out the interfaced used by a bunch of games...

Super Metroid maps writes to $2140 to various music effects/cues, and writes to the other three registers to various sound effects.Super Mario World selects track with writes to $2142, and the other three registers select sound effects (each on its own channel).

Other games (e.g. FF6) dynamically load patches, so the interface isn't as trivially discoverable.

SNESMod has a specific command to switch back to the IPL ROM, although the SNES end doesn't appear to be coded in by the developer.

If you're thinking of the Nintendo sound driver, it looks like storing an $FF to $2141 in Super Mario World switches back to the IPL ROM.

As for anything else... if at all possible, better look for hits for the register that controls whether or not the IPL ROM is activated. Of course, this is RAM we're talking about, so that means the code can modify itself to its own will...

Years later, I have begun work on my own music engine, and I'm at that point where I need to define the interface between it and the host program. So is there still no interest in defining a standard interface between homebrew music engines and 65816 host programs?

I think the big problem is that almost all the SNES music anybody cares about has already been made, and doesn't follow a single standard. If the goal is SPC playback, you're already hosed before you begin. If it isn't, why the push for a standard?

I haven't written any of my own sound driver yet, other than an untested sketch of the APU-side HDMA streaming code, and I have no idea what the rest of it is going to look like because I don't really understand how sound drivers work yet. Accordingly I don't think I have much to contribute to an attempt to define community standards. I have no problem conforming to such a standard if one gets traction, as long as it doesn't somehow force suboptimal design in other areas.

I think the big problem is that almost all the SNES music anybody cares about has already been made

I hope you didn't intend that as "Super NES homebrew ought not to exist, and if it does, it ought to be silent."

93143 wrote:

If it isn't, why the push for a standard?

At the bare minimum, so that homebrew SPCs that don't need streaming can fit into a compo cart without the user having to press Reset to switch from one entry to another. If you have ever heard of the NSF composing competition Famicompo Pico, this would prove valuable to the organizers of a hypothetical Super Famicompo.

For a standard to be a standard you need multiple competing parties to agree to follow it, and to make multiple competing parties follow it there A) needs to be multiple competing parties in the first place and B) needs to be a rational incentive for them to follow it. OS developers adhere to POSIX standards (where they do, to the degree that they do) because the benefits of that effort (more familiar environment for users, users more likely to be able to move other systems to theirs) outweigh the disadvantages (development burden, ease with which users can move from their system to others).

You don't really have either A) or B). Very very few people are developing sound engines for the SNES, and they don't really have any incentive to work with you or anyone else on some kind of standard here.

In the case of a compo cart, the organizers can and will need to impose standards on developers (w.r.t. the sound engine and other things technical and non-technical besides), and that would give developers a rational incentive to adhere to them. But if that's only a hypothetical, no one will care.

I think the big problem is that almost all the SNES music anybody cares about has already been made

I hope you didn't intend that as "Super NES homebrew ought not to exist, and if it does, it ought to be silent."

To be blunt, I don't expect SNES homebrew to ever get within an order of magnitude of the combined quantity and quality of the commercial library. There's good SNES music being made, but not a lot of it. Which brings us to the fact that there's already been a fair bit of chiptune work, and even some homebrew, using a handful of tools that I don't imagine conform to a common standard. And in some cases those tools continue to be popular.

The whole idea just seems a little like closing the barn door after the horse has left. I might lack perspective, but that's my feeling right now.

Wouldn't it be just as easy to have the "protocol" on the CPU side instead? Does it need to be in the S-SMP?

i.e. just provide a set of wrapper functions to interface with that game's sound engine on the CPU side, and just put them in a table or whatever's convenient. Call those functions and let the game's engine handle communication with the S-SMP however it likes. More or less like how an NSF rip tends to require a custom INIT stub to figure out how to set up / load a track to play.

I thought about this for an HDMA protocol. The first scanline $2140/$2141 hold the amount of bytes to transfer, and $2142/$2143 hold the spc-ram address. For DSP writes, a certain area of spc-ram stores a table for all the DSP writes. So in order to write to the DSP, do an HDMA fill to that spc-ram address.

just provide a set of wrapper functions to interface with that game's sound engine on the CPU side, and just put them in a table or whatever's convenient. Call those functions and let the game's engine handle communication with the S-SMP however it likes.

So conceptually more like CaitSith2's PSF-based SNSF spec than like "load an SPC and use these commands to communicate with it", except that the wrapper is relocatable code of some sort rather than an entire ROM structure.

rainwarrior wrote:

More or less like how an NSF rip tends to require a custom INIT stub to figure out how to set up / load a track to play.

NSF still defines a protocol that a hardware player can follow:

Start is LDA song_id LDX region_id JSR init_handler

Update is JSR play_handler once every update_periods[region_id] microseconds

Who is online

Users browsing this forum: No registered users and 9 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum