NSF File Structure

Questions and information regarding the source & NSF driver.
User avatar
SusiKette
Posts: 16
Joined: Fri Jun 23, 2017 5:34 pm
Location: Finland
Contact:

NSF File Structure

Postby SusiKette » Wed Dec 12, 2018 10:09 am

I figured people here would know something about the NSF file. This page has some information about it, but it doesn't explain everything. First off, I know I'm supposed to write the NSF file to the player's ROM space starting from $8000. Does this include the header of the file or only the part starting from $80 in the file? Once the file is written, are the Load, Init and Play addresses in the header the location where they are located in the ROM space? On that note, what exactly is located to those addresses? I have some kind of understanding of the Init and Play parts but the Load part is what I don't understand. The "Loading a tune into RAM" part doesn't seem to mention the address at all.

I only need the player to support NSF files exported from FamiTracker and only support VRC6 and NTSC mode for now. Since I'm working on single-track NSF files I probably don't need to implement bank swapping either. I only plan on implementing mandatory features since it's not intended to support everything. Only the things I need it to support in order to work in my project.
*Please make sure you are using FamiTracker v0.5 when trying to open my ftm files*

YouTube
Twitter

User avatar
MrNorbert1994
Posts: 14
Joined: Thu Jul 30, 2015 10:04 pm

Re: NSF File Structure

Postby MrNorbert1994 » Tue Feb 26, 2019 12:07 pm

"First off, I know I'm supposed to write the NSF file to the player's ROM space starting from $8000."
Well... if you write an NROM based game or let's say an MMC1 game, you can pretty much place you music code wherever you want.
The first $80 bytes are the header so after that is where your program comes from.
Also there is a calculating formula for NSFs if you want to go to a specific address.
For example: $C000
Your program origin comes from $8000.
So: $C000-$8000 = 4000 then add $80 (since header) -> $4080 offset.
"Once the file is written, are the Load, Init and Play addresses in the header the location where they are located in the ROM space?"
The load is usually starts from $8000, but again it depends on what game we are dealing with.
For about 90% it is located in the romspace.
Let's say Mega Man 2-6's PLAY entry point starts from $8000.
However sometimes you have to deal with games that has separated init and play calls for their music and sound effects routine.
Games like Home Alone 2 and Codemasters' games do this.
When this happens you have to write your own code for the play control pointers.
Let's say that Home Alone 2 uses play address $8000 and $8006
You have to write a playroutine code like
03:BD13: AD B6 04 LDA $04B6 = #$00 ;play ram pointer initalization
03:BD16: F0 05 BEQ $BD1D
03:BD18: C6 1D DEC $1D = #$00; Vibrato Enable
03:BD1A: 4C 00 80 JMP $8000 ; MUSIC PLAY
03:BD1D: 4C 06 80 JMP $8006 ; SFX PLAY
03:BD20: 60 RTS
So in situations like this your play in the NSF starts from $BD13 and $BD21 will be the place where you set up the initalization points.
As I said Load is just where you load the code.
For Bankswitching NSFs you ALWAYS have to load from $8000, and you have to do a very creative code placement of where to put your code and how to properly set up banks. (As in every single NSF the bankswitching bytes HAS to be set as: 00 01 02 03 04 05 06 07. Every other NSF that's not set up like bankswitching can be considered as malformated.)
If you are dealing with VRC6, you have to consider that for the NSF's mapper you have to change the $9001 and $9002 reads.


Return to “Source and development”

Who is online

Users browsing this forum: No registered users and 3 guests