MSU1 Specs

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

MSU1 Specs

Post by nocash »

Are there any complete MSU1 specs? And what does MSU stand for? Mass Storage Unit? Movie Sound Upgrade? Media Something Unnamed?

The best (inofficial) specs I could find are here http://helmet.kafuka.org/msu1.htm - that page does also have a (broken) link to official specs: http://byuu.org/msu1/ and it does have links to several forum threads (which I haven't check if they contain additional specs or scratch notes).

And there are two implemention notes on http://sd2snes.de/blog/ and some notes about transfer rates here: viewtopic.php?p=124578#p124578
EDIT: For transfer rate: byuu said "Needs to be fast enough to read 3.58Mbyte/s" - that isn't possible, or is it?
Fastest way I could think of would be DMA at 2.68Mbyte/s (assuming that the SNES doesn't contain any nasty feature that prevents using port 2000h-2007h for DMA).
Next fastest would be polling by software, which would be 0.51Mbyte/s (when using a 3-cycle load opcode and a 4-cycle store opcode at 3.58MHz).

For the seek times: I understand thdm as so: The audio/data seek busy status flags need to be checked only on initial seeks (when setting a new data address, or when selecting a new track). And there after, programmers can simply expect that data and audio arrives fast enough (even if the hardware is organized in sectors, possibly stored on a fragment filesystem, and possibly sharing the same memory chip for data and audio).

For hardware devrs that would mean that they must use hardware that is fast enough, and do suitable read-ahead caching on sequentially accessed memory chips. And when sharing the same media: give priority to data reads (and drop audio reads in case transfer is slowed down too much by slow SD cards, by read-retries, by filesystem fragmentation).

For "gamename-#.pcm" audio track filenames, I've looked at the Super Road Blaster binary at http://www.dforce3000.de/ it does 122 audio tracks, judging from their filenames, the "#" is supposed to be a unsigned decimal number in range 0..65535, without leading zeroes, ie. "0..9" for first 10 tracks, "10..99" for next 90 tracks, "100..999" for next 900 tracks, and so on.

The "gamename.xml" file - I hope that it's optional to interprete that file. I would prefer to detect MSU1 by presence of the "gamename.msu" data file, and expect the "gamename.sfc" file to contain a valid SNES header at FFxxh (with info about lorom/hirom/sram/etc). One fun caution: d4s does also has a "gamename.sfc" folder, which shouldn't be confused with the "gamename.sfc" file.
hyarion
Posts: 163
Joined: Tue May 05, 2009 6:12 pm
Contact:

Re: MSU1 Specs

Post by hyarion »

Archive.org to the rescue! https://web.archive.org/web/20101210124 ... .org/msu1/

But I'm afraid it doesn't contain the info you are looking for though.

If I remember correctly, the XML file is byuu's way of defining a cartridge in bsnes (instead of parsing often broken headers or relying on a third party database). So it might be non-optional if you want to make a msu enhanced homebrew that should be playable in bsnes, but nothing stops you from detecting it in some other way in your emulator.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: MSU1 Specs

Post by Near »

Don't forget that the SMP audio mute flag has to be cleared, or the SMP won't mix the audio signal from the cartridge line. If this isn't emulated, people will produce MSU hacks that don't run on real hardware.

> And what does MSU stand for?

Media Streaming Unit 1. MSU1 is a play on GSU1.

> EDIT: For transfer rate: byuu said "Needs to be fast enough to read 3.58Mbyte/s" - that isn't possible, or is it?

I keep doing that because the registers are in a FastROM space, but DMA is locked tot 8 clocks/transfer. So yes, max is 2.68MB/s.

> The audio/data seek busy status flags need to be checked only on initial seeks (when setting a new data address, or when selecting a new track). And there after, programmers can simply expect that data and audio arrives fast enough (even if the hardware is organized in sectors, possibly stored on a fragment filesystem, and possibly sharing the same memory chip for data and audio).

Yes. The initial seek should buffer enough audio samples to ensure it can handle any delay, before it allows playback to begin. The same goes for data read commands.

> And when sharing the same media: give priority to data reads (and drop audio reads in case transfer is slowed down too much by slow SD cards, by read-retries, by filesystem fragmentation).

You should ensure the media is fast enough that this never happens. But if you were forced into a corner, it would certainly be preferable to drop audio samples as that can't possibly crash the game like bad data reads could.

> The "gamename.xml" file - I hope that it's optional to interprete that file. I would prefer to detect MSU1 by presence of the "gamename.msu" data file, and expect the "gamename.sfc" file to contain a valid SNES header at FFxxh (with info about lorom/hirom/sram/etc). One fun caution: d4s does also has a "gamename.sfc" folder, which shouldn't be confused with the "gamename.sfc" file.

Yes, gamename.msu is how to detect the presence of the MSU1 with a file-based loader. And the audio filenames were gamename-%u.pcm. %u = 0 is possible, obviously. Modifying the FFxx header would have been too dangerous.

The PCM file format is 44.1KHz 16-bit stereo PCM little endian format. It cuts off the WAV header and replaces it with "MSU1" signature, and then a 4-byte loop point, little endian. This is the sample# (8 + sample*4 = file offset) to loop to. Use zero for normal behavior. There's no loop-end, that's the end of the audio stream. If you have a single WAV file that's bigger than 16GB, then obviously you're going to have a problem if you want a loop point past that boundary. I don't ... expect anyone to ever do that.

The custom header accomplished two goals: 1) no breaks if different MSU implementations supported different WAV formats (compression, sampling rate, etc), and 2) allowed looping audio without forced fade-in/fade-out (although with no tools, it'll take trial and error to cleanly loop a song this way.)

However ... I should say that you can still bypass this, and support 96KHz 24-bit 5.1 surround tracks if you really want. Obviously the real thing couldn't do this, but an emulator could. The actual SNES/MSU1 code doesn't care what format audio is in. The important part is getting the games to work on all emulators and all real hardware, which is what PCM tries to do: set a baseline. If you deviate, people aren't going to be able to use the game anywhere else.

> If I remember correctly, the XML file is byuu's way of defining a cartridge in bsnes (instead of parsing often broken headers or relying on a third party database).

d4s wrote Super Road Blaster right as I was developing game folders. There was a lot of experimentation at the time, so the format changed a bit as he was developing it. XML is not used at all in higan anymore. I use a much lighter weight BML format now, which is like YAML but more lightweight than that as well.

This is where it gets tricky. Currently to play an MSU1 game in higan, it has to be in the game folder format. That will have a manifest.bml. That file names the ROM, RAM, MSU data and audio track filenames. It also tells you where the MSU registers map to. You could actually move them, and also eventually spawn as many MSU instances as you wanted.

I don't expect anyone else to ever support game folders, BML, the ability to remap the entire bus and all special chip addresses based on a markup text file, or the ability to have multiple instances of any special chip in the same game.

So from a base perspective, the format you should distribute an MSU1 game in is:

Code: Select all

game.sfc/
  manifest.bml [optional]
  game.sfc
  game.msu
  game-0.pcm
  game-1.pcm
Since the manifest.bml file names all of the filenames, it's possible to mimic the structure above in higan, thus allowing the same "game.sfc/" folder to load on the sd2snes and higan with no changes.

I need to update my import tool to convert the above to load into higan without the manifest. Similarly, if you can accept importing the above, then you could organize MSU games however you liked. Merge it all into a ZIP archive, into a big flat file, whatever works for you.

And really long-term, I want to make an enhanced importer tool where you can give it a list of AVI / MP3 files, and it'll do the re-encoding and conversion into the .msu data file for you. That would allow MSU downloads to be ten times smaller. You'd input this archive into an importer tool, choose where you want to play the MSU game (sd2snes, higan, or other) and it'd produce output that would work there for you.

I just haven't had the time to get to this.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: MSU1 Specs

Post by tepples »

byuu wrote:The custom header [...] allowed looping audio without forced fade-in/fade-out (although with no tools, it'll take trial and error to cleanly loop a song this way.)
What do you mean by "no tools"? Every decent wave editor, like Audacity and Audition, can play and loop the selected portion of a wave and report the start of the selection as an offset in samples from the start of the file.
The important part is getting the games to work on all emulators and all real hardware, which is what PCM tries to do: set a baseline. If you deviate, people aren't going to be able to use the game anywhere else.
And by now, gigabytes of memory are probably cheaper than a decoder ASIC to put on a cartridge. (Or are they?)
I don't expect anyone else to ever support [...] the ability to have multiple instances of any special chip in the same game.
Unless you're one of those multi-chip NSF composers who thinks "four Namco 163s... 24 channels... fap fap fap". Or for someone who wants multiple music streams to make a rhythm game with vocal tracks (like Frequency, Amplitude, Rock Band Unplugged, or Rock Band Blitz). These would require the ability to start music streams paused in order to keep them synchronized.
And really long-term, I want to make an enhanced importer tool where you can give it a list of AVI / MP3 files, and it'll do the re-encoding and conversion into the .msu data file for you. That would allow MSU downloads to be ten times smaller. You'd input this archive into an importer tool, choose where you want to play the MSU game (sd2snes, higan, or other) and it'd produce output that would work there for you.
Excellent. So sort of like a tool that turns a .iso + a bunch of .ogg files into a .bin + .cue for burning, I guess. Otherwise, someone else would have started distributing games with a shell script/batch file to rebuild the msu/pcm files at install time. But I'd strongly recommend .ogg instead of .mp3 for three reasons:
  • The .mp3 spec is slightly unclear as to the actual encoder delay, unlike Vorbis where the delay is always defined as one MDCT block (and therefore always compensated exactly by the decoder).
  • Vorbis is more efficient with bits at a given subjective quality level. (Opus is even better but may take time to catch on.)
  • Vorbis is royalty-free so Fraunhofer and Technicolor can't sue you. (So is Opus.) This is why a lot of video games for disc-based consoles (and even Nintendo DS in the case of Guitar Hero On Tour) have started using .ogg background music.
AVI files might be even harder. What codec do you plan to use? Do you plan to use FFmpeg to decode them?
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: MSU1 Specs

Post by nocash »

hyarion wrote:Archive.org to the rescue! https://web.archive.org/web/20101210124 ... .org/msu1/
Thanks, I didn't check there yet! Okay that's really brief. One small difference is "d3-d0 = revision (always 1)". Meanwhile "d3" is used as track missing flag, and... I assume "d2-d0" are kept at "always 1", or did that bits already change to another revision number?
byuu wrote:Don't forget that the SMP audio mute flag has to be cleared, or the SMP won't mix the audio signal from the cartridge line. If this isn't emulated, people will produce MSU hacks that don't run on real hardware.
Good that you mention that. I did think about it a few days ago, but then... I did forgot about it again : - )
byuu wrote:This is the sample# (8 + sample*4 = file offset) to loop to.
Good to know. The kafuka.org page declared it as position in samples, too. But I wasn't 100% sure if it meant to do the +8 for skipping the header.

The filenames are a bit unclear to me. So far, I've seen four naming schemes:

Code: Select all

  Regular ROM      Folder (old)       Folder (new)     d4s
  game.sfc         program.rom        game.sfc         game.sfc
  game.msu         msu1.rom           game.msu         game.msu
  game-#.pcm       track-#.pcm        game-#.pcm       game-#.pcm
  game.xml         manifest.xml       manifest.bml     game.xml+manifest.xml
The "Regular" variant looks best to me (emulators would usually allow users to select ".sfc" and ".smc" files and the like, and from point, the emulator would know which files it need to look for (ie. keeping the same name with changed extensions and/or track number appended)). That variant is also more clear on which files belong together.
For the "Folder (new)" variant I can't see why it needs "manifest.xxx" instead of "game.xxx". That could go wrong if somebody moves the files around (like storing more than one game in a single folder). I guess the idea is something like looking for the "manifest" filename when opening a folder? But one could as well look for "foldername.bml", or better just for "*.bml". Or ideally use the "Regular" variant with "game.xml" (or "game.bml" if .xml is now dropped).
The "Folder (old)" variant is using all different filenames, and different extensions (.rom instead .sfc and .msu). It does also forcefully prevent using more than 100 tracks on a filesystem with 8.3 filename length limit. I hope that variant is dropped, and it's not any longer recommended to use that naming scheme! (?)
And finally, the "d4s" variant (as used in Super Road Blaster v1.2) is same as the "Regular" one (with two .xml files, so it would work either as game.xml or manifest.xml - though not as .bml).
byuu wrote:And really long-term, I want to make an enhanced importer tool where you can give it a list of AVI / MP3 files
Don't hurry too much! The idea is making me a bit nervous anyways. Faster download would be nice. Downside is that it'd be more difficult to use that files. Either one would need using a de-conversion tool before use (which may not work on all OSes, or which may require installing compilers if it were released as plain source code...). Or it would need to be implemented directly in emulators (might be difficult even if the OS offers decompression codecs), that sd2snes hardware would probably also be unable to support AVI/MP3 decoding on-chip.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: MSU1 Specs

Post by Near »

> What do you mean by "no tools"? Every decent wave editor, like Audacity and Audition, can play and loop the selected portion of a wave and report the start of the selection as an offset in samples from the start of the file.

I mean they don't work with the MSU1-PCM file format directly.

If you can extract the sample# from your Audacity loop file, and insert it into a PCM file, then that's great.

> And by now, gigabytes of memory are probably cheaper than a decoder ASIC to put on a cartridge. (Or are they?)

Probably. I wanted to keep the hardware design as simple as possible.

> These would require the ability to start music streams paused in order to keep them synchronized.

Merge it all to one audio stream to play. If you need more than one channel, that's outside the scope of what MSU1 wanted to accomplish. (Two streams would have been really nice for voice acting + CD audio, but oh well.)

I could have stuck an amd64 CPU at 2GHz into the MSU1, but then you'd never see a hardware implementation.

> AVI files might be even harder. What codec do you plan to use? Do you plan to use FFmpeg to decode them?

Don't know yet.

> Thanks, I didn't check there yet! Okay that's really brief. One small difference is "d3-d0 = revision (always 1)". Meanwhile "d3" is used as track missing flag, and... I assume "d2-d0" are kept at "always 1", or did that bits already change to another revision number?

He linked you to an older spec version. We added the track missing flag so that you could selectively replace songs instead of being required to replace all or none of them (think of a game ROM hack that let you drop in MP3s to replace the default audio. This'll let you optionally replace any track, but by default only replace some.)

We used d3 for this since it would have always been zero previously.

> For the "Folder (new)" variant I can't see why it needs "manifest.xxx" instead of "game.xxx". That could go wrong if somebody moves the files around (like storing more than one game in a single folder).

The point of game folders is one game = one folder. It's against the design to have two games in the same folder.

The files are supposed to be named: program.rom, save.ram, track-#.pcm (or actual track names, like "01 - Opening.pcm", up to the author.) But the manifest allows you to change them if you want.

> But one could as well look for "foldername.bml", or better just for "*.bml".

You could, I chose not to. game.sfc/game.bml is repetitive, especially for a long title. Renaming the game folder would require renaming the manifest file. Scanning for *.bml would require parsing all files in the folder instead of just doing an if(file::exists({pathname, "manifest.bml"})) call.

> It does also forcefully prevent using more than 100 tracks on a filesystem with 8.3 filename length limit.

I am unable to force myself to care less about that. gamename.sfc doesn't even allow us to name games properly, and you get MAME-style "actraisr.sfc" + "actrsrjp.sfc" nonsense. It's the 21st century now.

> And finally, the "d4s" variant (as used in Super Road Blaster v1.2) is same as the "Regular" one (with two .xml files, so it would work either as game.xml or manifest.xml - though not as .bml).

Go with regular or d4s in your examples, but ignore the XML files, and you'll be good.

> I hope that variant is dropped, and it's not any longer recommended to use that naming scheme!

My rationale for folders and a consistent file naming scheme is here: http://byuu.org/higan/features/game-library/
You certainly don't have to agree with it, and I'm sure you can think of disadvantages to it.
But after a few years of thinking about this, this is what I came up with and decided to do from my end.

I don't think it would be good for an MSU1 author to distribute in my format directly, specifically because nobody else will support it. A conversion tool that I make for my emulator will be needed to import from the base format described above.

> Don't hurry too much! The idea is making me a bit nervous anyways. Faster download would be nice. Downside is that it'd be more difficult to use that files. Either one would need using a de-conversion tool before use (which may not work on all OSes, or which may require installing compilers if it were released as plain source code...). Or it would need to be implemented directly in emulators (might be difficult even if the OS offers decompression codecs), that sd2snes hardware would probably also be unable to support AVI/MP3 decoding on-chip.

Yes, those are all serious concerns. The sd2snes definitely won't be able to decode AVI/MP3 in real-time, so they'd have to be converted by a tool that may not run on esoteric platforms like Haiku.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: MSU1 Specs

Post by tepples »

nocash wrote:Either one would need using a de-conversion tool before use (which may not work on all OSes, or which may require installing compilers if it were released as plain source code...).
Is it really that hard to install build-essential on Debian/Ubuntu/Mint, MinGW+MSYS on Windows, DJGPP on MS-DOS/FreeDOS, or whatever the port of GCC to Haiku is called?
nocash wrote:that sd2snes hardware would probably also be unable to support AVI/MP3 decoding on-chip.
But it might be able to decode an ADPCM flavor, such as BRR (Super NES), VAG (PS1/PS2), or IMA (DS).
byuu wrote:
nocash wrote:It does also forcefully prevent using more than 100 tracks on a filesystem with 8.3 filename length limit.
I am unable to force myself to care less about that.
Long file names on file systems compatible with Windows OS are still patented for a few more years.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: MSU1 Specs

Post by nocash »

byuu wrote:He linked you to an older spec version.
Well, then - is there a newer version? The link seems to be the newest existing version available via wayback machine.
byuu wrote:My rationale for folders and a consistent file naming scheme is here: http://byuu.org/higan/features/game-library/
I don't think it would be good for an MSU1 author to distribute in my format directly, specifically because nobody else will support it.
Okay, yes, I can think of some advantages and disadvantages. And I am puzzled what you are doing there : - )
First you made bsnes as first emulator that could load only .sfc files, but no .smc files.
And now you have higan that can only load .sfc folders, but no .sfc files.
You must really like doing things in unusual ways.
Which is fine. It could make life more difficult though (eg. when wanting to use a romimage on different emulators).

In no$sns, I would really like to get around using .xml or .bml files. Or possibly .hml - just in case you might happen to do something unexpected again : - )
So I would just hope/expect that all files are sharing the same filename (aside from their extensions and "-#" track suffix; without leading zeroes, ie. in the format as used by d4s).
tepples wrote:Is it really that hard to install build-essential on Debian/Ubuntu/Mint, MinGW+MSYS on Windows, DJGPP on MS-DOS/FreeDOS, or whatever the port of GCC to Haiku is called?
To some people, yes. To me it's just that I don't want have a compiler on my computer. And many other people won't even know what the fuck they are supposed to do with something that comes as plain source code.
tepples wrote:But it might be able to decode an ADPCM flavor, such as BRR (Super NES), VAG (PS1/PS2), or IMA (DS).
My concern was that the files should be distributed in a standarized format that is ready-for-use in emulators (or on that sd2snes hardware).
Some people might also dislike lossy compression like OGG/MP3/ADPCM.
Aside from that issue, yes, ADPCM would have the advantage that it could be implemented without too much efforts in emulators & on hardware.
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Re: MSU1 Specs

Post by MottZilla »

Maybe I missed something, what is this about AVIs? Does the SNES have some kind of video signal input like the Audio Input?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: MSU1 Specs

Post by tepples »

Probably for decoding AVIs to tile data that would be included in the main MSU image or something.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: MSU1 Specs

Post by Near »

> Well, then - is there a newer version? The link seems to be the newest existing version available via wayback machine.

There is not.

You are much better at documentation, whereas I usually just rely on source code to document how things work.

> You must really like doing things in unusual ways.

I like doing things in an optimal fashion, without letting backward-compatibility limit me. I wanted to do .sfc files sans headers before any of the coprocessor firmware was ever dumped, and before MSU1 existed. The concept of needing multiple files to play a game hadn't been a problem to consider up to that point. Then I wanted to get perfect per-game mapping, and came up with XML to allow that. Then I actually went about doing that myself because no one else was interested, and realized what a nightmare it'd be to hand-type 2,000 board mappings in XML myself, so I simplified that to BML. I thought about how awkward it was to explain linear/shadow/direct mapping types, and reduced it to a single mask parameter that works much better. Mapping is now a combination of reduce/mask + mirror/size.

It's a continual evolution. I never change things just for the sake of it, but I will break things if I feel it makes the format stronger. The more time passes, the more refined it gets, the less frequent the changes. My cooperative threading library and binary delta patching format have been stable for about three years now, very unlikely they will ever change again.

I have like one small nagging concern on SNES manifest files still, but making a decision on it shouldn't affect existing mappings.

> Which is fine. It could make life more difficult though (eg. when wanting to use a romimage on different emulators).

You can load a zipped SMC image with a copier header prepended, and firmware file stored in the same folder as the ZIP file merged into a single file, and it'll play it in higan.

But yes, if you take the folders out of higan and try and run them elsewhere, you will have to rename things. It's not at all friendly to someone who wants to run multiple emulators at the same time for whatever reason (compatibility is no longer one of those reasons.)

> In no$sns, I would really like to get around using .xml or .bml files. Or possibly .hml - just in case you might happen to do something unexpected again :-)

I think it would be really challenging to support the exact same semantics as higan/BML today. You can remap anything down to one-byte granularity. There's no super-fast way to do that: you need a giant 16MB table to tell you where each address space byte goes to. It's too slow to parse a tree / sub-divided nested granularity chain / etc* for each memory access. It's a big performance hit still. (* I've thought about countless ways to do this, please don't chime in with alternate theories on how to do this unless you test them in an actual emulator [tepples :P])

My big worry is that by only partially supporting it, that the format would 'splinter.' You'd end up with game folders that only work in one emulator, but not the other.

But I would certainly be thrilled if you could pull it off successfully. I'd love for the format to catch on more broadly. I spent a few years begging other SNES emulator authors to work with me on the format, and nobody ever did, so it has been entirely my own design, sadly.

> Probably for decoding AVIs to tile data that would be included in the main MSU image or something.

Right. Chrono Trigger anime opening is a 2MB MPEG, and a 60MB lossless video. Which, guess where that lossless video came from? An MPEG. Even lossless, it's full of MPEG artifacts anyway, because nobody has the uncompressed master except Square.

We can't make the MSU1 play videos like it plays audio, because the SNES doesn't work like that. You'd need a video passthru cable, and yeah ... fuck that. Nobody's making an SNES cart that has a MultiAV-in and MultiAV-out. So this would convert an AVI to the SNES format your game wants, so you can distribute your CT FMV+CD-audio pack as a 40MB download instead of as an 800MB download.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: MSU1 Specs

Post by nocash »

byuu wrote:You are much better at documentation, whereas I usually just rely on source code to document how things work.
Whew, thanks for the flowers : - ) okay, then I am trying to take your source code apart... and write some notes/questions.
One small warning: I've looked at some old bsnes source that I had laying around, so some details might be different in your current source. The msu file I had was dated 25 Jun 2012 (but the source package also included emulator.hpp with date 10 Aug 2012).

Reset - most eye-catching is this:

Code: Select all

void MSU1::reset() {
  create(MSU1::Enter, 44100);
  boot = true;
  mmio.data_offset  = 0;
  mmio.audio_offset = 0;
  mmio.audio_track  = 0;
  mmio.audio_volume = 255;
  mmio.data_busy    = true;
  mmio.audio_busy   = true;
  mmio.audio_repeat = false;
  mmio.audio_play   = false;
  mmio.audio_error  = false;
but there's also this:

Code: Select all

  if(boot == true) {
    boot = false;
    for(unsigned addr = 0x2000; addr <= 0x2007; addr++) mmio_write(addr, 0x00);
I am not sure how that two part are executed in order, and how often (only on coldboot, or also on warmboot). But I guess they are executed shortly after each other as ordered above.
So for example, volume would become ZERO, and busy flags would become FALSE automatically after reset, right?

Floating Point Unit

Code: Select all

    signed lchannel = (double)left  * (double)mmio.audio_volume / 255.0;
    signed rchannel = (double)right * (double)mmio.audio_volume / 255.0;
Is that really a floating point division by 255? That's something cannot be reasonably implemented in hardware (nor in emulators). Integer multiply and shift right 8 steps should do the same thing, and it'd be common to skip the calculation for max volume (ie. let "*255 shr 8" act is if it were "*256 shr 8")

Data Address - the basic idea here is to write 4 bytes to set the 32bit address, with the seek occuring on 4th write. There are some corner cases on "what happens when doing data reads after writing less than 4 address bytes" (which, one shouldn't ever do that). When implementing it same way as in your source code, it should act as so:
The Address Register gets incremented on each data read (so, when initializing address.lsb to zero, one should not expect it to stay at that value) (just mentioning in case somebody has all data stored on 256-byte boundaries, and thinks that it would be faster to rewrite only the upper 3 address bytes).
The filepointer (in the OS) also gets incremented on each data read (so it does usually increment in sync with the incrementing Address Register). The corner case is when somebody changes only the Address Register LSBs: Then Address Register and filepointer will have different values, with reads being done in respect to filepointer... unless you are loading/saving a snapshot: that would reinitialize the filepointer (and make it same as the Address Register value).

Play and Repeat Flags these flags exist in both Status and Control register. From the docs it wasn't quite clear to me if they have different meanings. But from the source code: Status.Play/Repeat values are identical to Control.Play/Repeat values. Aside from writing to control register, they are also manipulated automatically upon some events:
Reset: Play=0, Repeat=0
Selecting a new Track: Play=0, Repeat=0
Reaching end of Track: If Repeat=0 then Play=0
If "file not open": Play=0 (that case... appears to be same or similar the track not found error)

Busy Flags easiest case would be to have them set to 0=Ready all the time (assuming that either the hardware fast enough, or simply pausing the emulation when it isn't). If that works well, then I'll just do it that way. Looks as if you have implemented it as so, too (aside from busy bits being initiallly/temporarily set on reset).
Btw. worst case for audio seek that I could think of is this: Running the .sfc file from a compressed .zip or .7z file (which also contains compressed tracks). I'll probably not implement that case as it's slightly more difficult to decompress multiple files (and supporting that isn't needed for normal single-file SNES rom-images).
But if were supported, in a on-the-fly fashion (=decompressing a new track when needed) then it may cause huge 'seek' times.
For .7z files it may take several minutes (as it would need to decompress all preceeding files in the .7z archive).
For .zip files it may take a few seconds (as it would only need to skip the preceeding files in the .zip archive).
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Re: MSU1 Specs

Post by Near »

Thanks for the notes! Always fun to see what others can pick out that you just don't catch yourself.

I should hire you to review all of my source =)

> Whew, thanks for the flowers

Not sure what that means, but it was a compliment from me at any rate.

> but there's also this:

Actually, I'm not sure why that is there, either. I probably used that for initialization before setting each variable by hand, and forgot to remove it. It does have a nasty instance of initializing the data/audio ready states. Pretend it's not there for your implementation, I'll remove it on my end.

Code: Select all

  mmio.data_offset  = 0;
  mmio.audio_offset = 0;
  mmio.audio_track  = 0;
  mmio.audio_volume = 255;
  mmio.data_busy    = true;
  mmio.audio_busy   = true;
  mmio.audio_repeat = false;
  mmio.audio_play   = false;
  mmio.audio_error  = false;
That's the correct initialization state as intended.

> Is that really a floating point division by 255?

Yes, that's really what it is.

> That's something cannot be reasonably implemented in hardware (nor in emulators)

Hardware, fine. And yet I did it in my emulator, quite reasonably with / 255.0

Anyway, no reason to over-analyze here. 255 = 100% volume, 0 = muted. Use whichever micro-optimization you like. Nobody is going to notice a sample difference of +/-1 on a 16-bit sample.

(sorry to be crabby about that :P I know, bit-perfect emulation and all that. For some reason, I always hate doing floating-point in fixed-point.)

> The corner case is when somebody changes only the Address Register LSBs: Then Address Register and filepointer will have different values, with reads being done in respect to filepointer... unless you are loading/saving a snapshot: that would reinitialize the filepointer (and make it same as the Address Register value).

Good catch. Yes that would be one hell of an edge case, but possible. I should serialize the file offset separately from the MMIO register value. You need to keep two copies for this to work. One raw file offset, one MMIO register that is dumped into the file offset on 2003 write.

> Busy Flags easiest case would be to have them set to 0=Ready all the time (assuming that either the hardware fast enough, or simply pausing the emulation when it isn't). If that works well, then I'll just do it that way. Looks as if you have implemented it as so, too (aside from busy bits being initiallly/temporarily set on reset).

It's better to emulate a slight "seek delay", so that people don't write homebrew that expects the device to be immediately ready. That will force them to wait for the busy flags to clear. I need to test my sd2snes to get a good feel for its average delay time, and copy it. Haven't gotten around to it yet.

> But if were supported, in a on-the-fly fashion (=decompressing a new track when needed) then it may cause huge 'seek' times.

Well, you're an emulator. You can cheat and pretend that any long operation occurs instantly. Like we all did for DSP coprocessor functions prior to firmware being dumped and emulated.

But yeah, you probably want to keep it reasonable, and decompressing a 60MB PCM file from an archive will be a big performance hit for a real-time emulation.

Given MSU1 is new, people aren't in the habit of expecting MSU1 games to run inside ZIP archives, so I don't think people will complain too bitterly about it.

But if you really want to do that some day ... as you said, 7-zip is right out thanks to solid archives. But it should be possible to stream-decompress ZIP if you write your own deflate implementation that works in chunks. I think, anyway ... correct me if I'm wrong and you have to decode the entire file at once.
qwertymodo
Posts: 775
Joined: Mon Jul 02, 2012 7:46 am

Re: MSU1 Specs

Post by qwertymodo »

byuu wrote:> But if were supported, in a on-the-fly fashion (=decompressing a new track when needed) then it may cause huge 'seek' times.

Well, you're an emulator. You can cheat and pretend that any long operation occurs instantly. Like we all did for DSP coprocessor functions prior to firmware being dumped and emulated.

But yeah, you probably want to keep it reasonable, and decompressing a 60MB PCM file from an archive will be a big performance hit for a real-time emulation.

Given MSU1 is new, people aren't in the habit of expecting MSU1 games to run inside ZIP archives, so I don't think people will complain too bitterly about it.

But if you really want to do that some day ... as you said, 7-zip is right out thanks to solid archives. But it should be possible to stream-decompress ZIP if you write your own deflate implementation that works in chunks. I think, anyway ... correct me if I'm wrong and you have to decode the entire file at once.
IIRC, solid compression is optional in 7-zip
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: MSU1 Specs

Post by tepples »

But if you turn off solid compression, don't you lose so much ratio that you might as well use .zip for the sake of wider compatibility?
Post Reply