Here we'll explore other methods of controlling the sound engine. Since Borgman has a Music Trigger, there would normally not be much motivation to investigate other methods. However, this is a good opportunity to explore alternative solutions.

Pause Hack

This being a master system game, the pause hack (and here)is a way to trigger music when there is no trigger available. When the pause button on the master system is pressed, code at rom location [$66] is executed, meaning you can put whatever you like there. Normally the value is loaded into the accumulator a before calling the sound function. Codes for loading values into a register are followed by a call (CD) to the sound function address followed by the infinite loop code which freezes all game functions besides the music, which continues to play, and which can be accessed.

Common value for loading the 8 bit registers are $06, 0E, 16, 1E, 26, 2E, 3E. The last value is most common and loads the accumulator directly (3E). Sometimes 16 bit registers are loaded instead, but it is less common. Codes here. A lot of pause hacks look like this: 3E (ID) CD (LB) (HB) FB 18 FE. Id is a valid music id i.e. $85 and since code is read in Low Endian order (look it up) a function at 986D (logical address) is actually loaded as 6D 98 (Low Byte-High Byte). That is actually the value of the song loading function for this game, but since the trigger is always being checked (most LoadSong functions run once), it does not provide a valid solution.

Since SEGA games usually load the data into the acumulator, and we know the song ids as well as the trigger location, we will adapt the code slightly from how it is usually used.

  1. Go to the Memory Editor
  2. Select the ROM tab (left of RAM)
  3. Type 66 in the Goto field and press return.
  4. At $66 type 3E 85 32 03 DE FB 18 FE.

It should look like this:

This code says load $85 into a (3E 85), then load a into DE03 (32 LB HB). You can usde DE04, DE05 and DE06 as triggers as well, but the latency will be a little higher (not long enough to notice). You can load Ids from $81-AC, $B3 as you could in the memory trigger by pressing pause (usually spacebar). See Inputs>Configuration...

If we pretend that a trigger does not exist in this case to log a track, you would see if there was a good way to stop the music. Some games do not allow that so you need a slightly different solution. In this case there is a method, so this is what we would do to log a track we want.

  1. Stop the engine. ($00, $80) (You would normally need to look at the game code through a debugger to see how the game stops the music.
  2. Select Save slot (F6,F8)
  3. Save State
  4. Enter the desired ID
  5. Pause MEKA (F12)
  6. Start VGM Log (Alt+V)
  7. Hold Down Start (spacebar)
  8. Unpause MEKA (F12)
  9. Let go of Start the moment you hear the music engine start
  10. Change to frame skip (1/9)(press F2) (Use F4 to speed up if needed)
  11. When you've logged enough, stop the log (Alt+V)
  12. Change to Automatic (60hz) (F2)
  13. Load State
  14. Enter different ID and repeat from 4.

As you can see it is basically the same as the memory trigger method except that you wait until the music has started before you increase the speed of the emulator. This is not strictly necessary as MEKA is good at detecting the input, but it helps avoid user error until you are used to it. Some games disable the pause hack after a period of time, but they are not common. Most of the time you can rely on things remaining predictable.

Title Hack, Options Hack, Location Hack

These are all basically synonyms for one another. They differ from the pause hack only in the sense that they are run from a specific location. You can usually convert a Title Hack (TH), Options (Screen) Hack (OH) or Location Hack to a Pause Hack by noting what function is called immediately after loading the Song ID. In this instance we will do it in reverse since we already know the value loading method and trigger loading method.

Let's look for the trigger in the ROM using the Cheat Finder.

  1. Go to the Cheat Finder (Tools>Cheat Finder)
  2. Select ROM Tab
  3. Select Variable Size 24
  4. Select Constant
  5. In the entry field, type $DE0332 (part of our pause hack in reverse byte order)
  6. We get 7 (8) results, ([68] should be included if you haven't reloaded the rom since the Pause Hack exercise)

Now to see the results.

  1. Go to the Memory Editor
  2. Select the ROM tab if it isn't already selected
  3. Type the first address 973A and press return. You will see the results highlighted.
  4. Look before the highlighted area.
  5. You will see 1A which is a one byte instruction that loads the value of the location pointed to by de into a. ld a,(de) - Most likely it is loading the value at DE04, but this won't serve our purposes.

Since there aren't many results, look up the remaining value (99C0).

The location at $99C0 at first looks promising. A discrete value ($80) is loaded at $99BE into a. Unfortunately, this value is the value that the trigger is reset to each time it is triggered. Changing it will probably not give us what we want. Try changing the value at $99BF to something other than $80 and use the pause hack if you have it available or navigate to the RAM tab of the Memory Editor and look up/change the trigger to see what the effects are of changing the code.

If you have done this, you can see this is not what we want at all. This is probably the only place in the code that reverts the trigger to the expected value against which it is checked. Let's try again.

Since we know from the early results that a loads the value of the location of de (DE04), let's modify the search query in the Cheat Finder slightly.

  1. Go to the Cheat Finder
  2. If the settings have changed, select the ROM, 24, and Constant buttons from their relevant section.
  3. Press Reset Search
  4. Change the DE03 to DE04 so that it reads $DE0432

You will get 106 results. This is not ideal. If there were no other way, we would load the rom into an external hex editor and search the results. This would be time consuming, but might yield results if we were determined.

Fortunately, we have an alternative strategy. Normally the function value is more useful than searching for values loaded into the accumulator, but since we know what works in the pause hack, and have a good idea of how DE04 is loaded based on these results (106 is a lot of references), we will use that as the basis of our next search. We will be entering the value of the pause hack in reverse order starting with the lowest song id $81 and going up ($88 last music id)

  1. Go to the Cheat Finder
  2. Press Reset Search
  3. type $32(ID)3E (reverse of 3E ID 32, ID=$81-88)
  4. Go back to 2 and increase the ID by 1 until you get a result.
  5. You will get a result at $09FD, when you reach $84.
  1. Go to Memory Editor and navigate to 09FD using the ROM tab.
  2. Change the value to something else i.e $85
  3. Reset the system (Ctrl+Backspace)
  4. If the music changes, we have succeeded in finding the Title Hack.

You have succeed in finding the title hack. 09FE would be the value you would add to the appropriate subpage(s) of the Music Engine Control page if a hack was not already listed (memory trigger). If you like, you can continue looking up other values. $84-$88 can be found this way. So can a good amount of sfx $90+. If you wanted to experiment, for fun, you could change the music that loads at different parts of the game, or which sfx are used. It would be a good idea to keep notes of what was where so you could recreate/change your work as desired.

Let's make use of what we know.

  1. Start the debugger (Debug>Enabled or Scroll Lock)
  2. Set the breakpoint at 09FD by typing b x 9fd This will cause the debugger to stop when it reaches the place in rom where the title screen song id is loaded.
  3. Reset MEKA (Ctrl+Backspace)
  4. Press Cont in the debugger. It will stop when it reaches 09FD.
  5. Select Save slot (F6,F8)
  6. Save State

At this point, this save state is provisional. Let's test the Title screen to see how suitable it is for logging other ids. Some title screens do not time out at all and are great for logging. Many do, making them unsuitable without additional work.

You might remember that the title screen times out rather quickly, making it unsuitable for logging. If you preferred, you could instead work with the above instructions and use a Location Hack at the passageway. If you continued to search the values, you would verify that the Passageway music is ID $87 and that it is found at 71F7. In that case set the breakpoint at 71F6 and make the save state when it is triggered. Then set the value at 71F7 to what you like. This game has no options screen so there is not Options Hack for this game. The process is the same for all, so the name of the hack is merely a convention to note where it is used. More complicated hacks may load a 16 bit value, or a 16 bit value into a 16 bit register and an 8 bit value into an 8 bit register before calling the function. The concept remains the same.

For this example, assume that the Passageway location is unsuitable for logging since it's possible to walk right and ruin your log by triggering the message. We will suppose that the Title screen has been determined the best (or least worse) place to log and that it is desirable to find solutions to this problem.

Press Continue on the debugger and watch for anything that looks like a loop.

We're in luck, during the title sequence, there is a loop that executes code from BD5 to BD8 continuously. There is an instruction at BD5 that decreases hl. That looks like it might relate to a timer. Go to the memory editor and type BD5 in the rom window. Select the byte and NOP it (No operation = set to 00).

Does it stop the title screen from proceeding? Indeed it does.

Some cases to ponder:

  1. Does it affect the music at all? No
  2. Does it produce any other odd effects? No

We have had a quick success. In some cases doing something similar speeds up the timer or makes it impossible for the game to transition to other screens. The latter case is where the save game comes in handy, as you have a way of accessing the game after the timer has already successfully progressed through the code until the song id loads.

So as not to stop our inquiry. Let's assume that nopping the instruction at BD5 did not solve our problem. In that case, the instruction at BD2 holds the timer's value (true in this case, although it is loaded once and not set again).

  1. Reload the rom from the Load Rom window.
  2. Press continue until it loads past the Bios (enabled by default).
  3. Load your save state.
  4. NOP out BD2-BD4 using the memory editor.
  5. Press continue

Some cases to ponder:

  1. Does it affect the music at all? No
  2. Does it produce any other odd effects? The timer is slowed down considerably, not stopped. Some songs will not be able to be logged for 2-3 loops length. Not suitable.

Another try. Let's see if we can obtain the breakpoint where $D50E (RAM) is loaded prior to having its contents loaded into hl, which is our timer.

  1. Reload the rom from the Load Rom window.
  2. Press continue until it loads past the Bios (enabled by default). Address will be $0000.
  3. Don't Load State this time, just in case $D50E is loaded before the music ID is.
  4. Type b rw D50E in the debugger window
  5. Press Continue. Hopefully the value will not be written to much before being initialized with a non 00 value. If you continue it will hit our usual breakpoint at 9FD, the next one is what we want at A27.

If you look, you can see hl itself is used to load D50E. Let's change that value.

  1. Go to the memory editor.
  2. Change A24 from $21 80 15 to 21 FF FF.
  3. Reset MEKA
  4. Click continue
  5. If the breakpoint keeps getting triggered frequently, disable it by typing b disable # (where # is the id shown next to the breakpoint in [brackets].

What are the effects? The same as when we nopped out the command at BD2-BD4 in our earlier experiment. In other games, the result might be a very long timer, long enough to log what we want. Of course this is silly, and we are running out of useful elements to teach, though there are other tricks to learn. We could of course have bypassed all this by changing BD2-BD4 to FB 18 FE, which is of course, the infinite loop of the pause hack. As one last experiment try it and see. We could also use the Pause hack in conjunction with the title screen hack by setting Rom[$66] to FB 18 FE, and pressing pause (Spacebar) after the track started.

In general, I avoid the pause hack due to its not always working as expected. I prefer nopping out timers since they have nothing to do with the music engine, and they let the game run as normal.

On last caveat before we wrap up. In our case, some effects are played during the title sequence, emphasizing the computer symbols and calculations. In fact, they are effects, but they are played as part of track $84 and not part of the title sequence.

It works like this:

  1. Play $84
    1. Play $A4
    2. Play $A2
    3. Play $A3
    4. Play $A2

As opposed to:

  1. Load title sequence
    1. Play $84
    2. Play $A4
    3. Play $A2
    4. Play $A3
    5. Play $A2

If it HAD worked the second way, you would have effects playing during other ids and this would have presented another hurdle. It would be necessary to find where the sfx were played in code and either silence them, or prevent the code from reaching them. It would be a judgement call whether to continue or find another place to log.

Ok, back to work. We have confirmed the first method was effective. As before:

  1. Reload the rom from the Load Rom window.
  2. Press continue until it loads past the Bios (enabled by default).
  3. NOP out BD5 using the memory editor.
  4. Load your save state.

By now you should know the drill. Since you're not doing anything to affect the engine other than changing what it plays back, you don't have to worry about getting the sound engine silent.

  1. Go to $9FD in the Memory Editor and change the value at 9FE from $84 to something else (A desired id i.e $85)
  2. Since the debugger has MEKA paused, you have two options:
    1. Leave the debugger open
      1. Start VGM Log (Alt+V)
      2. Click Continue in the debugger (go to 3)
    2. Close the debugger
      1. Pause MEKA (F12)
      2. Load State (F7)
      3. Start VGM Log (Alt+V)
      4. and Unpause (F12) (go to 3)
  3. Change to frame skip (1/9)(press F2) (Use F4 to speed up if needed)
  4. When you've logged enough, stop the log (Alt+V)
  5. Change to Automatic (60hz) (F2)
  6. Load State
  7. Enter different ID and repeat from 2.1 or 2.2

If you're logging from the passageway, change your save state location, and id location accordingly. If desired you could set 3A0C to $80 to disable the scrolling text effect in the message screen and search and find other effects used in the area over which you had no control and disable them.

Congratulations, if you've made it this far. You have successfully navigated some challenging situations and are better prepared for when you work on your own projects. These solutions can be adapted to other cases, and it should be kept in mind, that this process requires some guesswork and intuition. We are looking at indirect code after it has been compiled, so our learning is a bit more indirect than if we had the original source. We are working with what the assembler decided was the best way to get what is essentially a sophisticated counting machine to do what the original program instructions required.

Learning to use the debugger is invaluable. In general, alot of what was done here could have been accomplished much more easily in an emulator like emulicious. I tend to have both emulators open while I work since each has its strengths.

Good luck in your efforts!




Return to top
0.199s