Removing background music from Super Mario Bros. for Twitch

Recently I've decided to do what few have done: complete Super Mario Bros. with no shortcuts. The reasoning behind it is simple. I want to experience the most famous game on the planet, and bring others along for the ride. As a kid I was able to beat the game, but using warp pipes. A warp pipe is a shortcut that lets you skip portions or entire levels. Basically in those younger years I was doing: World 1-1, 1-2 -> Warp to 4-1, 4-2 -> Warp to 8, and beat 8. That was acceptable in those days though. The whole point was to beat it! As an adult though I want to fully appreciate the hard work that Miyamoto and friends put into this classic masterpiece.

So for the past week I've been practicing playing Super Mario Bros. for about an hour, give or take. Once you get going, Mario has this momentum that becomes quite addictive. I recommend you give it a try sometime. My progression has been fairly linear - I used to get stuck on world 3, then 4-2, then 5-3 for awhile, now 6-4. To be honest the balance of levels feels a little off here and there, but that's for another day.

The Journey


One thing I do when I'm playing is have other music playing over the emulator. For awhile, this was tolerable, but it got to the point where I was sick of hearing the mix of my music with the background music of the game. Being a software developer and hobbyist run-of-the-mill ROM hacker, I hopped into #nesdev on irc.efnet.net and began my mission: remove background music from Super Mario Bros.

It's Dangerous To Go Alone Take This Excellent Disassembly of Super Mario Bros.


There was one particular user who was a great help there, alphamul3, and he pointed me to some resources and I was off. The most valuable resource was the entire disassembly of Super Mario Bros., with comments.  Now I have never, ever seen 6502 ("NES") assembly before, but it was awfully similar to that of Z80, which I do have experience with. This disassembly really shows the excellent internal design of SMB. You'll see soon how this was extremely helpful. Great job 1985 Nintendo R&D4 team. Past this point I had no help.

The Execution


First thing was to find anything related to Music. A quick search shows that SMB has different types of Music - most important being Area and Event Music. Bingo! We want to keep Event Music so we still hear Mario jumping, hitting blocks, and the satisfying victory music.

So next we look around for the "entry point" of when the area music is loaded. This turned out to be GetAreaMusic. A quick read of the comments shows that to prevent music from playing, we just have to return from this routine.

So this is what we had:
GetAreaMusic:
             lda OperMode           ;if in title screen mode, leave
             beq ExitGetM
             lda AltEntranceControl ;check for specific alternate mode of entry
             cmp #$02               ;if found, branch without checking starting position
             beq ChkAreaType        ;from area object data header
             ldy #$05               ;select music for pipe intro scene by default
             ... so on and so forth ...
 
And this is what I thought would work...
GetAreaMusic:
             rts                    ;screw all the music code gtfo
             beq ExitGetM
             lda AltEntranceControl      
             ... so on and so forth ...

...Until I tested the modification.

The Debugging


It turns out StarPowerMusic is a type of music that is activated elsewhere in the game's code. Every time it started in-game, it wouldn't stop playing - it'd continue to loop. I wondered how the game knew when stop the music, so I search around the places where the Area Music was being handled and found out about "Silence" Music.

So...armed with the knowledge that I have to activate this Silence Music, I recklessly had the game load it when GetAreaMusic is called. I honestly didn't expect it to work, but what must be happening is after StarPowerMusic is over, it calls GetAreaMusic again, which loads the Silence Music. I could be totally wrong here too. You just have to look at the disassembly to 100% know but there is a lot to look through :)

 You may be wondering though, how did I patch the ROM?

The Victory


There were two approaches I could've taken. One where I re-assemble the entire ROM. The other where I search for data that is hopefully what I'm really looking for, via trial-and-error. I took the latter approach.

Basically I turned the GroundMusic, WaterMusic, etc, identifiers into a "string of hex", searched for it in a hex editor, and found it first try. I then assembled my instructions using this excellent online assembler.

lda $80 ; Load Silence Music (0x80) into register A
sta $fb ; Store register A (Silence Music) into AreaMusicQueue (located at 0xFB in RAM)
rts ; Return from GetAreaMusic

= 0xA980 0x85FB 0x60

And inserted them to completely remove the background music!

Now I can play my regular awesome chiptunes along with Mario's jumps 'n' stuff.

Comments

  1. Dude, I'm so impressed with this. I've been playing around a little with the built in Hex Editor of FCEUX and managed to stop certain notes from playing, but this is the first time I've dealt with Hex in any form really so needless to say it wasn't what I was looking for...

    I'm still unable to apply the knowledge shared from this post to my own game, but I'm wondering if there's any way that you could help me out with getting rid of the Background music at all? It'd be a great help!

    Thanks,
    Mikey

    ReplyDelete
    Replies
    1. If you agree and want to contact me, the best way would be to email MikeyTaylor1998@hotmail.co.uk by the way!

      Delete

Post a Comment

Popular Posts