Extra Update: Here's part 3 if you've been here before!
IntroductionHello! In this series of articles, I'm going to document my first foray into the world of SNES romhacking. I have a specific goal in mind that I want to achieve, but it will be easier to show you rather than tell you. Please watch a bit of this and in particular, pay attention to the sound:
That's the game I want to hack. Zelda 3, more popularly known in North America as The Legend of Zelda: A Link to the Past. What I want to do with it is this:
How this is possible requires a brief history lesson. Back in the day, Nintendo worked with Philips and Sony to try and get a CD drive add-on to the SNES. It didn't work out. However, in developing his highly accurate SNES emulator bSNES (now called Higan) a person by the name Byuu implemented a co-processor chip called the MSU-1. The MSU-1 allows for the SNES to, among other things, play CD quality audio. The guy in the video above, as far as I can tell, never released his code for getting the MSU-1 to work with Zelda 3 though, but since I know it's possible, I've decided to attempt to replicate his work myself.
I'm afraid that the basics of assembly are too much for me to go into here (not to mention my own tenuous grasp on them), so instead I'll refer you to some tutorials.
So let's say we have our game's rom file, a hex editor and either the latest version of Higan or an SD2SNES. These are the minimum tools we need to get this show on the road. Now, there's a very nice guide here which tells us roughly what code we need to get the MSU-1 to play audio. I call this the Kawa document, and we'll be referring to it several times in our quest for MSU-1 audio in Zelda 3.
So now we have the code we need to get audio playing. Using the Kawa document, we also note that we need an audio file to play and an XML file. The XML file in the Kawa document says that part of it depends on the ROM. Sadly, I have been unable to find any sort of reference document which states exactly what goes into the XML file. There is a tool called SNESPurify though, which will generate an XML file for us, and then all we need to add is the <msu1> element from the Kawa document's example.
Also mentioned in the Kawa document is that we need a data file, either gamename.msu or msu1.rom. What is in this file? The Kawa document doesn't say exactly and I've been unable to find much in the way of definitive documentation on that either. However, I did manage to find several forum posts which say that the file simply needs to exist, without any data in it, to signal to Higan that the code being executed uses the MSU-1. For the time being, I'm assuming that the empty .msu file is what I need.
Next we'll need some audio to actually play during our game. After a lot of looking around, I decided to use the Zelda Reorchestrated soundtrack for Zelda 3. It's free to download and stream and it's a very nice sounding take on the original soundtrack. It might not be perfect (for example, I haven't checked to see if this soundtrack will loop properly) but it's good enough to get started with. With a quick application of wav2msu tool, we have some valid .pcm files to use.
Now all that's left is inserting the code from the Kawa document into the rom.
Editing the Game
The first thing we need to do is find where the game changes the background music. This is a bit tricky and varies from game to game, but the general bits of it are the same. The SNES SPC-700 is the chip that deals with the sound in your SNES and the way you communicate with it is by reading/writing memory addresses $2140 - $2143. If you follow the code with a debugger you can find where it writes a value to memory and signals a change in music track. Once you have found this point in the code, you've found where you need to hijack the code.
In Zelda 3, for example, at 09F4A6 in RAM (LoROM I think?) we get the code to load value 0B into the accumulator and then store that value to $012C. This plays the fairy theme at the file select. This is the point where we need to hijack the code to play our own MSU-1 fairy theme. There is some unused space in the ROM at 04EC1C where we can write our own function to play our music. So our first step is to jump to a subroutine at that location. We start at 0004F6A6 in the ROM (which is 09F4A6 in LoROM). Together, the LDA and STA there already use 5 bytes, so we have to make sure our own code matches. Here's the code I'm using presently to replace those 5 bytes:
22 1C EC 04The first four bytes are a JSL jump to our unused space in the ROM where we're going to write our function, and the last byte is a NOP in order to not disturb the code around the hijack point.
The next thing to do is to convert the code in the Kawa document to something we can use. Combining code from the section about checking for the MSU-1's presence and the section about playing an audio track, we get this assembly:
LDA $2002 \ Checks the first letter of the MSU IDCompiling that code by hand, we get:
CMP #$53 |it should be 'S' which is hex 53.
BNE #$13 / If it isn't, we skip over the MSU-1 code.
LDA #$FF \ Set the volume to 100%
STA $2006 /
LDA #$01 \ We set the track number to track 1
STA $2004 /
STZ $2005 | The MSU-1 won't play until we set $2005
LDA #$03 \ We set the MSU-1 to play the selected track
STA $2007 / on repeat.
RTL | We return to the hijack point. This is the end of the MSU-1 code.
LDA #$0B \ This code is only hit if we skip over the MSU-1
STA $012C | code. This just plays the normal non-MSU-1 song.
RTL / This is useful if the rom is played on something which doesn't support the MSU-1.
AD 02 20So, we take our hex editor to 00026E1C (04EC1C in LoROM) and start copying that hex in. At this point, assuming that our folder and files are named correctly, we should be able to run the game in Higan or the SD2SNES (or any other emulator that correctly implements the MSU-1 chip for that matter) and be able to hear a nice CD quality musical version of the fairy theme when we reach the file select screen. Except we don't.
C9 53 D0 13 A9 FF 8D 06 20
A9 01 8D 04 20
9C 05 20
A9 03 8D 07 20
6B A9 0B
8D 2C 01
What Goes Wrong1) Higan currently doesn't care for the Kawa document. At the very least it doesn't like .xml files, opting instead for a format called .bml which seems pretty similar, but there still isn't any information I can find about what exactly is supposed to go in there. Just a few scattered example files that people have posted for various games. Even using these examples as a template, I've been unable to get Higan to load my edited game at all. In fact, the only version of the program I've gotten to work with it is bSNES v060! And even then it suffers the same problem as when I try to run it on the SD2SNES...
2) SD2SNES doesn't play the MSU-1 music either! This is especially unfortunate since this is the platform I care about getting this to work on the most. Unfortunately, if Higan's specifications for using the MSU-1 have moved on, then the SD2SNES has been left behind and any new tutorials that will be written for the MSU-1's use in Higan won't apply to the SD2SNES.
3) The SD2SNES apparently doesn't recognize the MSU-1's presence! When I run my code on the SD2SNES, it appears to compare the MSU ID but then it branches and plays the normal music track. I used the bSNES v060 debugger on my patch and noted that the value it was getting from $2002 was in fact not #$53, leading me to believe that I must be doing something wrong in my code because I have other MSU-1 enhanced files that play fine on the SD2SNES. It is just mine that doesn't seem to work. It doesn't help that every example I can find online doesn't seem to do anything different from what I'm already doing.
4) The documentation for this chip is too scarce. I've sifted through every forum thread I can find on google that mentions the MSU-1 looking for some sort of technical information, but rarely have I found anything concrete and the Kawa document is the closest thing I've been able to find to a tutorial on how to use the chip. Also a bit maddening is that many of the resources that are linked point to byuu.org which makes sense since Byuu is the one who made the MSU-1 A Thing. However, back in May of this year, he redesigned and migrated his website and hasn't reposted all the old content yet. After a lot of frustration and thinking, I found that the wayback machine has a cached copy of the MSU-1 article from his site, but unfortunately it doesn't have much that helps me with my above problems.
5) I've posted a thread asking for help on a rom hacking forum, but no one has replied yet. I'm at the point where I'm attempting to post on Byuu's personal forums asking for help, but I really wish I didn't have to bother the people who frequent it since I'm sure they have better things to be doing than helping some stupid newbie. Another roadblock to posting on Byuu's forums is that I need to get my account approved by an administrator which hasn't happened yet despite having signed up a week ago.
ConclusionI'm pretty much at a dead end right now. I would LOVE to be adding the ability for myself (and others) to put a custom soundtrack into Zelda 3 and other games, but I'm finding myself unable even to get a single song to play!
What's the most frustrating though is that I can't figure out what's wrong. I've tried following every example I could find online, but none of them have been able to get this working on either SD2SNES or Higan (or any of the many versions of bSNES I've downloaded).
Unless I can get someone to tell me what I'm doing wrong and nudge me in the right direction, there will never be a part 2 to this series.
Update: Good news! There is a part 2 to this series now! Click here to check it out!