Page 1 of 1

Playing an NSF in-game

Posted: Wed Sep 13, 2006 2:29 pm
by Roth
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.

Posted: Wed Sep 13, 2006 7:56 pm
by ccovell
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.

Posted: Wed Sep 13, 2006 8:15 pm
by Roth
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.

Posted: Sat Sep 16, 2006 12:29 pm
by No Carrier
Roth wrote:The post you made will be good for any others that may not understand. Thanks.
Yep, thanks for that info!

NC

Posted: Wed Sep 03, 2008 3:14 am
by Laserbeak43
spamming(to track the topic later) :D