bbbradsmith/nsfplay

Bug? : IRQ support in NSF2

Shaw02 opened this issue · 10 comments

Hello.

I have poor English, but I would like to let know us the following phenomenon.
I appreciate it if you could fix the following phenomenon.

Phenomenon:

NSFPlay 2.4 cannot use IRQ on the following condition.

  • 0x05 in NSF Header: 0x02 (NSF Version 2).
  • 0x7C in NSF Header: 0x10 (IRQ Support)

if 0x7C is 0x00, NSFPlay 2.4 can use IRQ.

Background:

NSF2 Header (from https://wiki.nesdev.com/w/index.php/NSF2)

07C 1 BYTE NSF2 feature flags
bits 0-3: reserved, must be 0
bit 4: if set, this NSF may use the IRQ support features

Please refer the mckup263.nsf in this Web site.
http://rophon.music.coocan.jp/mckloda/upload.php

Thank you!

Sorry, I was not able to look at this back when you made the issue. The mckup263.nsf file you mentioned does not seem to be available anymore?

There are some test NSFs for the NSF2 features like IRQ that demonstrate that it works. They have source code which might help understand how to get it working:
https://github.com/bbbradsmith/nes-audio-tests

Good morning.
Thank you for your reply.

I would like to attach the my test nsf file.
⊿PCMIRQ.zip

0x7C in NSF Header: 0x10 (IRQ Support)

With regard to this nsf file, this is NSF version 2 with DPCM IRQ.
0x0005: 0x02
0x007C: 0x00

If I set 0x10 to address 0x007C, I've confirmed that it cannot play D-PCM.
I'm appreciate it if you could confirm this symptom.

image

To use IRQ with NSF2 there are 3 requirements:

  1. Header byte $05 = $02 (Activates NSF2 features.)
  2. Header byte $7C = $10 (bit 4 activates IRQ features.)
  3. During INIT you must store your IRQ vector to $FFFE and $FFFF.

Your program only does 1. To make it work, it must also do 2 and 3.

Part 3 is required because the IRQ vector is actually RAM (this was done for hardware compatibility).

You just need something like this in your INIT:

lda #<IRQ
sta $FFFE
lda #>IRQ
sta $FFFF

I think that is all that is needed here.

More info here: https://www.nesdev.org/wiki/NSF2

Alternatively: if you just want this to play without using the NSF2 specification, there is a compatibility option.

In the settings panel, near the bottom right is "Force IRQ enable" which is compatible with this NSF1 style of IRQ usage.

Thank you for your reply.

  1. Header byte $05 = $02 (Activates NSF2 features.)
  2. Header byte $7C = $10 (bit 4 activates IRQ features.)
  3. During INIT you must store your IRQ vector to $FFFE and $FFFF.

With regard to item 3, vector is already stored in 0xFFFE-FFFF.
To explain, I would like to show the memory viewer with the VirtuaNES.

image

In this condition, If I set the 0x10 to 0x007C, nsfplay can not play D-PCM.
If set the 0x00 to 0x007C, nsfplay can play D-PCM.

I appreciate it if you could this phenomenon and fix.

Thanks and best regards,

NSF2 replaces the IRQ vector, it does not keep what was there underneath. It has to be re-written in INIT.

As said above, the current specification of NSF2 required you to write the IRQ vector in INIT. It does not use what is in the bank underneath, it is separate writable RAM that blocks the ROM bank. (This was not a bug. This is how NSF2 was designed.)

However, I do think this is a good suggestion, so I added this:

066e782

Because the NSF2 value at $FFFE was not specified to be anything, it is OK to change the specification now to say that it will be loaded with the starting contents of the NSF ROM. This should be a backward compatible change.

If you want it to work with current version, add the write to INIT (LDA #<IRQ STA $FFFE LDA #>IRQ STA $FFFF). Otherwise in a future version the existing value will be pre-loaded, and I will update the specification when the future version is ready.

Good morning.
Thank you for your kindly support.

I've fix my startup code, and then I've confirmed that nsfplay2.4 can play Delta-PCM.

6d907fa

Thank you!!!

I have updated the Wiki with the new NSF2 specification for the future version.

https://www.nesdev.org/w/index.php?title=NSF2&curid=892&diff=20073&oldid=20069