Do it just like the
guide on Zophar's Domain says so. It's easy enough...
The method I use is to first write down each song with a hex number (remember that track 1 is actually 00) prefixed before it.
Example: Dragon Warrior 3 would be like this:
Code:
00-nothing
01-level up
02-ending1
03-castle
04-overworld
05-alefgard
...
Then you rearrange the lines of text.
Example: Let's say you wanted them in this order...Code:
03-castle
04-overworld
05-alefgard
02-ending1
01-level up
(notice that there are less tracks than before!)After you have your new song list, you need to turn it into a simple sequence of hex bytes. If you have a text editor that supports regular expressions
(like TextPad), then great! Replace "\([0-Fa-f]+\)-.*$\n" with "\1 ".
In our example you'll get this nice list of hex numbers: "03 04 05 02 01". You can copy and paste these directly into a hex editor!
Now that you have the new order for all the tracks, you have to add it into the NSF file.
First look at the NSF header, and make sure you make note of these fields:
Code:
0006 1 BYTE Total songs (1=1 song, 2=2 songs, etc)
0007 1 BYTE Starting song (1= 1st song, 2=2nd song, etc)
0008 2 WORD (lo/hi) load address of data (8000-FFFF)
000a 2 WORD (lo/hi) init address of data (8000-FFFF)
Note that the NSF's header is 0x80 bytes long. Also note the byte order for WORD sized fields, it's low then high. So when it says 00 80, it means 0x8000.
In many, many games, the load_address=0x8000, so that makes the math much easier for you.
Example: For Dragon Warrior 3 nsf...
The first 16 bytes look like this: 4E 45 53 4D 1A 01 2B 02 00 80 04 B9 00 80 44 72
You can see that the load_address=0x8000, init_address=0xB904.
Now you need some blank space, you'll be putting the song switching code, followed by the song table itself.
Look for some blank space, usually a field of 00's or FF's.
Example, DW3 contains blank space at 0x3BE0 in the nsf file.
Let's call it new_address.
You need to translate it from a NSF file address to a NES memory address. Subtract 0x80 for the NSF header, then add load_address. (new_address = xxxx - 0x80 + load_address)
Example: 0x3BE0 becomes 0xBB60
Now let's put in the ASM code to select the track. You can just place in hex bytes and fill in the blanks for this, no ASM knowledge needed. The ASM code is 7 bytes long, let's add a 00 for padding to make it 8.
Type this into the hex editor: AA BD __ __ 4C __ __ 00
The blanks are the two addresses, first is the address of the track table, next is the original init_address. Since the 6502 uses little-endian byte order (low byte first, high byte second), you swap your address bytes, so 0x1234 becomes (0x34 0x12).
Fill in the first blank with new_address+8 (in the correct byte order)
Fill in the second blank with the original init_address.
Example for DW3: AA BD 68 BB 4C 04 B9 00
After the 8 bytes are in, just paste in the song table.
Example for DW3: it was 03 04 05 02 01
Now that you have your new code in place, you need to change the NSF header to execute your code instead of the usual init_address. Change the init_address in the NSF header into new_address.
DW3 example, replace 0xB904 (0x04 0xB9) with 0xBB60 (0x60 0xBB)
Then test it out to make sure it works.
You can also change the total number of tracks if you like, and the first track to play. (remember that the first track has 1 added for some reason).