How do we add .bin Famitracker music into our prg code?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
How do we add .bin Famitracker music into our prg code?
by on (#112581)
So I'm trying to figure out how to add Famitracker binary music to my prg code but it's not really working even when loading to the load address it specifies.

Any ideas on how to incbin binary Famitracker tunes into prg code?

I attached an NSF I'd like to include in my prg, but I can't figure it out.
\
Thanks!
Re: How do we add .bin Famitracker music into our prg code?
by on (#112583)
Well, I think, it would be better to attach said binary file, instead of NSF.
From what I understand, you want to use a Famitracker music engine in your NES game, right?

Try to compile NSF driver source.

BTW: Which assembler do you use?
Re: How do we add .bin Famitracker music into our prg code?
by on (#112601)
Hello,

I'm trying to do exactly the same thing as iexpress. I wrote small NES ROM in assembly, composed some music in Famitracker, and now I want to play that music within my ROM.

I tries to follow the instructions I found here viewtopic.php?t=2026 and here viewtopic.php?f=10&t=6282 but I could not make it work. Here's what I did:

1) I located the three addresses specified in the NSF header (Load: $A896; Init: $AA55; Play: $AA58).
2) I removed the first 128 bytes of the NSF file.
3) I included the NSF file as follows in my PRG code (I use the Ophis assembler):

Code:
.text nsf
.org $A916
.incbin "no-header.nsf"

.text
.org $C000

reset:
  ; ...RAM initialization...
  jsr $A916 + $0A
loop:
  jmp loop

vblank:
  jsr $AA58
irq:
  rti

.advance $FFFA
.word vblank, reset, irq


No music plays. When I look at the memory using the FCEUX debugger, it looks like the content of no-header.nsf is stored at $C000 and not $A916... I have two questions:

1) Is this a mapper issue? I'm using Mapper #0. I have to admit those things still confuse me a lot. What mapper should I use to play an NSF file?
2) How can I tell which parts of RAM are used by the NSF music engine, and which parts are free for me to use for the rest of my program?

Thanks in advance!
Re: How do we add .bin Famitracker music into our prg code?
by on (#112602)
pmlt wrote:
reset:
; ...RAM initialization...
jsr $A916 + $0A

Why call beginning of file, when you know that you need to call Init?($AA55)

Quote:
No music plays. When I look at the memory using the FCEUX debugger, it looks like the content of no-header.nsf is stored at $C000 and not $A916...

How many PRG banks do you have in header, and are they 16kb or 8 kb banks?
NROM(Mapper #0) comes in 2 variants-16 kb and 32kb. If you use 16kb variant, then $8000-$BFFF gets mirrored to $C000-$FFFF

Quote:
1) Is this a mapper issue? I'm using Mapper #0. I have to admit those things still confuse me a lot. What mapper should I use to play an NSF file?

Any mapper can play music. Unless you use a extra channels. If you do, you have to change mapper.

Quote:
2) How can I tell which parts of RAM are used by the NSF music engine, and which parts are free for me to use for the rest of my program?

Look at RAM. You can also try to set breakcodes at one(or several) APU registers

Since I'm using it too, I'll just tell you:
It seems to be using 16 bytes of ZP,starting at $00 and whole page of $200.
Re: How do we add .bin Famitracker music into our prg code?
by on (#112618)
If LOAD is $A896 why do you have ".org $A916"? And what is "jsr $A916 + $0A"? Also, doesn't .org only set the program counter? You need to place the data at that location, not just set the program counter.

Also, your vblank NMI will never be called unless you turn it on. You want to jsr to INIT and then turn it on by writing to $2000 (see PPU registers).
Re: How do we add .bin Famitracker music into our prg code?
by on (#112621)
Denine wrote:
Quote:
1) Is this a mapper issue? I'm using Mapper #0. I have to admit those things still confuse me a lot. What mapper should I use to play an NSF file?

Any mapper can play music. Unless you use a extra channels. If you do, you have to change mapper

Let's clarify: If it's a non-banked NSF (most commercial ones are), you can use any mapper. If it's a banked NSF, in fact you can't use any mapper directly (I don't think an iNES mapper number has been allocated for the NSF mapper?)
Re: How do we add .bin Famitracker music into our prg code?
by on (#112622)
Also, if you're using Famitracker, a while ago I wrote a guide for using its .bin/asm export: http://famitracker.com/forum/posts.php?id=3681
Re: How do we add .bin Famitracker music into our prg code?
by on (#112647)
Quote:
Why call beginning of file, when you know that you need to call Init?($AA55)

I'm sorry, that was a copy-paste mistake on my part. I do execute "jsr $AA55" for the init phase, and I do enable vblank afterward, but still no music plays.

Quote:
How many PRG banks do you have in header, and are they 16kb or 8 kb banks?
NROM(Mapper #0) comes in 2 variants-16 kb and 32kb. If you use 16kb variant, then $8000-$BFFF gets mirrored to $C000-$FFFF


I use the value $01 as the fifth byte of my iNES header. Does that means I use 16kb variant? What should I put in to use the full range of PRG-ROM?
Re: How do we add .bin Famitracker music into our prg code?
by on (#112686)
Got it working! Here's what worked for me, in case anybody else had the same problem:

First, I had to change the fifth byte of the iNES header to $02 instead of $01 (thanks Denine!)

Second, I had to change my PRG code to the following (so that 0's get forcibly written from $8000 to my load address):
Code:
.org $8000

.advance $A916 ; Write 0's until we reach $A916
.incbin "no-header.nsf"

.advance $C000 ; Write 0's until we reach $C000

reset: 
; Init code...
        ; Disable all graphics.
        lda #$00
        sta $2000
        sta $2001
        ; Init registers for loading the tune
        lda #$00
        ldx #$00
       
        ; Call music init
        jsr $AA55

        ; Enable all graphics
        lda #%10001000
        sta $2000
        lda #%00011110
        sta $2001

        ; Transfer control to the VBLANK routines.
loop:   jmp loop

vblank: jsr $AA58
irq:    rti

.advance $FFFA
.word vblank, reset, irq


Thank you all for your help!