Playing an NSF in-game

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Post Reply
Roth
Posts: 399
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Playing an NSF in-game

Post by Roth » Wed Sep 13, 2006 2:29 pm

Hey all.

I started trying to get a song to play from my nsf. I'm obviously doing something wrong since the song won't play. Here's some snips of what I have:

Code: Select all

.org $c000

thesong:
.incbin "sleuth.nsf"
	rts

... ; vblank, RAM clear, etc.

	jsr sound

... ; code

sound:
	lda #%00011111
	sta $4015
	rts

song1:
	lda #$0
	ldx #$0
	jsr thesong
	lda #%10000000
	sta $2000
	jsr sound
	rts

... ; more code

vblank:  ; Actually is NMI, but I'm following NES101 and he called it Vblank :P
	jsr controller
	jsr sound
When I boot it up in Nintendulator, you can hear the speakers kick on from initializing the sound... but then no music. I'm not quite sure what is wrong. If anyone could help me out as to what I'm doing wrong, I'd appreciate it.

ccovell
Posts: 1006
Joined: Sun Mar 19, 2006 9:44 pm
Location: Japan
Contact:

Post by ccovell » Wed Sep 13, 2006 7:56 pm

This almost seems like a joke. You're joking, right?

So you incbin'ed an NSF and then JSR to it... Taking a look at the header of the NSF shows "NESMxxxxx" which the NES interprets as code and eventually runs into a BRK instruction.

Since I love NSFs and NES music, I'll help you out:

First, look at the header of the NSF, using a hex editor. Write down the bytes stored from 0x08-0x0D in the file. Those are the load address, init address, and play address, respectively (stored in 6502/Intel byte order). Then, using the same hex editor, remove the 128-byte header of the NSF, and save the remaining binary file in the same directory as your ASM code.

Incbin THAT binary file with the same origin ORG... as what the load address was of the NSF. You may have to put your own ASM code at a different location so the music code does not write overtop of it.

In your ASM code, set up two EQUs (constants, whatever) INIT_ADDR, and PLAY_ADDR and set those to the addresses you got from the NSF bytes 0x0A,0x0B and 0x0C,0x0D. Be sure to write it the right way, eg: INIT_ADD EQU $8000

In your ASM code when you set up RAM, etc, you type this in:

Code: Select all

lda #$01   ;or whatever number song you want
jsr INIT_ADDR
and inside your NMI/Vblank routine, you simply do this:

Code: Select all

jsr PLAY_ADDR
There's usually no need for you to set $4015 or anything. Just make sure your ASM code's RAM use doesn't conflict with the NSF's RAM use.

Roth
Posts: 399
Joined: Wed Aug 03, 2005 3:15 pm
Contact:

Post by Roth » Wed Sep 13, 2006 8:15 pm

ccovell wrote:This almost seems like a joke. You're joking, right?
Nope, not joking at all. Very new to this :)

Thanks for your post though. It's running now. I didn't understand how to implement it to play with through reading the header and using it's info without some assistance over AIM... it took a LONG time too. The post you made will be good for any others that may not understand. Thanks.

User avatar
No Carrier
Posts: 290
Joined: Tue Dec 13, 2005 4:19 pm
Location: Gainesville, FL - USA
Contact:

Post by No Carrier » Sat Sep 16, 2006 12:29 pm

Roth wrote:The post you made will be good for any others that may not understand. Thanks.
Yep, thanks for that info!

NC

User avatar
Laserbeak43
Posts: 188
Joined: Fri Sep 21, 2007 4:31 pm
Contact:

Post by Laserbeak43 » Wed Sep 03, 2008 3:14 am

spamming(to track the topic later) :D
Noob sticky!!
Please document this part of the NESdevWiki!! XD
YOU NEED A RETROMACHINESHOP!!

Post Reply