News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: Zelda II Title Music - VRC7  (Read 5997 times)

Ben Boldt

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
    • Fun Projects
Zelda II Title Music - VRC7
« on: May 17, 2020, 07:29:57 pm »
Inspired by this youtube video:

https://www.youtube.com/watch?v=wRCjkFQuMKs

I thought I would try my hand at making this happen in a real NES ROM, and maybe even get it hacked into Zelda II.  Staring by looking at Zelda II, it seems that its title screen music engine runs from a call to ROM address $18000 once per frame, and is controlled by RAM address $EA.  Normal game has its own music engine entry point located at $19000.

Infidelity has hacked Zelda II to run on MMC3 already, so it seems following his changes tweaked to VRC7 should be approachable.

Disch has hacked Final Fantasy I with a FANTASTIC Namco-163 music engine.  So to get things started, I decided to write a music engine similar to Disch's for VRC7.  And here we are with a demo:

https://sites.google.com/site/benboldt2/files/zelda_vrc7_v1.zip

I wrote the score using FCEUx, which sounds considerably different than Mesen.  I am thinking Mesen is probably the more accurate one...  So in this case you will want to use FCEUx to listen to it.  I will tweak it to sound best on a real cart eventually, which would likely to match Mesen.

This supports:
 - Similar music score format as Disch's
 - All Pulse, Triangle, and FM channels supported
 - Playing all notes at all octaves, register values in ROM tables
 - score loops and gotos
 - Envelopes for pulse channels via table
 - Arbitrary length envelopes
 - Envelopes can stop or loop back to an arbitrary index
 - Constant volume for pulse and FM channels
 - Vibrato for pulse channels via table of deltas
 - Vibrato pulse period MSB register update using the sweep trick
 - Vibratos can stop or loop back to an arbitrary index
 - FM sustain enable/disable
 - Pulse duty cycle
 - Main program can start and stop song writing to RAM location $EA
 - Snap-to notes, i.e. new frequency but envelope does not restart (not demonstrated, not found anywhere it sounds good)

Not supported yet:
 - Noise channel (at all)
 - Envelopes for FM channels (could be interesting)
 - Vibrato for Triangle or FM channels (needed)
 - Writing to the FM custom patch (needed)
 - Music scores stored on additional ROM pages, will be necessary if doing multiple songs.

I wanted to share and get some feedback.  I am new to writing 6502 ASM, wondering if my code could be more efficient.  It is a lot of code but only small chunks of it should run at a time.  I made a circular buffer for sending FM commands to the VRC7.  I find that simply checking and updating the buffer provides the necessary delays -- that doesn't say much for how efficient it is.  :S

I think it could be interesting to hack Zelda II with this.  Personally, and I don't mean to offend anyone, I found Zelda II to be flop, with the exception of the title screen.  Is anyone else interested in seeing this happen?  At the very least, I think this is becoming a good FM engine.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Zelda II Title Music - VRC7
« Reply #1 on: May 18, 2020, 02:58:43 pm »
I just want to say I'm always fascinated by these projects of yours and I don't want you to feel like they're going unnoticed.   :thumbsup:

But I also don't have a lot to say about them other than "this is pretty cool" which is why I rarely comment.

The sample ROM you provided sounds great in FCEUX (haven't tried Mesen), but I haven't looked at the code yet (hard for me to find time to do that these days).


Although I do take issue with your dislike of Zelda 2!  Zelda 2 is a great game!

nesrocks

  • Hero Member
  • *****
  • Posts: 685
    • View Profile
    • nesrocks.com
Re: Zelda II Title Music - VRC7
« Reply #2 on: May 18, 2020, 07:04:14 pm »
I don't like the Zelda series, which may be why I think Zelda 2 is my favorite and the only one that I actually enjoy replaying. This sounds like an interesting project!

ultimaweapon

  • Sr. Member
  • ****
  • Posts: 264
    • View Profile
Re: Zelda II Title Music - VRC7
« Reply #3 on: May 19, 2020, 02:19:32 pm »
Once finished, will on be able to use it to replace a song in a rom with another one?
Trust in the Heart of the Cards

Bregalad

  • Hero Member
  • *****
  • Posts: 2751
    • View Profile
Re: Zelda II Title Music - VRC7
« Reply #4 on: May 19, 2020, 04:31:31 pm »
I don't like the Zelda series, which may be why I think Zelda 2 is my favorite and the only one that I actually enjoy replaying. This sounds like an interesting project!
Well just like you I'm not a big fan of the Zelda series (*), but I like Zelda 2 even less than the others. Not that I find any Zelda game bad or unplayable, they're just too hard and not worth the trouble to continue playing past the 1st hour or so for me.

@OP : So you're replacing the entiere music engine to support VRC7 ? Or just extending the existing engine ? Anyway it sounds like a good idea for some games but I don't think Zelda 2 is good enough to deserve such a nice treatment, but it's all up to you naturally.

PolishedTurd

  • Full Member
  • ***
  • Posts: 183
    • View Profile
Re: Zelda II Title Music - VRC7
« Reply #5 on: May 19, 2020, 09:58:43 pm »
This is a cool project. The VRC7 sounds so beautiful to me. I would love it if there were a generalizable way to import an engine and songs into a ROM, even if it requires changing the mapper or expanding the ROM. Especially if the songs could be constructed on a reasonably modern platform.

I haven't played Lagrange Point yet, but I will play it one day, just for the music.

Ben Boldt

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
    • Fun Projects
Re: Zelda II Title Music - VRC7
« Reply #6 on: May 20, 2020, 12:56:16 am »
@OP : So you're replacing the entiere music engine to support VRC7 ? Or just extending the existing engine ?
Once finished, will on be able to use it to replace a song in a rom with another one?

I wrote a whole new music engine, is not extended from the existing one.

Typically music engines in games are 1 self-contained chunk of code that gets run once per frame.  In Zelda II, the code does a JSR $8000 once per frame during the title screen and returns when done doing all the music stuff.  It also uses RAM location $EA to control the music engine.  Writing $01 to $EA starts the title screen music, $80 stops it, and some other values play sound effects as you enter your name, etc.  The music engine resets $EA back to $00 once it uses it, to acknowledge and prepare for the next command.

My code is set up to add a JSR to my code first before the JSR $8000.  So any things that I want my music engine to take control of, it takes the value of $EA and sets it to $00 so that the original music engine doesn't see it.  And if there are things I want the original music engine to still do, I can just leave $EA alone, and let it pass through to the old engine take care of it.  All of this pertains just to the title screen.  Once you get into the game, apparently there is a different music engine at $9000, and it uses RAM addresses slightly differently.  I had planned to do just the title screen and leaving the original sound effects.

Adding this FM engine to an existing game is actually a lot easier than it sounds, at least in most cases.  The first thing you have to do is get the game running with the VRC7 mapper.  You have to find all the places where the original mapper is being written to, and then understand what that is doing, such as changing ROM pages, H/V mirroring, etc.  Then change those bits of code to do the same thing writing to VRC7 registers.  Nesdev wiki has all the info needed for that and emulator debuggers can help find them all.

Once the original game runs on VRC7, you would then expand the ROM.  VRC7 supports up to 512kiB PRG-ROM.  Then in this new extra space, drop in my music engine.  Then it will be only a matter of hooking in a call once per frame to the music engine on the new page (probably in place of the original call to the original music engine), and restoring the original page(s) when returning.

Right now my code has a circular buffer for sending commands to the VRC7 FM registers, and I did this because there are required delays between writing to FM registers.  I find that my buffer is inefficient enough that it defeats its own purpose, and I ought to just do some cycle burns.  But as it is now it does require an additional hook to pull commands out of the buffer.  I plan to make that go away though.

Disch

  • Hero Member
  • *****
  • Posts: 2814
  • NES Junkie
    • View Profile
Re: Zelda II Title Music - VRC7
« Reply #7 on: May 20, 2020, 11:21:37 am »
One of the bigger challenges to dropping a music engine into a new game that wasn't mentioned is looking for RAM conflicts.  The music engine is going to use areas of RAM to keep track of its internal state, and just dropping that into a game will cause problems if the game uses those same areas of RAM for its own stuff.

You'll need to find a chunk of RAM that is unused by the game and make sure that the new music engine confines itself to using that RAM only.


EDIT:  Unless you are talking specifically about Zelda 2 and you wrote this music engine to only use RAM that you know is available in Zelda 2.
« Last Edit: May 20, 2020, 11:31:03 am by Disch »

Bregalad

  • Hero Member
  • *****
  • Posts: 2751
    • View Profile
Re: Zelda II Title Music - VRC7
« Reply #8 on: May 20, 2020, 12:41:56 pm »
Yeah, but if you need to support more sound channel than the original sound engine, it's likely you need some free RAM somewhere. Also it would use more CPU time.

Finally, how do you keep unaltered music and sound effects ? You'd have to support those somehow.

Ben Boldt

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
    • Fun Projects
Re: Zelda II Title Music - VRC7
« Reply #9 on: May 20, 2020, 10:53:07 pm »
I know what you mean about CPU overhead.  The Zelda II overworld has lag just walking around the way it is.  Any little bit extra is destined to be a disaster.  Hopefully the title screen has some spare cycles though, that sounds reasonably possible.

Very good point with the RAM, I forgot all about that.  I am using somewhere on the order of 256 bytes new.  I also used a few bytes on the zero-page which, thinking about it now, I stole from the old music engine so I have bound to screwed something up with that if I plan to use the existing engine for sound effects.  In Zelda II, the title screen music stops when you are able to start using the menu, so a switch-over is possible there, avoiding conflicts I guess.

I am not very experienced hacking existing ROMs like this, so I have probably really understated the amount of work or potential pitfalls that I may soon face.  I can tell you from my experience though that any time someone uses the term "drop-in" (like I did), that's your sign they don't have any clue about what is involved to make that really happen.  :thumbsup:

I just want to get the noise channel working and sound as best as possible, that is my main goal.  A new project can be getting it into the real game.

bogaabogaa

  • Full Member
  • ***
  • Posts: 156
    • View Profile
Re: Zelda II Title Music - VRC7
« Reply #10 on: June 14, 2020, 02:13:48 am »
I have a general question about Nes music engine. There are some people that would like to make music for a game but confronted with the research needed and working it out with writing assembly or raw tracks into a hex editor most people will give up on the task.

There are tools like famitracker that can create tracks and I would imagine it will follow a format for given channels.

I am sure some people did think about making a music engine that can playback tracks made by famitracker. When you have a source that can be assembled with xkas (v14) cross assembler it is easy to patch the RAM locations you need for a given game and yes I am aware that you still might need to tweak some stuff in the game and replace the old music and sound samples.. what sounds like a tone of work too.

So far I did find a source to playback nsf music on a power pack and I did see it uses some trickery to get it to work that would not work on a ROM.

I am just curios if someone here is aware of the difficulties this project could involve? Or know good reasons why not to go for it?


CV ROM DiscordServer
https://discord.gg/PvFgxRg

Ben Boldt

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
    • Fun Projects
Re: Zelda II Title Music - VRC7
« Reply #11 on: June 14, 2020, 02:16:39 pm »
It is pretty much up to each game how it wants to handle its sound code.  It might be messy and scattered around, or it might be nice and organized with very specific entry points.

Most games have an NSF dump, and typically the the NSF contains only the sound-related code and data.  So someone already did the work identifying and isolating the music code/data.  I am not speaking from experience on this, but it might help to see how the NSF correlates to the original ROM, to help understand where the music code and data is and how it is accessed.

Ben Boldt

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
    • Fun Projects
Re: Zelda II Title Music - VRC7
« Reply #12 on: August 31, 2020, 01:12:40 am »
Sort of an update on this, I successfully got this engine running in Tetris:

https://youtu.be/tX-3elRAmbw

I got the "TetrisNESDisasm" Github project compiling which made life much easier for this sort of thing!!

September 03, 2020, 01:11:17 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Another update,

Music start/stop mostly working and original sound effects patched in.  Pretty glitchy but making progress!

https://www.youtube.com/watch?v=SqAf23aCR7Y

Edit:
I kind of like this idea more and more making Tetris VRC7...  I am looking at writing a score for Music-A (i.e. "Dance of the Sugar Plum Fairy" from The Nutcracker Suite).  The original Tetris score definitely is a unique take on this piece, partially due to limitation of sound channels but also some of its own charm that I would be a fool to ignore and replace with something more accurate to The Nutcracker.  It is also in a different key than the real song.  Maybe this was so that it got along better with Music-B and Music C??  Or the sound effects?  It's easy to throw something together but hard to keep its charm with these things.  I could easily make it sound like a generic Windows 95 MIDI file playing for example, but that's not what we would want here.
« Last Edit: September 04, 2020, 02:32:13 pm by Ben Boldt »

Ben Boldt

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
    • Fun Projects
Re: Zelda II Title Music - VRC7
« Reply #13 on: September 12, 2020, 03:23:36 am »
Update:
Getting closer on the Music-A score (Dance of the Sugar Plum Fairy):
https://youtu.be/-6XARnfIZgE

I noticed am intermittently missing a few FM note-off events here and there.  I will need to debug my code and see if I can fix that.  It seems all of my note-on events work, which do also push a note off then note on, so I think maybe my rests have an intermittent problem pushing a note-off.

Except for part of the initialization, this code now has all the necessary delays for VRC7 audio register writes.  I have removed my circular buffer and now I write directly and added cycle burn loops where necessary.  I feel kind of dirty putting cycle burns in there but they are more efficient than that buffer was!

Edit:
I found the bug with note-offs.  I first narrowed it down that it was not a problem with coexiting with Tetris by copy/pasting the music score into my original ROM that has just the gray screen with no game running.  It also had this same bug when run that way.  Additionally, I turned off the pulse channels in the emulator to prove it was not a pulse channel making these sounds.  It was definitely an FM channel.

Once per frame, I parse the next step(s) of the score for each channel.  Some items in the score invoke a delay and exit, such as "play note", "play rest", etc.  The code parses an unlimited number of items until it hits one of these delay-invoking items.

To make things a lot more efficient, I keep the 3 FM registers for each channel in RAM, and I write to the RAM copy while parsing and set a flag.  Then when I complete a delay-invoking item, I check those flags and write only the registers that got touched to the VRC7, one time.  This is especially important to optimize this way because each VRC7 FM register write has delay requirements.  (The code does not keep track if the register stayed the same though, it will write any register that got touched.)

The problem is that I never cleared the flags!  To set the flags, I did an 'INC' to the flag.  I figured I would never have 256 updates before a delay-invoking item so I wasn't too concerned about a rollover.  But since I never cleared these flags, if the update flag ever ended up a 0, the register got its update skipped that time, which tended to affect note-off events the most noticeably.  I heard a few other peculiar things that I didn't quite understand, probably other registers being skipped.  Anyway, very happy to have that fixed.
« Last Edit: September 12, 2020, 01:54:50 pm by Ben Boldt »

Ben Boldt

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
    • Fun Projects
Re: Zelda II Title Music - VRC7
« Reply #14 on: September 24, 2020, 11:47:40 pm »
I got Music-A working pretty well now, and sound effects are now handled properly.  The "fast" version of the music is still original.  Not sure how the normal music stops when you proceed to the 2nd menu screen but my code is not aware of it and not stopping, so that is the only known bug so far.  I had started some work on using the triangle channel in this music, which I think has potential to make it sound more authentic to the original.  For this patch, I disabled the triangle though.

Download patch:
https://sites.google.com/site/benboldt2/files/tetris_vrc7.bps

This is to be applied to "Tetris (U) [!].nes".

Let me know if you like it and would like to see more work done on it.