NES Music Format Spec --------------------- By: Kevin Horton khorton@iquest.net V1.32 - 11/27/1999 Added MMC5 register locations V1.30 - 11/14/1999 Added MMC5 audio bit, added some register info V1.20 - 09/12/1999 VRC and FDS prelim sound info added V1.00 - 05/11/1999 First official NSF specification file This file encompasses a way to transfer NES music data in a small, easy to use format. The basic idea is one rips the music/sound code from an NES game and prepends a small header to the data. A program of some form (6502/sound emulator) then takes the data and loads it into the proper place into the 6502's address space, then inits and plays the tune. Here's an overview of the header: offset # of bytes Function ---------------------------- 0000 5 STRING "NESM",01Ah ; denotes an NES sound format file 0005 1 BYTE Version number (currently 01h) 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) 000c 2 WORD (lo/hi) play address of data (8000-FFFF) 000e 32 STRING The name of the song, null terminated 002e 32 STRING The artist, if known, null terminated 004e 32 STRING The Copyright holder, null terminated 006e 2 WORD (lo/hi) speed, in 1/1000000th sec ticks, NTSC (see text) 0070 8 BYTE Bankswitch Init Values (see text) 0078 2 WORD (lo/hi) speed, in 1/1000000th sec ticks, PAL (see text) 007a 1 BYTE PAL/NTSC bits: bit 0: if clear, this is an NTSC tune bit 0: if set, this is a PAL tune bit 1: if set, this is a dual PAL/NTSC tune bits 2-7: not used. they *must* be 0 007b 1 BYTE Extra Sound Chip Support bit 0: if set, this song uses VRCVI bit 1: if set, this song uses VRCVII bit 2: if set, this song uses FDS Sound bit 3: if set, this song uses MMC5 audio bits 4-7: future expansion: they *must* be 0 007c 4 ---- 4 extra bytes for expansion (must be 00h) 0080 nnn ---- The music program/data follows This may look somewhat familiar; if so that's because this is somewhat sorta of based on the PSID file format for C64 music/sound. Loading a tune into RAM ----------------------- If offsets 0070h to 0077h have 00h in them, then bankswitching is *not* used. If one or more bytes are something other than 00h then bankswitching is used. If bankswitching is used then the load address is still used, but you now use (ADDRESS AND 0FFFh) to determine where on the first bank to load the data. Each bank is 4K in size, and that means there are 8 of them for the entire 08000h-0ffffh range in the 6502's address space. You determine where in memory the data goes by setting bytes 070h thru 077h in the file. These determine the inital bank values that will be used, and hence where the data will be loaded into the address space. Here's an example: METROID.NSF will be used for the following explaination. The file is set up like so: (starting at 070h in the file) 0070: 05 05 05 05 05 05 05 05 - 00 00 00 00 00 00 00 00 0080: ... music data goes here... Since 0070h-0077h are something other than 00h, then we know that this tune uses bankswitching. The load address for the data is specified as 08000h. We take this AND 0fffh and get 0000h, so we will load data in at byte 0 of bank 0, since data is loaded into the banks sequentially starting from bank 0 up until the ROM is fully loaded. Metroid has 6 4K banks in it, numbered 0 through 5. The 6502's address space has 8 4K bankswitchable blocks on it, starting at 08000h-08fffh, 09000h-09fffh, 0a000h-0afffh ... 0f000h-0ffffh. Each one of these is 4K in size, and the current bank is controlled by writes to 05ff8h thru 05fffh, one byte per bank. So, 05ff8h controls the 08000h-08fffh range, 05ff9h controls the 09000h-09fffh range, etc. up to 05fffh which controls the 0f000h-0ffffh range. When the song is loaded into RAM, it is loaded into the banks and not the 6502's address space. Once this is done, then the bank control registers are written to set up the inital bank values. To do this, the value at 0070h in the file is written to 05ff8h, 0071h is written to 05ff9h, etc. all the way to 0077h is written to 05fffh. This is only done once, when the song is loaded. It is not done after the song is loaded between each tune init so make sure that the rip takes this into account (the rip usually will). If the tune was not bankswitched, then it is simply loaded in at the specified load address, until EOF Initalizing a tune ------------------ This is pretty simple. Load the desired song # into the accumulator, minus 1 and set the X register to specify PAL (X=1) or NTSC (X=0). If this is a single standard tune (i.e. PAL *or* NTSC but not both) then the X register contents should not matter. Once the song # and optional PAL/NTSC standard are loaded, simply call the INIT address. Once init is done, it should perform an RTS. Playing a tune -------------- Once the tune has been initalized, it can now be played. To do this, simply call the play address several times a second. How many times per second is determined by offsets 006eh and 006fh in the file. These bytes denote the speed of playback in 1/1000000ths of a second. For the "usual" 60Hz playback rate, set this to 411ah. To generate a differing playback rate, use this formula: 1000000 PBRATE= --------- speed Where PBRATE is the value you stick into 006e/006fh in the file, and speed is the desired speed in hertz. "Proper" way to load the tune ----------------------------- 1) If the tune is bankswitched, go to #3. 2) Load the data into the 6502's address space starting at the specified load address. Go to #4. 3) Load the data into a RAM area, starting at (start_address AND 0fffh). Load the inital bank values into the bank select registers. 4) Tune load is done. "Proper" way to init a tune --------------------------- 1) Clear all RAM at 0000h-07ffh. 2) Init the sound registers by writing 00h to 04000-04013h. 3) Set volume register 04015h to 00fh. 4) Set the accumulator and X registers for the desired song. 5) Call the music init routine. "Proper" way to play a tune --------------------------- 1) Call the play address of the music at periodic intervals determined by the speed words. Which word to use is determined by which mode you are in- PAL or NTSC. Sound Chip Support ------------------ Byte 007bh of the file stores the sound chip flags. If a particular flag is set, those sound registers should be enabled. If the flag is clear, then those registers should be disabled. * VRCVI Uses registers 9000-9002, A000-A002, and B000-B002, write only. Caveats: 1) The above registers are *write only* and must not disrupt music code that happens to be stored there. 2) Major caveat: The A0 and A1 lines are flipped on a few games!! If you rip the music and it sounds all funny, flip around the xxx1 and xxx2 register pairs. (i.e. 9001 and 9002) 9000 and 9003 can be left untouched. I decided to do this since it would make things easier all around, and this means you only will have to change the music code in a very few places (6). Esper2 and Madara will need this change, while Castlevania 3j will not for instance. 3) See my VRCVI.TXT doc for a complete register description. * VRCVII Uses registers 9010 and 9030, write only. Caveats: 1) Same caveat as #1, above. 2) See my VRCVII.TXT doc for a complete register description. * FDS Sound uses registers from 4040 through 408F or thereabouts. Caveats: 1) I don't know much about this system... yet. I will be learning more about it pretty soon, however. I have some FDS "RAM" boxes at my disposal and will be hooking them up to HardNES pretty soon. Note that the above register descriptions can/will be changed. *MMC5 Sound Uses registers 5000-5015, write only. Caveats: 1) Same as #1, above. 2) Generating a proper doc file. Be patient. Caveats ------- 1) The starting song number and maximum song numbers start counting at 1, while the init address of the tune starts counting at 0. To "fix", simply pass the desired song number minus 1 to the init routine. 2) The NTSC speed word is used *only* for NTSC tunes, or dual PAL/NTSC tunes. The PAL speed word is used *only* for PAL tunes, or dual PAL/NTSC tunes. 3) The length of the text in the name, artist, and copyright fields must be 31 characters or less! There has to be at least a single NULL byte (00h) after the text, between fields. 4) If a field is not known (name, artist, copyright) then the field must contain the string "" (without quotes). That's it!