Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /storage/content/49/145849/famitracker.com/public_html/forum/classes/dbHandler.php on line 29 FamiTracker
Login:
Menu:
Post: Author:
FamiTracker > General > Source and development > Driver Interrupt Usage in NSF Export Owner: TYoung79 New post
Page 1 of 1 Sort:  
Driver Interrupt Usage in NSF Export Posted: 2014-01-23 19:34 Reply | Quote
TYoung79



Member for: 3071 days
Status: Offline

#53874
I was using version 0.3.7 of Famitracker, but I am now attempting to use the latest version 0.4.2.

With version 0.3.7, I would export to NSF and use the hack to strip the header from the NSF, then include the resulting file at the load address in my assembler. Init and Play were then jumps to their respective addresses. This worked fine with the driver code that was exported to the NSF that was part of version 0.3.7

With version 0.4.2, this technique does not seem to work. After some digging in my hex editor I notice that the exported driver no longer stops short of the end of the program bank. It goes to the end and stomps on the interrupt vectors. Apparently the driver and export NSF was modified between 0.3.7 and 0.4.2 to stomp on / take over the vectors at the end of the bank. The last 2 bytes of the exported file are the load address in little endian format. These end up stomping on the external IRQ vector. Is this intentional? The NSF wouldn't care, but a hacker trying to use the NSF in a ROM would.

Is there something I can do, so I can continue to get away with the old hack? For now I'll probably go back to the old Famitracker version. Later I may try to get the source driver included in my NES ROMs, rather than using the hack. It would be nice if the hack would still work, to make it easier for me to help beginners with this, and for convenience, if you don't need the interrupt vectors in the sound driver.

Thanks for any info or assistance!

Posted: 2014-01-23 21:57  (Last Edited: 2014-01-23 21:59) Reply | Quote
rainwarrior

Avatar

Member for: 4150 days
Location: Canada
Status: Offline

#53877
How does this stomp anything? If you're creating the ROM you can (and must) place the vectors you need to use in the vector table.

Are you having a problem with bankswitching? If your NSF is too big to run without bankswitching you can't just convert it to a regular NES ROM easily; there is no equivalent mapper that supports the required banking.

Also, this post may help if you want to build it from source: [url=http://famitracker.com/forum/posts.php?id=3681]http://famitracker.com/forum/posts.php?id=3681

Posted: 2014-01-23 22:20 Reply | Quote
TYoung79



Member for: 3071 days
Status: Offline

#53879
The NSF exported from Famitracker sets the Load address back from the end of the first bank. However, looking at what version 0.3.7 spit out, the Load address plus file size for the NSF ends short of the end of the bank (leaving the vector area for a ROM alone). The latest NSF spit out by 0.4.2 goes to the very end, filling up the bank and including the vector space. This is actually conflicting with the vectors and overwriting them when I .incbin the header stripped version of the NSF in NESASM. This is happening with a single track, simple song, that has very little data.

I'll probably just end up building from source.

This issue still produces a valid NSF - it just makes it difficult to hack it to use in your own ROM, with your own vectors.

Posted: 2014-01-23 22:21 Reply | Quote
jsr
Administrator

Avatar

Member for: 5925 days
Location: Sweden
Status: Offline

#53880
There are no changes that I'm aware of that would break things like that, so my guess is bankswitching problems too. Which mapper do you use?

I also strongly recommend building from sources as rainwarrior pointed out, as you'll have better control over things.

_______________________
Programmer and developer
Posted: 2014-01-23 23:16 Reply | Quote
TYoung79



Member for: 3071 days
Status: Offline

#53886
I am not even using bankswitching. Just a simple mapper 0 program for now.

I'm including the stripped NSF in the code like this in NESASM:

.bank 1
.org Music_Load
.incbin "music.nsf"

.org $FFFA
.dw NMI
.dw PRG
.dw 0


I think the stripped NSF fills the bank to BFFF/FFFF (mirrored) with the latest version. The assembler probably skips the vectors since they conflict with data that was already filled previously.

Was there a change to the sound driver that would make it go all the way to the end like that? That's really what I was wondering. That would make it impossible to do this, unless it is valid to delete not only the first 128 bytes (the header) but also the last 6.

This worked with a simple song and mapper 0 ROM in the past. I'm using the same code and building successfully still with version 0.3.7 of Famitracker.

Posted: 2014-01-23 23:19 Reply | Quote
TYoung79



Member for: 3071 days
Status: Offline

#53888
Thanks to both of you for your responses, BTW.. Much appreciated! I agree that building from sources is the best thing to do long term.

Posted: 2014-01-23 23:41 Reply | Quote
jsr
Administrator

Avatar

Member for: 5925 days
Location: Sweden
Status: Offline

#53889
Ok I see. Files are not padded with unused bytes, except when needed between DPCM samples. The file might be too large to fit, in that case it should be safe to remove some bytes and replace with the vectors, at least if you're using samples.

_______________________
Programmer and developer
Posted: 2014-01-24 00:01 Reply | Quote
TYoung79



Member for: 3071 days
Status: Offline

#53890
The strange thing, in looking in WinHex at a bunch of different exported NSFs, done in versions 0.3.7 and 0.4.2, is that if I look at the load address for location of the whole block, I note the following:

Version 0.3.7
Load_Address + NSF Filesize - 128d = BF08

Version 0.4.2
Load_Address + NSF Filesize - 128d = C000

This is just looking at the NSF and where the file will be located, then looking at where it will end with the formulas above, after I strip the header and incbin it into my ROM.

Perhaps there used to be some extra room at the end that isn't there now. Seems like there used to be a spare F8 bytes at the end of the bank, which inadvertently prevented the conflict with the vector table when doing this hack. Technically the NSF is using the vector table address space for what it stores at the tail end.

I'm just letting you know all this as info at this point. I suppose a helpful feature would be the ability to manually specify a load address when exporting to NSF. That may be easier said than done. I'd just subtract off 6 from the value that it wants to use and all jumps and everything would get shifted to match.

Thanks again.

RE: Driver Interrupt Usage in NSF Export Posted: 2014-02-03 00:36 Reply | Quote
TYoung79



Member for: 3071 days
Status: Offline

#54097
I've figured this all out at this point and wanted to post a response for others in the same boat.

Essentially, when you use mapper 0 with a 16 KB PRG-ROM, you have mirroring of $8000 and $C000. This is with the header ".inesprg 1" or similar. The NSF spit out by Famitracker, especially with newer versions, or with DPCM samples, is really designed for a 32 KB PRG-ROM. That is ".inesprg 2" and no mirroring. You have the full 15-bit unique address space from $8000 to $FFFF.

With older versions of Famitracker, if you had no DPCM samples, it just happened to be that the NSF output would fit all in the 16 KB bank and work with ".inesprg 1" (and the mirroring). Once the output of the NSF crosses the 16 KB boundary, the interrupt vectors won't work with 16 KB and mirroring. You all were right about the bank issues, but I'm describing in greater detail to make it clear.

You want to use 2 banks with mapper 0, and have a 32 KB ROM to keep things happy as far as newer versions and/or DPCM samples are concerned. The NSF driver may cross the 16KB boundary, and this is still compatible with hacking the output into a rom if you aren't trying to mirror the interrupt vectors from BFFA-BFFF to FFFA-FFFF. Additionally with DPCM, you will have some unique sample data in the 2nd bank, so you really need to represent the ROM as 32 KB so you aren't stomping on the stuff at $8000 as well.

For the nesasm users out there this means:
.inesprg 2 in the header
.bank 0 .org $8000 for the program code as usual
.bank 1 .org Load_Addr for the NSF as usual
.bank 3 .org $FFFA for the vectors
.bank 4 .org $0000 for the CHR ROM

bank 2 is assumed to contain the DPCM samples. You could perhaps place some code or data in it as space permits, past the end of the samples.

Hopefully this level of detail helps someone in the future.

Page 1 of 1 Sort: