Page 1 of 1

NSF playing

Posted: Tue Jan 09, 2007 11:19 am
by lynxsolaris
I was wondering if someone might be able to shed some light on an issue I'm having. This is my first '''real''' attempt at playing an NSF file from my code. My code runs just fine in Nintendulator but doesn't in FCEUXD. The sound just kinda crackles and makes other beeps. I was wondering if someone out there could run this rom and see if you can see why.

Here is the code.

Here is the rom.

Thanks for your time.

Posted: Tue Jan 09, 2007 12:19 pm
by Disch
I gave the code a once over -- but didn't really debug it. It didn't really play in my emu, either. The song started, but with crackles, unwanted noise, and then silence after a second or so.

Code: Select all

 lda #$ff
 txs

 inx 
 
 sta $2000
 sta $2001
I think you meant LDX, STX. You definately don't want to write unprepped X to the stack pointer, and certainly don't want to write $FF to $2000, $2001.

Code: Select all

 lda #$00
 tax
init_sound:
 lda $4000,X
 inx 
 dey 
 bne init_sound
You can't read $4000 - $4014, they're write only. Did you mean STA? What are you trying to do here anyway? You also have that DEY driving the loop... but you never set Y to anything initially.

Code: Select all

clear_oam1:
 lda $200,X
 lda $300,X
 lda $400,X
 lda $500,X
 lda $600,X
 lda $700,X
 lda $800,X
 inx
 bne clear_oam1
 rts
Again -- I think you meant STA. Mixing up LDA/STA is not a great mistake to make ;P. This is very possibly the major problem in your code.

Also -- $08xx isn't RAM, it's mirrored RAM (it mirrors zero page). Just seemed strange that you would write to it here.

Also, RAM is not OAM (though that's not an error in the code -- you're just calling it the wrong thing). OAM == Sprite RAM ($2004,$4014)


Lastly -- according to the NSF spec, $0F should be written to $4015 by the player before playing the tune. So I would do:

Code: Select all

LDA #$00
STA $4015
LDA #$0F
STA $4015
Before you call the INIT_ADDR to "reset" the sound channels (that will mute them, then restart them -- so they will all be silent, but will still be enabled). I don't know whether or not this makes a difference -- I remember if making a difference in some NSFs though (Castlevania comes to mind) -- as some NSFs never write to $4015.

Posted: Tue Jan 09, 2007 12:27 pm
by lynxsolaris
Hi Disch,


Yeah, I used some old code as a test just to see if I could get some music to play. I probably should just throw that code away and start fresh. I'll give it a shot from the beginning. Just thought it was kinda weird that it actually played in Nintendulator and nothing else.


Thanks.

Edit: wow ... I didn't realize how many mistakes that thing had! I'm trashing it right now!

Posted: Tue Jan 09, 2007 1:12 pm
by Disch
I was really bored -- so I typed this up. In theory this should drive an NSF without doing any PPU work or anything -- although I didn't test it (or even assemble it). But maybe you can use it as a reference? :

Code: Select all

reset:
  sei
  cld

  lda #0
  sta $2000
  sta $2001

  tax
: sta $00,X
  sta $100,X
  sta $200,X
  sta $300,X
  sta $400,X
  sta $500,X
  sta $600,X
  sta $700,X
  inx
  bne :-

  dex  ; X=FF
  txs


  ; clear sound regs

  tax  ; X=00
: sta $4000,X
  inx
  cpx #$14   ; ($4000-4013)
  bne :-

  sta $4015
  lda #$0F
  sta $4015
  lda #$40
  sta $4017


  ; Good to go!
  lda #2   ; 3rd track
  ldx #0   ; ntsc

  jsr INIT_ADDR

  lda #$80
  sta $2000   ; flip on NMIs

loop:
  jmp loop



nmi:
  jsr PLAY_ADDR
  rti

Posted: Tue Jan 09, 2007 1:42 pm
by lynxsolaris
Disch wrote:I was really bored -- so I typed this up. In theory this should drive an NSF without doing any PPU work or anything -- although I didn't test it (or even assemble it). But maybe you can use it as a reference? :

Code: Select all

reset:
  sei
  cld

  lda #0
  sta $2000
  sta $2001

  tax
: sta $00,X
  sta $100,X
  sta $200,X
  sta $300,X
  sta $400,X
  sta $500,X
  sta $600,X
  sta $700,X
  inx
  bne :-

  dex  ; X=FF
  txs


  ; clear sound regs

  tax  ; X=00
: sta $4000,X
  inx
  cpx #$14   ; ($4000-4013)
  bne :-

  sta $4015
  lda #$0F
  sta $4015
  lda #$40
  sta $4017


  ; Good to go!
  lda #2   ; 3rd track
  ldx #0   ; ntsc

  jsr INIT_ADDR

  lda #$80
  sta $2000   ; flip on NMIs

loop:
  jmp loop



nmi:
  jsr PLAY_ADDR
  rti


Thanks! I'm re-writing my stuff now. I'll be glad to use it as a reference.

Posted: Tue Jan 09, 2007 1:42 pm
by Quietust
lynxsolaris wrote:Just thought it was kinda weird that it actually played in Nintendulator and nothing else.
It's probably because Nintendulator initializes RAM to $00 rather than $FF - that alone can cause some very significant differences in code behavior if you're not initializing memory properly (which was most certainly the case here).

Posted: Tue Jan 09, 2007 2:01 pm
by lynxsolaris
Thanks guys. I have it working now.

Disch, thanks for the reference. It was most helpful!