Convert MML to assembly for FamiTone

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Convert MML to assembly for FamiTone
by on (#118092)
Hello everyone,

As far as MML goes, I have seen nesmus, and I've seen mck and its relatives. For FamiTone, the admonition is to use FamiTracker.

I've been working on a command-line tool to translate MML to assembly which is compatible with FamiTone. It's written in Lua, and I currently have it under a BSD 2-clause license here. It is a WIP and not ready to use in production, but I'd be happy to have some help with it. :)

Demo:
Code:
$ lua52 famml.lua
Famml! - Convert MML to assembly compatible with NES and FamiTone

   -h  See this help screen
   -o  Redirect output to a file, as opposed to standard output
   -p  Accept input from a pipe

   -a  Load assembler settings from a file (default is ca65)
   -s  Output sfx
   -m  Output music (default)
$ cat foobar
@v0 = {12 1 2 2 3 3}
$ lua52 famml.lua foobar
@v0:    .byte $CC
        .byte $C1
        .byte $C2
        .byte $C2
        .byte $C3
        .byte $C3
        .byte $7F
$ cat foobar | lua52 famml.lua -p
@v0:    .byte $CC
        .byte $C1
        .byte $C2
        .byte $C2
        .byte $C3
        .byte $C3
        .byte $7F
$ cat foobar | lua52 famml.lua -p -o output.s
$ cat output.s
@v0:    .byte $CC
        .byte $C1
        .byte $C2
        .byte $C2
        .byte $C3
        .byte $C3
        .byte $7F


It supports ca65, but all assembly output is in a Lua table, so this is easily expandable to other assemblers. The -a option allows for that, and more assembler output can be added into the code over time.

Currently, I'm only beginning to do the actual assembly output. (I've been fighting with an interactive mode for a couple days, which I decided to throw away.)

Notes:
* I don't like the name all that much. "Famml". Any suggestions?
* Of course, in the demonstration, I'm typing in lua52. On Unix, a quick cp famml.lua famml; chmod +x famml should do the trick just fine.
* AFAIK, it is compatible with Lua 5.0+, and I'm most certainly using it with Lua 5.2. It shouldn't be that difficult to change it so it'll work with previous versions of Lua, if you really must use one of them.
* HALP?

Thank you everybody. :)
Re: Convert MML to assembly for FamiTone
by on (#118099)
Will it support up to one expansion chip? Will you add the * and ? commands like the ones I have implemented in my MML? It looks like it is using too much RAM.
Re: Convert MML to assembly for FamiTone
by on (#118103)
zzo38 wrote:
Will it support up to one expansion chip? Will you add the * and ? commands like the ones I have implemented in my MML?

I don't believe I've seen your program, where is it? :) I'm really doing this to learn more on the subject, and I'm going off the FamiTone docs. From those, I don't know that FamiTone supports an expansion chip, but does it?

And what do the * and ? commands do? I'm learning MML along the way as well.

Quote:
It looks like it is using too much RAM.
What are your requirements? Personally, I'm not so concerned with this. I just want to make it complete. :) (Edit:) I'm seeing an average of 34kb, per collectgarbage("count"). So... All you'll ever need is 64k? :P
Re: Convert MML to assembly for FamiTone
by on (#118107)
Imperial wrote:
zzo38 wrote:
Will it support up to one expansion chip? Will you add the * and ? commands like the ones I have implemented in my MML?

I don't believe I've seen your program, where is it? :) I'm really doing this to learn more on the subject, and I'm going off the FamiTone docs. From those, I don't know that FamiTone supports an expansion chip, but does it?
I don't know much about FamiTone; I am just making suggestions. (ppMCK supports multiple expansions at once, because NSF does, but if you are making a game you must use the expansion audio of the mapper, so only up to one is possible.)

My program is at: http://zzo38computer.org/nes_program/ppmck.zip (it is an enhanced version of ppMCK). (I haven't documented it very well, though.)

Quote:
And what do the * and ? commands do? I'm learning MML along the way as well.
They are commands I made up (they aren't standard and only my own MML implementations include them as far as I know); * defines a macro which is a text replacement at compile-time, and ? is a "track questioning" command for use in macros to act differently on different channels. I do find them very useful for entering chords and sometimes for other things too.

Here is an example:
Code:
*+ ?GK0?HK4?IK7?JK12?.
*- ?GK0?HK3?IK7?JK12?.

GHIJ l2o2 |: *-e *+d :|4 *+c ^16^4. *-e4*+d4 ^8*-e8^4 *+b4


This example defines *+ for major chords and *- for minor chords (K is a transpose command), and then make some music using these chords. Other chords can be defined, too.

Quote:
Quote:
It looks like it is using too much RAM.
What are your requirements? Personally, I'm not so concerned with this. I just want to make it complete. :) (Edit:) I'm seeing an average of 34kb, per collectgarbage("count"). So... All you'll ever need is 64k? :P
I mean the RAM used by the game at runtime; it seems to use most of the zero page, from the documentation you give.

(I did intend to write a program for MML for use with NES/Famicom games (and I don't know whether or not I ever will, although I probably will if I write a game with more sophisticated music than that in Famicom Hangman); however, mine wouldn't be ca65 or FamiTone or Lua or these other things, so what you are doing is still useful and good things to do!)
Re: Convert MML to assembly for FamiTone
by on (#118109)
zzo38 wrote:
My program is at: http://zzo38computer.org/nes_program/ppmck.zip (it is an enhanced version of ppMCK). (I haven't documented it very well, though.)
"You need nkf (Network Kanji Filter) to compile ppmck properly on a un*x system." :?

Quote:
Quote:
And what do the * and ? commands do? I'm learning MML along the way as well.
They are commands I made up (they aren't standard and only my own MML implementations include them as far as I know); * defines a macro which is a text replacement at compile-time, and ? is a "track questioning" command for use in macros to act differently on different channels. I do find them very useful for entering chords and sometimes for other things too.

Here is an example:
Code:
*+ ?GK0?HK4?IK7?JK12?.
*- ?GK0?HK3?IK7?JK12?.

GHIJ l2o2 |: *-e *+d :|4 *+c ^16^4. *-e4*+d4 ^8*-e8^4 *+b4


This example defines *+ for major chords and *- for minor chords (K is a transpose command), and then make some music using these chords. Other chords can be defined, too.
That is interesting. :)

Quote:
I mean the RAM used by the game at runtime; it seems to use most of the zero page, from the documentation you give.
The assembly samples in the code are ripped from the source for Shiru's game, Chase. I don't have an NES or any equipment other than this computer, but it certainly works in the emulator.

Quote:
(I did intend to write a program for MML for use with NES/Famicom games (and I don't know whether or not I ever will, although I probably will if I write a game with more sophisticated music than that in Famicom Hangman); however, mine wouldn't be ca65 or FamiTone or Lua or these other things, so what you are doing is still useful and good things to do!)
:beer: :D Just learning as I go and I hope it is useful for someone. Including me! :p

________________________________________________________________________________________________

I've added a milestone target to the repository. I hate the name "Famml", but I'll keep it until the program gets better. What I'd really like is to keep learning more, and more, and target more systems than merely FamiTone. Just as Famml is expandable to other assemblers besides ca65, it should also be expandable in a similar way for other audio drivers. That way, Famml could become a little more of a general purpose MML-to-assembly translator, and then the name can go away, if it hasn't grown on me yet. :)
Re: Convert MML to assembly for FamiTone
by on (#118111)
FamiTone uses only 7 bytes of ZP and ~180 bytes of a RAM page, the latter could be unused part of the stack page (that's how I use it).
Re: Convert MML to assembly for FamiTone
by on (#118113)
A new name could be NESQuikMMLK (NES Quik MML Konverter)
Re: Convert MML to assembly for FamiTone
by on (#118114)
Shiru wrote:
FamiTone uses only 7 bytes of ZP and ~180 bytes of a RAM page, the latter could be unused part of the stack page (that's how I use it).

Thank you for all of this, Shiru. :) Your article on programming in C for NES and the downloads you released with it opened up a lot for me. I'm not an assembly programmer, but I'm picking up more as I go with all of this. (The "Machine Language for Beginners" book helps a great deal.) This is pretty educational. :)

Hamtaro126 wrote:
A new name could be NESQuikMMLK (NES Quik MML Konverter)
Ha! Well, my wife certainly likes it. :D
Re: Convert MML to assembly for FamiTone
by on (#118115)
Imperial wrote:
Ha! Well, my wife certainly likes it. :D


Y'Welcome!
Re: Convert MML to assembly for FamiTone
by on (#118116)
@zzo38: I managed to compile ppmck. :) I had to tweak a few things, but it works. I also installed kterm to along with it, just because.

EDIT: Without shamelessly bumping the thread, development can now be followed at my blog, as well as the repo on github. Thank you. :)